VirtualBox

source: vbox/trunk/src/VBox/Additions/linux/lightdm-greeter/liblightdm-gobject-1.5.0/greeter.c@ 82968

最後變更 在這個檔案從82968是 69506,由 vboxsync 提交於 7 年 前

More scm updates

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 46.6 KB
 
1/*
2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <[email protected]>
4 *
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.
9 */
10
11/*
12 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
13 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
14 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
15 * a choice of LGPL license versions is made available with the language indicating
16 * that LGPLv2 or any later version may be used, or where a choice of which version
17 * of the LGPL is applied is otherwise unspecified.
18 */
19
20#include "config.h"
21
22#include <stdlib.h>
23#include <string.h>
24#include <security/pam_appl.h>
25
26#include "lightdm/greeter.h"
27
28enum {
29 PROP_0,
30 PROP_DEFAULT_SESSION_HINT,
31 PROP_HIDE_USERS_HINT,
32 PROP_SHOW_MANUAL_LOGIN_HINT,
33 PROP_SHOW_REMOTE_LOGIN_HINT,
34 PROP_LOCK_HINT,
35 PROP_HAS_GUEST_ACCOUNT_HINT,
36 PROP_SELECT_USER_HINT,
37 PROP_SELECT_GUEST_HINT,
38 PROP_AUTOLOGIN_USER_HINT,
39 PROP_AUTOLOGIN_GUEST_HINT,
40 PROP_AUTOLOGIN_TIMEOUT_HINT,
41 PROP_AUTHENTICATION_USER,
42 PROP_IN_AUTHENTICATION,
43 PROP_IS_AUTHENTICATED,
44};
45
46enum {
47 SHOW_PROMPT,
48 SHOW_MESSAGE,
49 AUTHENTICATION_COMPLETE,
50 AUTOLOGIN_TIMER_EXPIRED,
51 LAST_SIGNAL
52};
53static guint signals[LAST_SIGNAL] = { 0 };
54
55typedef struct
56{
57 gboolean connected;
58
59 GIOChannel *to_server_channel, *from_server_channel;
60 guint8 *read_buffer;
61 gsize n_read;
62
63 gsize n_responses_waiting;
64 GList *responses_received;
65
66 GHashTable *hints;
67 guint autologin_timeout;
68
69 gchar *authentication_user;
70 gboolean in_authentication;
71 gboolean is_authenticated;
72 guint32 authenticate_sequence_number;
73 gboolean cancelling_authentication;
74} LightDMGreeterPrivate;
75
76G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
77
78#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
79
80#define HEADER_SIZE 8
81#define MAX_MESSAGE_LENGTH 1024
82
83/* Messages from the greeter to the server */
84typedef enum
85{
86 GREETER_MESSAGE_CONNECT = 0,
87 GREETER_MESSAGE_AUTHENTICATE,
88 GREETER_MESSAGE_AUTHENTICATE_AS_GUEST,
89 GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
90 GREETER_MESSAGE_START_SESSION,
91 GREETER_MESSAGE_CANCEL_AUTHENTICATION,
92 GREETER_MESSAGE_SET_LANGUAGE,
93 GREETER_MESSAGE_AUTHENTICATE_REMOTE
94} GreeterMessage;
95
96/* Messages from the server to the greeter */
97typedef enum
98{
99 SERVER_MESSAGE_CONNECTED = 0,
100 SERVER_MESSAGE_PROMPT_AUTHENTICATION,
101 SERVER_MESSAGE_END_AUTHENTICATION,
102 SERVER_MESSAGE_SESSION_RESULT
103} ServerMessage;
104
105/**
106 * lightdm_greeter_new:
107 *
108 * Create a new greeter.
109 *
110 * Return value: the new #LightDMGreeter
111 **/
112LightDMGreeter *
113lightdm_greeter_new ()
114{
115 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
116}
117
118static gboolean
119timed_login_cb (gpointer data)
120{
121 LightDMGreeter *greeter = data;
122 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
123
124 priv->autologin_timeout = 0;
125 g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
126
127 return FALSE;
128}
129
130static guint32
131int_length ()
132{
133 return 4;
134}
135
136static void
137write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
138{
139 if (*offset + 4 >= buffer_length)
140 return;
141 buffer[*offset] = value >> 24;
142 buffer[*offset+1] = (value >> 16) & 0xFF;
143 buffer[*offset+2] = (value >> 8) & 0xFF;
144 buffer[*offset+3] = value & 0xFF;
145 *offset += 4;
146}
147
148static void
149write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
150{
151 gint length = 0;
152
153 if (value)
154 length = strlen (value);
155 write_int (buffer, buffer_length, length, offset);
156 if (*offset + length >= buffer_length)
157 return;
158 memcpy (buffer + *offset, value, length);
159 *offset += length;
160}
161
162static guint32
163read_int (guint8 *message, gsize message_length, gsize *offset)
164{
165 guint32 value;
166 guint8 *buffer;
167
168 if (message_length - *offset < int_length ())
169 {
170 g_warning ("Not enough space for int, need %i, got %zi", int_length (), message_length - *offset);
171 return 0;
172 }
173
174 buffer = message + *offset;
175 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
176 *offset += int_length ();
177
178 return value;
179}
180
181static gchar *
182read_string (guint8 *message, gsize message_length, gsize *offset)
183{
184 guint32 length;
185 gchar *value;
186
187 length = read_int (message, message_length, offset);
188 if (message_length - *offset < length)
189 {
190 g_warning ("Not enough space for string, need %u, got %zu", length, message_length - *offset);
191 return g_strdup ("");
192 }
193
194 value = g_malloc (sizeof (gchar) * (length + 1));
195 memcpy (value, message + *offset, length);
196 value[length] = '\0';
197 *offset += length;
198
199 return value;
200}
201
202static guint32
203string_length (const gchar *value)
204{
205 if (value)
206 return int_length () + strlen (value);
207 else
208 return int_length ();
209}
210
211static void
212write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
213{
214 write_int (buffer, buffer_length, id, offset);
215 write_int (buffer, buffer_length, length, offset);
216}
217
218static guint32
219get_message_length (guint8 *message, gsize message_length)
220{
221 gsize offset = 4;
222 return read_int (message, message_length, &offset);
223}
224
225static void
226write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
227{
228 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
229 GIOStatus status;
230 GError *error = NULL;
231 guint32 stated_length;
232
233 /* Double check that we're sending well-formed messages. If we say we're
234 sending more than we do, we end up DOS'ing lightdm as it waits for the
235 rest. If we say we're sending less than we do, we confuse the heck out
236 of lightdm, as it starts reading headers from the middle of our
237 messages. */
238 stated_length = HEADER_SIZE + get_message_length (message, message_length);
239 if (stated_length != message_length)
240 {
241 g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
242 return;
243 }
244
245 status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
246 if (error)
247 g_warning ("Error writing to daemon: %s", error->message);
248 g_clear_error (&error);
249 if (status == G_IO_STATUS_NORMAL)
250 g_debug ("Wrote %zi bytes to daemon", message_length);
251 g_io_channel_flush (priv->to_server_channel, NULL);
252}
253
254static void
255handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
256{
257 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
258 gchar *version;
259 GString *hint_string;
260 int timeout;
261
262 version = read_string (message, message_length, offset);
263 hint_string = g_string_new ("");
264 while (*offset < message_length)
265 {
266 gchar *name, *value;
267
268 name = read_string (message, message_length, offset);
269 value = read_string (message, message_length, offset);
270 g_hash_table_insert (priv->hints, name, value);
271 g_string_append_printf (hint_string, " %s=%s", name, value);
272 }
273
274 g_debug ("Connected version=%s%s", version, hint_string->str);
275 g_free (version);
276 g_string_free (hint_string, TRUE);
277
278 /* Set timeout for default login */
279 timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
280 if (timeout)
281 {
282 g_debug ("Setting autologin timer for %d seconds", timeout);
283 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
284 }
285}
286
287static void
288handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
289{
290 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
291 guint32 sequence_number, n_messages, i;
292 gchar *username;
293
294 sequence_number = read_int (message, message_length, offset);
295 if (sequence_number != priv->authenticate_sequence_number)
296 {
297 g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
298 return;
299 }
300
301 if (priv->cancelling_authentication)
302 {
303 g_debug ("Ignoring prompt authentication as waiting for it to cancel");
304 return;
305 }
306
307 /* Update username */
308 username = read_string (message, message_length, offset);
309 if (strcmp (username, "") == 0)
310 {
311 g_free (username);
312 username = NULL;
313 }
314 g_free (priv->authentication_user);
315 priv->authentication_user = username;
316
317 g_list_free_full (priv->responses_received, g_free);
318 priv->responses_received = NULL;
319 priv->n_responses_waiting = 0;
320
321 n_messages = read_int (message, message_length, offset);
322 g_debug ("Prompt user with %d message(s)", n_messages);
323
324 for (i = 0; i < n_messages; i++)
325 {
326 int style;
327 gchar *text;
328
329 style = read_int (message, message_length, offset);
330 text = read_string (message, message_length, offset);
331
332 // FIXME: Should stop on prompts?
333 switch (style)
334 {
335 case PAM_PROMPT_ECHO_OFF:
336 priv->n_responses_waiting++;
337 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_SECRET);
338 break;
339 case PAM_PROMPT_ECHO_ON:
340 priv->n_responses_waiting++;
341 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_QUESTION);
342 break;
343 case PAM_ERROR_MSG:
344 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_ERROR);
345 break;
346 case PAM_TEXT_INFO:
347 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_INFO);
348 break;
349 }
350
351 g_free (text);
352 }
353}
354
355static void
356handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
357{
358 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
359 guint32 sequence_number, return_code;
360 gchar *username;
361
362 sequence_number = read_int (message, message_length, offset);
363
364 if (sequence_number != priv->authenticate_sequence_number)
365 {
366 g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number);
367 return;
368 }
369
370 username = read_string (message, message_length, offset);
371 return_code = read_int (message, message_length, offset);
372
373 g_debug ("Authentication complete for user %s with return code %d", username, return_code);
374
375 /* Update username */
376 if (strcmp (username, "") == 0)
377 {
378 g_free (username);
379 username = NULL;
380 }
381 g_free (priv->authentication_user);
382 priv->authentication_user = username;
383
384 priv->cancelling_authentication = FALSE;
385 priv->is_authenticated = (return_code == 0);
386
387 priv->in_authentication = FALSE;
388 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
389}
390
391static guint8 *
392read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
393{
394 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
395 gsize n_to_read, n_read;
396 guint8 *buffer;
397 GError *error = NULL;
398
399 /* Read the header, or the whole message if we already have that */
400 n_to_read = HEADER_SIZE;
401 if (priv->n_read >= HEADER_SIZE)
402 n_to_read += get_message_length (priv->read_buffer, priv->n_read);
403
404 do
405 {
406 GIOStatus status;
407 status = g_io_channel_read_chars (priv->from_server_channel,
408 (gchar *) priv->read_buffer + priv->n_read,
409 n_to_read - priv->n_read,
410 &n_read,
411 &error);
412 if (error)
413 g_warning ("Error reading from server: %s", error->message);
414 g_clear_error (&error);
415 if (status != G_IO_STATUS_NORMAL)
416 break;
417
418 g_debug ("Read %zi bytes from daemon", n_read);
419
420 priv->n_read += n_read;
421 } while (priv->n_read < n_to_read && block);
422
423 /* Stop if haven't got all the data we want */
424 if (priv->n_read != n_to_read)
425 return FALSE;
426
427 /* If have header, rerun for content */
428 if (priv->n_read == HEADER_SIZE)
429 {
430 n_to_read = get_message_length (priv->read_buffer, priv->n_read);
431 if (n_to_read > 0)
432 {
433 priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
434 return read_message (greeter, length, block);
435 }
436 }
437
438 buffer = priv->read_buffer;
439 *length = priv->n_read;
440
441 priv->read_buffer = g_malloc (priv->n_read);
442 priv->n_read = 0;
443
444 return buffer;
445}
446
447static gboolean
448from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
449{
450 LightDMGreeter *greeter = data;
451 guint8 *message;
452 gsize message_length, offset;
453 guint32 id;
454
455 message = read_message (greeter, &message_length, FALSE);
456 if (!message)
457 return TRUE;
458
459 offset = 0;
460 id = read_int (message, message_length, &offset);
461 read_int (message, message_length, &offset);
462 switch (id)
463 {
464 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
465 handle_prompt_authentication (greeter, message, message_length, &offset);
466 break;
467 case SERVER_MESSAGE_END_AUTHENTICATION:
468 handle_end_authentication (greeter, message, message_length, &offset);
469 break;
470 default:
471 g_warning ("Unknown message from server: %d", id);
472 break;
473 }
474 g_free (message);
475
476 return TRUE;
477}
478
479/**
480 * lightdm_greeter_connect_sync:
481 * @greeter: The greeter to connect
482 * @error: return location for a #GError, or %NULL
483 *
484 * Connects the greeter to the display manager. Will block until connected.
485 *
486 * Return value: #TRUE if successfully connected
487 **/
488gboolean
489lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
490{
491 LightDMGreeterPrivate *priv;
492 const gchar *fd;
493 guint8 message[MAX_MESSAGE_LENGTH];
494 guint8 *response;
495 gsize response_length, offset = 0;
496 guint32 id;
497
498 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
499
500 priv = GET_PRIVATE (greeter);
501
502 fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
503 if (!fd)
504 {
505 g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
506 return FALSE;
507 }
508 priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
509 g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL);
510
511 fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
512 if (!fd)
513 {
514 g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
515 return FALSE;
516 }
517 priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
518 g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
519 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
520
521 g_debug ("Connecting to display manager...");
522 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
523 write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
524 write_message (greeter, message, offset);
525
526 response = read_message (greeter, &response_length, TRUE);
527 if (!response)
528 return FALSE;
529
530 offset = 0;
531 id = read_int (response, response_length, &offset);
532 read_int (response, response_length, &offset);
533 if (id == SERVER_MESSAGE_CONNECTED)
534 handle_connected (greeter, response, response_length, &offset);
535 g_free (response);
536 if (id != SERVER_MESSAGE_CONNECTED)
537 {
538 g_warning ("Expected CONNECTED message, got %d", id);
539 return FALSE;
540 }
541
542 priv->connected = TRUE;
543
544 return TRUE;
545}
546
547/**
548 * lightdm_greeter_get_hint:
549 * @greeter: A #LightDMGreeter
550 * @name: The hint name to query.
551 *
552 * Get a hint.
553 *
554 * Return value: The value for this hint or #NULL if not set.
555 **/
556const gchar *
557lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
558{
559 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
560 return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
561}
562
563/**
564 * lightdm_greeter_get_default_session_hint:
565 * @greeter: A #LightDMGreeter
566 *
567 * Get the default session to use.
568 *
569 * Return value: The session name
570 **/
571const gchar *
572lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
573{
574 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
575 return lightdm_greeter_get_hint (greeter, "default-session");
576}
577
578/**
579 * lightdm_greeter_get_hide_users_hint:
580 * @greeter: A #LightDMGreeter
581 *
582 * Check if user accounts should be shown. If this is TRUE then the list of
583 * accounts should be taken from #LightDMUserList and displayed in the greeter
584 * for the user to choose from. Note that this list can be empty and it is
585 * recommended you show a method for the user to enter a username manually.
586 *
587 * If this option is shown the greeter should only allow these users to be
588 * chosen for login unless the manual login hint is set.
589 *
590 * Return value: #TRUE if the available users should not be shown.
591 */
592gboolean
593lightdm_greeter_get_hide_users_hint (LightDMGreeter *greeter)
594{
595 const gchar *value;
596
597 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
598 value = lightdm_greeter_get_hint (greeter, "hide-users");
599
600 return g_strcmp0 (value, "true") == 0;
601}
602
603/**
604 * lightdm_greeter_get_show_manual_login_hint:
605 * @greeter: A #LightDMGreeter
606 *
607 * Check if a manual login option should be shown. If set the GUI
608 * should provide a way for a username to be entered manually.
609 * Without this hint a greeter which is showing a user list can
610 * limit logins to only those users.
611 *
612 * Return value: #TRUE if a manual login option should be shown.
613 */
614gboolean
615lightdm_greeter_get_show_manual_login_hint (LightDMGreeter *greeter)
616{
617 const gchar *value;
618
619 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
620 value = lightdm_greeter_get_hint (greeter, "show-manual-login");
621
622 return g_strcmp0 (value, "true") == 0;
623}
624
625/**
626 * lightdm_greeter_get_show_remote_login_hint:
627 * @greeter: A #LightDMGreeter
628 *
629 * Check if a remote login option should be shown. If set the GUI
630 * should provide a way for a user to log into a remote desktop server.
631 *
632 * Return value: #TRUE if a remote login option should be shown.
633 */
634gboolean
635lightdm_greeter_get_show_remote_login_hint (LightDMGreeter *greeter)
636{
637 const gchar *value;
638
639 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
640 value = lightdm_greeter_get_hint (greeter, "show-remote-login");
641
642 return g_strcmp0 (value, "true") == 0;
643}
644
645/**
646 * lightdm_greeter_get_lock_hint:
647 * @greeter: A #LightDMGreeter
648 *
649 * Check if the greeter is acting as a lock screen.
650 *
651 * Return value: #TRUE if the greeter was triggered by locking the seat.
652 */
653gboolean
654lightdm_greeter_get_lock_hint (LightDMGreeter *greeter)
655{
656 const gchar *value;
657
658 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
659 value = lightdm_greeter_get_hint (greeter, "lock-screen");
660
661 return g_strcmp0 (value, "true") == 0;
662}
663
664/**
665 * lightdm_greeter_get_has_guest_account_hint:
666 * @greeter: A #LightDMGreeter
667 *
668 * Check if guest sessions are supported.
669 *
670 * Return value: #TRUE if guest sessions are supported.
671 */
672gboolean
673lightdm_greeter_get_has_guest_account_hint (LightDMGreeter *greeter)
674{
675 const gchar *value;
676
677 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
678 value = lightdm_greeter_get_hint (greeter, "has-guest-account");
679
680 return g_strcmp0 (value, "true") == 0;
681}
682
683/**
684 * lightdm_greeter_get_select_user_hint:
685 * @greeter: A #LightDMGreeter
686 *
687 * Get the user to select by default.
688 *
689 * Return value: A username
690 */
691const gchar *
692lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
693{
694 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
695 return lightdm_greeter_get_hint (greeter, "select-user");
696}
697
698/**
699 * lightdm_greeter_get_select_guest_hint:
700 * @greeter: A #LightDMGreeter
701 *
702 * Check if the guest account should be selected by default.
703 *
704 * Return value: #TRUE if the guest account should be selected by default.
705 */
706gboolean
707lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter)
708{
709 const gchar *value;
710
711 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
712 value = lightdm_greeter_get_hint (greeter, "select-guest");
713
714 return g_strcmp0 (value, "true") == 0;
715}
716
717/**
718 * lightdm_greeter_get_autologin_user_hint:
719 * @greeter: A #LightDMGreeter
720 *
721 * Get the user account to automatically logg into when the timer expires.
722 *
723 * Return value: The user account to automatically log into.
724 */
725const gchar *
726lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
727{
728 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
729 return lightdm_greeter_get_hint (greeter, "autologin-user");
730}
731
732/**
733 * lightdm_greeter_get_autologin_guest_hint:
734 * @greeter: A #LightDMGreeter
735 *
736 * Check if the guest account should be automatically logged into when the timer expires.
737 *
738 * Return value: #TRUE if the guest account should be automatically logged into.
739 */
740gboolean
741lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter)
742{
743 const gchar *value;
744
745 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
746 value = lightdm_greeter_get_hint (greeter, "autologin-guest");
747
748 return g_strcmp0 (value, "true") == 0;
749}
750
751/**
752 * lightdm_greeter_get_autologin_timeout_hint:
753 * @greeter: A #LightDMGreeter
754 *
755 * Get the number of seconds to wait before automaitcally logging in.
756 *
757 * Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
758 */
759gint
760lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter)
761{
762 const gchar *value;
763 gint timeout = 0;
764
765 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
766 value = lightdm_greeter_get_hint (greeter, "autologin-timeout");
767 if (value)
768 timeout = atoi (value);
769 if (timeout < 0)
770 timeout = 0;
771
772 return timeout;
773}
774
775/**
776 * lightdm_greeter_cancel_autologin:
777 * @greeter: A #LightDMGreeter
778 *
779 * Cancel the automatic login.
780 */
781void
782lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
783{
784 LightDMGreeterPrivate *priv;
785
786 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
787
788 priv = GET_PRIVATE (greeter);
789
790 if (priv->autologin_timeout)
791 g_source_remove (priv->autologin_timeout);
792 priv->autologin_timeout = 0;
793}
794
795/**
796 * lightdm_greeter_authenticate:
797 * @greeter: A #LightDMGreeter
798 * @username: (allow-none): A username or #NULL to prompt for a username.
799 *
800 * Starts the authentication procedure for a user.
801 **/
802void
803lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
804{
805 LightDMGreeterPrivate *priv;
806 guint8 message[MAX_MESSAGE_LENGTH];
807 gsize offset = 0;
808
809 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
810
811 priv = GET_PRIVATE (greeter);
812
813 g_return_if_fail (priv->connected);
814
815 priv->cancelling_authentication = FALSE;
816 priv->authenticate_sequence_number++;
817 priv->in_authentication = TRUE;
818 priv->is_authenticated = FALSE;
819 if (username != priv->authentication_user)
820 {
821 g_free (priv->authentication_user);
822 priv->authentication_user = g_strdup (username);
823 }
824
825 g_debug ("Starting authentication for user %s...", username);
826 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
827 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
828 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
829 write_message (greeter, message, offset);
830}
831
832/**
833 * lightdm_greeter_authenticate_as_guest:
834 * @greeter: A #LightDMGreeter
835 *
836 * Starts the authentication procedure for the guest user.
837 **/
838void
839lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
840{
841 LightDMGreeterPrivate *priv;
842 guint8 message[MAX_MESSAGE_LENGTH];
843 gsize offset = 0;
844
845 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
846
847 priv = GET_PRIVATE (greeter);
848
849 g_return_if_fail (priv->connected);
850
851 priv->cancelling_authentication = FALSE;
852 priv->authenticate_sequence_number++;
853 priv->in_authentication = TRUE;
854 priv->is_authenticated = FALSE;
855 g_free (priv->authentication_user);
856 priv->authentication_user = NULL;
857
858 g_debug ("Starting authentication for guest account...");
859 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
860 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
861 write_message (greeter, message, offset);
862}
863
864/**
865 * lightdm_greeter_authenticate_autologin:
866 * @greeter: A #LightDMGreeter
867 *
868 * Starts the authentication procedure for the automatic login user.
869 **/
870void
871lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
872{
873 const gchar *user;
874
875 user = lightdm_greeter_get_autologin_user_hint (greeter);
876 if (lightdm_greeter_get_autologin_guest_hint (greeter))
877 lightdm_greeter_authenticate_as_guest (greeter);
878 else if (user)
879 lightdm_greeter_authenticate (greeter, user);
880}
881
882/**
883 * lightdm_greeter_authenticate_remote:
884 * @greeter: A #LightDMGreeter
885 * @session: The name of a remote session
886 * @username: (allow-none): A username of #NULL to prompt for a username.
887 *
888 * Start authentication for a remote session type.
889 **/
890void
891lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
892{
893 LightDMGreeterPrivate *priv;
894 guint8 message[MAX_MESSAGE_LENGTH];
895 gsize offset = 0;
896
897 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
898
899 priv = GET_PRIVATE (greeter);
900
901 g_return_if_fail (priv->connected);
902
903 priv->cancelling_authentication = FALSE;
904 priv->authenticate_sequence_number++;
905 priv->in_authentication = TRUE;
906 priv->is_authenticated = FALSE;
907 g_free (priv->authentication_user);
908 priv->authentication_user = NULL;
909
910 if (username)
911 g_debug ("Starting authentication for remote session %s as user %s...", session, username);
912 else
913 g_debug ("Starting authentication for remote session %s...", session);
914 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
915 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
916 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
917 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
918 write_message (greeter, message, offset);
919}
920
921/**
922 * lightdm_greeter_respond:
923 * @greeter: A #LightDMGreeter
924 * @response: Response to a prompt
925 *
926 * Provide response to a prompt. May be one in a series.
927 **/
928void
929lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
930{
931 LightDMGreeterPrivate *priv;
932 guint8 message[MAX_MESSAGE_LENGTH];
933 gsize offset = 0;
934
935 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
936 g_return_if_fail (response != NULL);
937
938 priv = GET_PRIVATE (greeter);
939
940 g_return_if_fail (priv->connected);
941 g_return_if_fail (priv->n_responses_waiting > 0);
942
943 priv->n_responses_waiting--;
944 priv->responses_received = g_list_append (priv->responses_received, g_strdup (response));
945
946 if (priv->n_responses_waiting == 0)
947 {
948 guint32 msg_length;
949 GList *iter;
950
951 g_debug ("Providing response to display manager");
952
953 msg_length = int_length ();
954 for (iter = priv->responses_received; iter; iter = iter->next)
955 {
956 msg_length += string_length ((gchar *)iter->data);
957 }
958
959 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
960 write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset);
961 for (iter = priv->responses_received; iter; iter = iter->next)
962 {
963 write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset);
964 }
965 write_message (greeter, message, offset);
966
967 g_list_free_full (priv->responses_received, g_free);
968 priv->responses_received = NULL;
969 }
970}
971
972/**
973 * lightdm_greeter_cancel_authentication:
974 * @greeter: A #LightDMGreeter
975 *
976 * Cancel the current user authentication.
977 **/
978void
979lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
980{
981 LightDMGreeterPrivate *priv;
982 guint8 message[MAX_MESSAGE_LENGTH];
983 gsize offset = 0;
984
985 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
986
987 priv = GET_PRIVATE (greeter);
988
989 g_return_if_fail (priv->connected);
990
991 priv->cancelling_authentication = TRUE;
992 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
993 write_message (greeter, message, offset);
994}
995
996/**
997 * lightdm_greeter_get_in_authentication:
998 * @greeter: A #LightDMGreeter
999 *
1000 * Checks if the greeter is in the process of authenticating.
1001 *
1002 * Return value: #TRUE if the greeter is authenticating a user.
1003 **/
1004gboolean
1005lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
1006{
1007 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1008 return GET_PRIVATE (greeter)->in_authentication;
1009}
1010
1011/**
1012 * lightdm_greeter_get_is_authenticated:
1013 * @greeter: A #LightDMGreeter
1014 *
1015 * Checks if the greeter has successfully authenticated.
1016 *
1017 * Return value: #TRUE if the greeter is authenticated for login.
1018 **/
1019gboolean
1020lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
1021{
1022 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1023 return GET_PRIVATE (greeter)->is_authenticated;
1024}
1025
1026/**
1027 * lightdm_greeter_get_authentication_user:
1028 * @greeter: A #LightDMGreeter
1029 *
1030 * Get the user that is being authenticated.
1031 *
1032 * Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
1033 */
1034const gchar *
1035lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
1036{
1037 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1038 return GET_PRIVATE (greeter)->authentication_user;
1039}
1040
1041/**
1042 * lightdm_greeter_set_language:
1043 * @greeter: A #LightDMGreeter
1044 * @language: The language to use for this user.
1045 *
1046 * Set the language for the currently authenticated user.
1047 **/
1048void
1049lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
1050{
1051 LightDMGreeterPrivate *priv;
1052 guint8 message[MAX_MESSAGE_LENGTH];
1053 gsize offset = 0;
1054
1055 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1056
1057 priv = GET_PRIVATE (greeter);
1058
1059 g_return_if_fail (priv->connected);
1060
1061 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
1062 write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
1063 write_message (greeter, message, offset);
1064}
1065
1066/**
1067 * lightdm_greeter_start_session_sync:
1068 * @greeter: A #LightDMGreeter
1069 * @session: (allow-none): The session to log into or #NULL to use the default.
1070 * @error: return location for a #GError, or %NULL
1071 *
1072 * Start a session for the authenticated user.
1073 *
1074 * Return value: TRUE if the session was started.
1075 **/
1076gboolean
1077lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error)
1078{
1079 LightDMGreeterPrivate *priv;
1080 guint8 message[MAX_MESSAGE_LENGTH];
1081 guint8 *response;
1082 gsize response_length, offset = 0;
1083 guint32 id, return_code = 1;
1084
1085 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1086
1087 priv = GET_PRIVATE (greeter);
1088
1089 g_return_val_if_fail (priv->connected, FALSE);
1090 g_return_val_if_fail (priv->is_authenticated, FALSE);
1091
1092 if (session)
1093 g_debug ("Starting session %s", session);
1094 else
1095 g_debug ("Starting default session");
1096
1097 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
1098 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
1099 write_message (greeter, message, offset);
1100
1101 response = read_message (greeter, &response_length, TRUE);
1102 if (!response)
1103 return FALSE;
1104
1105 offset = 0;
1106 id = read_int (response, response_length, &offset);
1107 read_int (response, response_length, &offset);
1108 if (id == SERVER_MESSAGE_SESSION_RESULT)
1109 return_code = read_int (response, response_length, &offset);
1110 else
1111 g_warning ("Expected SESSION_RESULT message, got %d", id);
1112
1113 g_free (response);
1114
1115 return return_code == 0;
1116}
1117
1118static void
1119lightdm_greeter_init (LightDMGreeter *greeter)
1120{
1121 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
1122
1123 priv->read_buffer = g_malloc (HEADER_SIZE);
1124 priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1125}
1126
1127static void
1128lightdm_greeter_set_property (GObject *object,
1129 guint prop_id,
1130 const GValue *value,
1131 GParamSpec *pspec)
1132{
1133 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1134}
1135
1136static void
1137lightdm_greeter_get_property (GObject *object,
1138 guint prop_id,
1139 GValue *value,
1140 GParamSpec *pspec)
1141{
1142 LightDMGreeter *self;
1143
1144 self = LIGHTDM_GREETER (object);
1145
1146 switch (prop_id) {
1147 case PROP_DEFAULT_SESSION_HINT:
1148 g_value_set_string (value, lightdm_greeter_get_default_session_hint (self));
1149 break;
1150 case PROP_HIDE_USERS_HINT:
1151 g_value_set_boolean (value, lightdm_greeter_get_hide_users_hint (self));
1152 break;
1153 case PROP_SHOW_MANUAL_LOGIN_HINT:
1154 g_value_set_boolean (value, lightdm_greeter_get_show_manual_login_hint (self));
1155 break;
1156 case PROP_SHOW_REMOTE_LOGIN_HINT:
1157 g_value_set_boolean (value, lightdm_greeter_get_show_remote_login_hint (self));
1158 break;
1159 case PROP_LOCK_HINT:
1160 g_value_set_boolean (value, lightdm_greeter_get_lock_hint (self));
1161 break;
1162 case PROP_HAS_GUEST_ACCOUNT_HINT:
1163 g_value_set_boolean (value, lightdm_greeter_get_has_guest_account_hint (self));
1164 break;
1165 case PROP_SELECT_USER_HINT:
1166 g_value_set_string (value, lightdm_greeter_get_select_user_hint (self));
1167 break;
1168 case PROP_SELECT_GUEST_HINT:
1169 g_value_set_boolean (value, lightdm_greeter_get_select_guest_hint (self));
1170 break;
1171 case PROP_AUTOLOGIN_USER_HINT:
1172 g_value_set_string (value, lightdm_greeter_get_autologin_user_hint (self));
1173 break;
1174 case PROP_AUTOLOGIN_GUEST_HINT:
1175 g_value_set_boolean (value, lightdm_greeter_get_autologin_guest_hint (self));
1176 break;
1177 case PROP_AUTOLOGIN_TIMEOUT_HINT:
1178 g_value_set_int (value, lightdm_greeter_get_autologin_timeout_hint (self));
1179 break;
1180 case PROP_AUTHENTICATION_USER:
1181 g_value_set_string (value, lightdm_greeter_get_authentication_user (self));
1182 break;
1183 case PROP_IN_AUTHENTICATION:
1184 g_value_set_boolean (value, lightdm_greeter_get_in_authentication (self));
1185 break;
1186 case PROP_IS_AUTHENTICATED:
1187 g_value_set_boolean (value, lightdm_greeter_get_is_authenticated (self));
1188 break;
1189 default:
1190 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1191 break;
1192 }
1193}
1194
1195static void
1196marshal_VOID__STRING_INT (GClosure *closure,
1197 GValue *return_value G_GNUC_UNUSED,
1198 guint n_param_values,
1199 const GValue *param_values,
1200 gpointer invocation_hint G_GNUC_UNUSED,
1201 gpointer marshal_data)
1202{
1203 typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1,
1204 gpointer arg_1,
1205 gint arg_2,
1206 gpointer data2);
1207 register GMarshalFunc_VOID__STRING_INT callback;
1208 register GCClosure *cc = (GCClosure*) closure;
1209 register gpointer data1, data2;
1210
1211 g_return_if_fail (n_param_values == 3);
1212
1213 if (G_CCLOSURE_SWAP_DATA (closure))
1214 {
1215 data1 = closure->data;
1216 data2 = g_value_peek_pointer (param_values + 0);
1217 }
1218 else
1219 {
1220 data1 = g_value_peek_pointer (param_values + 0);
1221 data2 = closure->data;
1222 }
1223 callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
1224
1225 callback (data1,
1226 (param_values + 1)->data[0].v_pointer,
1227 (param_values + 2)->data[0].v_int,
1228 data2);
1229}
1230
1231static void
1232lightdm_greeter_finalize (GObject *object)
1233{
1234 LightDMGreeter *self = LIGHTDM_GREETER (object);
1235 LightDMGreeterPrivate *priv = GET_PRIVATE (self);
1236
1237 if (priv->to_server_channel)
1238 g_io_channel_unref (priv->to_server_channel);
1239 if (priv->from_server_channel)
1240 g_io_channel_unref (priv->from_server_channel);
1241 g_free (priv->authentication_user);
1242 g_hash_table_unref (priv->hints);
1243
1244 G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
1245}
1246
1247static void
1248lightdm_greeter_class_init (LightDMGreeterClass *klass)
1249{
1250 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1251
1252 g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
1253
1254 object_class->set_property = lightdm_greeter_set_property;
1255 object_class->get_property = lightdm_greeter_get_property;
1256 object_class->finalize = lightdm_greeter_finalize;
1257
1258 g_object_class_install_property (object_class,
1259 PROP_DEFAULT_SESSION_HINT,
1260 g_param_spec_string ("default-session-hint",
1261 "default-session-hint",
1262 "Default session hint",
1263 NULL,
1264 G_PARAM_READWRITE));
1265
1266 g_object_class_install_property (object_class,
1267 PROP_HIDE_USERS_HINT,
1268 g_param_spec_boolean ("hide-users-hint",
1269 "hide-users-hint",
1270 "Hide users hint",
1271 FALSE,
1272 G_PARAM_READABLE));
1273
1274 g_object_class_install_property (object_class,
1275 PROP_SHOW_MANUAL_LOGIN_HINT,
1276 g_param_spec_boolean ("show-manual-login-hint",
1277 "show-manual-login-hint",
1278 "Show manual login hint",
1279 FALSE,
1280 G_PARAM_READABLE));
1281
1282 g_object_class_install_property (object_class,
1283 PROP_SHOW_REMOTE_LOGIN_HINT,
1284 g_param_spec_boolean ("show-remote-login-hint",
1285 "show-remote-login-hint",
1286 "Show remote login hint",
1287 FALSE,
1288 G_PARAM_READABLE));
1289
1290 g_object_class_install_property (object_class,
1291 PROP_LOCK_HINT,
1292 g_param_spec_boolean ("lock-hint",
1293 "lock-hint",
1294 "Lock hint",
1295 FALSE,
1296 G_PARAM_READABLE));
1297
1298 g_object_class_install_property (object_class,
1299 PROP_HAS_GUEST_ACCOUNT_HINT,
1300 g_param_spec_boolean ("has-guest-account-hint",
1301 "has-guest-account-hint",
1302 "Has guest account hint",
1303 FALSE,
1304 G_PARAM_READABLE));
1305
1306 g_object_class_install_property (object_class,
1307 PROP_SELECT_USER_HINT,
1308 g_param_spec_string ("select-user-hint",
1309 "select-user-hint",
1310 "Select user hint",
1311 NULL,
1312 G_PARAM_READABLE));
1313
1314 g_object_class_install_property (object_class,
1315 PROP_SELECT_GUEST_HINT,
1316 g_param_spec_boolean ("select-guest-hint",
1317 "select-guest-hint",
1318 "Select guest account hint",
1319 FALSE,
1320 G_PARAM_READABLE));
1321
1322 g_object_class_install_property (object_class,
1323 PROP_AUTOLOGIN_USER_HINT,
1324 g_param_spec_string ("autologin-user-hint",
1325 "autologin-user-hint",
1326 "Autologin user hint",
1327 NULL,
1328 G_PARAM_READABLE));
1329
1330 g_object_class_install_property (object_class,
1331 PROP_AUTOLOGIN_GUEST_HINT,
1332 g_param_spec_boolean ("autologin-guest-hint",
1333 "autologin-guest-hint",
1334 "Autologin guest account hint",
1335 FALSE,
1336 G_PARAM_READABLE));
1337
1338 g_object_class_install_property (object_class,
1339 PROP_AUTOLOGIN_TIMEOUT_HINT,
1340 g_param_spec_int ("autologin-timeout-hint",
1341 "autologin-timeout-hint",
1342 "Autologin timeout hint",
1343 0, G_MAXINT, 0,
1344 G_PARAM_READABLE));
1345
1346 g_object_class_install_property (object_class,
1347 PROP_AUTHENTICATION_USER,
1348 g_param_spec_string ("authentication-user",
1349 "authentication-user",
1350 "The user being authenticated",
1351 NULL,
1352 G_PARAM_READABLE));
1353 g_object_class_install_property (object_class,
1354 PROP_IN_AUTHENTICATION,
1355 g_param_spec_boolean ("in-authentication",
1356 "in-authentication",
1357 "TRUE if a user is being authenticated",
1358 FALSE,
1359 G_PARAM_READABLE));
1360 g_object_class_install_property (object_class,
1361 PROP_IS_AUTHENTICATED,
1362 g_param_spec_boolean ("is-authenticated",
1363 "is-authenticated",
1364 "TRUE if the selected user is authenticated",
1365 FALSE,
1366 G_PARAM_READABLE));
1367
1368 /**
1369 * LightDMGreeter::show-prompt:
1370 * @greeter: A #LightDMGreeter
1371 * @text: Prompt text
1372 * @type: Prompt type
1373 *
1374 * The ::show-prompt signal gets emitted when the greeter should show a
1375 * prompt to the user. The given text should be displayed and an input
1376 * field for the user to provide a response.
1377 *
1378 * Call lightdm_greeter_respond() with the resultant input or
1379 * lightdm_greeter_cancel_authentication() to abort the authentication.
1380 **/
1381 signals[SHOW_PROMPT] =
1382 g_signal_new ("show-prompt",
1383 G_TYPE_FROM_CLASS (klass),
1384 G_SIGNAL_RUN_LAST,
1385 G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
1386 NULL, NULL,
1387 marshal_VOID__STRING_INT,
1388 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1389
1390 /**
1391 * LightDMGreeter::show-message:
1392 * @greeter: A #LightDMGreeter
1393 * @text: Message text
1394 * @type: Message type
1395 *
1396 * The ::show-message signal gets emitted when the greeter
1397 * should show a message to the user.
1398 **/
1399 signals[SHOW_MESSAGE] =
1400 g_signal_new ("show-message",
1401 G_TYPE_FROM_CLASS (klass),
1402 G_SIGNAL_RUN_LAST,
1403 G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
1404 NULL, NULL,
1405 marshal_VOID__STRING_INT,
1406 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1407
1408 /**
1409 * LightDMGreeter::authentication-complete:
1410 * @greeter: A #LightDMGreeter
1411 *
1412 * The ::authentication-complete signal gets emitted when the greeter
1413 * has completed authentication.
1414 *
1415 * Call lightdm_greeter_get_is_authenticated() to check if the authentication
1416 * was successful.
1417 **/
1418 signals[AUTHENTICATION_COMPLETE] =
1419 g_signal_new ("authentication-complete",
1420 G_TYPE_FROM_CLASS (klass),
1421 G_SIGNAL_RUN_LAST,
1422 G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
1423 NULL, NULL,
1424 g_cclosure_marshal_VOID__VOID,
1425 G_TYPE_NONE, 0);
1426
1427 /**
1428 * LightDMGreeter::autologin-timer-expired:
1429 * @greeter: A #LightDMGreeter
1430 *
1431 * The ::timed-login signal gets emitted when the automatic login timer has expired.
1432 * The application should then call lightdm_greeter_login().
1433 **/
1434 signals[AUTOLOGIN_TIMER_EXPIRED] =
1435 g_signal_new ("autologin-timer-expired",
1436 G_TYPE_FROM_CLASS (klass),
1437 G_SIGNAL_RUN_LAST,
1438 G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
1439 NULL, NULL,
1440 g_cclosure_marshal_VOID__VOID,
1441 G_TYPE_NONE, 0);
1442}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette