From 563a0f4244882a0c21d13fe7ff28c14eb7f5634f Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 8 Jan 2013 19:33:19 +0100 Subject: [PATCH 4/7] Add a mechanism to set the PIN Add DBus and libaccountsservice API to set the PIN for users, as well as pam-password-helper support to talk to pam_pin.so https://bugs.freedesktop.org/show_bug.cgi?id=51833 --- data/org.freedesktop.Accounts.User.xml | 3 ++- src/libaccountsservice/act-user.c | 2 +- src/libaccountsservice/act-user.h | 3 ++- src/pam-password-helper.c | 9 ++++++++- src/user.c | 27 +++++++++++++++++++++------ 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml index 0a1d318..8880052 100644 --- a/data/org.freedesktop.Accounts.User.xml +++ b/data/org.freedesktop.Accounts.User.xml @@ -536,6 +536,7 @@ - an unsigned integer specifying the kind of data: - 0 if the password is a regular password - 1 if the password is a really a hint (not a secret) + - 2 if the password is a PIN - the result of calling gcr_secret_exchange_send(). The calls must have been in the same order as they appear in the array. @@ -544,7 +545,7 @@ - Sets a new password and hint for this user. + Sets a new password, hint and PIN for this user. Note that setting a password has the side-effect of diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index 6313d1e..692b5db 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -1677,7 +1677,7 @@ act_user_set_password (ActUser *user, * @password_map: (element-type guint utf8): a #GHashTable mapping * #ActUserPasswordType to a plain-text password * - * Changes password and password hint of @user, using the + * Changes password, password hint and PIN of @user, using the * values taken from @password_map. * * Note this function is synchronous and ignores errors. diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h index d393ff2..7d01513 100644 --- a/src/libaccountsservice/act-user.h +++ b/src/libaccountsservice/act-user.h @@ -48,7 +48,8 @@ typedef enum { typedef enum { ACT_USER_PASSWORD_REGULAR, - ACT_USER_PASSWORD_HINT + ACT_USER_PASSWORD_HINT, + ACT_USER_PASSWORD_PIN } ActUserPasswordType; typedef struct _ActUser ActUser; diff --git a/src/pam-password-helper.c b/src/pam-password-helper.c index 000a619..54d2794 100644 --- a/src/pam-password-helper.c +++ b/src/pam-password-helper.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include static char *password; +static char *pin; static int answer_pam_message (int num_msg, @@ -52,7 +54,10 @@ answer_pam_message (int num_msg, */ for (i = 0; i < num_msg; i++) { if ((*msg)[i].msg_style == PAM_PROMPT_ECHO_OFF) { - resps[i].resp = strdup(password); + if (strcmp((*msg)[i].msg, "PIN") == 0) + resps[i].resp = pin ? strdup(pin) : NULL; + else + resps[i].resp = strdup(password); } else { resps[i].resp = NULL; } @@ -130,6 +135,7 @@ main (int argc, stdin = g_io_channel_unix_new (STDIN_FILENO); password = read_word (stdin, FALSE); + pin = read_word (stdin, TRUE); g_io_channel_unref (stdin); res = pam_start ("accountsservice", username, @@ -147,6 +153,7 @@ main (int argc, pam_end (pamh, res); g_free (password); + g_free (pin); return res == PAM_SUCCESS ? 0 : 2; } diff --git a/src/user.c b/src/user.c index c3e9e3d..361e63a 100644 --- a/src/user.c +++ b/src/user.c @@ -1503,12 +1503,21 @@ user_set_password_mode (AccountsUser *auser, } static char * -build_pam_helper_stdin (const char *password) +build_pam_helper_stdin (const char *password, + const char *pin) { - char *encoded_password, *result; + char *encoded_pin, *encoded_password, *result; encoded_password = g_uri_escape_string (password, NULL, FALSE); - result = g_strdup_printf ("%s\n", encoded_password); + + if (pin != NULL) { + encoded_pin = g_uri_escape_string (pin, NULL, FALSE); + + result = g_strdup_printf ("%s\n%s\n", encoded_password, encoded_pin); + g_free (encoded_pin); + } else { + result = g_strdup_printf ("%s\n", encoded_password); + } g_free (encoded_password); return result; @@ -1536,7 +1545,7 @@ user_change_password_authorized_cb (Daemon *daemon, argv[1] = user->user_name; argv[2] = NULL; - stdin = build_pam_helper_stdin (strings[0]); + stdin = build_pam_helper_stdin (strings[0], NULL); error = NULL; if (!spawn_with_login_uid_and_stdin (context, argv, stdin, &error)) { @@ -1622,7 +1631,7 @@ user_continue_change_password_authorized_cb (Daemon *daemon, const gchar *argv[6]; unsigned int type; const char *encrypted_password; - char *password_hint, *password; + char *password_hint, *password, *pin; char *stdin; sys_log (context, "change password of user '%s' (%d)", @@ -1643,6 +1652,7 @@ user_continue_change_password_authorized_cb (Daemon *daemon, password_hint = NULL; password = NULL; + pin = NULL; g_variant_iter_init (&iter, passwords); while (g_variant_iter_next (&iter, "(u&s)", &type, &encrypted_password)) { if (!gcr_secret_exchange_receive (exchange, encrypted_password)) { @@ -1659,6 +1669,10 @@ user_continue_change_password_authorized_cb (Daemon *daemon, g_free (password_hint); password_hint = g_strdup (gcr_secret_exchange_get_secret (exchange, NULL)); break; + case 2: + g_free (pin); + pin = g_strdup (gcr_secret_exchange_get_secret (exchange, NULL)); + break; default: throw_error (context, ERROR_INVALID, "invalid password type"); @@ -1670,7 +1684,7 @@ user_continue_change_password_authorized_cb (Daemon *daemon, argv[1] = user->user_name; argv[2] = NULL; - stdin = build_pam_helper_stdin (password); + stdin = build_pam_helper_stdin (password, pin); error = NULL; if (!spawn_with_login_uid_and_stdin (context, argv, stdin, &error)) { @@ -1708,6 +1722,7 @@ user_continue_change_password_authorized_cb (Daemon *daemon, out: g_free (password_hint); g_free (password); + g_free (pin); g_object_thaw_notify (G_OBJECT (user)); g_object_unref (exchange); } -- 1.8.1.2