Index: files/a0e4f1e0f5989505f4aab10d64194b635f9af53c.diff
===================================================================
--- files/a0e4f1e0f5989505f4aab10d64194b635f9af53c.diff	(revision 0)
+++ files/a0e4f1e0f5989505f4aab10d64194b635f9af53c.diff	(revision 0)
@@ -0,0 +1,247 @@
+diff --git a/contrib/pianobar.1 b/contrib/pianobar.1
+index dbff073..c5d3347 100644
+--- a/contrib/pianobar.1
++++ b/contrib/pianobar.1
+@@ -282,9 +282,8 @@ sorts by name from a to z, quickmix_01_name_za by type (quickmix at the
+ bottom) and name from z to a.
+ 
+ .TP
+-.B tls_ca_path = /etc/ssl/certs/ca-certificates.crt
+-File that contains the root certificate (and possibly intermediate
+-certificates) of Pandora’s CA.
++.B tls_fingerprint = D9980BA2CC0F97BB03822C6211EAEA4A06EEF427
++Hex-encoded SHA1 fingerprint of Pandora’s TLS certificate.
+ 
+ .TP
+ .B user = your@user.name
+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 *);
+diff --git a/src/main.c b/src/main.c
+index e14a88a..afa75da 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -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;
+ 
Index: Portfile
===================================================================
--- Portfile	(revision 87136)
+++ Portfile	(working copy)
@@ -4,12 +4,12 @@
 PortSystem                  1.0
 
 name                        pianobar
-version                     2011.09.22
+version                     2011.11.11
 categories                  audio
 platforms                   darwin
 maintainers                 gmail.com:aguynamedryan+pianobar
-homepage                    http://6xq.net/html/00/17.html
-master_sites                http://6xq.net/media/00/16/ 
+homepage                    http://6xq.net/projects/pianobar/
+master_sites                http://6xq.net/static/projects/pianobar/
 use_bzip2                   yes 
 
 description                 Console-based pandora.com player
@@ -24,11 +24,15 @@
 
 depends_lib                 port:libao \
                             port:faad2 \
-                            port:libmad
+                            port:libmad \
+                            port:gnutls
 
-checksums                   sha256  6e54d4881e7ada6b0443611b0853215e9e54253667a58310d96dfe38be258ed3 \
-                            rmd160  d69c4a94c59613fa6ca3e8ce2d9a6fe0878674a5
+checksums                   sha256  c1f5df7813b543992b79ac1558d27ff3fb0198f7bfb2d5d2e39173df4fae951b \
+                            rmd160  e2627ccf8a6423711494e91316504b14f5e4a7bd
 
+patch.pre_args              -p1
+patchfiles                  a0e4f1e0f5989505f4aab10d64194b635f9af53c.diff
+
 use_configure               no
 
 variant universal {}
