Ticket #32027: pianobar-2011.11.11.diff

File pianobar-2011.11.11.diff, 10.3 KB (added by ryandesign (Ryan Carsten Schmidt), 12 years ago)

revised patch

  • files/a0e4f1e0f5989505f4aab10d64194b635f9af53c.diff

     
     1diff --git a/contrib/pianobar.1 b/contrib/pianobar.1
     2index dbff073..c5d3347 100644
     3--- a/contrib/pianobar.1
     4+++ b/contrib/pianobar.1
     5@@ -282,9 +282,8 @@ sorts by name from a to z, quickmix_01_name_za by type (quickmix at the
     6 bottom) and name from z to a.
     7 
     8 .TP
     9-.B tls_ca_path = /etc/ssl/certs/ca-certificates.crt
     10-File that contains the root certificate (and possibly intermediate
     11-certificates) of Pandora’s CA.
     12+.B tls_fingerprint = D9980BA2CC0F97BB03822C6211EAEA4A06EEF427
     13+Hex-encoded SHA1 fingerprint of Pandora’s TLS certificate.
     14 
     15 .TP
     16 .B user = your@user.name
     17diff --git a/src/libwaitress/waitress.c b/src/libwaitress/waitress.c
     18index 8bb519a..7082ffd 100644
     19--- a/src/libwaitress/waitress.c
     20+++ b/src/libwaitress/waitress.c
     21@@ -53,21 +53,11 @@ typedef struct {
     22        size_t pos;
     23 } WaitressFetchBufCbBuffer_t;
     24 
     25-WaitressReturn_t WaitressInit (WaitressHandle_t *waith, const char *caPath) {
     26+void WaitressInit (WaitressHandle_t *waith) {
     27        assert (waith != NULL);
     28 
     29        memset (waith, 0, sizeof (*waith));
     30        waith->timeout = 30000;
     31-       if (caPath != NULL) {
     32-               gnutls_certificate_allocate_credentials (&waith->tlsCred);
     33-               if (gnutls_certificate_set_x509_trust_file (waith->tlsCred, caPath,
     34-                               GNUTLS_X509_FMT_PEM) <= 0) {
     35-                       return WAITRESS_RET_TLS_TRUSTFILE_ERR;
     36-               }
     37-               waith->tlsInitialized = true;
     38-       }
     39-
     40-       return WAITRESS_RET_OK;
     41 }
     42 
     43 void WaitressFree (WaitressHandle_t *waith) {
     44@@ -75,9 +65,6 @@ void WaitressFree (WaitressHandle_t *waith) {
     45 
     46        free (waith->url.url);
     47        free (waith->proxy.url);
     48-       if (waith->tlsInitialized) {
     49-               gnutls_certificate_free_credentials (waith->tlsCred);
     50-       }
     51        memset (waith, 0, sizeof (*waith));
     52 }
     53 
     54@@ -709,22 +696,10 @@ static int WaitressTlsVerify (gnutls_session_t session) {
     55        waith = gnutls_session_get_ptr (session);
     56        assert (waith != NULL);
     57 
     58-       if (gnutls_certificate_verify_peers2 (session, &status) != GNUTLS_E_SUCCESS) {
     59-               return GNUTLS_E_CERTIFICATE_ERROR;
     60-       }
     61-
     62-       /* don't accept invalid certs */
     63-       if (status & (GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND |
     64-                       GNUTLS_CERT_REVOKED | GNUTLS_CERT_EXPIRED |
     65-                       GNUTLS_CERT_NOT_ACTIVATED)) {
     66-               return GNUTLS_E_CERTIFICATE_ERROR;
     67-       }
     68-
     69        if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) {
     70                return GNUTLS_E_CERTIFICATE_ERROR;
     71        }
     72 
     73-       /* check hostname */
     74        if ((certList = gnutls_certificate_get_peers (session,
     75                        &certListSize)) == NULL) {
     76                return GNUTLS_E_CERTIFICATE_ERROR;
     77@@ -739,7 +714,14 @@ static int WaitressTlsVerify (gnutls_session_t session) {
     78                return GNUTLS_E_CERTIFICATE_ERROR;
     79        }
     80 
     81-       if (gnutls_x509_crt_check_hostname (cert, waith->url.host) == 0) {
     82+       char fingerprint[20];
     83+       size_t fingerprintSize = sizeof (fingerprint);
     84+       if (gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1, fingerprint,
     85+                       &fingerprintSize) != 0) {
     86+               return GNUTLS_E_CERTIFICATE_ERROR;
     87+       }
     88+
     89+       if (memcmp (fingerprint, waith->tlsFingerprint, sizeof (fingerprint)) != 0) {
     90                return GNUTLS_E_CERTIFICATE_ERROR;
     91        }
     92 
     93@@ -1036,8 +1018,6 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
     94        waith->request.write = WaitressOrdinaryWrite;
     95 
     96        if (waith->url.tls) {
     97-               assert (waith->tlsInitialized);
     98-
     99                waith->request.read = WaitressGnutlsRead;
     100                waith->request.write = WaitressGnutlsWrite;
     101                gnutls_init (&waith->request.tlsSession, GNUTLS_CLIENT);
     102@@ -1046,6 +1026,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
     103                                "PERFORMANCE", &err) != GNUTLS_E_SUCCESS) {
     104                        return WAITRESS_RET_ERR;
     105                }
     106+               gnutls_certificate_allocate_credentials (&waith->tlsCred);
     107                if (gnutls_credentials_set (waith->request.tlsSession,
     108                                GNUTLS_CRD_CERTIFICATE,
     109                                waith->tlsCred) != GNUTLS_E_SUCCESS) {
     110@@ -1083,6 +1064,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
     111        if (waith->url.tls) {
     112                gnutls_bye (waith->request.tlsSession, GNUTLS_SHUT_RDWR);
     113                gnutls_deinit (waith->request.tlsSession);
     114+               gnutls_certificate_free_credentials (waith->tlsCred);
     115        }
     116        close (waith->request.sockfd);
     117 
     118diff --git a/src/libwaitress/waitress.h b/src/libwaitress/waitress.h
     119index e1cf303..7e4401a 100644
     120--- a/src/libwaitress/waitress.h
     121+++ b/src/libwaitress/waitress.h
     122@@ -92,8 +92,8 @@ typedef struct {
     123        void *data;
     124        WaitressCbReturn_t (*callback) (void *, size_t, void *);
     125        int timeout;
     126+       const char *tlsFingerprint;
     127        gnutls_certificate_credentials_t tlsCred;
     128-       bool tlsInitialized;
     129 
     130        /* per-request data */
     131        struct {
     132@@ -110,7 +110,7 @@ typedef struct {
     133        } request;
     134 } WaitressHandle_t;
     135 
     136-WaitressReturn_t WaitressInit (WaitressHandle_t *, const char *);
     137+void WaitressInit (WaitressHandle_t *);
     138 void WaitressFree (WaitressHandle_t *);
     139 bool WaitressSetProxy (WaitressHandle_t *, const char *);
     140 char *WaitressUrlEncode (const char *);
     141diff --git a/src/main.c b/src/main.c
     142index e14a88a..afa75da 100644
     143--- a/src/main.c
     144+++ b/src/main.c
     145@@ -192,7 +192,7 @@ static void BarMainStartPlayback (BarApp_t *app, pthread_t *playerThread) {
     146                /* setup player */
     147                memset (&app->player, 0, sizeof (app->player));
     148 
     149-               WaitressInit (&app->player.waith, NULL);
     150+               WaitressInit (&app->player.waith);
     151                WaitressSetUrl (&app->player.waith, app->playlist->audioUrl);
     152 
     153                /* set up global proxy, player is NULLed on songfinish */
     154@@ -328,7 +328,6 @@ int main (int argc, char **argv) {
     155        static BarApp_t app;
     156        /* terminal attributes _before_ we started messing around with ~ECHO */
     157        struct termios termOrig;
     158-       WaitressReturn_t wRet;
     159 
     160        memset (&app, 0, sizeof (app));
     161 
     162@@ -355,19 +354,10 @@ int main (int argc, char **argv) {
     163                                app.settings.keys[BAR_KS_HELP]);
     164        }
     165 
     166-       if ((wRet = WaitressInit (&app.waith, app.settings.tlsCaPath)) != WAITRESS_RET_OK) {
     167-               if (wRet == WAITRESS_RET_TLS_TRUSTFILE_ERR) {
     168-                       BarUiMsg (&app.settings, MSG_ERR, "Can't load root certificates. "
     169-                                       "Please check the tls_ca_path setting in your config file.\n");
     170-               } else {
     171-                       BarUiMsg (&app.settings, MSG_ERR, "Can't initialize HTTP library: "
     172-                                       "%s\n", WaitressErrorToStr (wRet));
     173-               }
     174-               goto die;
     175-       }
     176-
     177+       WaitressInit (&app.waith);
     178        app.waith.url.host = strdup (PIANO_RPC_HOST);
     179        app.waith.url.tls = true;
     180+       app.waith.tlsFingerprint = app.settings.tlsFingerprint;
     181 
     182        /* init fds */
     183        FD_ZERO(&app.input.set);
     184@@ -388,7 +378,6 @@ int main (int argc, char **argv) {
     185 
     186        BarMainLoop (&app);
     187 
     188-die:
     189        if (app.input.fds[1] != -1) {
     190                close (app.input.fds[1]);
     191        }
     192diff --git a/src/settings.c b/src/settings.c
     193index f29fcfa..ee332cc 100644
     194--- a/src/settings.c
     195+++ b/src/settings.c
     196@@ -93,7 +93,6 @@ void BarSettingsDestroy (BarSettings_t *settings) {
     197        free (settings->npStationFormat);
     198        free (settings->listSongFormat);
     199        free (settings->fifo);
     200-       free (settings->tlsCaPath);
     201        for (size_t i = 0; i < MSG_COUNT; i++) {
     202                free (settings->msgFormat[i].prefix);
     203                free (settings->msgFormat[i].postfix);
     204@@ -132,7 +131,9 @@ void BarSettingsRead (BarSettings_t *settings) {
     205        settings->listSongFormat = strdup ("%i) %a - %t%r");
     206        settings->fifo = malloc (PATH_MAX * sizeof (*settings->fifo));
     207        BarGetXdgConfigDir (PACKAGE "/ctl", settings->fifo, PATH_MAX);
     208-       settings->tlsCaPath = strdup ("/etc/ssl/certs/ca-certificates.crt");
     209+       memcpy (settings->tlsFingerprint, "\xD9\x98\x0B\xA2\xCC\x0F\x97\xBB"
     210+                       "\x03\x82\x2C\x62\x11\xEA\xEA\x4A\x06\xEE\xF4\x27",
     211+                       sizeof (settings->tlsFingerprint));
     212 
     213        settings->msgFormat[MSG_NONE].prefix = NULL;
     214        settings->msgFormat[MSG_NONE].postfix = NULL;
     215@@ -241,9 +242,16 @@ void BarSettingsRead (BarSettings_t *settings) {
     216                } else if (streq ("fifo", key)) {
     217                        free (settings->fifo);
     218                        settings->fifo = strdup (val);
     219-               } else if (streq ("tls_ca_path", key)) {
     220-                       free (settings->tlsCaPath);
     221-                       settings->tlsCaPath = strdup (val);
     222+               } else if (streq ("tls_fingerprint", key)) {
     223+                       /* expects 40 byte hex-encoded sha1 */
     224+                       if (strlen (val) == 40) {
     225+                               for (size_t i = 0; i < 20; i++) {
     226+                                       char hex[3];
     227+                                       memcpy (hex, &val[i*2], 2);
     228+                                       hex[2] = '\0';
     229+                                       settings->tlsFingerprint[i] = strtol (hex, NULL, 16);
     230+                               }
     231+                       }
     232                } else if (strncmp (formatMsgPrefix, key,
     233                                strlen (formatMsgPrefix)) == 0) {
     234                        static const char *mapping[] = {"none", "info", "nowplaying",
     235diff --git a/src/settings.h b/src/settings.h
     236index 6cb4cb2..8ce1225 100644
     237--- a/src/settings.h
     238+++ b/src/settings.h
     239@@ -96,7 +96,7 @@ typedef struct {
     240        char *npStationFormat;
     241        char *listSongFormat;
     242        char *fifo;
     243-       char *tlsCaPath;
     244+       char tlsFingerprint[20];
     245        BarMsgFormatStr_t msgFormat[MSG_COUNT];
     246 } BarSettings_t;
     247 
  • Portfile

     
    44PortSystem                  1.0
    55
    66name                        pianobar
    7 version                     2011.09.22
     7version                     2011.11.11
    88categories                  audio
    99platforms                   darwin
    1010maintainers                 gmail.com:aguynamedryan+pianobar
    11 homepage                    http://6xq.net/html/00/17.html
    12 master_sites                http://6xq.net/media/00/16/
     11homepage                    http://6xq.net/projects/pianobar/
     12master_sites                http://6xq.net/static/projects/pianobar/
    1313use_bzip2                   yes
    1414
    1515description                 Console-based pandora.com player
     
    2424
    2525depends_lib                 port:libao \
    2626                            port:faad2 \
    27                             port:libmad
     27                            port:libmad \
     28                            port:gnutls
    2829
    29 checksums                   sha256  6e54d4881e7ada6b0443611b0853215e9e54253667a58310d96dfe38be258ed3 \
    30                             rmd160  d69c4a94c59613fa6ca3e8ce2d9a6fe0878674a5
     30checksums                   sha256  c1f5df7813b543992b79ac1558d27ff3fb0198f7bfb2d5d2e39173df4fae951b \
     31                            rmd160  e2627ccf8a6423711494e91316504b14f5e4a7bd
    3132
     33patch.pre_args              -p1
     34patchfiles                  a0e4f1e0f5989505f4aab10d64194b635f9af53c.diff
     35
    3236use_configure               no
    3337
    3438variant universal {}