summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/config-example2
-rw-r--r--contrib/pianobar.16
-rw-r--r--src/main.c77
-rw-r--r--src/settings.c3
-rw-r--r--src/settings.h2
5 files changed, 82 insertions, 8 deletions
diff --git a/contrib/config-example b/contrib/config-example
index f52d3a0..dbc8cc5 100644
--- a/contrib/config-example
+++ b/contrib/config-example
@@ -5,6 +5,8 @@
# User
#user = your@user.name
#password = password
+# or
+#password_command = gpg --decrypt ~/password
# Proxy (for those who are not living in the USA)
#control_proxy = http://127.0.0.1:9090/
diff --git a/contrib/pianobar.1 b/contrib/pianobar.1
index 4cc6d00..53bb301 100644
--- a/contrib/pianobar.1
+++ b/contrib/pianobar.1
@@ -297,6 +297,12 @@ Icon for loved songs.
Your pandora.com password. Plain-text.
.TP
+.B password_command = gpg --decrypt ~/password
+Use output of command as password. This setting is overridden by specifying a
+password with
+.B password.
+
+.TP
.B proxy = http://user:password@host:port/
Use a http proxy. Note that this setting overrides the http_proxy environment
variable. Only "Basic" http authentication is supported.
diff --git a/src/main.c b/src/main.c
index 1d24167..2465334 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,6 +31,7 @@ THE SOFTWARE.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+/* fork () */
#include <unistd.h>
#include <sys/select.h>
#include <time.h>
@@ -46,6 +47,10 @@ THE SOFTWARE.
#include <stdbool.h>
#include <limits.h>
#include <signal.h>
+/* waitpid () */
+#include <sys/types.h>
+#include <sys/wait.h>
+
/* pandora.com library */
#include <piano.h>
@@ -92,22 +97,78 @@ static bool BarMainLoginUser (BarApp_t *app) {
/* ask for username/password if none were provided in settings
*/
-static void BarMainGetLoginCredentials (BarSettings_t *settings,
+static bool BarMainGetLoginCredentials (BarSettings_t *settings,
BarReadlineFds_t *input) {
if (settings->username == NULL) {
char nameBuf[100];
+
BarUiMsg (settings, MSG_QUESTION, "Email: ");
BarReadlineStr (nameBuf, sizeof (nameBuf), input, BAR_RL_DEFAULT);
settings->username = strdup (nameBuf);
}
+
if (settings->password == NULL) {
char passBuf[100];
- BarUiMsg (settings, MSG_QUESTION, "Password: ");
- BarReadlineStr (passBuf, sizeof (passBuf), input, BAR_RL_NOECHO);
- /* write missing newline */
- puts ("");
- settings->password = strdup (passBuf);
+
+ if (settings->passwordCmd == NULL) {
+ BarUiMsg (settings, MSG_QUESTION, "Password: ");
+ BarReadlineStr (passBuf, sizeof (passBuf), input, BAR_RL_NOECHO);
+ /* write missing newline */
+ puts ("");
+ settings->password = strdup (passBuf);
+ } else {
+ pid_t chld;
+ int pipeFd[2];
+
+ BarUiMsg (settings, MSG_INFO, "Requesting password from external helper... ");
+
+ if (pipe (pipeFd) == -1) {
+ BarUiMsg (settings, MSG_NONE, "Error: %s\n", strerror (errno));
+ return false;
+ }
+
+ chld = fork ();
+ if (chld == 0) {
+ /* child */
+ close (pipeFd[0]);
+ dup2 (pipeFd[1], fileno (stdout));
+ execl ("/bin/sh", "/bin/sh", "-c", settings->passwordCmd, (char *) NULL);
+ BarUiMsg (settings, MSG_NONE, "Error: %s\n", strerror (errno));
+ close (pipeFd[1]);
+ exit (1);
+ } else if (chld == -1) {
+ BarUiMsg (settings, MSG_NONE, "Error: %s\n", strerror (errno));
+ return false;
+ } else {
+ /* parent */
+ int status;
+
+ close (pipeFd[1]);
+ memset (passBuf, 0, sizeof (passBuf));
+ read (pipeFd[0], passBuf, sizeof (passBuf)-1);
+ close (pipeFd[0]);
+
+ /* drop trailing newlines */
+ ssize_t len = strlen (passBuf)-1;
+ while (len >= 0 && passBuf[len] == '\n') {
+ passBuf[len] = '\0';
+ --len;
+ }
+
+ waitpid (chld, &status, 0);
+ if (WEXITSTATUS (status) == 0) {
+ settings->password = strdup (passBuf);
+ BarUiMsg (settings, MSG_NONE, "Ok.\n");
+ } else {
+ BarUiMsg (settings, MSG_NONE, "Error: Exit status %i.\n", WEXITSTATUS (status));
+ return false;
+ }
+ }
+
+ }
}
+
+ return true;
}
/* get station list
@@ -270,7 +331,9 @@ static void BarMainPrintTime (BarApp_t *app) {
static void BarMainLoop (BarApp_t *app) {
pthread_t playerThread;
- BarMainGetLoginCredentials (&app->settings, &app->input);
+ if (!BarMainGetLoginCredentials (&app->settings, &app->input)) {
+ return;
+ }
BarMainLoadProxy (&app->settings, &app->waith);
diff --git a/src/settings.c b/src/settings.c
index c8bcbfe..014c561 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -86,6 +86,7 @@ void BarSettingsDestroy (BarSettings_t *settings) {
free (settings->proxy);
free (settings->username);
free (settings->password);
+ free (settings->passwordCmd);
free (settings->autostartStation);
free (settings->eventCmd);
free (settings->loveIcon);
@@ -189,6 +190,8 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->username = strdup (val);
} else if (streq ("password", key)) {
settings->password = strdup (val);
+ } else if (streq ("password_command", key)) {
+ settings->passwordCmd = strdup (val);
} else if (streq ("rpc_host", key)) {
free (settings->rpcHost);
settings->rpcHost = strdup (val);
diff --git a/src/settings.h b/src/settings.h
index 0f4c6de..30915c2 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -87,7 +87,7 @@ typedef struct {
BarStationSorting_t sortOrder;
PianoAudioQuality_t audioQuality;
char *username;
- char *password;
+ char *password, *passwordCmd;
char *controlProxy; /* non-american listeners need this */
char *proxy;
char *autostartStation;