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,
46 static guint signals[LAST_SIGNAL] = { 0 };
50 /* TRUE if the daemon can reuse this greeter */
53 /* Channel to write to daemon */
54 GIOChannel *to_server_channel;
56 /* Channel to read from daemon */
57 GIOChannel *from_server_channel;
59 /* Data read from the daemon */
63 gsize n_responses_waiting;
64 GList *responses_received;
66 /* TRUE if have got a connect response */
69 /* Pending connect requests */
70 GList *connect_requests;
72 /* Pending start session requests */
73 GList *start_session_requests;
75 /* Pending ensure shared data dir requests */
76 GList *ensure_shared_data_dir_requests;
78 /* Hints provided by the daemon */
81 /* Timeout source to notify greeter to autologin */
82 guint autologin_timeout;
84 gchar *authentication_user;
85 gboolean in_authentication;
86 gboolean is_authenticated;
87 guint32 authenticate_sequence_number;
88 gboolean cancelling_authentication;
89 } LightDMGreeterPrivate;
91 G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
93 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
96 #define MAX_MESSAGE_LENGTH 1024
98 /* Messages from the greeter to the server */
101 GREETER_MESSAGE_CONNECT = 0,
102 GREETER_MESSAGE_AUTHENTICATE,
103 GREETER_MESSAGE_AUTHENTICATE_AS_GUEST,
104 GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
105 GREETER_MESSAGE_START_SESSION,
106 GREETER_MESSAGE_CANCEL_AUTHENTICATION,
107 GREETER_MESSAGE_SET_LANGUAGE,
108 GREETER_MESSAGE_AUTHENTICATE_REMOTE,
109 GREETER_MESSAGE_ENSURE_SHARED_DIR,
112 /* Messages from the server to the greeter */
115 SERVER_MESSAGE_CONNECTED = 0,
116 SERVER_MESSAGE_PROMPT_AUTHENTICATION,
117 SERVER_MESSAGE_END_AUTHENTICATION,
118 SERVER_MESSAGE_SESSION_RESULT,
119 SERVER_MESSAGE_SHARED_DIR_RESULT,
121 SERVER_MESSAGE_RESET,
124 /* Request sent to server */
127 GObject parent_instance;
128 GCancellable *cancellable;
129 GAsyncReadyCallback callback;
137 GObjectClass parent_class;
139 GType request_get_type (void);
140 static void request_iface_init (GAsyncResultIface *iface);
141 #define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request))
142 G_DEFINE_TYPE_WITH_CODE (Request, request, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, request_iface_init));
145 lightdm_prompt_type_get_type (void)
147 static GType enum_type = 0;
149 if (G_UNLIKELY(enum_type == 0)) {
150 static const GEnumValue values[] = {
151 { LIGHTDM_PROMPT_TYPE_QUESTION, "LIGHTDM_PROMPT_TYPE_QUESTION", "question" },
152 { LIGHTDM_PROMPT_TYPE_SECRET, "LIGHTDM_PROMPT_TYPE_SECRET", "secret" },
155 enum_type = g_enum_register_static (g_intern_static_string ("LightDMPromptType"), values);
162 lightdm_message_type_get_type (void)
164 static GType enum_type = 0;
166 if (G_UNLIKELY(enum_type == 0)) {
167 static const GEnumValue values[] = {
168 { LIGHTDM_MESSAGE_TYPE_INFO, "LIGHTDM_MESSAGE_TYPE_INFO", "info" },
169 { LIGHTDM_MESSAGE_TYPE_ERROR, "LIGHTDM_MESSAGE_TYPE_ERROR", "error" },
172 enum_type = g_enum_register_static (g_intern_static_string ("LightDMMessageType"), values);
180 * lightdm_greeter_new:
182 * Create a new greeter.
184 * Return value: the new #LightDMGreeter
187 lightdm_greeter_new (void)
189 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
193 * lightdm_greeter_set_resettable:
194 * @greeter: A #LightDMGreeter
195 * @resettable: Whether the greeter wants to be reset instead of killed after the user logs in
197 * Set whether the greeter will be reset instead of killed after the user logs in.
198 * This must be called before lightdm_greeter_connect is called.
201 lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable)
203 LightDMGreeterPrivate *priv;
205 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
207 priv = GET_PRIVATE (greeter);
209 g_return_if_fail (!priv->connected);
210 priv->resettable = resettable;
214 request_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
218 request = g_object_new (request_get_type (), NULL);
220 request->cancellable = g_object_ref (cancellable);
221 request->callback = callback;
222 request->user_data = user_data;
228 request_complete (Request *request, GObject *object)
230 request->complete = TRUE;
232 if (!request->callback)
235 if (request->cancellable && g_cancellable_is_cancelled (request->cancellable))
238 request->callback (object, G_ASYNC_RESULT (request), request->user_data);
242 timed_login_cb (gpointer data)
244 LightDMGreeter *greeter = data;
245 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
247 priv->autologin_timeout = 0;
248 g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
260 write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
262 if (*offset + 4 >= buffer_length)
264 buffer[*offset] = value >> 24;
265 buffer[*offset+1] = (value >> 16) & 0xFF;
266 buffer[*offset+2] = (value >> 8) & 0xFF;
267 buffer[*offset+3] = value & 0xFF;
272 write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
277 length = strlen (value);
278 write_int (buffer, buffer_length, length, offset);
279 if (*offset + length >= buffer_length)
282 memcpy (buffer + *offset, value, length);
287 read_int (guint8 *message, gsize message_length, gsize *offset)
292 if (message_length - *offset < int_length ())
294 g_warning ("Not enough space for int, need %i, got %zi", int_length (), message_length - *offset);
298 buffer = message + *offset;
299 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
300 *offset += int_length ();
306 read_string (guint8 *message, gsize message_length, gsize *offset)
311 length = read_int (message, message_length, offset);
312 if (message_length - *offset < length)
314 g_warning ("Not enough space for string, need %u, got %zu", length, message_length - *offset);
315 return g_strdup ("");
318 value = g_malloc (sizeof (gchar) * (length + 1));
319 memcpy (value, message + *offset, length);
320 value[length] = '\0';
327 string_length (const gchar *value)
330 return int_length () + strlen (value);
332 return int_length ();
336 write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
338 write_int (buffer, buffer_length, id, offset);
339 write_int (buffer, buffer_length, length, offset);
343 get_message_length (guint8 *message, gsize message_length)
346 return read_int (message, message_length, &offset);
350 send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
352 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
355 GError *error = NULL;
356 guint32 stated_length;
358 if (!priv->to_server_channel)
361 /* Double check that we're sending well-formed messages. If we say we're
362 sending more than we do, we end up DOS'ing lightdm as it waits for the
363 rest. If we say we're sending less than we do, we confuse the heck out
364 of lightdm, as it starts reading headers from the middle of our
366 stated_length = HEADER_SIZE + get_message_length (message, message_length);
367 if (stated_length != message_length)
369 g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
373 data = (gchar *) message;
374 data_length = message_length;
375 while (data_length > 0)
380 status = g_io_channel_write_chars (priv->to_server_channel, data, data_length, &n_written, &error);
382 g_warning ("Error writing to daemon: %s", error->message);
383 g_clear_error (&error);
384 if (status != G_IO_STATUS_NORMAL)
386 data_length -= n_written;
390 g_debug ("Wrote %zi bytes to daemon", message_length);
391 g_io_channel_flush (priv->to_server_channel, &error);
393 g_warning ("Failed to flush data to daemon: %s", error->message);
394 g_clear_error (&error);
400 handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
402 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
404 GString *hint_string;
408 version = read_string (message, message_length, offset);
409 hint_string = g_string_new ("");
410 while (*offset < message_length)
414 name = read_string (message, message_length, offset);
415 value = read_string (message, message_length, offset);
416 g_hash_table_insert (priv->hints, name, value);
417 g_string_append_printf (hint_string, " %s=%s", name, value);
420 priv->connected = TRUE;
421 g_debug ("Connected version=%s%s", version, hint_string->str);
423 g_string_free (hint_string, TRUE);
425 /* Set timeout for default login */
426 timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
429 g_debug ("Setting autologin timer for %d seconds", timeout);
430 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
433 /* Notify asynchronous caller */
434 request = g_list_nth_data (priv->connect_requests, 0);
437 request_complete (request, G_OBJECT (greeter));
438 priv->connect_requests = g_list_remove (priv->connect_requests, request);
439 g_object_unref (request);
444 handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
446 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
447 guint32 sequence_number, n_messages, i;
450 sequence_number = read_int (message, message_length, offset);
451 if (sequence_number != priv->authenticate_sequence_number)
453 g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
457 if (priv->cancelling_authentication)
459 g_debug ("Ignoring prompt authentication as waiting for it to cancel");
463 /* Update username */
464 username = read_string (message, message_length, offset);
465 if (strcmp (username, "") == 0)
470 g_free (priv->authentication_user);
471 priv->authentication_user = username;
473 g_list_free_full (priv->responses_received, g_free);
474 priv->responses_received = NULL;
475 priv->n_responses_waiting = 0;
477 n_messages = read_int (message, message_length, offset);
478 g_debug ("Prompt user with %d message(s)", n_messages);
480 for (i = 0; i < n_messages; i++)
485 style = read_int (message, message_length, offset);
486 text = read_string (message, message_length, offset);
488 // FIXME: Should stop on prompts?
491 case PAM_PROMPT_ECHO_OFF:
492 priv->n_responses_waiting++;
493 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_SECRET);
495 case PAM_PROMPT_ECHO_ON:
496 priv->n_responses_waiting++;
497 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_QUESTION);
500 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_ERROR);
503 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_INFO);
512 handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
514 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
515 guint32 sequence_number, return_code;
518 sequence_number = read_int (message, message_length, offset);
520 if (sequence_number != priv->authenticate_sequence_number)
522 g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number);
526 username = read_string (message, message_length, offset);
527 return_code = read_int (message, message_length, offset);
529 g_debug ("Authentication complete for user %s with return code %d", username, return_code);
531 /* Update username */
532 if (strcmp (username, "") == 0)
537 g_free (priv->authentication_user);
538 priv->authentication_user = username;
540 priv->cancelling_authentication = FALSE;
541 priv->is_authenticated = (return_code == 0);
543 priv->in_authentication = FALSE;
544 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
548 handle_idle (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
550 g_signal_emit (G_OBJECT (greeter), signals[IDLE], 0);
554 handle_reset (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
556 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
557 GString *hint_string;
559 g_hash_table_remove_all (priv->hints);
561 hint_string = g_string_new ("");
562 while (*offset < message_length)
566 name = read_string (message, message_length, offset);
567 value = read_string (message, message_length, offset);
568 g_hash_table_insert (priv->hints, name, value);
569 g_string_append_printf (hint_string, " %s=%s", name, value);
572 g_debug ("Reset%s", hint_string->str);
573 g_string_free (hint_string, TRUE);
575 g_signal_emit (G_OBJECT (greeter), signals[RESET], 0);
579 handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
581 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
584 /* Notify asynchronous caller */
585 request = g_list_nth_data (priv->start_session_requests, 0);
588 request->return_code = read_int (message, message_length, offset);
589 request_complete (request, G_OBJECT (greeter));
590 priv->start_session_requests = g_list_remove (priv->start_session_requests, request);
591 g_object_unref (request);
596 handle_shared_dir_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
598 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
601 /* Notify asynchronous caller */
602 request = g_list_nth_data (priv->ensure_shared_data_dir_requests, 0);
605 request->dir = read_string (message, message_length, offset);
606 /* Blank data dir means invalid user */
607 if (g_strcmp0 (request->dir, "") == 0)
609 g_free (request->dir);
612 request_complete (request, G_OBJECT (greeter));
613 priv->ensure_shared_data_dir_requests = g_list_remove (priv->ensure_shared_data_dir_requests, request);
614 g_object_unref (request);
619 handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
624 id = read_int (message, message_length, &offset);
625 read_int (message, message_length, &offset);
628 case SERVER_MESSAGE_CONNECTED:
629 handle_connected (greeter, message, message_length, &offset);
631 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
632 handle_prompt_authentication (greeter, message, message_length, &offset);
634 case SERVER_MESSAGE_END_AUTHENTICATION:
635 handle_end_authentication (greeter, message, message_length, &offset);
637 case SERVER_MESSAGE_SESSION_RESULT:
638 handle_session_result (greeter, message, message_length, &offset);
640 case SERVER_MESSAGE_SHARED_DIR_RESULT:
641 handle_shared_dir_result (greeter, message, message_length, &offset);
643 case SERVER_MESSAGE_IDLE:
644 handle_idle (greeter, message, message_length, &offset);
646 case SERVER_MESSAGE_RESET:
647 handle_reset (greeter, message, message_length, &offset);
650 g_warning ("Unknown message from server: %d", id);
656 recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
658 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
659 gsize n_to_read, n_read;
661 GError *error = NULL;
663 if (!priv->from_server_channel)
666 /* Read the header, or the whole message if we already have that */
667 n_to_read = HEADER_SIZE;
668 if (priv->n_read >= HEADER_SIZE)
669 n_to_read += get_message_length (priv->read_buffer, priv->n_read);
674 status = g_io_channel_read_chars (priv->from_server_channel,
675 (gchar *) priv->read_buffer + priv->n_read,
676 n_to_read - priv->n_read,
680 g_warning ("Error reading from server: %s", error->message);
681 g_clear_error (&error);
682 if (status != G_IO_STATUS_NORMAL)
685 g_debug ("Read %zi bytes from daemon", n_read);
687 priv->n_read += n_read;
688 } while (priv->n_read < n_to_read && block);
690 /* Stop if haven't got all the data we want */
691 if (priv->n_read != n_to_read)
694 /* If have header, rerun for content */
695 if (priv->n_read == HEADER_SIZE)
697 n_to_read = get_message_length (priv->read_buffer, priv->n_read);
700 priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
701 return recv_message (greeter, length, block);
705 buffer = priv->read_buffer;
706 *length = priv->n_read;
708 priv->read_buffer = g_malloc (priv->n_read);
715 from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
717 LightDMGreeter *greeter = data;
719 gsize message_length;
721 /* Read one message and process it */
722 message = recv_message (greeter, &message_length, FALSE);
725 handle_message (greeter, message, message_length);
733 send_connect (LightDMGreeter *greeter, gboolean resettable)
735 guint8 message[MAX_MESSAGE_LENGTH];
738 g_debug ("Connecting to display manager...");
739 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset);
740 write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
741 write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset);
743 return send_message (greeter, message, offset);
747 send_start_session (LightDMGreeter *greeter, const gchar *session)
749 guint8 message[MAX_MESSAGE_LENGTH];
753 g_debug ("Starting session %s", session);
755 g_debug ("Starting default session");
757 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
758 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
759 return send_message (greeter, message, offset);
763 send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username)
765 guint8 message[MAX_MESSAGE_LENGTH];
768 g_debug ("Ensuring data directory for user %s", username);
770 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
771 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
772 return send_message (greeter, message, offset);
776 * lightdm_greeter_connect_to_daemon:
777 * @greeter: The greeter to connect
778 * @cancellable: (allow-none): A #GCancellable or %NULL.
779 * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
780 * @user_data: (allow-none): data to pass to the @callback or %NULL.
782 * Asynchronously connects the greeter to the display manager.
784 * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_connect_to_daemon_finish() to get the result of the operation.
786 * See lightdm_greeter_connect_to_daemon_sync() for the synchronous version.
789 lightdm_greeter_connect_to_daemon (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
791 LightDMGreeterPrivate *priv;
794 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
796 priv = GET_PRIVATE (greeter);
798 request = request_new (cancellable, callback, user_data);
799 priv->connect_requests = g_list_append (priv->connect_requests, request);
800 send_connect (greeter, priv->resettable);
804 * lightdm_greeter_connect_to_daemon_finish:
805 * @greeter: The greeter the the request was done with
806 * @result: A #GAsyncResult.
807 * @error: return location for a #GError, or %NULL
809 * Finishes an operation started with lightdm_greeter_connect_to_daemon().
811 * Return value: #TRUE if successfully connected
814 lightdm_greeter_connect_to_daemon_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
816 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
817 return REQUEST (result)->complete;
821 * lightdm_greeter_connect_to_daemon_sync:
822 * @greeter: The greeter to connect
823 * @error: return location for a #GError, or %NULL
825 * Connects the greeter to the display manager. Will block until connected.
827 * Return value: #TRUE if successfully connected
830 lightdm_greeter_connect_to_daemon_sync (LightDMGreeter *greeter, GError **error)
832 LightDMGreeterPrivate *priv;
836 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
838 priv = GET_PRIVATE (greeter);
840 /* Read until we are connected */
841 send_connect (greeter, priv->resettable);
842 request = request_new (NULL, NULL, NULL);
843 priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request));
847 gsize message_length;
849 message = recv_message (greeter, &message_length, TRUE);
852 handle_message (greeter, message, message_length);
854 } while (!request->complete);
856 result = request->complete;
857 g_object_unref (request);
863 * lightdm_greeter_connect_sync:
864 * @greeter: The greeter to connect
865 * @error: return location for a #GError, or %NULL
867 * Connects the greeter to the display manager. Will block until connected.
869 * Return value: #TRUE if successfully connected
871 * Deprecated: 1.11.1: Use lightdm_greeter_connect_to_daemon_sync() instead
874 lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
876 return lightdm_greeter_connect_to_daemon_sync (greeter, error);
880 * lightdm_greeter_get_hint:
881 * @greeter: A #LightDMGreeter
882 * @name: The hint name to query.
886 * Return value: (nullable): The value for this hint or #NULL if not set.
889 lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
891 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
892 return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
896 * lightdm_greeter_get_default_session_hint:
897 * @greeter: A #LightDMGreeter
899 * Get the default session to use.
901 * Return value: The session name
904 lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
906 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
907 return lightdm_greeter_get_hint (greeter, "default-session");
911 * lightdm_greeter_get_hide_users_hint:
912 * @greeter: A #LightDMGreeter
914 * Check if user accounts should be shown. If this is TRUE then the list of
915 * accounts should be taken from #LightDMUserList and displayed in the greeter
916 * for the user to choose from. Note that this list can be empty and it is
917 * recommended you show a method for the user to enter a username manually.
919 * If this option is shown the greeter should only allow these users to be
920 * chosen for login unless the manual login hint is set.
922 * Return value: #TRUE if the available users should not be shown.
925 lightdm_greeter_get_hide_users_hint (LightDMGreeter *greeter)
929 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
930 value = lightdm_greeter_get_hint (greeter, "hide-users");
932 return g_strcmp0 (value, "true") == 0;
936 * lightdm_greeter_get_show_manual_login_hint:
937 * @greeter: A #LightDMGreeter
939 * Check if a manual login option should be shown. If set the GUI
940 * should provide a way for a username to be entered manually.
941 * Without this hint a greeter which is showing a user list can
942 * limit logins to only those users.
944 * Return value: #TRUE if a manual login option should be shown.
947 lightdm_greeter_get_show_manual_login_hint (LightDMGreeter *greeter)
951 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
952 value = lightdm_greeter_get_hint (greeter, "show-manual-login");
954 return g_strcmp0 (value, "true") == 0;
958 * lightdm_greeter_get_show_remote_login_hint:
959 * @greeter: A #LightDMGreeter
961 * Check if a remote login option should be shown. If set the GUI
962 * should provide a way for a user to log into a remote desktop server.
964 * Return value: #TRUE if a remote login option should be shown.
967 lightdm_greeter_get_show_remote_login_hint (LightDMGreeter *greeter)
971 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
972 value = lightdm_greeter_get_hint (greeter, "show-remote-login");
974 return g_strcmp0 (value, "true") == 0;
978 * lightdm_greeter_get_lock_hint:
979 * @greeter: A #LightDMGreeter
981 * Check if the greeter is acting as a lock screen.
983 * Return value: #TRUE if the greeter was triggered by locking the seat.
986 lightdm_greeter_get_lock_hint (LightDMGreeter *greeter)
990 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
991 value = lightdm_greeter_get_hint (greeter, "lock-screen");
993 return g_strcmp0 (value, "true") == 0;
997 * lightdm_greeter_get_has_guest_account_hint:
998 * @greeter: A #LightDMGreeter
1000 * Check if guest sessions are supported.
1002 * Return value: #TRUE if guest sessions are supported.
1005 lightdm_greeter_get_has_guest_account_hint (LightDMGreeter *greeter)
1009 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1010 value = lightdm_greeter_get_hint (greeter, "has-guest-account");
1012 return g_strcmp0 (value, "true") == 0;
1016 * lightdm_greeter_get_select_user_hint:
1017 * @greeter: A #LightDMGreeter
1019 * Get the user to select by default.
1021 * Return value: (nullable): A username or %NULL if no particular user should be selected.
1024 lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
1026 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1027 return lightdm_greeter_get_hint (greeter, "select-user");
1031 * lightdm_greeter_get_select_guest_hint:
1032 * @greeter: A #LightDMGreeter
1034 * Check if the guest account should be selected by default.
1036 * Return value: #TRUE if the guest account should be selected by default.
1039 lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter)
1043 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1044 value = lightdm_greeter_get_hint (greeter, "select-guest");
1046 return g_strcmp0 (value, "true") == 0;
1050 * lightdm_greeter_get_autologin_user_hint:
1051 * @greeter: A #LightDMGreeter
1053 * Get the user account to automatically log into when the timer expires.
1055 * Return value: (nullable): The user account to automatically log into or %NULL if none configured.
1058 lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
1060 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1061 return lightdm_greeter_get_hint (greeter, "autologin-user");
1065 * lightdm_greeter_get_autologin_guest_hint:
1066 * @greeter: A #LightDMGreeter
1068 * Check if the guest account should be automatically logged into when the timer expires.
1070 * Return value: #TRUE if the guest account should be automatically logged into.
1073 lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter)
1077 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1078 value = lightdm_greeter_get_hint (greeter, "autologin-guest");
1080 return g_strcmp0 (value, "true") == 0;
1084 * lightdm_greeter_get_autologin_timeout_hint:
1085 * @greeter: A #LightDMGreeter
1087 * Get the number of seconds to wait before automaitcally logging in.
1089 * Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
1092 lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter)
1097 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1098 value = lightdm_greeter_get_hint (greeter, "autologin-timeout");
1100 timeout = atoi (value);
1108 * lightdm_greeter_cancel_autologin:
1109 * @greeter: A #LightDMGreeter
1111 * Cancel the automatic login.
1114 lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
1116 LightDMGreeterPrivate *priv;
1118 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1120 priv = GET_PRIVATE (greeter);
1122 if (priv->autologin_timeout)
1123 g_source_remove (priv->autologin_timeout);
1124 priv->autologin_timeout = 0;
1128 * lightdm_greeter_authenticate:
1129 * @greeter: A #LightDMGreeter
1130 * @username: (allow-none): A username or #NULL to prompt for a username.
1132 * Starts the authentication procedure for a user.
1135 lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
1137 LightDMGreeterPrivate *priv;
1138 guint8 message[MAX_MESSAGE_LENGTH];
1141 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1143 priv = GET_PRIVATE (greeter);
1145 g_return_if_fail (priv->connected);
1147 priv->cancelling_authentication = FALSE;
1148 priv->authenticate_sequence_number++;
1149 priv->in_authentication = TRUE;
1150 priv->is_authenticated = FALSE;
1151 if (username != priv->authentication_user)
1153 g_free (priv->authentication_user);
1154 priv->authentication_user = g_strdup (username);
1157 g_debug ("Starting authentication for user %s...", username);
1158 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
1159 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1160 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
1161 send_message (greeter, message, offset);
1165 * lightdm_greeter_authenticate_as_guest:
1166 * @greeter: A #LightDMGreeter
1168 * Starts the authentication procedure for the guest user.
1171 lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
1173 LightDMGreeterPrivate *priv;
1174 guint8 message[MAX_MESSAGE_LENGTH];
1177 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1179 priv = GET_PRIVATE (greeter);
1181 g_return_if_fail (priv->connected);
1183 priv->cancelling_authentication = FALSE;
1184 priv->authenticate_sequence_number++;
1185 priv->in_authentication = TRUE;
1186 priv->is_authenticated = FALSE;
1187 g_free (priv->authentication_user);
1188 priv->authentication_user = NULL;
1190 g_debug ("Starting authentication for guest account...");
1191 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
1192 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1193 send_message (greeter, message, offset);
1197 * lightdm_greeter_authenticate_autologin:
1198 * @greeter: A #LightDMGreeter
1200 * Starts the authentication procedure for the automatic login user.
1203 lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
1207 user = lightdm_greeter_get_autologin_user_hint (greeter);
1208 if (lightdm_greeter_get_autologin_guest_hint (greeter))
1209 lightdm_greeter_authenticate_as_guest (greeter);
1211 lightdm_greeter_authenticate (greeter, user);
1215 * lightdm_greeter_authenticate_remote:
1216 * @greeter: A #LightDMGreeter
1217 * @session: The name of a remote session
1218 * @username: (allow-none): A username of #NULL to prompt for a username.
1220 * Start authentication for a remote session type.
1223 lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
1225 LightDMGreeterPrivate *priv;
1226 guint8 message[MAX_MESSAGE_LENGTH];
1229 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1231 priv = GET_PRIVATE (greeter);
1233 g_return_if_fail (priv->connected);
1235 priv->cancelling_authentication = FALSE;
1236 priv->authenticate_sequence_number++;
1237 priv->in_authentication = TRUE;
1238 priv->is_authenticated = FALSE;
1239 g_free (priv->authentication_user);
1240 priv->authentication_user = NULL;
1243 g_debug ("Starting authentication for remote session %s as user %s...", session, username);
1245 g_debug ("Starting authentication for remote session %s...", session);
1246 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
1247 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1248 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
1249 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
1250 send_message (greeter, message, offset);
1254 * lightdm_greeter_respond:
1255 * @greeter: A #LightDMGreeter
1256 * @response: Response to a prompt
1258 * Provide response to a prompt. May be one in a series.
1261 lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
1263 LightDMGreeterPrivate *priv;
1264 guint8 message[MAX_MESSAGE_LENGTH];
1267 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1268 g_return_if_fail (response != NULL);
1270 priv = GET_PRIVATE (greeter);
1272 g_return_if_fail (priv->connected);
1273 g_return_if_fail (priv->n_responses_waiting > 0);
1275 priv->n_responses_waiting--;
1276 priv->responses_received = g_list_append (priv->responses_received, g_strdup (response));
1278 if (priv->n_responses_waiting == 0)
1283 g_debug ("Providing response to display manager");
1285 msg_length = int_length ();
1286 for (iter = priv->responses_received; iter; iter = iter->next)
1287 msg_length += string_length ((gchar *)iter->data);
1289 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
1290 write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset);
1291 for (iter = priv->responses_received; iter; iter = iter->next)
1292 write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset);
1293 send_message (greeter, message, offset);
1295 g_list_free_full (priv->responses_received, g_free);
1296 priv->responses_received = NULL;
1301 * lightdm_greeter_cancel_authentication:
1302 * @greeter: A #LightDMGreeter
1304 * Cancel the current user authentication.
1307 lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
1309 LightDMGreeterPrivate *priv;
1310 guint8 message[MAX_MESSAGE_LENGTH];
1313 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1315 priv = GET_PRIVATE (greeter);
1317 g_return_if_fail (priv->connected);
1319 priv->cancelling_authentication = TRUE;
1320 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
1321 send_message (greeter, message, offset);
1325 * lightdm_greeter_get_in_authentication:
1326 * @greeter: A #LightDMGreeter
1328 * Checks if the greeter is in the process of authenticating.
1330 * Return value: #TRUE if the greeter is authenticating a user.
1333 lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
1335 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1336 return GET_PRIVATE (greeter)->in_authentication;
1340 * lightdm_greeter_get_is_authenticated:
1341 * @greeter: A #LightDMGreeter
1343 * Checks if the greeter has successfully authenticated.
1345 * Return value: #TRUE if the greeter is authenticated for login.
1348 lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
1350 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1351 return GET_PRIVATE (greeter)->is_authenticated;
1355 * lightdm_greeter_get_authentication_user:
1356 * @greeter: A #LightDMGreeter
1358 * Get the user that is being authenticated.
1360 * Return value: (nullable): The username of the authentication user being authenticated or #NULL if no authentication in progress.
1363 lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
1365 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1366 return GET_PRIVATE (greeter)->authentication_user;
1370 * lightdm_greeter_set_language:
1371 * @greeter: A #LightDMGreeter
1372 * @language: The language to use for this user in the form of a locale specification (e.g. "de_DE.UTF-8").
1374 * Set the language for the currently authenticated user.
1377 lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
1379 LightDMGreeterPrivate *priv;
1380 guint8 message[MAX_MESSAGE_LENGTH];
1383 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1385 priv = GET_PRIVATE (greeter);
1387 g_return_if_fail (priv->connected);
1389 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
1390 write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
1391 send_message (greeter, message, offset);
1395 * lightdm_greeter_start_session:
1396 * @greeter: A #LightDMGreeter
1397 * @session: (allow-none): The session to log into or #NULL to use the default.
1398 * @cancellable: (allow-none): A #GCancellable or %NULL.
1399 * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
1400 * @user_data: (allow-none): data to pass to the @callback or %NULL.
1402 * Asynchronously start a session for the authenticated user.
1404 * 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.
1406 * See lightdm_greeter_start_session_sync() for the synchronous version.
1409 lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1411 LightDMGreeterPrivate *priv;
1414 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1416 priv = GET_PRIVATE (greeter);
1418 send_start_session (greeter, session);
1419 request = request_new (cancellable, callback, user_data);
1420 priv->start_session_requests = g_list_append (priv->start_session_requests, request);
1424 * lightdm_greeter_start_session_finish:
1425 * @greeter: A #LightDMGreeter
1426 * @result: A #GAsyncResult.
1427 * @error: return location for a #GError, or %NULL
1429 * Start a session for the authenticated user.
1431 * Return value: TRUE if the session was started.
1434 lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
1436 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1437 return REQUEST (result)->return_code == 0;
1441 * lightdm_greeter_start_session_sync:
1442 * @greeter: A #LightDMGreeter
1443 * @session: (allow-none): The session to log into or #NULL to use the default.
1444 * @error: return location for a #GError, or %NULL
1446 * Start a session for the authenticated user.
1448 * Return value: TRUE if the session was started.
1451 lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error)
1453 LightDMGreeterPrivate *priv;
1455 guint32 return_code;
1457 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1459 priv = GET_PRIVATE (greeter);
1461 g_return_val_if_fail (priv->connected, FALSE);
1462 g_return_val_if_fail (priv->is_authenticated, FALSE);
1464 /* Read until the session is started */
1465 send_start_session (greeter, session);
1466 request = request_new (NULL, NULL, NULL);
1467 priv->start_session_requests = g_list_append (priv->start_session_requests, g_object_ref (request));
1471 gsize message_length;
1473 message = recv_message (greeter, &message_length, TRUE);
1476 handle_message (greeter, message, message_length);
1478 } while (!request->complete);
1480 return_code = request->return_code;
1481 g_object_unref (request);
1483 return return_code == 0;
1487 * lightdm_greeter_ensure_shared_data_dir:
1488 * @greeter: A #LightDMGreeter
1489 * @username: A username
1490 * @cancellable: (allow-none): A #GCancellable or %NULL.
1491 * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
1492 * @user_data: (allow-none): data to pass to the @callback or %NULL.
1494 * Ensure that a shared data dir for the given user is available. Both the
1495 * greeter user and @username will have write access to that folder. The
1496 * intention is that larger pieces of shared data would be stored there (files
1497 * that the greeter creates but wants to give to a user -- like camera
1498 * photos -- or files that the user creates but wants the greeter to
1499 * see -- like contact avatars).
1501 * LightDM will automatically create these if the user actually logs in, so
1502 * greeters only need to call this method if they want to store something in
1503 * the directory themselves.
1506 lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1508 LightDMGreeterPrivate *priv;
1511 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1513 priv = GET_PRIVATE (greeter);
1515 send_ensure_shared_data_dir (greeter, username);
1516 request = request_new (cancellable, callback, user_data);
1517 priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request);
1521 * lightdm_greeter_ensure_shared_data_dir_finish:
1522 * @result: A #GAsyncResult.
1523 * @greeter: A #LightDMGreeter
1525 * Function to call from lightdm_greeter_ensure_shared_data_dir callback.
1527 * Return value: The path to the shared directory, free with g_free.
1530 lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result)
1532 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1533 return g_strdup (REQUEST (result)->dir);
1537 * lightdm_greeter_ensure_shared_data_dir_sync:
1538 * @greeter: A #LightDMGreeter
1539 * @username: A username
1541 * Ensure that a shared data dir for the given user is available. Both the
1542 * greeter user and @username will have write access to that folder. The
1543 * intention is that larger pieces of shared data would be stored there (files
1544 * that the greeter creates but wants to give to a user -- like camera
1545 * photos -- or files that the user creates but wants the greeter to
1546 * see -- like contact avatars).
1548 * LightDM will automatically create these if the user actually logs in, so
1549 * greeters only need to call this method if they want to store something in
1550 * the directory themselves.
1552 * Return value: The path to the shared directory, free with g_free.
1555 lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username)
1557 LightDMGreeterPrivate *priv;
1561 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1563 priv = GET_PRIVATE (greeter);
1565 g_return_val_if_fail (priv->connected, NULL);
1567 /* Read until a response */
1568 send_ensure_shared_data_dir (greeter, username);
1569 request = request_new (NULL, NULL, NULL);
1570 priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, g_object_ref (request));
1574 gsize message_length;
1576 message = recv_message (greeter, &message_length, TRUE);
1579 handle_message (greeter, message, message_length);
1581 } while (!request->complete);
1583 data_dir = g_strdup (request->dir);
1584 g_object_unref (request);
1590 lightdm_greeter_init (LightDMGreeter *greeter)
1592 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
1595 priv->read_buffer = g_malloc (HEADER_SIZE);
1596 priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1598 fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
1601 GError *error = NULL;
1603 priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
1604 g_io_channel_set_encoding (priv->to_server_channel, NULL, &error);
1606 g_warning ("Failed to set encoding on to server channel to binary: %s\n", error->message);
1607 g_clear_error (&error);
1610 g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
1612 fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
1615 GError *error = NULL;
1617 priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
1618 g_io_channel_set_encoding (priv->from_server_channel, NULL, &error);
1620 g_warning ("Failed to set encoding on from server channel to binary: %s\n", error->message);
1621 g_clear_error (&error);
1622 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
1625 g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
1629 lightdm_greeter_set_property (GObject *object,
1631 const GValue *value,
1634 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1638 lightdm_greeter_get_property (GObject *object,
1643 LightDMGreeter *self;
1645 self = LIGHTDM_GREETER (object);
1648 case PROP_DEFAULT_SESSION_HINT:
1649 g_value_set_string (value, lightdm_greeter_get_default_session_hint (self));
1651 case PROP_HIDE_USERS_HINT:
1652 g_value_set_boolean (value, lightdm_greeter_get_hide_users_hint (self));
1654 case PROP_SHOW_MANUAL_LOGIN_HINT:
1655 g_value_set_boolean (value, lightdm_greeter_get_show_manual_login_hint (self));
1657 case PROP_SHOW_REMOTE_LOGIN_HINT:
1658 g_value_set_boolean (value, lightdm_greeter_get_show_remote_login_hint (self));
1660 case PROP_LOCK_HINT:
1661 g_value_set_boolean (value, lightdm_greeter_get_lock_hint (self));
1663 case PROP_HAS_GUEST_ACCOUNT_HINT:
1664 g_value_set_boolean (value, lightdm_greeter_get_has_guest_account_hint (self));
1666 case PROP_SELECT_USER_HINT:
1667 g_value_set_string (value, lightdm_greeter_get_select_user_hint (self));
1669 case PROP_SELECT_GUEST_HINT:
1670 g_value_set_boolean (value, lightdm_greeter_get_select_guest_hint (self));
1672 case PROP_AUTOLOGIN_USER_HINT:
1673 g_value_set_string (value, lightdm_greeter_get_autologin_user_hint (self));
1675 case PROP_AUTOLOGIN_GUEST_HINT:
1676 g_value_set_boolean (value, lightdm_greeter_get_autologin_guest_hint (self));
1678 case PROP_AUTOLOGIN_TIMEOUT_HINT:
1679 g_value_set_int (value, lightdm_greeter_get_autologin_timeout_hint (self));
1681 case PROP_AUTHENTICATION_USER:
1682 g_value_set_string (value, lightdm_greeter_get_authentication_user (self));
1684 case PROP_IN_AUTHENTICATION:
1685 g_value_set_boolean (value, lightdm_greeter_get_in_authentication (self));
1687 case PROP_IS_AUTHENTICATED:
1688 g_value_set_boolean (value, lightdm_greeter_get_is_authenticated (self));
1691 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1697 lightdm_greeter_finalize (GObject *object)
1699 LightDMGreeter *self = LIGHTDM_GREETER (object);
1700 LightDMGreeterPrivate *priv = GET_PRIVATE (self);
1702 if (priv->to_server_channel)
1703 g_io_channel_unref (priv->to_server_channel);
1704 if (priv->from_server_channel)
1705 g_io_channel_unref (priv->from_server_channel);
1706 g_free (priv->authentication_user);
1707 g_hash_table_unref (priv->hints);
1709 G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
1713 lightdm_greeter_class_init (LightDMGreeterClass *klass)
1715 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1717 g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
1719 object_class->set_property = lightdm_greeter_set_property;
1720 object_class->get_property = lightdm_greeter_get_property;
1721 object_class->finalize = lightdm_greeter_finalize;
1723 g_object_class_install_property (object_class,
1724 PROP_DEFAULT_SESSION_HINT,
1725 g_param_spec_string ("default-session-hint",
1726 "default-session-hint",
1727 "Default session hint",
1731 g_object_class_install_property (object_class,
1732 PROP_HIDE_USERS_HINT,
1733 g_param_spec_boolean ("hide-users-hint",
1739 g_object_class_install_property (object_class,
1740 PROP_SHOW_MANUAL_LOGIN_HINT,
1741 g_param_spec_boolean ("show-manual-login-hint",
1742 "show-manual-login-hint",
1743 "Show manual login hint",
1747 g_object_class_install_property (object_class,
1748 PROP_SHOW_REMOTE_LOGIN_HINT,
1749 g_param_spec_boolean ("show-remote-login-hint",
1750 "show-remote-login-hint",
1751 "Show remote login hint",
1755 g_object_class_install_property (object_class,
1757 g_param_spec_boolean ("lock-hint",
1763 g_object_class_install_property (object_class,
1764 PROP_HAS_GUEST_ACCOUNT_HINT,
1765 g_param_spec_boolean ("has-guest-account-hint",
1766 "has-guest-account-hint",
1767 "Has guest account hint",
1771 g_object_class_install_property (object_class,
1772 PROP_SELECT_USER_HINT,
1773 g_param_spec_string ("select-user-hint",
1779 g_object_class_install_property (object_class,
1780 PROP_SELECT_GUEST_HINT,
1781 g_param_spec_boolean ("select-guest-hint",
1782 "select-guest-hint",
1783 "Select guest account hint",
1787 g_object_class_install_property (object_class,
1788 PROP_AUTOLOGIN_USER_HINT,
1789 g_param_spec_string ("autologin-user-hint",
1790 "autologin-user-hint",
1791 "Autologin user hint",
1795 g_object_class_install_property (object_class,
1796 PROP_AUTOLOGIN_GUEST_HINT,
1797 g_param_spec_boolean ("autologin-guest-hint",
1798 "autologin-guest-hint",
1799 "Autologin guest account hint",
1803 g_object_class_install_property (object_class,
1804 PROP_AUTOLOGIN_TIMEOUT_HINT,
1805 g_param_spec_int ("autologin-timeout-hint",
1806 "autologin-timeout-hint",
1807 "Autologin timeout hint",
1811 g_object_class_install_property (object_class,
1812 PROP_AUTHENTICATION_USER,
1813 g_param_spec_string ("authentication-user",
1814 "authentication-user",
1815 "The user being authenticated",
1818 g_object_class_install_property (object_class,
1819 PROP_IN_AUTHENTICATION,
1820 g_param_spec_boolean ("in-authentication",
1821 "in-authentication",
1822 "TRUE if a user is being authenticated",
1825 g_object_class_install_property (object_class,
1826 PROP_IS_AUTHENTICATED,
1827 g_param_spec_boolean ("is-authenticated",
1829 "TRUE if the selected user is authenticated",
1834 * LightDMGreeter::show-prompt:
1835 * @greeter: A #LightDMGreeter
1836 * @text: Prompt text
1837 * @type: Prompt type
1839 * The ::show-prompt signal gets emitted when the greeter should show a
1840 * prompt to the user. The given text should be displayed and an input
1841 * field for the user to provide a response.
1843 * Call lightdm_greeter_respond() with the resultant input or
1844 * lightdm_greeter_cancel_authentication() to abort the authentication.
1846 signals[SHOW_PROMPT] =
1847 g_signal_new (LIGHTDM_GREETER_SIGNAL_SHOW_PROMPT,
1848 G_TYPE_FROM_CLASS (klass),
1850 G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
1853 G_TYPE_NONE, 2, G_TYPE_STRING, lightdm_prompt_type_get_type ());
1856 * LightDMGreeter::show-message:
1857 * @greeter: A #LightDMGreeter
1858 * @text: Message text
1859 * @type: Message type
1861 * The ::show-message signal gets emitted when the greeter
1862 * should show a message to the user.
1864 signals[SHOW_MESSAGE] =
1865 g_signal_new (LIGHTDM_GREETER_SIGNAL_SHOW_MESSAGE,
1866 G_TYPE_FROM_CLASS (klass),
1868 G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
1871 G_TYPE_NONE, 2, G_TYPE_STRING, lightdm_message_type_get_type ());
1874 * LightDMGreeter::authentication-complete:
1875 * @greeter: A #LightDMGreeter
1877 * The ::authentication-complete signal gets emitted when the greeter
1878 * has completed authentication.
1880 * Call lightdm_greeter_get_is_authenticated() to check if the authentication
1883 signals[AUTHENTICATION_COMPLETE] =
1884 g_signal_new (LIGHTDM_GREETER_SIGNAL_AUTHENTICATION_COMPLETE,
1885 G_TYPE_FROM_CLASS (klass),
1887 G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
1893 * LightDMGreeter::autologin-timer-expired:
1894 * @greeter: A #LightDMGreeter
1896 * The ::timed-login signal gets emitted when the automatic login timer has expired.
1897 * The application should then call lightdm_greeter_login().
1899 signals[AUTOLOGIN_TIMER_EXPIRED] =
1900 g_signal_new (LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED,
1901 G_TYPE_FROM_CLASS (klass),
1903 G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
1909 * LightDMGreeter::idle:
1910 * @greeter: A #LightDMGreeter
1912 * The ::idle signal gets emitted when the user has logged in and the
1913 * greeter is no longer needed.
1915 * This signal only matters if the greeter has marked itself as
1916 * resettable using lightdm_greeter_set_resettable().
1919 g_signal_new (LIGHTDM_GREETER_SIGNAL_IDLE,
1920 G_TYPE_FROM_CLASS (klass),
1922 G_STRUCT_OFFSET (LightDMGreeterClass, idle),
1928 * LightDMGreeter::reset:
1929 * @greeter: A #LightDMGreeter
1931 * The ::reset signal gets emitted when the user is returning to a greeter
1932 * that was previously marked idle.
1934 * This signal only matters if the greeter has marked itself as
1935 * resettable using lightdm_greeter_set_resettable().
1938 g_signal_new (LIGHTDM_GREETER_SIGNAL_RESET,
1939 G_TYPE_FROM_CLASS (klass),
1941 G_STRUCT_OFFSET (LightDMGreeterClass, reset),
1948 request_init (Request *request)
1953 request_finalize (GObject *object)
1955 Request *request = REQUEST (object);
1957 g_free (request->dir);
1958 g_clear_object (&request->cancellable);
1960 G_OBJECT_CLASS (request_parent_class)->finalize (object);
1964 request_class_init (RequestClass *klass)
1966 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1967 object_class->finalize = request_finalize;
1971 request_get_user_data (GAsyncResult *result)
1973 return REQUEST (result)->user_data;
1977 request_get_source_object (GAsyncResult *res)
1983 request_iface_init (GAsyncResultIface *iface)
1985 iface->get_user_data = request_get_user_data;
1986 iface->get_source_object = request_get_source_object;