diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | doc/lightdm-gobject-0-sections.txt | 1 | ||||
-rw-r--r-- | liblightdm-gobject/greeter.c | 36 | ||||
-rw-r--r-- | liblightdm-qt/QLightDM/greeter.cpp | 31 | ||||
-rw-r--r-- | src/greeter.c | 34 |
5 files changed, 71 insertions, 35 deletions
@@ -5,7 +5,9 @@ Overview of changes in lightdm 0.4.4 username. * Rename ldm_greeter_provide_secret to ldm_greeter_respond - responses may not be secrets. - * Simplify Vala bindings + * Fix error where an authentication failure from a previous session could + be interpreted as a failure in the current session. + * Simplify Vala bindings and add missing methods Overview of changes in lightdm 0.4.2 diff --git a/doc/lightdm-gobject-0-sections.txt b/doc/lightdm-gobject-0-sections.txt index 5c930cca..ad4ec3c7 100644 --- a/doc/lightdm-gobject-0-sections.txt +++ b/doc/lightdm-gobject-0-sections.txt @@ -152,5 +152,4 @@ LDM_GREETER_GET_CLASS <SUBSECTION Private> LdmGreeterClass LdmGreeterPrivate -ldm_greeter_get_user_defaults </SECTION> diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c index 59be56c8..0170d67c 100644 --- a/liblightdm-gobject/greeter.c +++ b/liblightdm-gobject/greeter.c @@ -106,6 +106,7 @@ struct _LdmGreeterPrivate gchar *authentication_user; gboolean in_authentication; gboolean is_authenticated; + guint32 authenticate_sequence_number; gchar *timed_user; gint login_delay; @@ -324,7 +325,7 @@ from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data) { LdmGreeter *greeter = data; gsize offset; - guint32 id, return_code; + guint32 id, sequence_number, return_code; if (!read_packet (greeter, FALSE)) return TRUE; @@ -365,16 +366,23 @@ from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data) handle_prompt_authentication (greeter, &offset); break; case GREETER_MESSAGE_END_AUTHENTICATION: + sequence_number = read_int (greeter, &offset); return_code = read_int (greeter, &offset); - g_debug ("Authentication complete with return code %d", return_code); - greeter->priv->is_authenticated = (return_code == 0); - if (!greeter->priv->is_authenticated) + + if (sequence_number == greeter->priv->authenticate_sequence_number) { - g_free (greeter->priv->authentication_user); - greeter->priv->authentication_user = NULL; + g_debug ("Authentication complete with return code %d", return_code); + greeter->priv->is_authenticated = (return_code == 0); + if (!greeter->priv->is_authenticated) + { + g_free (greeter->priv->authentication_user); + greeter->priv->authentication_user = NULL; + } + g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0); + greeter->priv->in_authentication = FALSE; } - g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0); - greeter->priv->in_authentication = FALSE; + else + g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number); break; default: g_warning ("Unknown message from server: %d", id); @@ -1282,18 +1290,21 @@ ldm_greeter_login (LdmGreeter *greeter, const char *username) if (!username) username = ""; + greeter->priv->authenticate_sequence_number++; greeter->priv->in_authentication = TRUE; greeter->priv->is_authenticated = FALSE; g_free (greeter->priv->authentication_user); greeter->priv->authentication_user = g_strdup (username); + g_debug ("Starting authentication for user %s...", username); - write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_LOGIN, string_length (username), &offset); + write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_LOGIN, int_length () + string_length (username), &offset); + write_int (message, MAX_MESSAGE_LENGTH, greeter->priv->authenticate_sequence_number, &offset); write_string (message, MAX_MESSAGE_LENGTH, username, &offset); write_message (greeter, message, offset); } /** - * ldm_greeter_login_with_user_promp: + * ldm_greeter_login_with_user_prompt: * @greeter: A #LdmGreeter * * Starts the authentication procedure, prompting the greeter for a username. @@ -1318,12 +1329,15 @@ ldm_greeter_login_as_guest (LdmGreeter *greeter) g_return_if_fail (LDM_IS_GREETER (greeter)); + greeter->priv->authenticate_sequence_number++; greeter->priv->in_authentication = TRUE; greeter->priv->is_authenticated = FALSE; g_free (greeter->priv->authentication_user); greeter->priv->authentication_user = NULL; + g_debug ("Starting authentication for guest account..."); - write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_LOGIN_AS_GUEST, 0, &offset); + write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_LOGIN_AS_GUEST, int_length (), &offset); + write_int (message, MAX_MESSAGE_LENGTH, greeter->priv->authenticate_sequence_number, &offset); write_message (greeter, message, offset); } diff --git a/liblightdm-qt/QLightDM/greeter.cpp b/liblightdm-qt/QLightDM/greeter.cpp index 6dbe6503..344c08fb 100644 --- a/liblightdm-qt/QLightDM/greeter.cpp +++ b/liblightdm-qt/QLightDM/greeter.cpp @@ -77,6 +77,7 @@ public: bool inAuthentication; bool isAuthenticated; QString authenticationUser; + int authenticateSequenceNumber; }; @@ -88,6 +89,7 @@ Greeter::Greeter(QObject *parent) : d->nRead = 0; d->config = 0; d->sessionsModel = new SessionsModel(this); + d->authenticateSequenceNumber = 0; } Greeter::~Greeter() @@ -220,18 +222,22 @@ void Greeter::login(const QString &username) d->isAuthenticated = false; d->authenticationUser = username; qDebug() << "Starting authentication for user " << username << "..."; - writeHeader(GREETER_MESSAGE_LOGIN, stringLength(username)); + writeHeader(GREETER_MESSAGE_LOGIN, intLength() + stringLength(username)); + d->authenticateSequenceNumber++; + writeInt(d->authenticateSequenceNumber); writeString(username); flush(); } void Greeter::loginAsGuest() { + d->authenticateSequenceNumber++; d->inAuthentication = true; d->isAuthenticated = false; d->authenticationUser = ""; qDebug() << "Starting authentication for guest account"; - writeHeader(GREETER_MESSAGE_LOGIN_AS_GUEST, 0); + writeHeader(GREETER_MESSAGE_LOGIN_AS_GUEST, intLength()); + writeInt(d->authenticateSequenceNumber); flush(); } @@ -316,7 +322,7 @@ void Greeter::onRead(int fd) int offset = 0; int id = readInt(&offset); readInt(&offset); - int nMessages, returnCode; + int nMessages, sequenceNumber, returnCode; switch(id) { case GREETER_MESSAGE_CONNECTED: @@ -365,14 +371,21 @@ void Greeter::onRead(int fd) } break; case GREETER_MESSAGE_END_AUTHENTICATION: + sequenceNumber = readInt(&offset); returnCode = readInt(&offset); - qDebug() << "Authentication complete with return code " << returnCode; - d->isAuthenticated = (returnCode == 0); - if(!d->isAuthenticated) { - d->authenticationUser = ""; + + if (sequenceNumber == d->authenticateSequenceNumber) + { + qDebug() << "Authentication complete with return code " << returnCode; + d->isAuthenticated = (returnCode == 0); + if(!d->isAuthenticated) { + d->authenticationUser = ""; + } + emit authenticationComplete(d->isAuthenticated); + d->inAuthentication = false; } - emit authenticationComplete(d->isAuthenticated); - d->inAuthentication = false; + else + qDebug () << "Ignoring end authentication with invalid sequence number " << sequenceNumber; break; default: qDebug() << "Unknown message from server: " << id; diff --git a/src/greeter.c b/src/greeter.c index 9df8655f..3e1ea286 100644 --- a/src/greeter.c +++ b/src/greeter.c @@ -57,6 +57,9 @@ struct GreeterPrivate /* Timeout for greeter to respond to quit request */ guint quit_timeout; + /* Sequence number of current PAM session */ + guint32 authentication_sequence_number; + /* PAM session being constructed by the greeter */ PAMSession *pam_session; @@ -225,12 +228,13 @@ pam_messages_cb (PAMSession *session, int num_msg, const struct pam_message **ms } static void -send_end_authentication (Greeter *greeter, int result) +send_end_authentication (Greeter *greeter, guint32 sequence_number, int result) { guint8 message[MAX_MESSAGE_LENGTH]; gsize offset = 0; - write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_END_AUTHENTICATION, int_length (), &offset); + write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_END_AUTHENTICATION, int_length () + int_length (), &offset); + write_int (message, MAX_MESSAGE_LENGTH, sequence_number, &offset); write_int (message, MAX_MESSAGE_LENGTH, result, &offset); write_message (greeter, message, offset); } @@ -247,7 +251,7 @@ authentication_result_cb (PAMSession *session, int result, Greeter *greeter) pam_session_authorize (session); } - send_end_authentication (greeter, result); + send_end_authentication (greeter, greeter->priv->authentication_sequence_number, result); } static void @@ -266,7 +270,7 @@ reset_session (Greeter *greeter) } static void -start_authentication (Greeter *greeter, PAMSession *session) +start_authentication (Greeter *greeter, guint32 sequence_number, PAMSession *session) { GError *error = NULL; @@ -275,6 +279,7 @@ start_authentication (Greeter *greeter, PAMSession *session) // return; greeter->priv->pam_session = session; + greeter->priv->authentication_sequence_number = sequence_number; g_signal_connect (G_OBJECT (greeter->priv->pam_session), "got-messages", G_CALLBACK (pam_messages_cb), greeter); g_signal_connect (G_OBJECT (greeter->priv->pam_session), "authentication-result", G_CALLBACK (authentication_result_cb), greeter); @@ -282,12 +287,12 @@ start_authentication (Greeter *greeter, PAMSession *session) if (!pam_session_start (greeter->priv->pam_session, &error)) { g_warning ("Failed to start authentication: %s", error->message); - send_end_authentication (greeter, PAM_SYSTEM_ERR); + send_end_authentication (greeter, sequence_number, PAM_SYSTEM_ERR); } } static void -handle_login (Greeter *greeter, const gchar *username) +handle_login (Greeter *greeter, guint32 sequence_number, const gchar *username) { if (username[0] == '\0') { @@ -299,11 +304,11 @@ handle_login (Greeter *greeter, const gchar *username) reset_session (greeter); greeter->priv->using_guest_account = FALSE; - start_authentication (greeter, pam_session_new ("lightdm"/*FIXMEgreeter->priv->pam_service*/, username)); + start_authentication (greeter, sequence_number, pam_session_new ("lightdm"/*FIXMEgreeter->priv->pam_service*/, username)); } static void -handle_login_as_guest (Greeter *greeter) +handle_login_as_guest (Greeter *greeter, guint32 sequence_number) { g_debug ("Greeter start authentication for guest account"); @@ -312,19 +317,19 @@ handle_login_as_guest (Greeter *greeter) if (!guest_account_get_is_enabled ()) { g_debug ("Guest account is disabled"); - send_end_authentication (greeter, PAM_USER_UNKNOWN); + send_end_authentication (greeter, sequence_number, PAM_USER_UNKNOWN); return; } if (!guest_account_ref ()) { g_debug ("Unable to create guest account"); - send_end_authentication (greeter, PAM_USER_UNKNOWN); + send_end_authentication (greeter, sequence_number, PAM_USER_UNKNOWN); return; } greeter->priv->using_guest_account = TRUE; - start_authentication (greeter, pam_session_new ("lightdm-autologin"/*FIXMEgreeter->priv->pam_service*/, guest_account_get_username ())); + start_authentication (greeter, sequence_number, pam_session_new ("lightdm-autologin"/*FIXMEgreeter->priv->pam_service*/, guest_account_get_username ())); } static void @@ -475,6 +480,7 @@ got_data_cb (Greeter *greeter) gsize n_to_read, n_read, offset; GIOStatus status; int id, n_secrets, i; + guint32 sequence_number; gchar *username, *session_name; gchar **secrets; GError *error = NULL; @@ -527,12 +533,14 @@ got_data_cb (Greeter *greeter) handle_connect (greeter); break; case GREETER_MESSAGE_LOGIN: + sequence_number = read_int (greeter, &offset); username = read_string (greeter, &offset); - handle_login (greeter, username); + handle_login (greeter, sequence_number, username); g_free (username); break; case GREETER_MESSAGE_LOGIN_AS_GUEST: - handle_login_as_guest (greeter); + sequence_number = read_int (greeter, &offset); + handle_login_as_guest (greeter, sequence_number); break; case GREETER_MESSAGE_CONTINUE_AUTHENTICATION: n_secrets = read_int (greeter, &offset); |