diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libwaitress/waitress.c | 40 | ||||
| -rw-r--r-- | src/libwaitress/waitress.h | 4 | ||||
| -rw-r--r-- | src/main.c | 17 | ||||
| -rw-r--r-- | src/settings.c | 18 | ||||
| -rw-r--r-- | src/settings.h | 2 | 
5 files changed, 30 insertions, 51 deletions
| diff --git a/src/libwaitress/waitress.c b/src/libwaitress/waitress.c index 8bb519a..7082ffd 100644 --- a/src/libwaitress/waitress.c +++ b/src/libwaitress/waitress.c @@ -53,21 +53,11 @@ typedef struct {  	size_t pos;  } WaitressFetchBufCbBuffer_t; -WaitressReturn_t WaitressInit (WaitressHandle_t *waith, const char *caPath) { +void WaitressInit (WaitressHandle_t *waith) {  	assert (waith != NULL);  	memset (waith, 0, sizeof (*waith));  	waith->timeout = 30000; -	if (caPath != NULL) { -		gnutls_certificate_allocate_credentials (&waith->tlsCred); -		if (gnutls_certificate_set_x509_trust_file (waith->tlsCred, caPath, -				GNUTLS_X509_FMT_PEM) <= 0) { -			return WAITRESS_RET_TLS_TRUSTFILE_ERR; -		} -		waith->tlsInitialized = true; -	} - -	return WAITRESS_RET_OK;  }  void WaitressFree (WaitressHandle_t *waith) { @@ -75,9 +65,6 @@ void WaitressFree (WaitressHandle_t *waith) {  	free (waith->url.url);  	free (waith->proxy.url); -	if (waith->tlsInitialized) { -		gnutls_certificate_free_credentials (waith->tlsCred); -	}  	memset (waith, 0, sizeof (*waith));  } @@ -709,22 +696,10 @@ static int WaitressTlsVerify (gnutls_session_t session) {  	waith = gnutls_session_get_ptr (session);  	assert (waith != NULL); -	if (gnutls_certificate_verify_peers2 (session, &status) != GNUTLS_E_SUCCESS) { -		return GNUTLS_E_CERTIFICATE_ERROR; -	} - -	/* don't accept invalid certs */ -	if (status & (GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND | -			GNUTLS_CERT_REVOKED | GNUTLS_CERT_EXPIRED | -			GNUTLS_CERT_NOT_ACTIVATED)) { -		return GNUTLS_E_CERTIFICATE_ERROR; -	} -  	if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) {  		return GNUTLS_E_CERTIFICATE_ERROR;  	} -	/* check hostname */  	if ((certList = gnutls_certificate_get_peers (session,  			&certListSize)) == NULL) {  		return GNUTLS_E_CERTIFICATE_ERROR; @@ -739,7 +714,14 @@ static int WaitressTlsVerify (gnutls_session_t session) {  		return GNUTLS_E_CERTIFICATE_ERROR;  	} -	if (gnutls_x509_crt_check_hostname (cert, waith->url.host) == 0) { +	char fingerprint[20]; +	size_t fingerprintSize = sizeof (fingerprint); +	if (gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1, fingerprint, +			&fingerprintSize) != 0) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	if (memcmp (fingerprint, waith->tlsFingerprint, sizeof (fingerprint)) != 0) {  		return GNUTLS_E_CERTIFICATE_ERROR;  	} @@ -1036,8 +1018,6 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {  	waith->request.write = WaitressOrdinaryWrite;  	if (waith->url.tls) { -		assert (waith->tlsInitialized); -  		waith->request.read = WaitressGnutlsRead;  		waith->request.write = WaitressGnutlsWrite;  		gnutls_init (&waith->request.tlsSession, GNUTLS_CLIENT); @@ -1046,6 +1026,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {  				"PERFORMANCE", &err) != GNUTLS_E_SUCCESS) {  			return WAITRESS_RET_ERR;  		} +		gnutls_certificate_allocate_credentials (&waith->tlsCred);  		if (gnutls_credentials_set (waith->request.tlsSession,  				GNUTLS_CRD_CERTIFICATE,  				waith->tlsCred) != GNUTLS_E_SUCCESS) { @@ -1083,6 +1064,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {  	if (waith->url.tls) {  		gnutls_bye (waith->request.tlsSession, GNUTLS_SHUT_RDWR);  		gnutls_deinit (waith->request.tlsSession); +		gnutls_certificate_free_credentials (waith->tlsCred);  	}  	close (waith->request.sockfd); diff --git a/src/libwaitress/waitress.h b/src/libwaitress/waitress.h index e1cf303..7e4401a 100644 --- a/src/libwaitress/waitress.h +++ b/src/libwaitress/waitress.h @@ -92,8 +92,8 @@ typedef struct {  	void *data;  	WaitressCbReturn_t (*callback) (void *, size_t, void *);  	int timeout; +	const char *tlsFingerprint;  	gnutls_certificate_credentials_t tlsCred; -	bool tlsInitialized;  	/* per-request data */  	struct { @@ -110,7 +110,7 @@ typedef struct {  	} request;  } WaitressHandle_t; -WaitressReturn_t WaitressInit (WaitressHandle_t *, const char *); +void WaitressInit (WaitressHandle_t *);  void WaitressFree (WaitressHandle_t *);  bool WaitressSetProxy (WaitressHandle_t *, const char *);  char *WaitressUrlEncode (const char *); @@ -192,7 +192,7 @@ static void BarMainStartPlayback (BarApp_t *app, pthread_t *playerThread) {  		/* setup player */  		memset (&app->player, 0, sizeof (app->player)); -		WaitressInit (&app->player.waith, NULL); +		WaitressInit (&app->player.waith);  		WaitressSetUrl (&app->player.waith, app->playlist->audioUrl);  		/* set up global proxy, player is NULLed on songfinish */ @@ -328,7 +328,6 @@ int main (int argc, char **argv) {  	static BarApp_t app;  	/* terminal attributes _before_ we started messing around with ~ECHO */  	struct termios termOrig; -	WaitressReturn_t wRet;  	memset (&app, 0, sizeof (app)); @@ -355,19 +354,10 @@ int main (int argc, char **argv) {  				app.settings.keys[BAR_KS_HELP]);  	} -	if ((wRet = WaitressInit (&app.waith, app.settings.tlsCaPath)) != WAITRESS_RET_OK) { -		if (wRet == WAITRESS_RET_TLS_TRUSTFILE_ERR) { -			BarUiMsg (&app.settings, MSG_ERR, "Can't load root certificates. " -					"Please check the tls_ca_path setting in your config file.\n"); -		} else { -			BarUiMsg (&app.settings, MSG_ERR, "Can't initialize HTTP library: " -					"%s\n", WaitressErrorToStr (wRet)); -		} -		goto die; -	} - +	WaitressInit (&app.waith);  	app.waith.url.host = strdup (PIANO_RPC_HOST);  	app.waith.url.tls = true; +	app.waith.tlsFingerprint = app.settings.tlsFingerprint;  	/* init fds */  	FD_ZERO(&app.input.set); @@ -388,7 +378,6 @@ int main (int argc, char **argv) {  	BarMainLoop (&app); -die:  	if (app.input.fds[1] != -1) {  		close (app.input.fds[1]);  	} diff --git a/src/settings.c b/src/settings.c index f29fcfa..ee332cc 100644 --- a/src/settings.c +++ b/src/settings.c @@ -93,7 +93,6 @@ void BarSettingsDestroy (BarSettings_t *settings) {  	free (settings->npStationFormat);  	free (settings->listSongFormat);  	free (settings->fifo); -	free (settings->tlsCaPath);  	for (size_t i = 0; i < MSG_COUNT; i++) {  		free (settings->msgFormat[i].prefix);  		free (settings->msgFormat[i].postfix); @@ -132,7 +131,9 @@ void BarSettingsRead (BarSettings_t *settings) {  	settings->listSongFormat = strdup ("%i) %a - %t%r");  	settings->fifo = malloc (PATH_MAX * sizeof (*settings->fifo));  	BarGetXdgConfigDir (PACKAGE "/ctl", settings->fifo, PATH_MAX); -	settings->tlsCaPath = strdup ("/etc/ssl/certs/ca-certificates.crt"); +	memcpy (settings->tlsFingerprint, "\xD9\x98\x0B\xA2\xCC\x0F\x97\xBB" +			"\x03\x82\x2C\x62\x11\xEA\xEA\x4A\x06\xEE\xF4\x27", +			sizeof (settings->tlsFingerprint));  	settings->msgFormat[MSG_NONE].prefix = NULL;  	settings->msgFormat[MSG_NONE].postfix = NULL; @@ -241,9 +242,16 @@ void BarSettingsRead (BarSettings_t *settings) {  		} else if (streq ("fifo", key)) {  			free (settings->fifo);  			settings->fifo = strdup (val); -		} else if (streq ("tls_ca_path", key)) { -			free (settings->tlsCaPath); -			settings->tlsCaPath = strdup (val); +		} else if (streq ("tls_fingerprint", key)) { +			/* expects 40 byte hex-encoded sha1 */ +			if (strlen (val) == 40) { +				for (size_t i = 0; i < 20; i++) { +					char hex[3]; +					memcpy (hex, &val[i*2], 2); +					hex[2] = '\0'; +					settings->tlsFingerprint[i] = strtol (hex, NULL, 16); +				} +			}  		} else if (strncmp (formatMsgPrefix, key,  				strlen (formatMsgPrefix)) == 0) {  			static const char *mapping[] = {"none", "info", "nowplaying", diff --git a/src/settings.h b/src/settings.h index 6cb4cb2..8ce1225 100644 --- a/src/settings.h +++ b/src/settings.h @@ -96,7 +96,7 @@ typedef struct {  	char *npStationFormat;  	char *listSongFormat;  	char *fifo; -	char *tlsCaPath; +	char tlsFingerprint[20];  	BarMsgFormatStr_t msgFormat[MSG_COUNT];  } BarSettings_t; | 
