summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libpiano/crypt.c17
-rw-r--r--src/libpiano/crypt.h7
-rw-r--r--src/libpiano/piano.c31
-rw-r--r--src/libpiano/piano.h14
-rw-r--r--src/libpiano/request.c17
-rw-r--r--src/libpiano/response.c9
-rw-r--r--src/main.c4
-rw-r--r--src/settings.c28
-rw-r--r--src/settings.h3
9 files changed, 97 insertions, 33 deletions
diff --git a/src/libpiano/crypt.c b/src/libpiano/crypt.c
index 6dafcca..29ad3cb 100644
--- a/src/libpiano/crypt.c
+++ b/src/libpiano/crypt.c
@@ -32,11 +32,13 @@ THE SOFTWARE.
/* decrypt hex-encoded, blowfish-crypted string: decode 2 hex-encoded blocks,
* decrypt, byteswap
+ * @param gcrypt handle
* @param hex string
* @param decrypted string length (without trailing NUL)
* @return decrypted string or NULL
*/
-char *PianoDecryptString (const char * const input, size_t * const retSize) {
+char *PianoDecryptString (gcry_cipher_hd_t h, const char * const input,
+ size_t * const retSize) {
size_t inputLen = strlen (input);
gcry_error_t gret;
unsigned char *output;
@@ -53,26 +55,22 @@ char *PianoDecryptString (const char * const input, size_t * const retSize) {
output[i] = strtol (hex, NULL, 16);
}
- gcry_cipher_hd_t h;
- gcry_cipher_open (&h, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0);
- gcry_cipher_setkey (h, (unsigned char *) "R=U!LH$O2B#", 11);
gret = gcry_cipher_decrypt (h, output, outputLen, NULL, 0);
if (gret) {
- fprintf (stderr, "Failure: %s/%s\n", gcry_strsource (gret), gcry_strerror (gret));
return NULL;
}
- gcry_cipher_close (h);
*retSize = outputLen;
return (char *) output;
}
/* blowfish-encrypt/hex-encode string
+ * @param gcrypt handle
* @param encrypt this
* @return encrypted, hex-encoded string
*/
-char *PianoEncryptString (const char *s) {
+char *PianoEncryptString (gcry_cipher_hd_t h, const char *s) {
unsigned char *paddedInput, *hexOutput;
size_t inputLen = strlen (s);
/* blowfish expects two 32 bit blocks */
@@ -82,12 +80,8 @@ char *PianoEncryptString (const char *s) {
paddedInput = calloc (paddedInputLen+1, sizeof (*paddedInput));
memcpy (paddedInput, s, inputLen);
- gcry_cipher_hd_t h;
- gcry_cipher_open (&h, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0);
- gcry_cipher_setkey (h, (unsigned char *) "6#26FRL$ZWD", 11);
gret = gcry_cipher_encrypt (h, paddedInput, paddedInputLen, NULL, 0);
if (gret) {
- fprintf (stderr, "Failure: %s/%s\n", gcry_strsource (gret), gcry_strerror (gret));
return NULL;
}
@@ -96,7 +90,6 @@ char *PianoEncryptString (const char *s) {
snprintf ((char * restrict) &hexOutput[i*2], 3, "%02x", paddedInput[i]);
}
- gcry_cipher_close (h);
free (paddedInput);
return (char *) hexOutput;
diff --git a/src/libpiano/crypt.h b/src/libpiano/crypt.h
index 945e9e6..59820e2 100644
--- a/src/libpiano/crypt.h
+++ b/src/libpiano/crypt.h
@@ -24,7 +24,10 @@ THE SOFTWARE.
#ifndef _CRYPH_H
#define _CRYPT_H
-char *PianoDecryptString (const char * const, size_t * const);
-char *PianoEncryptString (const char *strInput);
+#include <gcrypt.h>
+
+char *PianoDecryptString (gcry_cipher_hd_t, const char * const,
+ size_t * const);
+char *PianoEncryptString (gcry_cipher_hd_t, const char *);
#endif /* _CRYPT_H */
diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c
index f9dfa51..bd8847b 100644
--- a/src/libpiano/piano.c
+++ b/src/libpiano/piano.c
@@ -40,8 +40,23 @@ THE SOFTWARE.
* @param piano handle
* @return nothing
*/
-void PianoInit (PianoHandle_t *ph) {
+void PianoInit (PianoHandle_t *ph, const char *partnerUser,
+ const char *partnerPassword, const char *device, const char *inkey,
+ const char *outkey) {
memset (ph, 0, sizeof (*ph));
+ ph->partner.user = strdup (partnerUser);
+ ph->partner.password = strdup (partnerPassword);
+ ph->partner.device = strdup (device);
+
+ gcry_cipher_open (&ph->partner.in, GCRY_CIPHER_BLOWFISH,
+ GCRY_CIPHER_MODE_ECB, 0);
+ gcry_cipher_setkey (ph->partner.in, (const unsigned char *) inkey,
+ strlen (inkey));
+
+ gcry_cipher_open (&ph->partner.out, GCRY_CIPHER_BLOWFISH,
+ GCRY_CIPHER_MODE_ECB, 0);
+ gcry_cipher_setkey (ph->partner.out, (const unsigned char *) outkey,
+ strlen (outkey));
}
/* destroy artist linked list
@@ -150,6 +165,18 @@ void PianoDestroyUserInfo (PianoUserInfo_t *user) {
free (user->listenerId);
}
+/* destroy partner
+ */
+static void PianoDestroyPartner (PianoPartner_t *partner) {
+ free (partner->user);
+ free (partner->password);
+ free (partner->device);
+ free (partner->authToken);
+ gcry_cipher_close (partner->in);
+ gcry_cipher_close (partner->out);
+ memset (partner, 0, sizeof (*partner));
+}
+
/* frees the whole piano handle structure
* @param piano handle
* @return nothing
@@ -157,6 +184,7 @@ void PianoDestroyUserInfo (PianoUserInfo_t *user) {
void PianoDestroy (PianoHandle_t *ph) {
PianoDestroyUserInfo (&ph->user);
PianoDestroyStations (ph->stations);
+ PianoDestroyPartner (&ph->partner);
/* destroy genre stations */
PianoGenreCategory_t *curGenreCat = ph->genreStations, *lastGenreCat;
while (curGenreCat != NULL) {
@@ -166,7 +194,6 @@ void PianoDestroy (PianoHandle_t *ph) {
curGenreCat = curGenreCat->next;
free (lastGenreCat);
}
- free (ph->partnerAuthToken);
memset (ph, 0, sizeof (*ph));
}
diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h
index 6d20747..86dcce0 100644
--- a/src/libpiano/piano.h
+++ b/src/libpiano/piano.h
@@ -25,6 +25,7 @@ THE SOFTWARE.
#define _PIANO_H
#include <stdbool.h>
+#include <gcrypt.h>
/* this is our public API; don't expect this api to be stable as long as
* pandora does not provide a stable api
@@ -106,14 +107,19 @@ typedef struct PianoGenreCategory {
struct PianoGenreCategory *next;
} PianoGenreCategory_t;
+typedef struct PianoPartner {
+ gcry_cipher_hd_t in, out;
+ char *authToken, *device, *user, *password;
+ unsigned int id;
+} PianoPartner_t;
+
typedef struct PianoHandle {
PianoUserInfo_t user;
/* linked lists */
PianoStation_t *stations;
PianoGenreCategory_t *genreStations;
+ PianoPartner_t partner;
int timeOffset;
- char *partnerAuthToken;
- unsigned int partnerId;
} PianoHandle_t;
typedef struct PianoSearchResult {
@@ -291,7 +297,9 @@ typedef enum {
} PianoReturn_t;
-void PianoInit (PianoHandle_t *);
+void PianoInit (PianoHandle_t *, const char *,
+ const char *, const char *, const char *,
+ const char *);
void PianoDestroy (PianoHandle_t *);
void PianoDestroyPlaylist (PianoSong_t *);
void PianoDestroySearchResult (PianoSearchResult_t *);
diff --git a/src/libpiano/request.c b/src/libpiano/request.c
index a5a33e9..3a1d7fb 100644
--- a/src/libpiano/request.c
+++ b/src/libpiano/request.c
@@ -70,11 +70,11 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
req->secure = true;
json_object_object_add (j, "username",
- json_object_new_string ("android"));
+ json_object_new_string (ph->partner.user));
json_object_object_add (j, "password",
- json_object_new_string ("AC7IBG09A3DTSYM4R41UJWL07VLN8JI7"));
+ json_object_new_string (ph->partner.password));
json_object_object_add (j, "deviceModel",
- json_object_new_string ("android-generic"));
+ json_object_new_string (ph->partner.device));
json_object_object_add (j, "version",
json_object_new_string ("5"));
json_object_object_add (j, "includeUrls",
@@ -95,16 +95,16 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
json_object_object_add (j, "password",
json_object_new_string (logindata->password));
json_object_object_add (j, "partnerAuthToken",
- json_object_new_string (ph->partnerAuthToken));
+ json_object_new_string (ph->partner.authToken));
json_object_object_add (j, "syncTime",
json_object_new_int (timestamp));
- urlencAuthToken = WaitressUrlEncode (ph->partnerAuthToken);
+ urlencAuthToken = WaitressUrlEncode (ph->partner.authToken);
assert (urlencAuthToken != NULL);
snprintf (req->urlPath, sizeof (req->urlPath),
PIANO_RPC_PATH "method=auth.userLogin&"
"auth_token=%s&partner_id=%i", urlencAuthToken,
- ph->partnerId);
+ ph->partner.id);
free (urlencAuthToken);
break;
@@ -483,7 +483,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH
"method=%s&auth_token=%s&partner_id=%i&user_id=%s", method,
- urlencAuthToken, ph->partnerId, ph->user.listenerId);
+ urlencAuthToken, ph->partner.id, ph->user.listenerId);
free (urlencAuthToken);
@@ -496,7 +496,8 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
/* json to string */
jsonSendBuf = json_object_to_json_string (j);
if (encrypted) {
- if ((req->postData = PianoEncryptString (jsonSendBuf)) == NULL) {
+ if ((req->postData = PianoEncryptString (ph->partner.out,
+ jsonSendBuf)) == NULL) {
return PIANO_RET_OUT_OF_MEMORY;
}
} else {
diff --git a/src/libpiano/response.c b/src/libpiano/response.c
index 65af76e..4b33248 100644
--- a/src/libpiano/response.c
+++ b/src/libpiano/response.c
@@ -103,8 +103,9 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {
size_t decryptedSize;
ret = PIANO_RET_ERR;
- if ((decryptedTimestamp = PianoDecryptString (cryptedTimestamp,
- &decryptedSize)) != NULL && decryptedSize > 4) {
+ if ((decryptedTimestamp = PianoDecryptString (ph->partner.in,
+ cryptedTimestamp, &decryptedSize)) != NULL &&
+ decryptedSize > 4) {
/* skip four bytes garbage(?) at beginning */
timestamp = strtoul (decryptedTimestamp+4, NULL, 0);
ph->timeOffset = realTimestamp - timestamp;
@@ -112,9 +113,9 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {
}
free (decryptedTimestamp);
/* get auth token */
- ph->partnerAuthToken = PianoJsonStrdup (result,
+ ph->partner.authToken = PianoJsonStrdup (result,
"partnerAuthToken");
- ph->partnerId = json_object_get_int (
+ ph->partner.id = json_object_get_int (
json_object_object_get (result, "partnerId"));
++reqData->step;
break;
diff --git a/src/main.c b/src/main.c
index 43f3ffc..26099f5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -341,11 +341,13 @@ int main (int argc, char **argv) {
/* init some things */
ao_initialize ();
gnutls_global_init ();
- PianoInit (&app.ph);
BarSettingsInit (&app.settings);
BarSettingsRead (&app.settings);
+ PianoInit (&app.ph, app.settings.partnerUser, app.settings.partnerPassword,
+ app.settings.device, app.settings.inkey, app.settings.outkey);
+
BarUiMsg (&app.settings, MSG_NONE,
"Welcome to " PACKAGE " (" VERSION ")! ");
if (app.settings.keys[BAR_KS_HELP] == BAR_KS_DISABLED) {
diff --git a/src/settings.c b/src/settings.c
index d1dcc7f..d603387 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -93,6 +93,11 @@ void BarSettingsDestroy (BarSettings_t *settings) {
free (settings->npStationFormat);
free (settings->listSongFormat);
free (settings->fifo);
+ free (settings->partnerUser);
+ free (settings->partnerPassword);
+ free (settings->device);
+ free (settings->inkey);
+ free (settings->outkey);
for (size_t i = 0; i < MSG_COUNT; i++) {
free (settings->msgFormat[i].prefix);
free (settings->msgFormat[i].postfix);
@@ -131,6 +136,11 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->npSongFormat = strdup ("\"%t\" by \"%a\" on \"%l\"%r%@%s");
settings->npStationFormat = strdup ("Station \"%n\" (%i)");
settings->listSongFormat = strdup ("%i) %a - %t%r");
+ settings->partnerUser = strdup ("android");
+ settings->partnerPassword = strdup ("AC7IBG09A3DTSYM4R41UJWL07VLN8JI7");
+ settings->device = strdup ("android-generic");
+ settings->inkey = strdup ("R=U!LH$O2B#");
+ settings->outkey = strdup ("6#26FRL$ZWD");
settings->fifo = malloc (PATH_MAX * sizeof (*settings->fifo));
BarGetXdgConfigDir (PACKAGE "/ctl", settings->fifo, PATH_MAX);
memcpy (settings->tlsFingerprint, "\xA2\xA0\xBE\x8A\x37\x92\x39\xAE"
@@ -179,6 +189,24 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->username = strdup (val);
} else if (streq ("password", key)) {
settings->password = strdup (val);
+ } else if (streq ("partner_user", key)) {
+ free (settings->partnerUser);
+ settings->partnerUser = strdup (val);
+ } else if (streq ("partner_password", key)) {
+ free (settings->partnerPassword);
+ settings->partnerPassword = strdup (val);
+ } else if (streq ("device", key)) {
+ free (settings->device);
+ settings->device = strdup (val);
+ } else if (streq ("encrypt_password", key)) {
+ free (settings->outkey);
+ settings->outkey = strdup (val);
+ } else if (streq ("decrypt_password", key)) {
+ free (settings->inkey);
+ settings->inkey = strdup (val);
+ } else if (memcmp ("act_", key, 4) == 0) {
+ } else if (memcmp ("act_", key, 4) == 0) {
+ } else if (memcmp ("act_", key, 4) == 0) {
} else if (memcmp ("act_", key, 4) == 0) {
size_t i;
/* keyboard shortcuts */
diff --git a/src/settings.h b/src/settings.h
index ce3732b..ff19882 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2011
+Copyright (c) 2008-2012
Lars-Dominik Braun <lars@6xq.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -99,6 +99,7 @@ typedef struct {
char *npStationFormat;
char *listSongFormat;
char *fifo;
+ char *partnerUser, *partnerPassword, *device, *inkey, *outkey;
char tlsFingerprint[20];
char keys[BAR_KS_COUNT];
BarMsgFormatStr_t msgFormat[MSG_COUNT];