diff options
Diffstat (limited to 'src/libpiano')
| -rw-r--r-- | src/libpiano/crypt.c | 17 | ||||
| -rw-r--r-- | src/libpiano/crypt.h | 7 | ||||
| -rw-r--r-- | src/libpiano/piano.c | 31 | ||||
| -rw-r--r-- | src/libpiano/piano.h | 14 | ||||
| -rw-r--r-- | src/libpiano/request.c | 17 | ||||
| -rw-r--r-- | src/libpiano/response.c | 9 | 
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; | 
