From 962dee5cdd3b468318916d9c8862bc4c3653c402 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Thu, 11 Oct 2012 18:09:46 +0200 Subject: New setting: Read password from external command Closes #314. --- src/main.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ src/settings.c | 3 +++ src/settings.h | 2 +- 3 files changed, 74 insertions(+), 8 deletions(-) (limited to 'src') 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 #include #include +/* fork () */ #include #include #include @@ -46,6 +47,10 @@ THE SOFTWARE. #include #include #include +/* waitpid () */ +#include +#include + /* pandora.com library */ #include @@ -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; -- cgit v1.2.3