diff options
Diffstat (limited to 'src/greeter.c')
-rw-r--r-- | src/greeter.c | 284 |
1 files changed, 126 insertions, 158 deletions
diff --git a/src/greeter.c b/src/greeter.c index 1bbed854..bf725ac3 100644 --- a/src/greeter.c +++ b/src/greeter.c @@ -24,7 +24,7 @@ enum { enum { CONNECTED, - DISCONNECTED, + DISCONNECTED, CREATE_SESSION, START_SESSION, LAST_SIGNAL @@ -111,7 +111,7 @@ typedef enum SERVER_MESSAGE_SHARED_DIR_RESULT, SERVER_MESSAGE_IDLE, SERVER_MESSAGE_RESET, - SERVER_MESSAGE_CONNECTED_V2, + SERVER_MESSAGE_CONNECTED_V2, } ServerMessage; static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data); @@ -125,24 +125,25 @@ greeter_new (void) void greeter_set_file_descriptors (Greeter *greeter, int to_greeter_fd, int from_greeter_fd) { - g_autoptr(GError) to_error = NULL; - g_autoptr(GError) from_error = NULL; - g_return_if_fail (greeter != NULL); g_return_if_fail (greeter->priv->to_greeter_input < 0); g_return_if_fail (greeter->priv->from_greeter_output < 0); - greeter->priv->to_greeter_input = to_greeter_fd; + greeter->priv->to_greeter_input = to_greeter_fd; greeter->priv->to_greeter_channel = g_io_channel_unix_new (greeter->priv->to_greeter_input); + g_autoptr(GError) to_error = NULL; g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, &to_error); if (to_error) g_warning ("Failed to set encoding on to greeter channel to binary: %s\n", to_error->message); + greeter->priv->from_greeter_output = from_greeter_fd; greeter->priv->from_greeter_channel = g_io_channel_unix_new (greeter->priv->from_greeter_output); + g_autoptr(GError) from_error = NULL; g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, &from_error); if (from_error) g_warning ("Failed to set encoding on from greeter channel to binary: %s\n", from_error->message); g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE); + greeter->priv->from_greeter_watch = g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter); } @@ -167,7 +168,7 @@ greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gcha void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest) { - g_return_if_fail (greeter != NULL); + g_return_if_fail (greeter != NULL); greeter->priv->allow_guest = allow_guest; } @@ -215,9 +216,7 @@ secure_free (Greeter *greeter, void *ptr) static void secure_freev (Greeter *greeter, gchar **v) { - int i; - - for (i = 0; v[i]; i++) + for (int i = 0; v[i]; i++) secure_free (greeter, v[i]); g_free (v); } @@ -234,17 +233,14 @@ int_length (void) static void write_message (Greeter *greeter, guint8 *message, gsize message_length) { - gchar *data; - gsize data_length; - g_autoptr(GError) error = NULL; - - data = (gchar *) message; - data_length = message_length; + gchar *data = (gchar *) message; + gsize data_length = message_length; while (data_length > 0) { GIOStatus status; gsize n_written; + g_autoptr(GError) error = NULL; status = g_io_channel_write_chars (greeter->priv->to_greeter_channel, data, data_length, &n_written, &error); if (error) g_warning ("Error writing to greeter: %s", error->message); @@ -254,6 +250,7 @@ write_message (Greeter *greeter, guint8 *message, gsize message_length) data += n_written; } + g_autoptr(GError) error = NULL; g_io_channel_flush (greeter->priv->to_greeter_channel, &error); if (error) g_warning ("Failed to flush data to greeter: %s", error->message); @@ -275,7 +272,6 @@ static void write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset) { gint length; - if (value) length = strlen (value); else @@ -309,21 +305,20 @@ string_length (const gchar *value) static void handle_connect (Greeter *greeter, const gchar *version, gboolean resettable, guint32 api_version) { - guint8 message[MAX_MESSAGE_LENGTH]; - gsize offset = 0; - guint32 env_length = 0; - GHashTableIter iter; - gpointer key, value; - g_debug ("Greeter connected version=%s api=%u resettable=%s", version, api_version, resettable ? "true" : "false"); greeter->priv->api_version = api_version; greeter->priv->resettable = resettable; + guint32 env_length = 0; + GHashTableIter iter; g_hash_table_iter_init (&iter, greeter->priv->hints); + gpointer key, value; while (g_hash_table_iter_next (&iter, &key, &value)) env_length += string_length (key) + string_length (value); + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; if (api_version == 0) { write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_CONNECTED, string_length (VERSION) + env_length, &offset); @@ -356,28 +351,23 @@ handle_connect (Greeter *greeter, const gchar *version, gboolean resettable, gui static void pam_messages_cb (Session *session, Greeter *greeter) { - int i; - guint32 size; - guint8 message[MAX_MESSAGE_LENGTH]; - const struct pam_message *messages; - int messages_length; - gsize offset = 0; - int n_prompts = 0; - - messages = session_get_messages (session); - messages_length = session_get_messages_length (session); + const struct pam_message *messages = session_get_messages (session); + int messages_length = session_get_messages_length (session); /* Respond to d-bus query with messages */ g_debug ("Prompt greeter with %d message(s)", messages_length); - size = int_length () + string_length (session_get_username (session)) + int_length (); - for (i = 0; i < messages_length; i++) + guint32 size = int_length () + string_length (session_get_username (session)) + int_length (); + for (int i = 0; i < messages_length; i++) size += int_length () + string_length (messages[i].msg); + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_PROMPT_AUTHENTICATION, size, &offset); write_int (message, MAX_MESSAGE_LENGTH, greeter->priv->authentication_sequence_number, &offset); write_string (message, MAX_MESSAGE_LENGTH, session_get_username (session), &offset); write_int (message, MAX_MESSAGE_LENGTH, messages_length, &offset); - for (i = 0; i < messages_length; i++) + int n_prompts = 0; + for (int i = 0; i < messages_length; i++) { write_int (message, MAX_MESSAGE_LENGTH, messages[i].msg_style, &offset); write_string (message, MAX_MESSAGE_LENGTH, messages[i].msg, &offset); @@ -403,7 +393,6 @@ send_end_authentication (Greeter *greeter, guint32 sequence_number, const gchar { guint8 message[MAX_MESSAGE_LENGTH]; gsize offset = 0; - write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_END_AUTHENTICATION, int_length () + string_length (username) + int_length (), &offset); write_int (message, MAX_MESSAGE_LENGTH, sequence_number, &offset); write_string (message, MAX_MESSAGE_LENGTH, username, &offset); @@ -416,7 +405,6 @@ greeter_idle (Greeter *greeter) { guint8 message[MAX_MESSAGE_LENGTH]; gsize offset = 0; - write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_IDLE, 0, &offset); write_message (greeter, message, offset); } @@ -424,18 +412,17 @@ greeter_idle (Greeter *greeter) void greeter_reset (Greeter *greeter) { - guint8 message[MAX_MESSAGE_LENGTH]; - gsize offset = 0; - guint32 length = 0; - GHashTableIter iter; - gpointer key, value; - g_return_if_fail (greeter != NULL); + GHashTableIter iter; g_hash_table_iter_init (&iter, greeter->priv->hints); + gpointer key, value; + guint32 length = 0; while (g_hash_table_iter_next (&iter, &key, &value)) length += string_length (key) + string_length (value); + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_RESET, length, &offset); g_hash_table_iter_init (&iter, greeter->priv->hints); while (g_hash_table_iter_next (&iter, &key, &value)) @@ -449,11 +436,9 @@ greeter_reset (Greeter *greeter) static void authentication_complete_cb (Session *session, Greeter *greeter) { - int result; - g_debug ("Authenticate result for user %s: %s", session_get_username (session), session_get_authentication_result_string (session)); - result = session_get_authentication_result (session); + int result = session_get_authentication_result (session); if (session_get_is_authenticated (session)) { if (session_get_user (session)) @@ -486,9 +471,6 @@ reset_session (Greeter *greeter) static void handle_authenticate (Greeter *greeter, guint32 sequence_number, const gchar *username) { - const gchar *autologin_username, *service; - gboolean is_interactive; - if (username[0] == '\0') { g_debug ("Greeter start authentication"); @@ -516,7 +498,9 @@ handle_authenticate (Greeter *greeter, guint32 sequence_number, const gchar *use g_signal_connect (G_OBJECT (greeter->priv->authentication_session), SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), greeter); /* Use non-interactive service for autologin user */ - autologin_username = g_hash_table_lookup (greeter->priv->hints, "autologin-user"); + const gchar *autologin_username = g_hash_table_lookup (greeter->priv->hints, "autologin-user"); + const gchar *service; + gboolean is_interactive; if (autologin_username != NULL && g_strcmp0 (username, autologin_username) == 0) { service = greeter->priv->autologin_pam_service; @@ -557,27 +541,20 @@ handle_authenticate_as_guest (Greeter *greeter, guint32 sequence_number) static gchar * get_remote_session_service (const gchar *session_name) { - g_autoptr(GKeyFile) session_desktop_file = NULL; - gboolean result; - const gchar *c; - g_autofree gchar *remote_sessions_dir = NULL; - g_autofree gchar *filename = NULL; - g_autofree gchar *path = NULL; - g_autoptr(GError) error = NULL; - /* Validate session name doesn't contain directory separators */ - for (c = session_name; *c; c++) + for (const gchar *c = session_name; *c; c++) { if (*c == '/') return NULL; } /* Load the session file */ - session_desktop_file = g_key_file_new (); - filename = g_strdup_printf ("%s.desktop", session_name); - remote_sessions_dir = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory"); - path = g_build_filename (remote_sessions_dir, filename, NULL); - result = g_key_file_load_from_file (session_desktop_file, path, G_KEY_FILE_NONE, &error); + g_autoptr(GKeyFile) session_desktop_file = g_key_file_new (); + g_autofree gchar *filename = g_strdup_printf ("%s.desktop", session_name); + g_autofree gchar *remote_sessions_dir = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory"); + g_autofree gchar *path = g_build_filename (remote_sessions_dir, filename, NULL); + g_autoptr(GError) error = NULL; + gboolean result = g_key_file_load_from_file (session_desktop_file, path, G_KEY_FILE_NONE, &error); if (error) g_debug ("Failed to load session file %s: %s", path, error->message); if (!result) @@ -589,8 +566,6 @@ get_remote_session_service (const gchar *session_name) static void handle_authenticate_remote (Greeter *greeter, const gchar *session_name, const gchar *username, guint32 sequence_number) { - g_autofree gchar *service = NULL; - if (username[0] == '\0') { g_debug ("Greeter start authentication for remote session %s", session_name); @@ -601,7 +576,7 @@ handle_authenticate_remote (Greeter *greeter, const gchar *session_name, const g reset_session (greeter); - service = get_remote_session_service (session_name); + g_autofree gchar *service = get_remote_session_service (session_name); if (!service) { send_end_authentication (greeter, sequence_number, "", PAM_SYSTEM_ERR); @@ -635,20 +610,16 @@ handle_authenticate_remote (Greeter *greeter, const gchar *session_name, const g static void handle_continue_authentication (Greeter *greeter, gchar **secrets) { - int messages_length; - const struct pam_message *messages; - struct pam_response *response; - int i, j, n_prompts = 0; - /* Not in authentication */ if (greeter->priv->authentication_session == NULL) return; - messages_length = session_get_messages_length (greeter->priv->authentication_session); - messages = session_get_messages (greeter->priv->authentication_session); + int messages_length = session_get_messages_length (greeter->priv->authentication_session); + const struct pam_message *messages = session_get_messages (greeter->priv->authentication_session); /* Check correct number of responses */ - for (i = 0; i < messages_length; i++) + int n_prompts = 0; + for (int i = 0; i < messages_length; i++) { int msg_style = messages[i].msg_style; if (msg_style == PAM_PROMPT_ECHO_OFF || msg_style == PAM_PROMPT_ECHO_ON) @@ -663,8 +634,8 @@ handle_continue_authentication (Greeter *greeter, gchar **secrets) g_debug ("Continue authentication"); /* Build response */ - response = calloc (messages_length, sizeof (struct pam_response)); - for (i = 0, j = 0; i < messages_length; i++) + struct pam_response *response = calloc (messages_length, sizeof (struct pam_response)); + for (int i = 0, j = 0; i < messages_length; i++) { int msg_style = messages[i].msg_style; if (msg_style == PAM_PROMPT_ECHO_OFF || msg_style == PAM_PROMPT_ECHO_ON) @@ -678,7 +649,7 @@ handle_continue_authentication (Greeter *greeter, gchar **secrets) session_respond (greeter->priv->authentication_session, response); - for (i = 0; i < messages_length; i++) + for (int i = 0; i < messages_length; i++) secure_free (greeter, response[i].resp); free (response); } @@ -697,21 +668,18 @@ handle_cancel_authentication (Greeter *greeter) static void handle_start_session (Greeter *greeter, const gchar *session) { - gboolean result; - guint8 message[MAX_MESSAGE_LENGTH]; - gsize offset = 0; - SessionType session_type = SESSION_TYPE_LOCAL; - if (strcmp (session, "") == 0) session = NULL; /* Use session type chosen in remote session */ + SessionType session_type = SESSION_TYPE_LOCAL; if (greeter->priv->remote_session) { session_type = SESSION_TYPE_REMOTE; session = greeter->priv->remote_session; } + gboolean result; if (greeter->priv->guest_account_authenticated || session_get_is_authenticated (greeter->priv->authentication_session)) { if (session) @@ -727,6 +695,8 @@ handle_start_session (Greeter *greeter, const gchar *session) result = FALSE; } + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SESSION_RESULT, int_length (), &offset); write_int (message, MAX_MESSAGE_LENGTH, result ? 0 : 1, &offset); write_message (greeter, message, offset); @@ -735,8 +705,6 @@ handle_start_session (Greeter *greeter, const gchar *session) static void handle_set_language (Greeter *greeter, const gchar *language) { - User *user; - if (!greeter->priv->guest_account_authenticated && !session_get_is_authenticated (greeter->priv->authentication_session)) { g_debug ("Ignoring set language request, user is not authorized"); @@ -751,21 +719,19 @@ handle_set_language (Greeter *greeter, const gchar *language) } g_debug ("Greeter sets language %s", language); - user = session_get_user (greeter->priv->authentication_session); + User *user = session_get_user (greeter->priv->authentication_session); user_set_language (user, language); } static void handle_ensure_shared_dir (Greeter *greeter, const gchar *username) { - g_autofree gchar *dir = NULL; - guint8 message[MAX_MESSAGE_LENGTH]; - gsize offset = 0; - g_debug ("Greeter requests data directory for user %s", username); - dir = shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), username); + g_autofree gchar *dir = shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), username); + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SHARED_DIR_RESULT, string_length (dir), &offset); write_string (message, MAX_MESSAGE_LENGTH, dir, &offset); write_message (greeter, message, offset); @@ -774,15 +740,13 @@ handle_ensure_shared_dir (Greeter *greeter, const gchar *username) static guint32 read_int (Greeter *greeter, gsize *offset) { - guint32 value; - guint8 *buffer; if (greeter->priv->n_read - *offset < sizeof (guint32)) { g_warning ("Not enough space for int, need %zu, got %zu", sizeof (guint32), greeter->priv->n_read - *offset); return 0; } - buffer = greeter->priv->read_buffer + *offset; - value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; + guint8 *buffer = greeter->priv->read_buffer + *offset; + guint32 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; *offset += int_length (); return value; } @@ -808,17 +772,14 @@ get_message_length (Greeter *greeter) static gchar * read_string_full (Greeter *greeter, gsize *offset, void* (*alloc_fn)(size_t n)) { - guint32 length; - gchar *value; - - length = read_int (greeter, offset); + guint32 length = read_int (greeter, offset); if (greeter->priv->n_read - *offset < length) { g_warning ("Not enough space for string, need %u, got %zu", length, greeter->priv->n_read - *offset); return g_strdup (""); } - value = (*alloc_fn) (sizeof (gchar) * (length + 1)); + gchar *value = (*alloc_fn) (sizeof (gchar) * (length + 1)); memcpy (value, greeter->priv->read_buffer + *offset, length); value[length] = '\0'; *offset += length; @@ -845,18 +806,6 @@ static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data) { Greeter *greeter = data; - gsize n_to_read, n_read, offset; - GIOStatus status; - int id, length, i; - guint32 sequence_number, n_secrets, max_secrets; - g_autofree gchar *version = NULL; - g_autofree gchar *username = NULL; - g_autofree gchar *session_name = NULL; - g_autofree gchar *language = NULL; - gchar **secrets; - gboolean resettable = FALSE; - guint32 api_version = 0; - g_autoptr(GError) error = NULL; if (condition == G_IO_HUP) { @@ -866,7 +815,7 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) return FALSE; } - n_to_read = HEADER_SIZE; + gsize n_to_read = HEADER_SIZE; if (greeter->priv->n_read >= HEADER_SIZE) { n_to_read = get_message_length (greeter); @@ -877,11 +826,13 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) } } - status = g_io_channel_read_chars (greeter->priv->from_greeter_channel, - (gchar *) greeter->priv->read_buffer + greeter->priv->n_read, - n_to_read - greeter->priv->n_read, - &n_read, - &error); + gsize n_read; + g_autoptr(GError) error = NULL; + GIOStatus status = g_io_channel_read_chars (greeter->priv->from_greeter_channel, + (gchar *) greeter->priv->read_buffer + greeter->priv->n_read, + n_to_read - greeter->priv->n_read, + &n_read, + &error); if (error) g_warning ("Error reading from greeter: %s", error->message); if (status == G_IO_STATUS_EOF) @@ -910,64 +861,83 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) } } - offset = 0; - id = read_int (greeter, &offset); - length = HEADER_SIZE + read_int (greeter, &offset); + gsize offset = 0; + int id = read_int (greeter, &offset); + int length = HEADER_SIZE + read_int (greeter, &offset); switch (id) { case GREETER_MESSAGE_CONNECT: - version = read_string (greeter, &offset); - if (offset < length) - resettable = read_int (greeter, &offset) != 0; - if (offset < length) - api_version = read_int (greeter, &offset); - handle_connect (greeter, version, resettable, api_version); + { + g_autofree gchar *version = read_string (greeter, &offset); + gboolean resettable = FALSE; + if (offset < length) + resettable = read_int (greeter, &offset) != 0; + guint32 api_version = 0; + if (offset < length) + api_version = read_int (greeter, &offset); + handle_connect (greeter, version, resettable, api_version); + } break; case GREETER_MESSAGE_AUTHENTICATE: - sequence_number = read_int (greeter, &offset); - username = read_string (greeter, &offset); - handle_authenticate (greeter, sequence_number, username); + { + guint32 sequence_number = read_int (greeter, &offset); + g_autofree gchar *username = read_string (greeter, &offset); + handle_authenticate (greeter, sequence_number, username); + } break; case GREETER_MESSAGE_AUTHENTICATE_AS_GUEST: - sequence_number = read_int (greeter, &offset); - handle_authenticate_as_guest (greeter, sequence_number); + { + guint32 sequence_number = read_int (greeter, &offset); + handle_authenticate_as_guest (greeter, sequence_number); + } break; case GREETER_MESSAGE_AUTHENTICATE_REMOTE: - sequence_number = read_int (greeter, &offset); - session_name = read_string (greeter, &offset); - username = read_string (greeter, &offset); - handle_authenticate_remote (greeter, session_name, username, sequence_number); + { + guint32 sequence_number = read_int (greeter, &offset); + g_autofree gchar *session_name = read_string (greeter, &offset); + g_autofree gchar *username = read_string (greeter, &offset); + handle_authenticate_remote (greeter, session_name, username, sequence_number); + } break; case GREETER_MESSAGE_CONTINUE_AUTHENTICATION: - n_secrets = read_int (greeter, &offset); - max_secrets = (G_MAXUINT32 - 1) / sizeof (gchar *); - if (n_secrets > max_secrets) { - g_warning ("Array length of %u elements too long", n_secrets); - greeter->priv->from_greeter_watch = 0; - return FALSE; + guint32 n_secrets = read_int (greeter, &offset); + guint32 max_secrets = (G_MAXUINT32 - 1) / sizeof (gchar *); + if (n_secrets > max_secrets) + { + g_warning ("Array length of %u elements too long", n_secrets); + greeter->priv->from_greeter_watch = 0; + return FALSE; + } + gchar **secrets = g_malloc (sizeof (gchar *) * (n_secrets + 1)); + guint32 i; + for (i = 0; i < n_secrets; i++) + secrets[i] = read_secret (greeter, &offset); + secrets[i] = NULL; + handle_continue_authentication (greeter, secrets); + secure_freev (greeter, secrets); } - secrets = g_malloc (sizeof (gchar *) * (n_secrets + 1)); - for (i = 0; i < n_secrets; i++) - secrets[i] = read_secret (greeter, &offset); - secrets[i] = NULL; - handle_continue_authentication (greeter, secrets); - secure_freev (greeter, secrets); break; case GREETER_MESSAGE_CANCEL_AUTHENTICATION: handle_cancel_authentication (greeter); break; case GREETER_MESSAGE_START_SESSION: - session_name = read_string (greeter, &offset); - handle_start_session (greeter, session_name); + { + g_autofree gchar *session_name = read_string (greeter, &offset); + handle_start_session (greeter, session_name); + } break; case GREETER_MESSAGE_SET_LANGUAGE: - language = read_string (greeter, &offset); - handle_set_language (greeter, language); + { + g_autofree gchar *language = read_string (greeter, &offset); + handle_set_language (greeter, language); + } break; case GREETER_MESSAGE_ENSURE_SHARED_DIR: - username = read_string (greeter, &offset); - handle_ensure_shared_dir (greeter, username); + { + g_autofree gchar *username = read_string (greeter, &offset); + handle_ensure_shared_dir (greeter, username); + } break; default: g_warning ("Unknown message from greeter: %d", id); @@ -989,11 +959,9 @@ greeter_get_guest_authenticated (Greeter *greeter) Session * greeter_take_authentication_session (Greeter *greeter) { - Session *session; - g_return_val_if_fail (greeter != NULL, NULL); - session = greeter->priv->authentication_session; + Session *session = greeter->priv->authentication_session; if (greeter->priv->authentication_session) g_signal_handlers_disconnect_matched (greeter->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter); greeter->priv->authentication_session = NULL; |