From f6df7d7e510f2d8879ec54dce32fee2b691dc32d Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Tue, 2 Jul 2013 17:13:47 +0200
Subject: piano: Check for libgcrypt errors

Fixes mysterious segfaults from issue #369 and #293.
---
 INSTALL              |  2 +-
 src/libpiano/piano.c | 32 +++++++++++++++++++++++---------
 src/libpiano/piano.h |  3 ++-
 src/main.c           | 10 ++++++++--
 4 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/INSTALL b/INSTALL
index 45ca024..3283027 100644
--- a/INSTALL
+++ b/INSTALL
@@ -8,7 +8,7 @@ Dependencies
 - pthreads
 - libao
 - gnutls
-- gcrypt
+- gcrypt (with blowfish cipher enabled)
 - json-c
 - libfaad2 (compiled with --without-drm)
 - libmad (optional, Pandora One users only)
diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c
index fac5da5..9020a6a 100644
--- a/src/libpiano/piano.c
+++ b/src/libpiano/piano.c
@@ -40,7 +40,7 @@ THE SOFTWARE.
  *	@param piano handle
  *	@return nothing
  */
-void PianoInit (PianoHandle_t *ph, const char *partnerUser,
+PianoReturn_t PianoInit (PianoHandle_t *ph, const char *partnerUser,
 		const char *partnerPassword, const char *device, const char *inkey,
 		const char *outkey) {
 	memset (ph, 0, sizeof (*ph));
@@ -48,15 +48,25 @@ void PianoInit (PianoHandle_t *ph, const char *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));
+	if (gcry_cipher_open (&ph->partner.in, GCRY_CIPHER_BLOWFISH,
+			GCRY_CIPHER_MODE_ECB, 0) != GPG_ERR_NO_ERROR) {
+		return PIANO_RET_GCRY_ERR;
+	}
+	if (gcry_cipher_setkey (ph->partner.in, (const unsigned char *) inkey,
+			strlen (inkey)) != GPG_ERR_NO_ERROR) {
+		return PIANO_RET_GCRY_ERR;
+	}
 
-	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));
+	if (gcry_cipher_open (&ph->partner.out, GCRY_CIPHER_BLOWFISH,
+			GCRY_CIPHER_MODE_ECB, 0) != GPG_ERR_NO_ERROR) {
+		return PIANO_RET_GCRY_ERR;
+	}
+	if (gcry_cipher_setkey (ph->partner.out, (const unsigned char *) outkey,
+			strlen (outkey)) != GPG_ERR_NO_ERROR) {
+		return PIANO_RET_GCRY_ERR;
+	}
+
+	return PIANO_RET_OK;
 }
 
 /*	destroy artist linked list
@@ -258,6 +268,10 @@ const char *PianoErrorToStr (PianoReturn_t ret) {
 			return "Selected audio quality is not available.";
 			break;
 
+		case PIANO_RET_GCRY_ERR:
+			return "libgcrypt initialization failed.";
+			break;
+
 		/* pandora error messages */
 		case PIANO_RET_P_INTERNAL:
 			return "Internal error.";
diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h
index dc05250..04f33b5 100644
--- a/src/libpiano/piano.h
+++ b/src/libpiano/piano.h
@@ -250,6 +250,7 @@ typedef enum {
 	PIANO_RET_OUT_OF_MEMORY = 4,
 	PIANO_RET_INVALID_LOGIN = 5,
 	PIANO_RET_QUALITY_UNAVAILABLE = 6,
+	PIANO_RET_GCRY_ERR = 7,
 
 	/* pandora error codes */
 	PIANO_RET_P_INTERNAL = PIANO_RET_OFFSET+0,
@@ -297,7 +298,7 @@ typedef enum {
 	PIANO_RET_P_RATE_LIMIT = PIANO_RET_OFFSET+1039,
 } PianoReturn_t;
 
-void PianoInit (PianoHandle_t *, const char *,
+PianoReturn_t PianoInit (PianoHandle_t *, const char *,
 		const char *, const char *, const char *,
 		const char *);
 void PianoDestroy (PianoHandle_t *);
diff --git a/src/main.c b/src/main.c
index c8bf5c6..9232f9e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -424,8 +424,14 @@ int main (int argc, char **argv) {
 	BarSettingsInit (&app.settings);
 	BarSettingsRead (&app.settings);
 
-	PianoInit (&app.ph, app.settings.partnerUser, app.settings.partnerPassword,
-			app.settings.device, app.settings.inkey, app.settings.outkey);
+	PianoReturn_t pret;
+	if ((pret = PianoInit (&app.ph, app.settings.partnerUser,
+			app.settings.partnerPassword, app.settings.device,
+			app.settings.inkey, app.settings.outkey)) != PIANO_RET_OK) {
+		BarUiMsg (&app.settings, MSG_ERR, "Initialization failed:"
+				" %s\n", PianoErrorToStr (pret));
+		return 0;
+	}
 
 	BarUiMsg (&app.settings, MSG_NONE,
 			"Welcome to " PACKAGE " (" VERSION ")! ");
-- 
cgit v1.2.3