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,
39 AUTHENTICATION_COMPLETE,
41 AUTOLOGIN_TIMER_EXPIRED,
45 static guint signals[LAST_SIGNAL] = { 0 };
49 GIOChannel *to_server_channel, *from_server_channel;
54 guint autologin_timeout;
56 gchar *authentication_user;
57 gboolean in_authentication;
58 gboolean is_authenticated;
59 guint32 authenticate_sequence_number;
60 gboolean cancelling_authentication;
61 } LightDMGreeterPrivate;
63 G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
65 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
68 #define MAX_MESSAGE_LENGTH 1024
70 /* Messages from the greeter to the server */
73 GREETER_MESSAGE_CONNECT = 0,
74 GREETER_MESSAGE_AUTHENTICATE,
75 GREETER_MESSAGE_AUTHENTICATE_AS_GUEST,
76 GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
77 GREETER_MESSAGE_START_SESSION,
78 GREETER_MESSAGE_CANCEL_AUTHENTICATION
81 /* Messages from the server to the greeter */
84 SERVER_MESSAGE_CONNECTED = 0,
86 SERVER_MESSAGE_PROMPT_AUTHENTICATION,
87 SERVER_MESSAGE_END_AUTHENTICATION,
88 SERVER_MESSAGE_SESSION_FAILED,
92 * lightdm_greeter_new:
94 * Create a new greeter.
96 * Return value: the new #LightDMGreeter
99 lightdm_greeter_new ()
101 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
105 timed_login_cb (gpointer data)
107 LightDMGreeter *greeter = data;
108 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
110 priv->autologin_timeout = 0;
111 g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
123 write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
125 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
126 GError *error = NULL;
128 if (g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, NULL) != G_IO_STATUS_NORMAL)
129 g_warning ("Error writing to daemon: %s", error->message);
131 g_debug ("Wrote %zi bytes to daemon", message_length);
132 g_clear_error (&error);
133 g_io_channel_flush (priv->to_server_channel, NULL);
137 write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
139 if (*offset + 4 >= buffer_length)
141 buffer[*offset] = value >> 24;
142 buffer[*offset+1] = (value >> 16) & 0xFF;
143 buffer[*offset+2] = (value >> 8) & 0xFF;
144 buffer[*offset+3] = value & 0xFF;
149 write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
151 gint length = strlen (value);
152 write_int (buffer, buffer_length, length, offset);
153 if (*offset + length >= buffer_length)
155 memcpy (buffer + *offset, value, length);
160 read_int (LightDMGreeter *greeter, gsize *offset)
162 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
166 if (priv->n_read - *offset < int_length ())
168 g_warning ("Not enough space for int, need %i, got %zi", int_length (), priv->n_read - *offset);
172 buffer = priv->read_buffer + *offset;
173 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
174 *offset += int_length ();
180 read_string (LightDMGreeter *greeter, gsize *offset)
182 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
186 length = read_int (greeter, offset);
187 if (priv->n_read - *offset < length)
189 g_warning ("Not enough space for string, need %u, got %zu", length, priv->n_read - *offset);
190 return g_strdup ("");
193 value = g_malloc (sizeof (gchar) * (length + 1));
194 memcpy (value, priv->read_buffer + *offset, length);
195 value[length] = '\0';
202 string_length (const gchar *value)
204 return int_length () + strlen (value);
208 write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
210 write_int (buffer, buffer_length, id, offset);
211 write_int (buffer, buffer_length, length, offset);
214 static guint32 get_packet_length (LightDMGreeter *greeter)
217 return read_int (greeter, &offset);
221 handle_connected (LightDMGreeter *greeter, guint32 length, gsize *offset)
223 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
225 GString *hint_string;
228 version = read_string (greeter, offset);
229 hint_string = g_string_new ("");
230 while (*offset < length)
234 name = read_string (greeter, offset);
235 value = read_string (greeter, offset);
236 g_hash_table_insert (priv->hints, name, value);
237 g_string_append_printf (hint_string, " %s=%s", name, value);
240 g_debug ("Connected version=%s%s", version, hint_string->str);
242 g_string_free (hint_string, TRUE);
244 /* Set timeout for default login */
245 timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
248 g_debug ("Setting autologin timer for %d seconds", timeout);
249 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
251 g_signal_emit (G_OBJECT (greeter), signals[CONNECTED], 0);
255 handle_prompt_authentication (LightDMGreeter *greeter, gsize *offset)
257 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
258 guint32 sequence_number, n_messages, i;
260 sequence_number = read_int (greeter, offset);
261 if (sequence_number != priv->authenticate_sequence_number)
263 g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
267 if (priv->cancelling_authentication)
269 g_debug ("Ignoring prompt authentication as waiting for it to cancel");
273 n_messages = read_int (greeter, offset);
274 g_debug ("Prompt user with %d message(s)", n_messages);
276 for (i = 0; i < n_messages; i++)
281 msg_style = read_int (greeter, offset);
282 msg = read_string (greeter, offset);
284 // FIXME: Should stop on prompts?
287 case PAM_PROMPT_ECHO_OFF:
288 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg, LIGHTDM_PROMPT_TYPE_SECRET);
290 case PAM_PROMPT_ECHO_ON:
291 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg, LIGHTDM_PROMPT_TYPE_QUESTION);
294 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg, LIGHTDM_MESSAGE_TYPE_ERROR);
297 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg, LIGHTDM_MESSAGE_TYPE_INFO);
306 handle_end_authentication (LightDMGreeter *greeter, gsize *offset)
308 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
309 guint32 sequence_number, return_code;
311 sequence_number = read_int (greeter, offset);
312 return_code = read_int (greeter, offset);
314 if (sequence_number != priv->authenticate_sequence_number)
316 g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number);
320 g_debug ("Authentication complete with return code %d", return_code);
321 priv->cancelling_authentication = FALSE;
322 priv->is_authenticated = (return_code == 0);
323 if (!priv->is_authenticated)
325 g_free (priv->authentication_user);
326 priv->authentication_user = NULL;
328 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
329 priv->in_authentication = FALSE;
333 handle_session_failed (LightDMGreeter *greeter, gsize *offset)
335 g_debug ("Session failed to start");
336 g_signal_emit (G_OBJECT (greeter), signals[SESSION_FAILED], 0);
340 handle_quit (LightDMGreeter *greeter, gsize *offset)
342 g_debug ("Got quit request from server");
343 g_signal_emit (G_OBJECT (greeter), signals[QUIT], 0);
347 read_packet (LightDMGreeter *greeter, gboolean block)
349 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
350 gsize n_to_read, n_read;
351 GError *error = NULL;
353 /* Read the header, or the whole packet if we already have that */
354 n_to_read = HEADER_SIZE;
355 if (priv->n_read >= HEADER_SIZE)
356 n_to_read += get_packet_length (greeter);
361 status = g_io_channel_read_chars (priv->from_server_channel,
362 (gchar *) priv->read_buffer + priv->n_read,
363 n_to_read - priv->n_read,
366 if (status == G_IO_STATUS_ERROR)
367 g_warning ("Error reading from server: %s", error->message);
368 g_clear_error (&error);
369 if (status != G_IO_STATUS_NORMAL)
372 g_debug ("Read %zi bytes from daemon", n_read);
374 priv->n_read += n_read;
375 } while (priv->n_read < n_to_read && block);
377 /* Stop if haven't got all the data we want */
378 if (priv->n_read != n_to_read)
381 /* If have header, rerun for content */
382 if (priv->n_read == HEADER_SIZE)
384 n_to_read = get_packet_length (greeter);
387 priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
388 return read_packet (greeter, block);
396 from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
398 LightDMGreeter *greeter = data;
399 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
403 if (!read_packet (greeter, FALSE))
407 id = read_int (greeter, &offset);
408 length = read_int (greeter, &offset);
411 case SERVER_MESSAGE_CONNECTED:
412 handle_connected (greeter, length, &offset);
414 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
415 handle_prompt_authentication (greeter, &offset);
417 case SERVER_MESSAGE_END_AUTHENTICATION:
418 handle_end_authentication (greeter, &offset);
420 case SERVER_MESSAGE_SESSION_FAILED:
421 handle_session_failed (greeter, &offset);
423 case SERVER_MESSAGE_QUIT:
424 handle_quit (greeter, &offset);
427 g_warning ("Unknown message from server: %d", id);
437 * lightdm_greeter_connect_to_server:
438 * @greeter: The greeter to connect
440 * Connects the greeter to the display manager.
442 * Return value: #TRUE if successfully connected
445 lightdm_greeter_connect_to_server (LightDMGreeter *greeter)
447 LightDMGreeterPrivate *priv;
449 guint8 message[MAX_MESSAGE_LENGTH];
452 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
454 priv = GET_PRIVATE (greeter);
456 fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
459 g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
462 priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
463 g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL);
465 fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
468 g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
471 priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
472 g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
473 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
475 g_debug ("Connecting to display manager...");
476 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
477 write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
478 write_message (greeter, message, offset);
484 * lightdm_greeter_get_hint:
485 * @greeter: A #LightDMGreeter
486 * @name: The hint name to query.
490 * Return value: The value for this hint or #NULL if not set.
493 lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
495 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
496 return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
500 * lightdm_greeter_get_default_session_hint:
501 * @greeter: A #LightDMGreeter
503 * Get the default session to use.
505 * Return value: The session name
508 lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
510 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
511 return lightdm_greeter_get_hint (greeter, "default-session");
515 * lightdm_greeter_get_hide_users_hint:
516 * @greeter: A #LightDMGreeter
518 * Check if user accounts should be shown.
520 * Return value: #TRUE if the available users should not be shown.
523 lightdm_greeter_get_hide_users_hint (LightDMGreeter *greeter)
527 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
528 value = lightdm_greeter_get_hint (greeter, "hide-users");
530 return g_strcmp0 (value, "true") == 0;
534 * lightdm_greeter_get_has_guest_account_hint:
535 * @greeter: A #LightDMGreeter
537 * Check if guest sessions are supported.
539 * Return value: #TRUE if guest sessions are supported.
542 lightdm_greeter_get_has_guest_account_hint (LightDMGreeter *greeter)
546 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
547 value = lightdm_greeter_get_hint (greeter, "has-guest-account");
549 return g_strcmp0 (value, "true") == 0;
553 * lightdm_greeter_get_select_user_hint:
554 * @greeter: A #LightDMGreeter
556 * Get the user to select by default.
558 * Return value: A username
561 lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
563 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
564 return lightdm_greeter_get_hint (greeter, "select-user");
568 * lightdm_greeter_get_select_guest_hint:
569 * @greeter: A #LightDMGreeter
571 * Check if the guest account should be selected by default.
573 * Return value: #TRUE if the guest account should be selected by default.
576 lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter)
580 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
581 value = lightdm_greeter_get_hint (greeter, "select-guest");
583 return g_strcmp0 (value, "true") == 0;
587 * lightdm_greeter_get_autologin_user_hint:
588 * @greeter: A #LightDMGreeter
590 * Get the user account to automatically logg into when the timer expires.
592 * Return value: The user account to automatically log into.
595 lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
597 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
598 return lightdm_greeter_get_hint (greeter, "autologin-user");
602 * lightdm_greeter_get_autologin_guest_hint:
603 * @greeter: A #LightDMGreeter
605 * Check if the guest account should be automatically logged into when the timer expires.
607 * Return value: #TRUE if the guest account should be automatically logged into.
610 lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter)
614 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
615 value = lightdm_greeter_get_hint (greeter, "autologin-guest");
617 return g_strcmp0 (value, "true") == 0;
621 * lightdm_greeter_get_autologin_timeout_hint:
622 * @greeter: A #LightDMGreeter
624 * Get the number of seconds to wait before automaitcally logging in.
626 * Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
629 lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter)
634 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
635 value = lightdm_greeter_get_hint (greeter, "autologin-timeout");
637 timeout = atoi (value);
645 * lightdm_greeter_cancel_autologin:
646 * @greeter: A #LightDMGreeter
648 * Cancel the automatic login.
651 lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
653 LightDMGreeterPrivate *priv;
655 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
657 priv = GET_PRIVATE (greeter);
659 if (priv->autologin_timeout)
660 g_source_remove (priv->autologin_timeout);
661 priv->autologin_timeout = 0;
665 * lightdm_greeter_authenticate:
666 * @greeter: A #LightDMGreeter
667 * @username: (allow-none): A username or #NULL to prompt for a username.
669 * Starts the authentication procedure for a user.
672 lightdm_greeter_authenticate (LightDMGreeter *greeter, const char *username)
674 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
675 guint8 message[MAX_MESSAGE_LENGTH];
678 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
683 priv->cancelling_authentication = FALSE;
684 priv->authenticate_sequence_number++;
685 priv->in_authentication = TRUE;
686 priv->is_authenticated = FALSE;
687 g_free (priv->authentication_user);
688 priv->authentication_user = g_strdup (username);
690 g_debug ("Starting authentication for user %s...", username);
691 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
692 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
693 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
694 write_message (greeter, message, offset);
698 * lightdm_greeter_authenticate_as_guest:
699 * @greeter: A #LightDMGreeter
701 * Starts the authentication procedure for the guest user.
704 lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
706 LightDMGreeterPrivate *priv;
707 guint8 message[MAX_MESSAGE_LENGTH];
710 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
712 priv = GET_PRIVATE (greeter);
714 priv->cancelling_authentication = FALSE;
715 priv->authenticate_sequence_number++;
716 priv->in_authentication = TRUE;
717 priv->is_authenticated = FALSE;
718 g_free (priv->authentication_user);
719 priv->authentication_user = NULL;
721 g_debug ("Starting authentication for guest account...");
722 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
723 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
724 write_message (greeter, message, offset);
728 * lightdm_greeter_respond:
729 * @greeter: A #LightDMGreeter
730 * @response: Response to a prompt
732 * Provide response to a prompt.
735 lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
737 guint8 message[MAX_MESSAGE_LENGTH];
740 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
741 g_return_if_fail (response != NULL);
743 g_debug ("Providing response to display manager");
744 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, int_length () + string_length (response), &offset);
745 // FIXME: Could be multiple responses required
746 write_int (message, MAX_MESSAGE_LENGTH, 1, &offset);
747 write_string (message, MAX_MESSAGE_LENGTH, response, &offset);
748 write_message (greeter, message, offset);
752 * lightdm_greeter_cancel_authentication:
753 * @greeter: A #LightDMGreeter
755 * Cancel the current user authentication.
758 lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
760 LightDMGreeterPrivate *priv;
761 guint8 message[MAX_MESSAGE_LENGTH];
764 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
766 priv = GET_PRIVATE (greeter);
768 priv->cancelling_authentication = TRUE;
769 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
770 write_message (greeter, message, offset);
774 * lightdm_greeter_get_in_authentication:
775 * @greeter: A #LightDMGreeter
777 * Checks if the greeter is in the process of authenticating.
779 * Return value: #TRUE if the greeter is authenticating a user.
782 lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
784 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
785 return GET_PRIVATE (greeter)->in_authentication;
789 * lightdm_greeter_get_is_authenticated:
790 * @greeter: A #LightDMGreeter
792 * Checks if the greeter has successfully authenticated.
794 * Return value: #TRUE if the greeter is authenticated for login.
797 lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
799 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
800 return GET_PRIVATE (greeter)->is_authenticated;
804 * lightdm_greeter_get_authentication_user:
805 * @greeter: A #LightDMGreeter
807 * Get the user that is being authenticated.
809 * Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
812 lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
814 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
815 return GET_PRIVATE (greeter)->authentication_user;
819 * lightdm_greeter_start_session:
820 * @greeter: A #LightDMGreeter
821 * @session: (allow-none): The session to log into or #NULL to use the default
823 * Start a session for the logged in user.
826 lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session)
828 guint8 message[MAX_MESSAGE_LENGTH];
831 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
836 g_debug ("Starting session %s", session);
837 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
838 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
839 write_message (greeter, message, offset);
843 * lightdm_greeter_start_default_session:
844 * @greeter: A #LightDMGreeter
846 * Start the default session for the authenticated user.
849 lightdm_greeter_start_default_session (LightDMGreeter *greeter)
851 lightdm_greeter_start_session (greeter, NULL);
855 lightdm_greeter_init (LightDMGreeter *greeter)
857 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
859 priv->read_buffer = g_malloc (HEADER_SIZE);
860 priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
864 lightdm_greeter_set_property (GObject *object,
869 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
873 lightdm_greeter_get_property (GObject *object,
878 LightDMGreeter *self;
880 self = LIGHTDM_GREETER (object);
883 case PROP_DEFAULT_SESSION_HINT:
884 g_value_set_string (value, lightdm_greeter_get_default_session_hint (self));
886 case PROP_HIDE_USERS_HINT:
887 g_value_set_boolean (value, lightdm_greeter_get_hide_users_hint (self));
889 case PROP_HAS_GUEST_ACCOUNT_HINT:
890 g_value_set_boolean (value, lightdm_greeter_get_has_guest_account_hint (self));
892 case PROP_SELECT_USER_HINT:
893 g_value_set_string (value, lightdm_greeter_get_select_user_hint (self));
895 case PROP_SELECT_GUEST_HINT:
896 g_value_set_boolean (value, lightdm_greeter_get_select_guest_hint (self));
898 case PROP_AUTOLOGIN_USER_HINT:
899 g_value_set_string (value, lightdm_greeter_get_autologin_user_hint (self));
901 case PROP_AUTOLOGIN_GUEST_HINT:
902 g_value_set_boolean (value, lightdm_greeter_get_autologin_guest_hint (self));
904 case PROP_AUTOLOGIN_TIMEOUT_HINT:
905 g_value_set_int (value, lightdm_greeter_get_autologin_timeout_hint (self));
907 case PROP_AUTHENTICATION_USER:
908 g_value_set_string (value, lightdm_greeter_get_authentication_user (self));
910 case PROP_IN_AUTHENTICATION:
911 g_value_set_boolean (value, lightdm_greeter_get_in_authentication (self));
913 case PROP_IS_AUTHENTICATED:
914 g_value_set_boolean (value, lightdm_greeter_get_is_authenticated (self));
917 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
923 marshal_VOID__STRING_INT (GClosure *closure,
924 GValue *return_value G_GNUC_UNUSED,
925 guint n_param_values,
926 const GValue *param_values,
927 gpointer invocation_hint G_GNUC_UNUSED,
928 gpointer marshal_data)
930 typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1,
934 register GMarshalFunc_VOID__STRING_INT callback;
935 register GCClosure *cc = (GCClosure*) closure;
936 register gpointer data1, data2;
938 g_return_if_fail (n_param_values == 3);
940 if (G_CCLOSURE_SWAP_DATA (closure))
942 data1 = closure->data;
943 data2 = g_value_peek_pointer (param_values + 0);
947 data1 = g_value_peek_pointer (param_values + 0);
948 data2 = closure->data;
950 callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
953 (param_values + 1)->data[0].v_pointer,
954 (param_values + 2)->data[0].v_int,
959 lightdm_greeter_finalize (GObject *object)
961 LightDMGreeter *self = LIGHTDM_GREETER (object);
962 LightDMGreeterPrivate *priv = GET_PRIVATE (self);
964 if (priv->to_server_channel)
965 g_io_channel_unref (priv->to_server_channel);
966 if (priv->from_server_channel)
967 g_io_channel_unref (priv->from_server_channel);
968 g_free (priv->authentication_user);
969 g_hash_table_unref (priv->hints);
971 G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
975 lightdm_greeter_class_init (LightDMGreeterClass *klass)
977 GObjectClass *object_class = G_OBJECT_CLASS (klass);
979 g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
981 object_class->set_property = lightdm_greeter_set_property;
982 object_class->get_property = lightdm_greeter_get_property;
983 object_class->finalize = lightdm_greeter_finalize;
985 g_object_class_install_property (object_class,
986 PROP_DEFAULT_SESSION_HINT,
987 g_param_spec_string ("default-session-hint",
988 "default-session-hint",
989 "Default session hint",
993 g_object_class_install_property (object_class,
994 PROP_HIDE_USERS_HINT,
995 g_param_spec_boolean ("hide-users-hint",
1001 g_object_class_install_property (object_class,
1002 PROP_HAS_GUEST_ACCOUNT_HINT,
1003 g_param_spec_boolean ("has-guest-account-hint",
1004 "has-guest-account-hint",
1005 "Has guest account hint",
1009 g_object_class_install_property (object_class,
1010 PROP_SELECT_USER_HINT,
1011 g_param_spec_string ("select-user-hint",
1017 g_object_class_install_property (object_class,
1018 PROP_SELECT_GUEST_HINT,
1019 g_param_spec_boolean ("select-guest-hint",
1020 "select-guest-hint",
1021 "Select guest account hint",
1025 g_object_class_install_property (object_class,
1026 PROP_AUTOLOGIN_USER_HINT,
1027 g_param_spec_string ("autologin-user-hint",
1028 "autologin-user-hint",
1029 "Autologin user hint",
1033 g_object_class_install_property (object_class,
1034 PROP_AUTOLOGIN_GUEST_HINT,
1035 g_param_spec_boolean ("autologin-guest-hint",
1036 "autologin-guest-hint",
1037 "Autologin guest account hint",
1041 g_object_class_install_property (object_class,
1042 PROP_AUTOLOGIN_TIMEOUT_HINT,
1043 g_param_spec_int ("autologin-timeout-hint",
1044 "autologin-timeout-hint",
1045 "Autologin timeout hint",
1049 g_object_class_install_property (object_class,
1050 PROP_AUTHENTICATION_USER,
1051 g_param_spec_string ("authentication-user",
1052 "authentication-user",
1053 "The user being authenticated",
1056 g_object_class_install_property (object_class,
1057 PROP_IN_AUTHENTICATION,
1058 g_param_spec_boolean ("in-authentication",
1059 "in-authentication",
1060 "TRUE if a user is being authenticated",
1063 g_object_class_install_property (object_class,
1064 PROP_IS_AUTHENTICATED,
1065 g_param_spec_boolean ("is-authenticated",
1067 "TRUE if the selected user is authenticated",
1072 * LightDMGreeter::connected:
1073 * @greeter: A #LightDMGreeter
1075 * The ::connected signal gets emitted when the greeter connects to the
1078 signals[CONNECTED] =
1079 g_signal_new ("connected",
1080 G_TYPE_FROM_CLASS (klass),
1082 G_STRUCT_OFFSET (LightDMGreeterClass, connected),
1084 g_cclosure_marshal_VOID__VOID,
1088 * LightDMGreeter::show-prompt:
1089 * @greeter: A #LightDMGreeter
1090 * @text: Prompt text
1091 * @type: Prompt type
1093 * The ::show-prompt signal gets emitted when the greeter should show a
1094 * prompt to the user. The given text should be displayed and an input
1095 * field for the user to provide a response.
1097 * Call lightdm_greeter_respond() with the resultant input or
1098 * lightdm_greeter_cancel_authentication() to abort the authentication.
1100 signals[SHOW_PROMPT] =
1101 g_signal_new ("show-prompt",
1102 G_TYPE_FROM_CLASS (klass),
1104 G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
1106 marshal_VOID__STRING_INT,
1107 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1110 * LightDMGreeter::show-message:
1111 * @greeter: A #LightDMGreeter
1112 * @text: Message text
1113 * @type: Message type
1115 * The ::show-message signal gets emitted when the greeter
1116 * should show a message to the user.
1118 signals[SHOW_MESSAGE] =
1119 g_signal_new ("show-message",
1120 G_TYPE_FROM_CLASS (klass),
1122 G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
1124 marshal_VOID__STRING_INT,
1125 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1128 * LightDMGreeter::authentication-complete:
1129 * @greeter: A #LightDMGreeter
1131 * The ::authentication-complete signal gets emitted when the greeter
1132 * has completed authentication.
1134 * Call lightdm_greeter_get_is_authenticated() to check if the authentication
1137 signals[AUTHENTICATION_COMPLETE] =
1138 g_signal_new ("authentication-complete",
1139 G_TYPE_FROM_CLASS (klass),
1141 G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
1143 g_cclosure_marshal_VOID__VOID,
1147 * LightDMGreeter::session-failed:
1148 * @greeter: A #LightDMGreeter
1150 * The ::session-failed signal gets emitted when the deamon has failed
1151 * to start the requested session.
1153 signals[SESSION_FAILED] =
1154 g_signal_new ("session-failed",
1155 G_TYPE_FROM_CLASS (klass),
1157 G_STRUCT_OFFSET (LightDMGreeterClass, session_failed),
1159 g_cclosure_marshal_VOID__VOID,
1163 * LightDMGreeter::autologin-timer-expired:
1164 * @greeter: A #LightDMGreeter
1166 * The ::timed-login signal gets emitted when the automatic login timer has expired.
1167 * The application should then call lightdm_greeter_login().
1169 signals[AUTOLOGIN_TIMER_EXPIRED] =
1170 g_signal_new ("autologin-timer-expired",
1171 G_TYPE_FROM_CLASS (klass),
1173 G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
1175 g_cclosure_marshal_VOID__VOID,
1179 * LightDMGreeter::quit:
1180 * @greeter: A #LightDMGreeter
1182 * The ::quit signal gets emitted when the greeter should exit.
1185 g_signal_new ("quit",
1186 G_TYPE_FROM_CLASS (klass),
1188 G_STRUCT_OFFSET (LightDMGreeterClass, quit),
1190 g_cclosure_marshal_VOID__VOID,