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 2 or version 3 of the License.
8 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
15 #include <security/pam_appl.h>
17 #include "lightdm/greeter.h"
21 PROP_DEFAULT_SESSION_HINT,
23 PROP_SHOW_MANUAL_LOGIN_HINT,
24 PROP_SHOW_REMOTE_LOGIN_HINT,
26 PROP_HAS_GUEST_ACCOUNT_HINT,
27 PROP_SELECT_USER_HINT,
28 PROP_SELECT_GUEST_HINT,
29 PROP_AUTOLOGIN_USER_HINT,
30 PROP_AUTOLOGIN_GUEST_HINT,
31 PROP_AUTOLOGIN_TIMEOUT_HINT,
32 PROP_AUTHENTICATION_USER,
33 PROP_IN_AUTHENTICATION,
34 PROP_IS_AUTHENTICATED,
40 AUTHENTICATION_COMPLETE,
41 AUTOLOGIN_TIMER_EXPIRED,
44 static guint signals[LAST_SIGNAL] = { 0 };
48 /* Channel to write to daemon */
49 GIOChannel *to_server_channel;
51 /* Channel to read from daemon */
52 GIOChannel *from_server_channel;
54 /* Data read from the daemon */
58 gsize n_responses_waiting;
59 GList *responses_received;
61 /* TRUE if have got a connect response */
64 /* Pending connect requests */
65 GList *connect_requests;
67 /* Pending start session requests */
68 GList *start_session_requests;
70 /* Pending ensure shared data dir requests */
71 GList *ensure_shared_data_dir_requests;
73 /* Mapping of username to shared data directories */
74 GHashTable *shared_data_dirs;
76 /* Hints provided by the daemon */
79 /* Timeout source to notify greeter to autologin */
80 guint autologin_timeout;
82 gchar *authentication_user;
83 gboolean in_authentication;
84 gboolean is_authenticated;
85 guint32 authenticate_sequence_number;
86 gboolean cancelling_authentication;
87 } LightDMGreeterPrivate;
89 G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
91 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
94 #define MAX_MESSAGE_LENGTH 1024
96 /* Messages from the greeter to the server */
99 GREETER_MESSAGE_CONNECT = 0,
100 GREETER_MESSAGE_AUTHENTICATE,
101 GREETER_MESSAGE_AUTHENTICATE_AS_GUEST,
102 GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
103 GREETER_MESSAGE_START_SESSION,
104 GREETER_MESSAGE_CANCEL_AUTHENTICATION,
105 GREETER_MESSAGE_SET_LANGUAGE,
106 GREETER_MESSAGE_AUTHENTICATE_REMOTE,
107 GREETER_MESSAGE_ENSURE_SHARED_DIR,
110 /* Messages from the server to the greeter */
113 SERVER_MESSAGE_CONNECTED = 0,
114 SERVER_MESSAGE_PROMPT_AUTHENTICATION,
115 SERVER_MESSAGE_END_AUTHENTICATION,
116 SERVER_MESSAGE_SESSION_RESULT,
117 SERVER_MESSAGE_SHARED_DIR_RESULT,
120 /* Request sent to server */
123 GObject parent_instance;
124 GCancellable *cancellable;
125 GAsyncReadyCallback callback;
133 GObjectClass parent_class;
135 GType request_get_type (void);
136 static void request_iface_init (GAsyncResultIface *iface);
137 #define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request))
138 G_DEFINE_TYPE_WITH_CODE (Request, request, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, request_iface_init));
141 * lightdm_greeter_new:
143 * Create a new greeter.
145 * Return value: the new #LightDMGreeter
148 lightdm_greeter_new (void)
150 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
154 request_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
158 request = g_object_new (request_get_type (), NULL);
160 request->cancellable = g_object_ref (cancellable);
161 request->callback = callback;
162 request->user_data = user_data;
168 request_call_callback (Request *request)
170 if (!request->callback)
173 if (request->cancellable && g_cancellable_is_cancelled (request->cancellable))
180 timed_login_cb (gpointer data)
182 LightDMGreeter *greeter = data;
183 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
185 priv->autologin_timeout = 0;
186 g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
198 write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
200 if (*offset + 4 >= buffer_length)
202 buffer[*offset] = value >> 24;
203 buffer[*offset+1] = (value >> 16) & 0xFF;
204 buffer[*offset+2] = (value >> 8) & 0xFF;
205 buffer[*offset+3] = value & 0xFF;
210 write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
215 length = strlen (value);
216 write_int (buffer, buffer_length, length, offset);
217 if (*offset + length >= buffer_length)
219 memcpy (buffer + *offset, value, length);
224 read_int (guint8 *message, gsize message_length, gsize *offset)
229 if (message_length - *offset < int_length ())
231 g_warning ("Not enough space for int, need %i, got %zi", int_length (), message_length - *offset);
235 buffer = message + *offset;
236 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
237 *offset += int_length ();
243 read_string (guint8 *message, gsize message_length, gsize *offset)
248 length = read_int (message, message_length, offset);
249 if (message_length - *offset < length)
251 g_warning ("Not enough space for string, need %u, got %zu", length, message_length - *offset);
252 return g_strdup ("");
255 value = g_malloc (sizeof (gchar) * (length + 1));
256 memcpy (value, message + *offset, length);
257 value[length] = '\0';
264 string_length (const gchar *value)
267 return int_length () + strlen (value);
269 return int_length ();
273 write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
275 write_int (buffer, buffer_length, id, offset);
276 write_int (buffer, buffer_length, length, offset);
280 get_message_length (guint8 *message, gsize message_length)
283 return read_int (message, message_length, &offset);
287 send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
289 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
291 GError *error = NULL;
292 guint32 stated_length;
294 if (!priv->to_server_channel)
297 /* Double check that we're sending well-formed messages. If we say we're
298 sending more than we do, we end up DOS'ing lightdm as it waits for the
299 rest. If we say we're sending less than we do, we confuse the heck out
300 of lightdm, as it starts reading headers from the middle of our
302 stated_length = HEADER_SIZE + get_message_length (message, message_length);
303 if (stated_length != message_length)
305 g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
309 status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
311 g_warning ("Error writing to daemon: %s", error->message);
312 g_clear_error (&error);
313 if (status != G_IO_STATUS_NORMAL)
316 g_debug ("Wrote %zi bytes to daemon", message_length);
317 g_io_channel_flush (priv->to_server_channel, NULL);
323 handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
325 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
327 GString *hint_string;
331 version = read_string (message, message_length, offset);
332 hint_string = g_string_new ("");
333 while (*offset < message_length)
337 name = read_string (message, message_length, offset);
338 value = read_string (message, message_length, offset);
339 g_hash_table_insert (priv->hints, name, value);
340 g_string_append_printf (hint_string, " %s=%s", name, value);
343 priv->connected = TRUE;
344 g_debug ("Connected version=%s%s", version, hint_string->str);
346 g_string_free (hint_string, TRUE);
348 /* Set timeout for default login */
349 timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
352 g_debug ("Setting autologin timer for %d seconds", timeout);
353 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
356 /* Notify asynchronous caller */
357 request = g_list_nth_data (priv->connect_requests, 0);
360 request->complete = TRUE;
361 if (request_call_callback (request))
362 request->callback (G_OBJECT (greeter), G_ASYNC_RESULT (request), request->user_data);
363 priv->connect_requests = g_list_remove (priv->connect_requests, request);
364 g_object_unref (request);
369 handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
371 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
372 guint32 sequence_number, n_messages, i;
375 sequence_number = read_int (message, message_length, offset);
376 if (sequence_number != priv->authenticate_sequence_number)
378 g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
382 if (priv->cancelling_authentication)
384 g_debug ("Ignoring prompt authentication as waiting for it to cancel");
388 /* Update username */
389 username = read_string (message, message_length, offset);
390 if (strcmp (username, "") == 0)
395 g_free (priv->authentication_user);
396 priv->authentication_user = username;
398 g_list_free_full (priv->responses_received, g_free);
399 priv->responses_received = NULL;
400 priv->n_responses_waiting = 0;
402 n_messages = read_int (message, message_length, offset);
403 g_debug ("Prompt user with %d message(s)", n_messages);
405 for (i = 0; i < n_messages; i++)
410 style = read_int (message, message_length, offset);
411 text = read_string (message, message_length, offset);
413 // FIXME: Should stop on prompts?
416 case PAM_PROMPT_ECHO_OFF:
417 priv->n_responses_waiting++;
418 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_SECRET);
420 case PAM_PROMPT_ECHO_ON:
421 priv->n_responses_waiting++;
422 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_QUESTION);
425 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_ERROR);
428 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_INFO);
437 handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
439 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
440 guint32 sequence_number, return_code;
443 sequence_number = read_int (message, message_length, offset);
445 if (sequence_number != priv->authenticate_sequence_number)
447 g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number);
451 username = read_string (message, message_length, offset);
452 return_code = read_int (message, message_length, offset);
454 g_debug ("Authentication complete for user %s with return code %d", username, return_code);
456 /* Update username */
457 if (strcmp (username, "") == 0)
462 g_free (priv->authentication_user);
463 priv->authentication_user = username;
465 priv->cancelling_authentication = FALSE;
466 priv->is_authenticated = (return_code == 0);
468 priv->in_authentication = FALSE;
469 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
473 handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
475 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
478 /* Notify asynchronous caller */
479 request = g_list_nth_data (priv->start_session_requests, 0);
482 request->return_code = read_int (message, message_length, offset);
483 request->complete = TRUE;
484 if (request_call_callback (request))
485 request->callback (G_OBJECT (greeter), G_ASYNC_RESULT (request), request->user_data);
486 priv->start_session_requests = g_list_remove (priv->start_session_requests, request);
487 g_object_unref (request);
492 handle_shared_dir_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
494 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
497 /* Notify asynchronous caller */
498 request = g_list_nth_data (priv->ensure_shared_data_dir_requests, 0);
501 request->dir = read_string (message, message_length, offset);
502 /* Blank data dir means invalid user */
503 if (g_strcmp0 (request->dir, "") == 0)
505 g_free (request->dir);
508 request->complete = TRUE;
509 if (request_call_callback (request))
510 request->callback (G_OBJECT (greeter), G_ASYNC_RESULT (request), request->user_data);
511 priv->ensure_shared_data_dir_requests = g_list_remove (priv->ensure_shared_data_dir_requests, request);
512 g_object_unref (request);
517 handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
522 id = read_int (message, message_length, &offset);
523 read_int (message, message_length, &offset);
526 case SERVER_MESSAGE_CONNECTED:
527 handle_connected (greeter, message, message_length, &offset);
529 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
530 handle_prompt_authentication (greeter, message, message_length, &offset);
532 case SERVER_MESSAGE_END_AUTHENTICATION:
533 handle_end_authentication (greeter, message, message_length, &offset);
535 case SERVER_MESSAGE_SESSION_RESULT:
536 handle_session_result (greeter, message, message_length, &offset);
538 case SERVER_MESSAGE_SHARED_DIR_RESULT:
539 handle_shared_dir_result (greeter, message, message_length, &offset);
542 g_warning ("Unknown message from server: %d", id);
548 recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
550 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
551 gsize n_to_read, n_read;
553 GError *error = NULL;
555 if (!priv->from_server_channel)
558 /* Read the header, or the whole message if we already have that */
559 n_to_read = HEADER_SIZE;
560 if (priv->n_read >= HEADER_SIZE)
561 n_to_read += get_message_length (priv->read_buffer, priv->n_read);
566 status = g_io_channel_read_chars (priv->from_server_channel,
567 (gchar *) priv->read_buffer + priv->n_read,
568 n_to_read - priv->n_read,
572 g_warning ("Error reading from server: %s", error->message);
573 g_clear_error (&error);
574 if (status != G_IO_STATUS_NORMAL)
577 g_debug ("Read %zi bytes from daemon", n_read);
579 priv->n_read += n_read;
580 } while (priv->n_read < n_to_read && block);
582 /* Stop if haven't got all the data we want */
583 if (priv->n_read != n_to_read)
586 /* If have header, rerun for content */
587 if (priv->n_read == HEADER_SIZE)
589 n_to_read = get_message_length (priv->read_buffer, priv->n_read);
592 priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
593 return recv_message (greeter, length, block);
597 buffer = priv->read_buffer;
598 *length = priv->n_read;
600 priv->read_buffer = g_malloc (priv->n_read);
607 from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
609 LightDMGreeter *greeter = data;
611 gsize message_length;
613 /* Read one message and process it */
614 message = recv_message (greeter, &message_length, FALSE);
617 handle_message (greeter, message, message_length);
625 send_connect (LightDMGreeter *greeter)
627 guint8 message[MAX_MESSAGE_LENGTH];
630 g_debug ("Connecting to display manager...");
631 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
632 write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
633 return send_message (greeter, message, offset);
637 send_start_session (LightDMGreeter *greeter, const gchar *session)
639 guint8 message[MAX_MESSAGE_LENGTH];
643 g_debug ("Starting session %s", session);
645 g_debug ("Starting default session");
647 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
648 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
649 return send_message (greeter, message, offset);
653 send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username)
655 guint8 message[MAX_MESSAGE_LENGTH];
658 g_debug ("Ensuring data directory for user %s", username);
660 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
661 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
662 return send_message (greeter, message, offset);
666 * lightdm_greeter_connect:
667 * @greeter: The greeter to connect
668 * @cancellable: (allow-none): A #GCancellable or %NULL.
669 * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
670 * @user_data: (allow-none): data to pass to the @callback or %NULL.
672 * Asynchronously connects the greeter to the display manager.
674 * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_connect_finish() to get the result of the operation.
676 * See lightdm_greeter_connect_sync() for the synchronous version.
679 lightdm_greeter_connect (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
681 LightDMGreeterPrivate *priv;
684 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
686 priv = GET_PRIVATE (greeter);
688 request = request_new (cancellable, callback, user_data);
689 priv->connect_requests = g_list_append (priv->connect_requests, request);
690 send_connect (greeter);
694 * lightdm_greeter_connect_finish:
695 * @result: A #GAsyncResult.
696 * @error: return location for a #GError, or %NULL
698 * Finishes an operation started with lightdm_greeter_connect().
700 * Return value: #TRUE if successfully connected
703 lightdm_greeter_connect_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
705 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
706 return REQUEST (result)->complete;
710 * lightdm_greeter_connect_sync:
711 * @greeter: The greeter to connect
712 * @error: return location for a #GError, or %NULL
714 * Connects the greeter to the display manager. Will block until connected.
716 * Return value: #TRUE if successfully connected
719 lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
721 LightDMGreeterPrivate *priv;
724 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
726 priv = GET_PRIVATE (greeter);
728 /* Read until we are connected */
729 send_connect (greeter);
730 request = request_new (NULL, NULL, NULL);
731 priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request));
735 gsize message_length;
737 message = recv_message (greeter, &message_length, TRUE);
740 handle_message (greeter, message, message_length);
742 } while (!request->complete);
744 g_object_unref (request);
746 return request->complete;
750 * lightdm_greeter_get_hint:
751 * @greeter: A #LightDMGreeter
752 * @name: The hint name to query.
756 * Return value: The value for this hint or #NULL if not set.
759 lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
761 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
762 return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
766 * lightdm_greeter_get_default_session_hint:
767 * @greeter: A #LightDMGreeter
769 * Get the default session to use.
771 * Return value: The session name
774 lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
776 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
777 return lightdm_greeter_get_hint (greeter, "default-session");
781 * lightdm_greeter_get_hide_users_hint:
782 * @greeter: A #LightDMGreeter
784 * Check if user accounts should be shown. If this is TRUE then the list of
785 * accounts should be taken from #LightDMUserList and displayed in the greeter
786 * for the user to choose from. Note that this list can be empty and it is
787 * recommended you show a method for the user to enter a username manually.
789 * If this option is shown the greeter should only allow these users to be
790 * chosen for login unless the manual login hint is set.
792 * Return value: #TRUE if the available users should not be shown.
795 lightdm_greeter_get_hide_users_hint (LightDMGreeter *greeter)
799 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
800 value = lightdm_greeter_get_hint (greeter, "hide-users");
802 return g_strcmp0 (value, "true") == 0;
806 * lightdm_greeter_get_show_manual_login_hint:
807 * @greeter: A #LightDMGreeter
809 * Check if a manual login option should be shown. If set the GUI
810 * should provide a way for a username to be entered manually.
811 * Without this hint a greeter which is showing a user list can
812 * limit logins to only those users.
814 * Return value: #TRUE if a manual login option should be shown.
817 lightdm_greeter_get_show_manual_login_hint (LightDMGreeter *greeter)
821 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
822 value = lightdm_greeter_get_hint (greeter, "show-manual-login");
824 return g_strcmp0 (value, "true") == 0;
828 * lightdm_greeter_get_show_remote_login_hint:
829 * @greeter: A #LightDMGreeter
831 * Check if a remote login option should be shown. If set the GUI
832 * should provide a way for a user to log into a remote desktop server.
834 * Return value: #TRUE if a remote login option should be shown.
837 lightdm_greeter_get_show_remote_login_hint (LightDMGreeter *greeter)
841 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
842 value = lightdm_greeter_get_hint (greeter, "show-remote-login");
844 return g_strcmp0 (value, "true") == 0;
848 * lightdm_greeter_get_lock_hint:
849 * @greeter: A #LightDMGreeter
851 * Check if the greeter is acting as a lock screen.
853 * Return value: #TRUE if the greeter was triggered by locking the seat.
856 lightdm_greeter_get_lock_hint (LightDMGreeter *greeter)
860 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
861 value = lightdm_greeter_get_hint (greeter, "lock-screen");
863 return g_strcmp0 (value, "true") == 0;
867 * lightdm_greeter_get_has_guest_account_hint:
868 * @greeter: A #LightDMGreeter
870 * Check if guest sessions are supported.
872 * Return value: #TRUE if guest sessions are supported.
875 lightdm_greeter_get_has_guest_account_hint (LightDMGreeter *greeter)
879 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
880 value = lightdm_greeter_get_hint (greeter, "has-guest-account");
882 return g_strcmp0 (value, "true") == 0;
886 * lightdm_greeter_get_select_user_hint:
887 * @greeter: A #LightDMGreeter
889 * Get the user to select by default.
891 * Return value: A username
894 lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
896 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
897 return lightdm_greeter_get_hint (greeter, "select-user");
901 * lightdm_greeter_get_select_guest_hint:
902 * @greeter: A #LightDMGreeter
904 * Check if the guest account should be selected by default.
906 * Return value: #TRUE if the guest account should be selected by default.
909 lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter)
913 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
914 value = lightdm_greeter_get_hint (greeter, "select-guest");
916 return g_strcmp0 (value, "true") == 0;
920 * lightdm_greeter_get_autologin_user_hint:
921 * @greeter: A #LightDMGreeter
923 * Get the user account to automatically logg into when the timer expires.
925 * Return value: The user account to automatically log into.
928 lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
930 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
931 return lightdm_greeter_get_hint (greeter, "autologin-user");
935 * lightdm_greeter_get_autologin_guest_hint:
936 * @greeter: A #LightDMGreeter
938 * Check if the guest account should be automatically logged into when the timer expires.
940 * Return value: #TRUE if the guest account should be automatically logged into.
943 lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter)
947 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
948 value = lightdm_greeter_get_hint (greeter, "autologin-guest");
950 return g_strcmp0 (value, "true") == 0;
954 * lightdm_greeter_get_autologin_timeout_hint:
955 * @greeter: A #LightDMGreeter
957 * Get the number of seconds to wait before automaitcally logging in.
959 * Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
962 lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter)
967 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
968 value = lightdm_greeter_get_hint (greeter, "autologin-timeout");
970 timeout = atoi (value);
978 * lightdm_greeter_cancel_autologin:
979 * @greeter: A #LightDMGreeter
981 * Cancel the automatic login.
984 lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
986 LightDMGreeterPrivate *priv;
988 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
990 priv = GET_PRIVATE (greeter);
992 if (priv->autologin_timeout)
993 g_source_remove (priv->autologin_timeout);
994 priv->autologin_timeout = 0;
998 * lightdm_greeter_authenticate:
999 * @greeter: A #LightDMGreeter
1000 * @username: (allow-none): A username or #NULL to prompt for a username.
1002 * Starts the authentication procedure for a user.
1005 lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
1007 LightDMGreeterPrivate *priv;
1008 guint8 message[MAX_MESSAGE_LENGTH];
1011 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1013 priv = GET_PRIVATE (greeter);
1015 g_return_if_fail (priv->connected);
1017 priv->cancelling_authentication = FALSE;
1018 priv->authenticate_sequence_number++;
1019 priv->in_authentication = TRUE;
1020 priv->is_authenticated = FALSE;
1021 if (username != priv->authentication_user)
1023 g_free (priv->authentication_user);
1024 priv->authentication_user = g_strdup (username);
1027 g_debug ("Starting authentication for user %s...", username);
1028 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
1029 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1030 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
1031 send_message (greeter, message, offset);
1035 * lightdm_greeter_authenticate_as_guest:
1036 * @greeter: A #LightDMGreeter
1038 * Starts the authentication procedure for the guest user.
1041 lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
1043 LightDMGreeterPrivate *priv;
1044 guint8 message[MAX_MESSAGE_LENGTH];
1047 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1049 priv = GET_PRIVATE (greeter);
1051 g_return_if_fail (priv->connected);
1053 priv->cancelling_authentication = FALSE;
1054 priv->authenticate_sequence_number++;
1055 priv->in_authentication = TRUE;
1056 priv->is_authenticated = FALSE;
1057 g_free (priv->authentication_user);
1058 priv->authentication_user = NULL;
1060 g_debug ("Starting authentication for guest account...");
1061 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
1062 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1063 send_message (greeter, message, offset);
1067 * lightdm_greeter_authenticate_autologin:
1068 * @greeter: A #LightDMGreeter
1070 * Starts the authentication procedure for the automatic login user.
1073 lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
1077 user = lightdm_greeter_get_autologin_user_hint (greeter);
1078 if (lightdm_greeter_get_autologin_guest_hint (greeter))
1079 lightdm_greeter_authenticate_as_guest (greeter);
1081 lightdm_greeter_authenticate (greeter, user);
1085 * lightdm_greeter_authenticate_remote:
1086 * @greeter: A #LightDMGreeter
1087 * @session: The name of a remote session
1088 * @username: (allow-none): A username of #NULL to prompt for a username.
1090 * Start authentication for a remote session type.
1093 lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
1095 LightDMGreeterPrivate *priv;
1096 guint8 message[MAX_MESSAGE_LENGTH];
1099 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1101 priv = GET_PRIVATE (greeter);
1103 g_return_if_fail (priv->connected);
1105 priv->cancelling_authentication = FALSE;
1106 priv->authenticate_sequence_number++;
1107 priv->in_authentication = TRUE;
1108 priv->is_authenticated = FALSE;
1109 g_free (priv->authentication_user);
1110 priv->authentication_user = NULL;
1113 g_debug ("Starting authentication for remote session %s as user %s...", session, username);
1115 g_debug ("Starting authentication for remote session %s...", session);
1116 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
1117 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1118 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
1119 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
1120 send_message (greeter, message, offset);
1124 * lightdm_greeter_respond:
1125 * @greeter: A #LightDMGreeter
1126 * @response: Response to a prompt
1128 * Provide response to a prompt. May be one in a series.
1131 lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
1133 LightDMGreeterPrivate *priv;
1134 guint8 message[MAX_MESSAGE_LENGTH];
1137 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1138 g_return_if_fail (response != NULL);
1140 priv = GET_PRIVATE (greeter);
1142 g_return_if_fail (priv->connected);
1143 g_return_if_fail (priv->n_responses_waiting > 0);
1145 priv->n_responses_waiting--;
1146 priv->responses_received = g_list_append (priv->responses_received, g_strdup (response));
1148 if (priv->n_responses_waiting == 0)
1153 g_debug ("Providing response to display manager");
1155 msg_length = int_length ();
1156 for (iter = priv->responses_received; iter; iter = iter->next)
1157 msg_length += string_length ((gchar *)iter->data);
1159 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
1160 write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset);
1161 for (iter = priv->responses_received; iter; iter = iter->next)
1162 write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset);
1163 send_message (greeter, message, offset);
1165 g_list_free_full (priv->responses_received, g_free);
1166 priv->responses_received = NULL;
1171 * lightdm_greeter_cancel_authentication:
1172 * @greeter: A #LightDMGreeter
1174 * Cancel the current user authentication.
1177 lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
1179 LightDMGreeterPrivate *priv;
1180 guint8 message[MAX_MESSAGE_LENGTH];
1183 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1185 priv = GET_PRIVATE (greeter);
1187 g_return_if_fail (priv->connected);
1189 priv->cancelling_authentication = TRUE;
1190 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
1191 send_message (greeter, message, offset);
1195 * lightdm_greeter_get_in_authentication:
1196 * @greeter: A #LightDMGreeter
1198 * Checks if the greeter is in the process of authenticating.
1200 * Return value: #TRUE if the greeter is authenticating a user.
1203 lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
1205 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1206 return GET_PRIVATE (greeter)->in_authentication;
1210 * lightdm_greeter_get_is_authenticated:
1211 * @greeter: A #LightDMGreeter
1213 * Checks if the greeter has successfully authenticated.
1215 * Return value: #TRUE if the greeter is authenticated for login.
1218 lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
1220 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1221 return GET_PRIVATE (greeter)->is_authenticated;
1225 * lightdm_greeter_get_authentication_user:
1226 * @greeter: A #LightDMGreeter
1228 * Get the user that is being authenticated.
1230 * Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
1233 lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
1235 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1236 return GET_PRIVATE (greeter)->authentication_user;
1240 * lightdm_greeter_set_language:
1241 * @greeter: A #LightDMGreeter
1242 * @language: The language to use for this user in the form of a locale specification (e.g. "de_DE.UTF-8").
1244 * Set the language for the currently authenticated user.
1247 lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
1249 LightDMGreeterPrivate *priv;
1250 guint8 message[MAX_MESSAGE_LENGTH];
1253 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1255 priv = GET_PRIVATE (greeter);
1257 g_return_if_fail (priv->connected);
1259 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
1260 write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
1261 send_message (greeter, message, offset);
1265 * lightdm_greeter_start_session:
1266 * @greeter: A #LightDMGreeter
1267 * @session: (allow-none): The session to log into or #NULL to use the default.
1268 * @cancellable: (allow-none): A #GCancellable or %NULL.
1269 * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
1270 * @user_data: (allow-none): data to pass to the @callback or %NULL.
1272 * Asynchronously start a session for the authenticated user.
1274 * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_start_session_finish() to get the result of the operation.
1276 * See lightdm_greeter_start_session_sync() for the synchronous version.
1279 lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1281 LightDMGreeterPrivate *priv;
1284 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1286 priv = GET_PRIVATE (greeter);
1288 send_start_session (greeter, session);
1289 request = request_new (cancellable, callback, user_data);
1290 priv->start_session_requests = g_list_append (priv->start_session_requests, request);
1294 * lightdm_greeter_start_session_finish:
1295 * @greeter: A #LightDMGreeter
1296 * @result: A #GAsyncResult.
1297 * @error: return location for a #GError, or %NULL
1299 * Start a session for the authenticated user.
1301 * Return value: TRUE if the session was started.
1304 lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
1306 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1307 return REQUEST (result)->return_code == 0;
1311 * lightdm_greeter_start_session_sync:
1312 * @greeter: A #LightDMGreeter
1313 * @session: (allow-none): The session to log into or #NULL to use the default.
1314 * @error: return location for a #GError, or %NULL
1316 * Start a session for the authenticated user.
1318 * Return value: TRUE if the session was started.
1321 lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error)
1323 LightDMGreeterPrivate *priv;
1325 guint32 return_code;
1327 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1329 priv = GET_PRIVATE (greeter);
1331 g_return_val_if_fail (priv->connected, FALSE);
1332 g_return_val_if_fail (priv->is_authenticated, FALSE);
1334 /* Read until the session is started */
1335 send_start_session (greeter, session);
1336 request = request_new (NULL, NULL, NULL);
1337 priv->start_session_requests = g_list_append (priv->start_session_requests, g_object_ref (request));
1341 gsize message_length;
1343 message = recv_message (greeter, &message_length, TRUE);
1346 handle_message (greeter, message, message_length);
1348 } while (!request->complete);
1350 return_code = request->return_code;
1351 g_object_unref (request);
1353 return return_code == 0;
1357 * lightdm_greeter_ensure_shared_data_dir:
1358 * @greeter: A #LightDMGreeter
1359 * @username: A username
1360 * @cancellable: (allow-none): A #GCancellable or %NULL.
1361 * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
1362 * @user_data: (allow-none): data to pass to the @callback or %NULL.
1364 * Ensure that a shared data dir for the given user is available. Both the
1365 * greeter user and @username will have write access to that folder. The
1366 * intention is that larger pieces of shared data would be stored there (files
1367 * that the greeter creates but wants to give to a user -- like camera
1368 * photos -- or files that the user creates but wants the greeter to
1369 * see -- like contact avatars).
1371 * LightDM will automatically create these if the user actually logs in, so
1372 * greeters only need to call this method if they want to store something in
1373 * the directory themselves.
1376 lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1378 LightDMGreeterPrivate *priv;
1381 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1383 priv = GET_PRIVATE (greeter);
1385 send_ensure_shared_data_dir (greeter, username);
1386 request = request_new (cancellable, callback, user_data);
1387 priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request);
1391 * lightdm_greeter_ensure_shared_data_dir_finish:
1392 * @result: A #GAsyncResult.
1393 * @greeter: A #LightDMGreeter
1396 * Return value: The path to the shared directory, free with g_free.
1399 lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result)
1401 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1402 return g_strdup (REQUEST (result)->dir);
1406 * lightdm_greeter_ensure_shared_data_dir_sync:
1407 * @greeter: A #LightDMGreeter
1408 * @username: A username
1410 * Ensure that a shared data dir for the given user is available. Both the
1411 * greeter user and @username will have write access to that folder. The
1412 * intention is that larger pieces of shared data would be stored there (files
1413 * that the greeter creates but wants to give to a user -- like camera
1414 * photos -- or files that the user creates but wants the greeter to
1415 * see -- like contact avatars).
1417 * LightDM will automatically create these if the user actually logs in, so
1418 * greeters only need to call this method if they want to store something in
1419 * the directory themselves.
1421 * Return value: The path to the shared directory, free with g_free.
1424 lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username)
1426 LightDMGreeterPrivate *priv;
1430 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1432 priv = GET_PRIVATE (greeter);
1434 g_return_val_if_fail (priv->connected, NULL);
1436 /* Read until a response */
1437 send_ensure_shared_data_dir (greeter, username);
1438 request = request_new (NULL, NULL, NULL);
1439 priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, g_object_ref (request));
1443 gsize message_length;
1445 message = recv_message (greeter, &message_length, TRUE);
1448 handle_message (greeter, message, message_length);
1450 } while (!request->complete);
1452 data_dir = g_strdup (request->dir);
1453 g_object_unref (request);
1459 lightdm_greeter_init (LightDMGreeter *greeter)
1461 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
1464 priv->read_buffer = g_malloc (HEADER_SIZE);
1465 priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1467 fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
1470 priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
1471 g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL);
1474 g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
1476 fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
1479 priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
1480 g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
1481 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
1484 g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
1488 lightdm_greeter_set_property (GObject *object,
1490 const GValue *value,
1493 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1497 lightdm_greeter_get_property (GObject *object,
1502 LightDMGreeter *self;
1504 self = LIGHTDM_GREETER (object);
1507 case PROP_DEFAULT_SESSION_HINT:
1508 g_value_set_string (value, lightdm_greeter_get_default_session_hint (self));
1510 case PROP_HIDE_USERS_HINT:
1511 g_value_set_boolean (value, lightdm_greeter_get_hide_users_hint (self));
1513 case PROP_SHOW_MANUAL_LOGIN_HINT:
1514 g_value_set_boolean (value, lightdm_greeter_get_show_manual_login_hint (self));
1516 case PROP_SHOW_REMOTE_LOGIN_HINT:
1517 g_value_set_boolean (value, lightdm_greeter_get_show_remote_login_hint (self));
1519 case PROP_LOCK_HINT:
1520 g_value_set_boolean (value, lightdm_greeter_get_lock_hint (self));
1522 case PROP_HAS_GUEST_ACCOUNT_HINT:
1523 g_value_set_boolean (value, lightdm_greeter_get_has_guest_account_hint (self));
1525 case PROP_SELECT_USER_HINT:
1526 g_value_set_string (value, lightdm_greeter_get_select_user_hint (self));
1528 case PROP_SELECT_GUEST_HINT:
1529 g_value_set_boolean (value, lightdm_greeter_get_select_guest_hint (self));
1531 case PROP_AUTOLOGIN_USER_HINT:
1532 g_value_set_string (value, lightdm_greeter_get_autologin_user_hint (self));
1534 case PROP_AUTOLOGIN_GUEST_HINT:
1535 g_value_set_boolean (value, lightdm_greeter_get_autologin_guest_hint (self));
1537 case PROP_AUTOLOGIN_TIMEOUT_HINT:
1538 g_value_set_int (value, lightdm_greeter_get_autologin_timeout_hint (self));
1540 case PROP_AUTHENTICATION_USER:
1541 g_value_set_string (value, lightdm_greeter_get_authentication_user (self));
1543 case PROP_IN_AUTHENTICATION:
1544 g_value_set_boolean (value, lightdm_greeter_get_in_authentication (self));
1546 case PROP_IS_AUTHENTICATED:
1547 g_value_set_boolean (value, lightdm_greeter_get_is_authenticated (self));
1550 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1556 lightdm_greeter_finalize (GObject *object)
1558 LightDMGreeter *self = LIGHTDM_GREETER (object);
1559 LightDMGreeterPrivate *priv = GET_PRIVATE (self);
1561 if (priv->to_server_channel)
1562 g_io_channel_unref (priv->to_server_channel);
1563 if (priv->from_server_channel)
1564 g_io_channel_unref (priv->from_server_channel);
1565 g_free (priv->authentication_user);
1566 g_hash_table_unref (priv->hints);
1568 G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
1572 lightdm_greeter_class_init (LightDMGreeterClass *klass)
1574 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1576 g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
1578 object_class->set_property = lightdm_greeter_set_property;
1579 object_class->get_property = lightdm_greeter_get_property;
1580 object_class->finalize = lightdm_greeter_finalize;
1582 g_object_class_install_property (object_class,
1583 PROP_DEFAULT_SESSION_HINT,
1584 g_param_spec_string ("default-session-hint",
1585 "default-session-hint",
1586 "Default session hint",
1588 G_PARAM_READWRITE));
1590 g_object_class_install_property (object_class,
1591 PROP_HIDE_USERS_HINT,
1592 g_param_spec_boolean ("hide-users-hint",
1598 g_object_class_install_property (object_class,
1599 PROP_SHOW_MANUAL_LOGIN_HINT,
1600 g_param_spec_boolean ("show-manual-login-hint",
1601 "show-manual-login-hint",
1602 "Show manual login hint",
1606 g_object_class_install_property (object_class,
1607 PROP_SHOW_REMOTE_LOGIN_HINT,
1608 g_param_spec_boolean ("show-remote-login-hint",
1609 "show-remote-login-hint",
1610 "Show remote login hint",
1614 g_object_class_install_property (object_class,
1616 g_param_spec_boolean ("lock-hint",
1622 g_object_class_install_property (object_class,
1623 PROP_HAS_GUEST_ACCOUNT_HINT,
1624 g_param_spec_boolean ("has-guest-account-hint",
1625 "has-guest-account-hint",
1626 "Has guest account hint",
1630 g_object_class_install_property (object_class,
1631 PROP_SELECT_USER_HINT,
1632 g_param_spec_string ("select-user-hint",
1638 g_object_class_install_property (object_class,
1639 PROP_SELECT_GUEST_HINT,
1640 g_param_spec_boolean ("select-guest-hint",
1641 "select-guest-hint",
1642 "Select guest account hint",
1646 g_object_class_install_property (object_class,
1647 PROP_AUTOLOGIN_USER_HINT,
1648 g_param_spec_string ("autologin-user-hint",
1649 "autologin-user-hint",
1650 "Autologin user hint",
1654 g_object_class_install_property (object_class,
1655 PROP_AUTOLOGIN_GUEST_HINT,
1656 g_param_spec_boolean ("autologin-guest-hint",
1657 "autologin-guest-hint",
1658 "Autologin guest account hint",
1662 g_object_class_install_property (object_class,
1663 PROP_AUTOLOGIN_TIMEOUT_HINT,
1664 g_param_spec_int ("autologin-timeout-hint",
1665 "autologin-timeout-hint",
1666 "Autologin timeout hint",
1670 g_object_class_install_property (object_class,
1671 PROP_AUTHENTICATION_USER,
1672 g_param_spec_string ("authentication-user",
1673 "authentication-user",
1674 "The user being authenticated",
1677 g_object_class_install_property (object_class,
1678 PROP_IN_AUTHENTICATION,
1679 g_param_spec_boolean ("in-authentication",
1680 "in-authentication",
1681 "TRUE if a user is being authenticated",
1684 g_object_class_install_property (object_class,
1685 PROP_IS_AUTHENTICATED,
1686 g_param_spec_boolean ("is-authenticated",
1688 "TRUE if the selected user is authenticated",
1693 * LightDMGreeter::show-prompt:
1694 * @greeter: A #LightDMGreeter
1695 * @text: Prompt text
1696 * @type: Prompt type
1698 * The ::show-prompt signal gets emitted when the greeter should show a
1699 * prompt to the user. The given text should be displayed and an input
1700 * field for the user to provide a response.
1702 * Call lightdm_greeter_respond() with the resultant input or
1703 * lightdm_greeter_cancel_authentication() to abort the authentication.
1705 signals[SHOW_PROMPT] =
1706 g_signal_new ("show-prompt",
1707 G_TYPE_FROM_CLASS (klass),
1709 G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
1712 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1715 * LightDMGreeter::show-message:
1716 * @greeter: A #LightDMGreeter
1717 * @text: Message text
1718 * @type: Message type
1720 * The ::show-message signal gets emitted when the greeter
1721 * should show a message to the user.
1723 signals[SHOW_MESSAGE] =
1724 g_signal_new ("show-message",
1725 G_TYPE_FROM_CLASS (klass),
1727 G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
1730 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1733 * LightDMGreeter::authentication-complete:
1734 * @greeter: A #LightDMGreeter
1736 * The ::authentication-complete signal gets emitted when the greeter
1737 * has completed authentication.
1739 * Call lightdm_greeter_get_is_authenticated() to check if the authentication
1742 signals[AUTHENTICATION_COMPLETE] =
1743 g_signal_new ("authentication-complete",
1744 G_TYPE_FROM_CLASS (klass),
1746 G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
1752 * LightDMGreeter::autologin-timer-expired:
1753 * @greeter: A #LightDMGreeter
1755 * The ::timed-login signal gets emitted when the automatic login timer has expired.
1756 * The application should then call lightdm_greeter_login().
1758 signals[AUTOLOGIN_TIMER_EXPIRED] =
1759 g_signal_new ("autologin-timer-expired",
1760 G_TYPE_FROM_CLASS (klass),
1762 G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
1769 request_init (Request *request)
1774 request_finalize (GObject *object)
1776 Request *request = REQUEST (object);
1778 g_free (request->dir);
1779 if (request->cancellable)
1780 g_object_unref (request->cancellable);
1782 G_OBJECT_CLASS (request_parent_class)->finalize (object);
1786 request_class_init (RequestClass *klass)
1788 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1789 object_class->finalize = request_finalize;
1793 request_get_user_data (GAsyncResult *result)
1795 return REQUEST (result)->user_data;
1799 request_get_source_object (GAsyncResult *res)
1805 request_is_tagged (GAsyncResult *res, gpointer source_tag)
1811 request_iface_init (GAsyncResultIface *iface)
1813 iface->get_user_data = request_get_user_data;
1814 iface->get_source_object = request_get_source_object;
1815 iface->is_tagged = request_is_tagged;