summaryrefslogtreecommitdiff
path: root/src/libpiano
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpiano')
-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
6 files changed, 64 insertions, 31 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;