2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 3 of the License, or (at your option) any
8 * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
16 #include <security/pam_appl.h>
18 #include "lightdm/greeter.h"
22 PROP_DEFAULT_SESSION_HINT,
24 PROP_HAS_GUEST_ACCOUNT_HINT,
25 PROP_SELECT_USER_HINT,
26 PROP_SELECT_GUEST_HINT,
27 PROP_AUTOLOGIN_USER_HINT,
28 PROP_AUTOLOGIN_GUEST_HINT,
29 PROP_AUTOLOGIN_TIMEOUT_HINT,
30 PROP_AUTHENTICATION_USER,
31 PROP_IN_AUTHENTICATION,
32 PROP_IS_AUTHENTICATED,
38 AUTHENTICATION_COMPLETE,
39 AUTOLOGIN_TIMER_EXPIRED,
42 static guint signals[LAST_SIGNAL] = { 0 };
46 GIOChannel *to_server_channel, *from_server_channel;
51 guint autologin_timeout;
53 gchar *authentication_user;
54 gboolean in_authentication;
55 gboolean is_authenticated;
56 guint32 authenticate_sequence_number;
57 gboolean cancelling_authentication;
58 } LightDMGreeterPrivate;
60 G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
62 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
65 #define MAX_MESSAGE_LENGTH 1024
67 /* Messages from the greeter to the server */
70 GREETER_MESSAGE_CONNECT = 0,
71 GREETER_MESSAGE_AUTHENTICATE,
72 GREETER_MESSAGE_AUTHENTICATE_AS_GUEST,
73 GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
74 GREETER_MESSAGE_START_SESSION,
75 GREETER_MESSAGE_CANCEL_AUTHENTICATION
78 /* Messages from the server to the greeter */
81 SERVER_MESSAGE_CONNECTED = 0,
82 SERVER_MESSAGE_PROMPT_AUTHENTICATION,
83 SERVER_MESSAGE_END_AUTHENTICATION,
84 SERVER_MESSAGE_SESSION_RESULT
88 * lightdm_greeter_new:
90 * Create a new greeter.
92 * Return value: the new #LightDMGreeter
95 lightdm_greeter_new ()
97 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
101 timed_login_cb (gpointer data)
103 LightDMGreeter *greeter = data;
104 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
106 priv->autologin_timeout = 0;
107 g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
119 write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
121 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
122 GError *error = NULL;
124 if (g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, NULL) != G_IO_STATUS_NORMAL)
125 g_warning ("Error writing to daemon: %s", error->message);
127 g_debug ("Wrote %zi bytes to daemon", message_length);
128 g_clear_error (&error);
129 g_io_channel_flush (priv->to_server_channel, NULL);
133 write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
135 if (*offset + 4 >= buffer_length)
137 buffer[*offset] = value >> 24;
138 buffer[*offset+1] = (value >> 16) & 0xFF;
139 buffer[*offset+2] = (value >> 8) & 0xFF;
140 buffer[*offset+3] = value & 0xFF;
145 write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
147 gint length = strlen (value);
148 write_int (buffer, buffer_length, length, offset);
149 if (*offset + length >= buffer_length)
151 memcpy (buffer + *offset, value, length);
156 read_int (guint8 *message, gsize message_length, gsize *offset)
161 if (message_length - *offset < int_length ())
163 g_warning ("Not enough space for int, need %i, got %zi", int_length (), message_length - *offset);
167 buffer = message + *offset;
168 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
169 *offset += int_length ();
175 read_string (guint8 *message, gsize message_length, gsize *offset)
180 length = read_int (message, message_length, offset);
181 if (message_length - *offset < length)
183 g_warning ("Not enough space for string, need %u, got %zu", length, message_length - *offset);
184 return g_strdup ("");
187 value = g_malloc (sizeof (gchar) * (length + 1));
188 memcpy (value, message + *offset, length);
189 value[length] = '\0';
196 string_length (const gchar *value)
198 return int_length () + strlen (value);
202 write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
204 write_int (buffer, buffer_length, id, offset);
205 write_int (buffer, buffer_length, length, offset);
209 get_message_length (guint8 *message, gsize message_length)
212 return read_int (message, message_length, &offset);
216 handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
218 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
220 GString *hint_string;
223 version = read_string (message, message_length, offset);
224 hint_string = g_string_new ("");
225 while (*offset < message_length)
229 name = read_string (message, message_length, offset);
230 value = read_string (message, message_length, offset);
231 g_hash_table_insert (priv->hints, name, value);
232 g_string_append_printf (hint_string, " %s=%s", name, value);
235 g_debug ("Connected version=%s%s", version, hint_string->str);
237 g_string_free (hint_string, TRUE);
239 /* Set timeout for default login */
240 timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
243 g_debug ("Setting autologin timer for %d seconds", timeout);
244 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
249 handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
251 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
252 guint32 sequence_number, n_messages, i;
254 sequence_number = read_int (message, message_length, offset);
255 if (sequence_number != priv->authenticate_sequence_number)
257 g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
261 if (priv->cancelling_authentication)
263 g_debug ("Ignoring prompt authentication as waiting for it to cancel");
267 n_messages = read_int (message, message_length, offset);
268 g_debug ("Prompt user with %d message(s)", n_messages);
270 for (i = 0; i < n_messages; i++)
275 msg_style = read_int (message, message_length, offset);
276 msg = read_string (message, message_length, offset);
278 // FIXME: Should stop on prompts?
281 case PAM_PROMPT_ECHO_OFF:
282 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg, LIGHTDM_PROMPT_TYPE_SECRET);
284 case PAM_PROMPT_ECHO_ON:
285 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg, LIGHTDM_PROMPT_TYPE_QUESTION);
288 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg, LIGHTDM_MESSAGE_TYPE_ERROR);
291 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg, LIGHTDM_MESSAGE_TYPE_INFO);
300 handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
302 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
303 guint32 sequence_number, return_code;
305 sequence_number = read_int (message, message_length, offset);
306 return_code = read_int (message, message_length, offset);
308 if (sequence_number != priv->authenticate_sequence_number)
310 g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number);
314 g_debug ("Authentication complete with return code %d", return_code);
315 priv->cancelling_authentication = FALSE;
316 priv->is_authenticated = (return_code == 0);
317 if (!priv->is_authenticated)
319 g_free (priv->authentication_user);
320 priv->authentication_user = NULL;
323 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
324 priv->in_authentication = FALSE;
328 read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
330 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
331 gsize n_to_read, n_read;
333 GError *error = NULL;
335 /* Read the header, or the whole message if we already have that */
336 n_to_read = HEADER_SIZE;
337 if (priv->n_read >= HEADER_SIZE)
338 n_to_read += get_message_length (priv->read_buffer, priv->n_read);
343 status = g_io_channel_read_chars (priv->from_server_channel,
344 (gchar *) priv->read_buffer + priv->n_read,
345 n_to_read - priv->n_read,
348 if (status == G_IO_STATUS_ERROR)
349 g_warning ("Error reading from server: %s", error->message);
350 g_clear_error (&error);
351 if (status != G_IO_STATUS_NORMAL)
354 g_debug ("Read %zi bytes from daemon", n_read);
356 priv->n_read += n_read;
357 } while (priv->n_read < n_to_read && block);
359 /* Stop if haven't got all the data we want */
360 if (priv->n_read != n_to_read)
363 /* If have header, rerun for content */
364 if (priv->n_read == HEADER_SIZE)
366 n_to_read = get_message_length (priv->read_buffer, priv->n_read);
369 priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
370 return read_message (greeter, length, block);
374 buffer = priv->read_buffer;
375 *length = priv->n_read;
377 priv->read_buffer = g_malloc (priv->n_read);
384 from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
386 LightDMGreeter *greeter = data;
388 gsize message_length, offset;
391 message = read_message (greeter, &message_length, FALSE);
396 id = read_int (message, message_length, &offset);
397 read_int (message, message_length, &offset);
400 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
401 handle_prompt_authentication (greeter, message, message_length, &offset);
403 case SERVER_MESSAGE_END_AUTHENTICATION:
404 handle_end_authentication (greeter, message, message_length, &offset);
407 g_warning ("Unknown message from server: %d", id);
416 * lightdm_greeter_connect_sync:
417 * @greeter: The greeter to connect
419 * Connects the greeter to the display manager. Will block until connected.
421 * Return value: #TRUE if successfully connected
424 lightdm_greeter_connect_sync (LightDMGreeter *greeter)
426 LightDMGreeterPrivate *priv;
428 guint8 message[MAX_MESSAGE_LENGTH];
430 gsize response_length, offset = 0;
433 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
435 priv = GET_PRIVATE (greeter);
437 fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
440 g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
443 priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
444 g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL);
446 fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
449 g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
452 priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
453 g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
454 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
456 g_debug ("Connecting to display manager...");
457 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
458 write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
459 write_message (greeter, message, offset);
461 response = read_message (greeter, &response_length, TRUE);
466 id = read_int (response, response_length, &offset);
467 read_int (response, response_length, &offset);
468 if (id == SERVER_MESSAGE_CONNECTED)
469 handle_connected (greeter, response, response_length, &offset);
471 g_warning ("Expected CONNECTED message, got %d", id);
479 * lightdm_greeter_get_hint:
480 * @greeter: A #LightDMGreeter
481 * @name: The hint name to query.
485 * Return value: The value for this hint or #NULL if not set.
488 lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
490 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
491 return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
495 * lightdm_greeter_get_default_session_hint:
496 * @greeter: A #LightDMGreeter
498 * Get the default session to use.
500 * Return value: The session name
503 lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
505 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
506 return lightdm_greeter_get_hint (greeter, "default-session");
510 * lightdm_greeter_get_hide_users_hint:
511 * @greeter: A #LightDMGreeter
513 * Check if user accounts should be shown.
515 * Return value: #TRUE if the available users should not be shown.
518 lightdm_greeter_get_hide_users_hint (LightDMGreeter *greeter)
522 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
523 value = lightdm_greeter_get_hint (greeter, "hide-users");
525 return g_strcmp0 (value, "true") == 0;
529 * lightdm_greeter_get_has_guest_account_hint:
530 * @greeter: A #LightDMGreeter
532 * Check if guest sessions are supported.
534 * Return value: #TRUE if guest sessions are supported.
537 lightdm_greeter_get_has_guest_account_hint (LightDMGreeter *greeter)
541 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
542 value = lightdm_greeter_get_hint (greeter, "has-guest-account");
544 return g_strcmp0 (value, "true") == 0;
548 * lightdm_greeter_get_select_user_hint:
549 * @greeter: A #LightDMGreeter
551 * Get the user to select by default.
553 * Return value: A username
556 lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
558 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
559 return lightdm_greeter_get_hint (greeter, "select-user");
563 * lightdm_greeter_get_select_guest_hint:
564 * @greeter: A #LightDMGreeter
566 * Check if the guest account should be selected by default.
568 * Return value: #TRUE if the guest account should be selected by default.
571 lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter)
575 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
576 value = lightdm_greeter_get_hint (greeter, "select-guest");
578 return g_strcmp0 (value, "true") == 0;
582 * lightdm_greeter_get_autologin_user_hint:
583 * @greeter: A #LightDMGreeter
585 * Get the user account to automatically logg into when the timer expires.
587 * Return value: The user account to automatically log into.
590 lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
592 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
593 return lightdm_greeter_get_hint (greeter, "autologin-user");
597 * lightdm_greeter_get_autologin_guest_hint:
598 * @greeter: A #LightDMGreeter
600 * Check if the guest account should be automatically logged into when the timer expires.
602 * Return value: #TRUE if the guest account should be automatically logged into.
605 lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter)
609 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
610 value = lightdm_greeter_get_hint (greeter, "autologin-guest");
612 return g_strcmp0 (value, "true") == 0;
616 * lightdm_greeter_get_autologin_timeout_hint:
617 * @greeter: A #LightDMGreeter
619 * Get the number of seconds to wait before automaitcally logging in.
621 * Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
624 lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter)
629 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
630 value = lightdm_greeter_get_hint (greeter, "autologin-timeout");
632 timeout = atoi (value);
640 * lightdm_greeter_cancel_autologin:
641 * @greeter: A #LightDMGreeter
643 * Cancel the automatic login.
646 lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
648 LightDMGreeterPrivate *priv;
650 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
652 priv = GET_PRIVATE (greeter);
654 if (priv->autologin_timeout)
655 g_source_remove (priv->autologin_timeout);
656 priv->autologin_timeout = 0;
660 * lightdm_greeter_authenticate:
661 * @greeter: A #LightDMGreeter
662 * @username: (allow-none): A username or #NULL to prompt for a username.
664 * Starts the authentication procedure for a user.
667 lightdm_greeter_authenticate (LightDMGreeter *greeter, const char *username)
669 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
670 guint8 message[MAX_MESSAGE_LENGTH];
673 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
678 priv->cancelling_authentication = FALSE;
679 priv->authenticate_sequence_number++;
680 priv->in_authentication = TRUE;
681 priv->is_authenticated = FALSE;
682 g_free (priv->authentication_user);
683 priv->authentication_user = g_strdup (username);
685 g_debug ("Starting authentication for user %s...", username);
686 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
687 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
688 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
689 write_message (greeter, message, offset);
693 * lightdm_greeter_authenticate_as_guest:
694 * @greeter: A #LightDMGreeter
696 * Starts the authentication procedure for the guest user.
699 lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
701 LightDMGreeterPrivate *priv;
702 guint8 message[MAX_MESSAGE_LENGTH];
705 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
707 priv = GET_PRIVATE (greeter);
709 priv->cancelling_authentication = FALSE;
710 priv->authenticate_sequence_number++;
711 priv->in_authentication = TRUE;
712 priv->is_authenticated = FALSE;
713 g_free (priv->authentication_user);
714 priv->authentication_user = NULL;
716 g_debug ("Starting authentication for guest account...");
717 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
718 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
719 write_message (greeter, message, offset);
723 * lightdm_greeter_respond:
724 * @greeter: A #LightDMGreeter
725 * @response: Response to a prompt
727 * Provide response to a prompt.
730 lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
732 guint8 message[MAX_MESSAGE_LENGTH];
735 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
736 g_return_if_fail (response != NULL);
738 g_debug ("Providing response to display manager");
739 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, int_length () + string_length (response), &offset);
740 // FIXME: Could be multiple responses required
741 write_int (message, MAX_MESSAGE_LENGTH, 1, &offset);
742 write_string (message, MAX_MESSAGE_LENGTH, response, &offset);
743 write_message (greeter, message, offset);
747 * lightdm_greeter_cancel_authentication:
748 * @greeter: A #LightDMGreeter
750 * Cancel the current user authentication.
753 lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
755 LightDMGreeterPrivate *priv;
756 guint8 message[MAX_MESSAGE_LENGTH];
759 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
761 priv = GET_PRIVATE (greeter);
763 priv->cancelling_authentication = TRUE;
764 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
765 write_message (greeter, message, offset);
769 * lightdm_greeter_get_in_authentication:
770 * @greeter: A #LightDMGreeter
772 * Checks if the greeter is in the process of authenticating.
774 * Return value: #TRUE if the greeter is authenticating a user.
777 lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
779 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
780 return GET_PRIVATE (greeter)->in_authentication;
784 * lightdm_greeter_get_is_authenticated:
785 * @greeter: A #LightDMGreeter
787 * Checks if the greeter has successfully authenticated.
789 * Return value: #TRUE if the greeter is authenticated for login.
792 lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
794 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
795 return GET_PRIVATE (greeter)->is_authenticated;
799 * lightdm_greeter_get_authentication_user:
800 * @greeter: A #LightDMGreeter
802 * Get the user that is being authenticated.
804 * Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
807 lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
809 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
810 return GET_PRIVATE (greeter)->authentication_user;
814 * lightdm_greeter_start_session_sync:
815 * @greeter: A #LightDMGreeter
816 * @session: (allow-none): The session to log into or #NULL to use the default.
818 * Start a session for the authenticated user.
820 * Return value: TRUE if the session was started.
823 lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session)
825 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
826 guint8 message[MAX_MESSAGE_LENGTH];
828 gsize response_length, offset = 0;
829 guint32 id, return_code = 1;
831 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
832 g_return_val_if_fail (priv->is_authenticated, FALSE);
837 g_debug ("Starting default session");
840 g_debug ("Starting session %s", session);
842 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
843 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
844 write_message (greeter, message, offset);
846 response = read_message (greeter, &response_length, TRUE);
851 id = read_int (response, response_length, &offset);
852 read_int (response, response_length, &offset);
853 if (id == SERVER_MESSAGE_SESSION_RESULT)
854 return_code = read_int (response, response_length, &offset);
856 g_warning ("Expected SESSION_RESULT message, got %d", id);
860 return return_code == 0;
864 lightdm_greeter_init (LightDMGreeter *greeter)
866 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
868 priv->read_buffer = g_malloc (HEADER_SIZE);
869 priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
873 lightdm_greeter_set_property (GObject *object,
878 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
882 lightdm_greeter_get_property (GObject *object,
887 LightDMGreeter *self;
889 self = LIGHTDM_GREETER (object);
892 case PROP_DEFAULT_SESSION_HINT:
893 g_value_set_string (value, lightdm_greeter_get_default_session_hint (self));
895 case PROP_HIDE_USERS_HINT:
896 g_value_set_boolean (value, lightdm_greeter_get_hide_users_hint (self));
898 case PROP_HAS_GUEST_ACCOUNT_HINT:
899 g_value_set_boolean (value, lightdm_greeter_get_has_guest_account_hint (self));
901 case PROP_SELECT_USER_HINT:
902 g_value_set_string (value, lightdm_greeter_get_select_user_hint (self));
904 case PROP_SELECT_GUEST_HINT:
905 g_value_set_boolean (value, lightdm_greeter_get_select_guest_hint (self));
907 case PROP_AUTOLOGIN_USER_HINT:
908 g_value_set_string (value, lightdm_greeter_get_autologin_user_hint (self));
910 case PROP_AUTOLOGIN_GUEST_HINT:
911 g_value_set_boolean (value, lightdm_greeter_get_autologin_guest_hint (self));
913 case PROP_AUTOLOGIN_TIMEOUT_HINT:
914 g_value_set_int (value, lightdm_greeter_get_autologin_timeout_hint (self));
916 case PROP_AUTHENTICATION_USER:
917 g_value_set_string (value, lightdm_greeter_get_authentication_user (self));
919 case PROP_IN_AUTHENTICATION:
920 g_value_set_boolean (value, lightdm_greeter_get_in_authentication (self));
922 case PROP_IS_AUTHENTICATED:
923 g_value_set_boolean (value, lightdm_greeter_get_is_authenticated (self));
926 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
932 marshal_VOID__STRING_INT (GClosure *closure,
933 GValue *return_value G_GNUC_UNUSED,
934 guint n_param_values,
935 const GValue *param_values,
936 gpointer invocation_hint G_GNUC_UNUSED,
937 gpointer marshal_data)
939 typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1,
943 register GMarshalFunc_VOID__STRING_INT callback;
944 register GCClosure *cc = (GCClosure*) closure;
945 register gpointer data1, data2;
947 g_return_if_fail (n_param_values == 3);
949 if (G_CCLOSURE_SWAP_DATA (closure))
951 data1 = closure->data;
952 data2 = g_value_peek_pointer (param_values + 0);
956 data1 = g_value_peek_pointer (param_values + 0);
957 data2 = closure->data;
959 callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
962 (param_values + 1)->data[0].v_pointer,
963 (param_values + 2)->data[0].v_int,
968 lightdm_greeter_finalize (GObject *object)
970 LightDMGreeter *self = LIGHTDM_GREETER (object);
971 LightDMGreeterPrivate *priv = GET_PRIVATE (self);
973 if (priv->to_server_channel)
974 g_io_channel_unref (priv->to_server_channel);
975 if (priv->from_server_channel)
976 g_io_channel_unref (priv->from_server_channel);
977 g_free (priv->authentication_user);
978 g_hash_table_unref (priv->hints);
980 G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
984 lightdm_greeter_class_init (LightDMGreeterClass *klass)
986 GObjectClass *object_class = G_OBJECT_CLASS (klass);
988 g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
990 object_class->set_property = lightdm_greeter_set_property;
991 object_class->get_property = lightdm_greeter_get_property;
992 object_class->finalize = lightdm_greeter_finalize;
994 g_object_class_install_property (object_class,
995 PROP_DEFAULT_SESSION_HINT,
996 g_param_spec_string ("default-session-hint",
997 "default-session-hint",
998 "Default session hint",
1000 G_PARAM_READWRITE));
1002 g_object_class_install_property (object_class,
1003 PROP_HIDE_USERS_HINT,
1004 g_param_spec_boolean ("hide-users-hint",
1010 g_object_class_install_property (object_class,
1011 PROP_HAS_GUEST_ACCOUNT_HINT,
1012 g_param_spec_boolean ("has-guest-account-hint",
1013 "has-guest-account-hint",
1014 "Has guest account hint",
1018 g_object_class_install_property (object_class,
1019 PROP_SELECT_USER_HINT,
1020 g_param_spec_string ("select-user-hint",
1026 g_object_class_install_property (object_class,
1027 PROP_SELECT_GUEST_HINT,
1028 g_param_spec_boolean ("select-guest-hint",
1029 "select-guest-hint",
1030 "Select guest account hint",
1034 g_object_class_install_property (object_class,
1035 PROP_AUTOLOGIN_USER_HINT,
1036 g_param_spec_string ("autologin-user-hint",
1037 "autologin-user-hint",
1038 "Autologin user hint",
1042 g_object_class_install_property (object_class,
1043 PROP_AUTOLOGIN_GUEST_HINT,
1044 g_param_spec_boolean ("autologin-guest-hint",
1045 "autologin-guest-hint",
1046 "Autologin guest account hint",
1050 g_object_class_install_property (object_class,
1051 PROP_AUTOLOGIN_TIMEOUT_HINT,
1052 g_param_spec_int ("autologin-timeout-hint",
1053 "autologin-timeout-hint",
1054 "Autologin timeout hint",
1058 g_object_class_install_property (object_class,
1059 PROP_AUTHENTICATION_USER,
1060 g_param_spec_string ("authentication-user",
1061 "authentication-user",
1062 "The user being authenticated",
1065 g_object_class_install_property (object_class,
1066 PROP_IN_AUTHENTICATION,
1067 g_param_spec_boolean ("in-authentication",
1068 "in-authentication",
1069 "TRUE if a user is being authenticated",
1072 g_object_class_install_property (object_class,
1073 PROP_IS_AUTHENTICATED,
1074 g_param_spec_boolean ("is-authenticated",
1076 "TRUE if the selected user is authenticated",
1081 * LightDMGreeter::show-prompt:
1082 * @greeter: A #LightDMGreeter
1083 * @text: Prompt text
1084 * @type: Prompt type
1086 * The ::show-prompt signal gets emitted when the greeter should show a
1087 * prompt to the user. The given text should be displayed and an input
1088 * field for the user to provide a response.
1090 * Call lightdm_greeter_respond() with the resultant input or
1091 * lightdm_greeter_cancel_authentication() to abort the authentication.
1093 signals[SHOW_PROMPT] =
1094 g_signal_new ("show-prompt",
1095 G_TYPE_FROM_CLASS (klass),
1097 G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
1099 marshal_VOID__STRING_INT,
1100 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1103 * LightDMGreeter::show-message:
1104 * @greeter: A #LightDMGreeter
1105 * @text: Message text
1106 * @type: Message type
1108 * The ::show-message signal gets emitted when the greeter
1109 * should show a message to the user.
1111 signals[SHOW_MESSAGE] =
1112 g_signal_new ("show-message",
1113 G_TYPE_FROM_CLASS (klass),
1115 G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
1117 marshal_VOID__STRING_INT,
1118 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1121 * LightDMGreeter::authentication-complete:
1122 * @greeter: A #LightDMGreeter
1124 * The ::authentication-complete signal gets emitted when the greeter
1125 * has completed authentication.
1127 * Call lightdm_greeter_get_is_authenticated() to check if the authentication
1130 signals[AUTHENTICATION_COMPLETE] =
1131 g_signal_new ("authentication-complete",
1132 G_TYPE_FROM_CLASS (klass),
1134 G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
1136 g_cclosure_marshal_VOID__VOID,
1140 * LightDMGreeter::autologin-timer-expired:
1141 * @greeter: A #LightDMGreeter
1143 * The ::timed-login signal gets emitted when the automatic login timer has expired.
1144 * The application should then call lightdm_greeter_login().
1146 signals[AUTOLOGIN_TIMER_EXPIRED] =
1147 g_signal_new ("autologin-timer-expired",
1148 G_TYPE_FROM_CLASS (klass),
1150 G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
1152 g_cclosure_marshal_VOID__VOID,