diff options
-rw-r--r-- | liblightdm-gobject/greeter.c | 45 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/scripts/login-multi-prompt.conf | 39 | ||||
-rw-r--r-- | tests/src/libsystem.c | 11 | ||||
-rw-r--r-- | tests/src/test-runner.c | 2 | ||||
-rwxr-xr-x | tests/test-login-gobject-multi-prompt | 2 |
6 files changed, 94 insertions, 7 deletions
diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c index 0a603240..2d31b84c 100644 --- a/liblightdm-gobject/greeter.c +++ b/liblightdm-gobject/greeter.c @@ -51,6 +51,9 @@ typedef struct guint8 *read_buffer; gsize n_read; + gsize n_responses_waiting; + GList *responses_received; + GHashTable *hints; guint autologin_timeout; @@ -301,6 +304,10 @@ handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize me g_free (priv->authentication_user); priv->authentication_user = username; + g_list_free_full (priv->responses_received, g_free); + priv->responses_received = NULL; + priv->n_responses_waiting = 0; + n_messages = read_int (message, message_length, offset); g_debug ("Prompt user with %d message(s)", n_messages); @@ -316,9 +323,11 @@ handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize me switch (style) { case PAM_PROMPT_ECHO_OFF: + priv->n_responses_waiting++; g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_SECRET); break; case PAM_PROMPT_ECHO_ON: + priv->n_responses_waiting++; g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_QUESTION); break; case PAM_ERROR_MSG: @@ -827,7 +836,7 @@ lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter) * @greeter: A #LightDMGreeter * @response: Response to a prompt * - * Provide response to a prompt. + * Provide response to a prompt. May be one in a series. **/ void lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response) @@ -842,13 +851,35 @@ lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response) priv = GET_PRIVATE (greeter); g_return_if_fail (priv->connected); + g_return_if_fail (priv->n_responses_waiting > 0); - g_debug ("Providing response to display manager"); - write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, int_length () + string_length (response), &offset); - // FIXME: Could be multiple responses required - write_int (message, MAX_MESSAGE_LENGTH, 1, &offset); - write_string (message, MAX_MESSAGE_LENGTH, response, &offset); - write_message (greeter, message, offset); + priv->n_responses_waiting--; + priv->responses_received = g_list_append (priv->responses_received, g_strdup (response)); + + if (priv->n_responses_waiting == 0) + { + guint32 msg_length; + GList *iter; + + g_debug ("Providing response to display manager"); + + msg_length = int_length (); + for (iter = priv->responses_received; iter; iter = iter->next) + { + msg_length += string_length ((gchar *)iter->data); + } + + write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset); + write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset); + for (iter = priv->responses_received; iter; iter = iter->next) + { + write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset); + } + write_message (greeter, message, offset); + + g_list_free_full (priv->responses_received, g_free); + priv->responses_received = NULL; + } } /** diff --git a/tests/Makefile.am b/tests/Makefile.am index 93b47f33..7d87c3ab 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,6 +58,7 @@ TESTS = \ test-login-gobject-new-authtok \ test-login-gobject-info-prompt \ test-login-gobject-multi-info-prompt \ + test-login-gobject-multi-prompt \ test-login-gobject-pick-session \ test-login-gobject-previous-session \ test-login-gobject-wrong-password \ @@ -207,6 +208,7 @@ EXTRA_DIST = \ scripts/login-manual.conf \ scripts/login-manual-previous-session.conf \ scripts/login-multi-info-prompt.conf \ + scripts/login-multi-prompt.conf \ scripts/login-new-authtok.conf \ scripts/login-no-password.conf \ scripts/login-pam.conf \ diff --git a/tests/scripts/login-multi-prompt.conf b/tests/scripts/login-multi-prompt.conf new file mode 100644 index 00000000..ed24986b --- /dev/null +++ b/tests/scripts/login-multi-prompt.conf @@ -0,0 +1,39 @@ +# +# Check multiple PAM informational messages on login are passed to a greeter +# + +[LightDM] +minimum-display-number=50 + +#?RUNNER DAEMON-START + +# X server starts +#?XSERVER :50 START +#?XSERVER :50 INDICATE-READY + +# LightDM connects to X server +#?XSERVER :50 ACCEPT-CONNECT + +# Greeter starts +#?GREETER :50 START +#?XSERVER :50 ACCEPT-CONNECT +#?GREETER :50 CONNECT-XSERVER +#?GREETER :50 CONNECT-TO-DAEMON +#?GREETER :50 CONNECTED-TO-DAEMON + +# Log into account and see an informational prompt +#?*GREETER :50 AUTHENTICATE USERNAME=multi-prompt +#?GREETER :50 SHOW-PROMPT TEXT="Favorite Color:" +#?GREETER :50 SHOW-PROMPT TEXT="Password:" + +# Respond with password and check response is correctly handled +#?*GREETER :50 RESPOND TEXT="blue" +#?*GREETER :50 RESPOND TEXT="password" +#?GREETER :50 AUTHENTICATION-COMPLETE USERNAME=multi-prompt AUTHENTICATED=TRUE + +# Cleanup +#?*STOP-DAEMON +# Don't know what order they will terminate +#?(GREETER :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15) +#?(GREETER :50 TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15) +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/src/libsystem.c b/tests/src/libsystem.c index 2b944837..855f668b 100644 --- a/tests/src/libsystem.c +++ b/tests/src/libsystem.c @@ -546,6 +546,13 @@ pam_authenticate (pam_handle_t *pamh, int flags) msg[n_messages]->msg = "You should have seen three messages"; n_messages++; } + if (strcmp (pamh->user, "multi-prompt") == 0) + { + msg[n_messages] = malloc (sizeof (struct pam_message)); + msg[n_messages]->msg_style = PAM_PROMPT_ECHO_ON; + msg[n_messages]->msg = "Favorite Color:"; + n_messages++; + } msg[n_messages] = malloc (sizeof (struct pam_message)); msg[n_messages]->msg_style = PAM_PROMPT_ECHO_OFF; msg[n_messages]->msg = "Password:"; @@ -568,6 +575,10 @@ pam_authenticate (pam_handle_t *pamh, int flags) if (entry) password_matches = strcmp (entry->pw_passwd, resp[password_index].resp) == 0; + + if (password_matches && strcmp (pamh->user, "multi-prompt") == 0) + password_matches = strcmp ("blue", resp[0].resp) == 0; + for (i = 0; i < n_messages; i++) { if (resp[i].resp) diff --git a/tests/src/test-runner.c b/tests/src/test-runner.c index 491a16c8..516a6788 100644 --- a/tests/src/test-runner.c +++ b/tests/src/test-runner.c @@ -1391,6 +1391,8 @@ main (int argc, char **argv) {"cred-unavail", "password", TRUE, "Cred Unavail", NULL, NULL, NULL, NULL, 1029}, /* This account sends informational messages for each PAM function that is called */ {"log-pam", "password", TRUE, "Log PAM", NULL, NULL, NULL, NULL, 1030}, + /* This account shows multiple prompts on login */ + {"multi-prompt", "password", TRUE, "Multi Prompt", NULL, NULL, NULL, NULL, 1031}, {NULL, NULL, FALSE, NULL, NULL, NULL, NULL, NULL, 0} }; passwd_data = g_string_new (""); diff --git a/tests/test-login-gobject-multi-prompt b/tests/test-login-gobject-multi-prompt new file mode 100755 index 00000000..7f4f52e8 --- /dev/null +++ b/tests/test-login-gobject-multi-prompt @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner login-multi-prompt test-gobject-greeter |