Merge lp:~robert-ancell/lightdm/passive-authentication into lp:lightdm

Proposed by Robert Ancell on 2013-07-21
Status: Work in progress
Proposed branch: lp:~robert-ancell/lightdm/passive-authentication
Merge into: lp:lightdm
Diff against target: 793 lines (+372/-7)
18 files modified
data/lightdm.conf (+2/-0)
liblightdm-gobject/greeter.c (+75/-0)
liblightdm-gobject/lightdm/greeter.h (+4/-1)
liblightdm-qt/QLightDM/greeter.h (+2/-0)
liblightdm-qt/greeter.cpp (+16/-1)
src/greeter.c (+111/-2)
src/greeter.h (+1/-1)
src/seat.c (+8/-2)
src/session.c (+14/-0)
src/session.h (+4/-0)
tests/Makefile.am (+5/-0)
tests/scripts/fingerprint.conf (+38/-0)
tests/scripts/smartcard.conf (+36/-0)
tests/src/libsystem.c (+38/-0)
tests/src/test-gobject-greeter.c (+10/-0)
tests/src/test-runner.c (+4/-0)
tests/test-fingerprint (+2/-0)
tests/test-smartcard (+2/-0)
To merge this branch: bzr merge lp:~robert-ancell/lightdm/passive-authentication
Reviewer Review Type Date Requested Status
LightDM Development Team 2013-07-21 Pending
Review via email: mp+176042@code.launchpad.net

Commit message

Add support for authentication that is not initiated graphically from the greeter, e.g. using fingerprint scanners / smartcard systems.

To post a comment you must log in.
1537. By Robert Ancell on 2013-07-21

Merge with trunk

1538. By Robert Ancell on 2013-07-21

Remove cclosure that is no longer required

1539. By Robert Ancell on 2013-07-21

Merge with trunk

1540. By Robert Ancell on 2013-08-17

Merge with trunk

1541. By Robert Ancell on 2013-08-18

Merge with trunk

1542. By Robert Ancell on 2013-08-18

Remove stray files

1543. By Robert Ancell on 2013-08-21

Merge with trunk

1544. By Robert Ancell on 2013-09-20

Merge with trunk

1545. By Robert Ancell on 2013-10-30

Merge with trunk

1546. By Robert Ancell on 2014-03-04

Merge with trunk

1547. By Robert Ancell on 2014-04-29

Merge with trunk

1548. By Robert Ancell on 2014-10-02

Merge with trunk

Unmerged revisions

1548. By Robert Ancell on 2014-10-02

Merge with trunk

1547. By Robert Ancell on 2014-04-29

Merge with trunk

1546. By Robert Ancell on 2014-03-04

Merge with trunk

1545. By Robert Ancell on 2013-10-30

Merge with trunk

1544. By Robert Ancell on 2013-09-20

Merge with trunk

1543. By Robert Ancell on 2013-08-21

Merge with trunk

1542. By Robert Ancell on 2013-08-18

Remove stray files

1541. By Robert Ancell on 2013-08-18

Merge with trunk

1540. By Robert Ancell on 2013-08-17

Merge with trunk

1539. By Robert Ancell on 2013-07-21

Merge with trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/lightdm.conf'
2--- data/lightdm.conf 2014-09-10 03:33:25 +0000
3+++ data/lightdm.conf 2014-10-02 07:53:03 +0000
4@@ -68,6 +68,7 @@
5 # greeter-setup-script = Script to run when starting a greeter (runs as root)
6 # session-setup-script = Script to run when starting a user session (runs as root)
7 # session-cleanup-script = Script to run when quitting a user session (runs as root)
8+# passive-services = PAM services to run which are triggered by external events (e.g. fingerprint, smartcard)
9 # autologin-guest = True to log in as guest by default
10 # autologin-user = User to log in with by default (overrides autologin-guest)
11 # autologin-user-timeout = Number of seconds to wait before loading default user
12@@ -109,6 +110,7 @@
13 #greeter-setup-script=
14 #session-setup-script=
15 #session-cleanup-script=
16+#passive-services=
17 #autologin-guest=false
18 #autologin-user=
19 #autologin-user-timeout=0
20
21=== modified file 'liblightdm-gobject/greeter.c'
22--- liblightdm-gobject/greeter.c 2014-09-29 23:42:38 +0000
23+++ liblightdm-gobject/greeter.c 2014-10-02 07:53:03 +0000
24@@ -41,6 +41,7 @@
25 AUTOLOGIN_TIMER_EXPIRED,
26 IDLE,
27 RESET,
28+ OFFER_AUTHENTICATION,
29 LAST_SIGNAL
30 };
31 static guint signals[LAST_SIGNAL] = { 0 };
32@@ -107,6 +108,7 @@
33 GREETER_MESSAGE_SET_LANGUAGE,
34 GREETER_MESSAGE_AUTHENTICATE_REMOTE,
35 GREETER_MESSAGE_ENSURE_SHARED_DIR,
36+ GREETER_MESSAGE_CHANGE_AUTHENTICATION,
37 } GreeterMessage;
38
39 /* Messages from the server to the greeter */
40@@ -119,6 +121,7 @@
41 SERVER_MESSAGE_SHARED_DIR_RESULT,
42 SERVER_MESSAGE_IDLE,
43 SERVER_MESSAGE_RESET,
44+ SERVER_MESSAGE_OFFER_AUTHENTICATION,
45 } ServerMessage;
46
47 /* Request sent to server */
48@@ -509,6 +512,20 @@
49 }
50
51 static void
52+handle_offer_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
53+{
54+ gchar *service;
55+
56+ service = read_string (message, message_length, offset);
57+
58+ g_debug ("Offering authentication with service %s", service);
59+
60+ g_signal_emit (G_OBJECT (greeter), signals[OFFER_AUTHENTICATION], 0, service);
61+
62+ g_free (service);
63+}
64+
65+static void
66 handle_idle (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
67 {
68 g_signal_emit (G_OBJECT (greeter), signals[IDLE], 0);
69@@ -595,6 +612,9 @@
70 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
71 handle_prompt_authentication (greeter, message, message_length, &offset);
72 break;
73+ case SERVER_MESSAGE_OFFER_AUTHENTICATION:
74+ handle_offer_authentication (greeter, message, message_length, &offset);
75+ break;
76 case SERVER_MESSAGE_END_AUTHENTICATION:
77 handle_end_authentication (greeter, message, message_length, &offset);
78 break;
79@@ -1212,6 +1232,40 @@
80 }
81
82 /**
83+ * lightdm_greeter_change_authentication:
84+ * @greeter: A #LightDMGreeter
85+ * @service: The service to change to (as received from ::offer-authentication)
86+ *
87+ * Sets the requested service as the active authentication.
88+ **/
89+void
90+lightdm_greeter_change_authentication (LightDMGreeter *greeter, const gchar *service)
91+{
92+ LightDMGreeterPrivate *priv;
93+ guint8 message[MAX_MESSAGE_LENGTH];
94+ gsize offset = 0;
95+
96+ g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
97+
98+ priv = GET_PRIVATE (greeter);
99+
100+ g_return_if_fail (priv->connected);
101+
102+ priv->cancelling_authentication = FALSE;
103+ priv->authenticate_sequence_number++;
104+ priv->in_authentication = TRUE;
105+ priv->is_authenticated = FALSE;
106+ g_free (priv->authentication_user);
107+ priv->authentication_user = NULL;
108+
109+ g_debug ("Changing to authentication service %s...", service);
110+ write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CHANGE_AUTHENTICATION, int_length () + string_length (service), &offset);
111+ write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
112+ write_string (message, MAX_MESSAGE_LENGTH, service, &offset);
113+ send_message (greeter, message, offset);
114+}
115+
116+/**
117 * lightdm_greeter_respond:
118 * @greeter: A #LightDMGreeter
119 * @response: Response to a prompt
120@@ -1866,6 +1920,27 @@
121 G_TYPE_NONE, 0);
122
123 /**
124+ * LightDMGreeter::offer-authentication:
125+ * @greeter: A #LightDMGreeter
126+ * @service: The service that can be changed to
127+ *
128+ * The ::offer-authentication signal gets emitted when an uninitiated
129+ * authentication starts, for example a smartcard or fingerprint is
130+ * presented.
131+ *
132+ * If this authentication can be used the application should then call
133+ * lightdm_greeter_change_authentication().
134+ **/
135+ signals[OFFER_AUTHENTICATION] =
136+ g_signal_new ("offer-authentication",
137+ G_TYPE_FROM_CLASS (klass),
138+ G_SIGNAL_RUN_LAST,
139+ G_STRUCT_OFFSET (LightDMGreeterClass, offer_authentication),
140+ NULL, NULL,
141+ NULL,
142+ G_TYPE_NONE, 1, G_TYPE_STRING);
143+
144+ /**
145 * LightDMGreeter::idle:
146 * @greeter: A #LightDMGreeter
147 *
148
149=== modified file 'liblightdm-gobject/lightdm/greeter.h'
150--- liblightdm-gobject/lightdm/greeter.h 2014-09-29 23:42:38 +0000
151+++ liblightdm-gobject/lightdm/greeter.h 2014-10-02 07:53:03 +0000
152@@ -29,6 +29,7 @@
153 #define LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED "autologin-timer-expired"
154 #define LIGHTDM_GREETER_SIGNAL_IDLE "idle"
155 #define LIGHTDM_GREETER_SIGNAL_RESET "reset"
156+#define LIGHTDM_GREETER_SIGNAL_OFFER_AUTHENTICATION "offer-authentication"
157
158 /**
159 * LightDMPromptType:
160@@ -67,12 +68,12 @@
161 void (*autologin_timer_expired)(LightDMGreeter *greeter);
162 void (*idle)(LightDMGreeter *greeter);
163 void (*reset)(LightDMGreeter *greeter);
164+ void (*offer_authentication) (LightDMGreeter *greeter, const gchar *service);
165
166 /* Reserved */
167 void (*reserved1) (void);
168 void (*reserved2) (void);
169 void (*reserved3) (void);
170- void (*reserved4) (void);
171 } LightDMGreeterClass;
172
173 GType lightdm_greeter_get_type (void);
174@@ -123,6 +124,8 @@
175
176 void lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username);
177
178+void lightdm_greeter_change_authentication (LightDMGreeter *greeter, const gchar *service);
179+
180 void lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response);
181
182 void lightdm_greeter_cancel_authentication (LightDMGreeter *greeter);
183
184=== modified file 'liblightdm-qt/QLightDM/greeter.h'
185--- liblightdm-qt/QLightDM/greeter.h 2014-09-19 03:16:14 +0000
186+++ liblightdm-qt/QLightDM/greeter.h 2014-10-02 07:53:03 +0000
187@@ -77,6 +77,7 @@
188 void authenticateAsGuest();
189 void authenticateAutologin();
190 void authenticateRemote(const QString &session=QString(), const QString &username=QString());
191+ void changeAuthentication(const QString &service);
192 void respond(const QString &response);
193 void cancelAuthentication();
194 void setLanguage (const QString &language);
195@@ -91,6 +92,7 @@
196 void autologinTimerExpired();
197 void idle();
198 void reset();
199+ void offerAuthentication(QString service);
200
201 private:
202 GreeterPrivate *d_ptr;
203
204=== modified file 'liblightdm-qt/greeter.cpp'
205--- liblightdm-qt/greeter.cpp 2014-09-29 23:42:38 +0000
206+++ liblightdm-qt/greeter.cpp 2014-10-02 07:53:03 +0000
207@@ -35,7 +35,7 @@
208 static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data);
209 static void cb_idle(LightDMGreeter *greeter, gpointer data);
210 static void cb_reset(LightDMGreeter *greeter, gpointer data);
211-
212+ static void cb_offerAuthentication(LightDMGreeter *greeter, const gchar *service, gpointer data);
213 private:
214 Q_DECLARE_PUBLIC(Greeter)
215 };
216@@ -54,6 +54,7 @@
217 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED, G_CALLBACK (cb_autoLoginExpired), this);
218 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_IDLE, G_CALLBACK (cb_idle), this);
219 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_RESET, G_CALLBACK (cb_reset), this);
220+ g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_OFFER_AUTHENTICATION, G_CALLBACK (cb_offerAuthentication), this);
221 }
222
223 void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data)
224@@ -106,6 +107,14 @@
225 Q_EMIT that->q_func()->reset();
226 }
227
228+void GreeterPrivate::cb_offerAuthentication(LightDMGreeter *greeter, const gchar *service, gpointer data)
229+{
230+ Q_UNUSED(greeter);
231+ GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
232+ QString service_string = QString::fromUtf8(service);
233+ Q_EMIT that->q_func()->offerAuthentication(service_string);
234+}
235+
236 Greeter::Greeter(QObject *parent) :
237 QObject(parent),
238 d_ptr(new GreeterPrivate(this))
239@@ -154,6 +163,12 @@
240 lightdm_greeter_authenticate_remote(d->ldmGreeter, session.toLocal8Bit().data(), username.toLocal8Bit().data());
241 }
242
243+void Greeter::changeAuthentication(const QString &service)
244+{
245+ Q_D(Greeter);
246+ lightdm_greeter_change_authentication(d->ldmGreeter, service.toLocal8Bit().data());
247+}
248+
249 void Greeter::respond(const QString &response)
250 {
251 Q_D(Greeter);
252
253=== modified file 'src/greeter.c'
254--- src/greeter.c 2014-09-29 23:42:38 +0000
255+++ src/greeter.c 2014-10-02 07:53:03 +0000
256@@ -40,6 +40,9 @@
257 gchar *pam_service;
258 gchar *autologin_pam_service;
259
260+ /* PAM services to that are triggered by external events */
261+ gchar **passive_services;
262+
263 /* Buffer for data read from greeter */
264 guint8 *read_buffer;
265 gsize n_read;
266@@ -63,6 +66,9 @@
267 /* PAM session being constructed by the greeter */
268 Session *authentication_session;
269
270+ /* Background sessions being authenticated by the greeter */
271+ GList *passive_sessions;
272+
273 /* TRUE if a the greeter can handle a reset; else we will just kill it instead */
274 gboolean resettable;
275
276@@ -95,6 +101,7 @@
277 GREETER_MESSAGE_SET_LANGUAGE,
278 GREETER_MESSAGE_AUTHENTICATE_REMOTE,
279 GREETER_MESSAGE_ENSURE_SHARED_DIR,
280+ GREETER_MESSAGE_CHANGE_AUTHENTICATION,
281 } GreeterMessage;
282
283 /* Messages from the server to the greeter */
284@@ -107,6 +114,7 @@
285 SERVER_MESSAGE_SHARED_DIR_RESULT,
286 SERVER_MESSAGE_IDLE,
287 SERVER_MESSAGE_RESET,
288+ SERVER_MESSAGE_OFFER_AUTHENTICATION,
289 } ServerMessage;
290
291 static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);
292@@ -118,12 +126,13 @@
293 }
294
295 void
296-greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service)
297+greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service, gchar **passive_services)
298 {
299 g_free (greeter->priv->pam_service);
300 greeter->priv->pam_service = g_strdup (pam_service);
301 g_free (greeter->priv->autologin_pam_service);
302 greeter->priv->autologin_pam_service = g_strdup (autologin_pam_service);
303+ greeter->priv->passive_services = g_strdupv (passive_services);
304 }
305
306 void
307@@ -258,6 +267,33 @@
308 }
309
310 static void
311+offer_service (Greeter *greeter, const gchar *service)
312+{
313+ guint8 message[MAX_MESSAGE_LENGTH];
314+ gsize offset = 0;
315+ guint32 length;
316+
317+ g_debug ("Greeter offering authentication with service %s", service);
318+
319+ length = string_length (service);
320+ write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_OFFER_AUTHENTICATION, length, &offset);
321+ write_string (message, MAX_MESSAGE_LENGTH, service, &offset);
322+ write_message (greeter, message, offset);
323+}
324+
325+static void
326+passive_messages_cb (Session *session, Greeter *greeter)
327+{
328+ offer_service (greeter, session_get_pam_service (session));
329+}
330+
331+static void
332+passive_complete_cb (Session *session, Greeter *greeter)
333+{
334+ offer_service (greeter, session_get_pam_service (session));
335+}
336+
337+static void
338 handle_connect (Greeter *greeter, const gchar *version, gboolean resettable)
339 {
340 guint8 message[MAX_MESSAGE_LENGTH];
341@@ -265,6 +301,7 @@
342 guint32 length;
343 GHashTableIter iter;
344 gpointer key, value;
345+ int i;
346
347 l_debug (greeter, "Greeter connected version=%s resettable=%s", version, resettable ? "true" : "false");
348
349@@ -285,6 +322,24 @@
350 }
351 write_message (greeter, message, offset);
352
353+ /* Start background authentications */
354+ if (greeter->priv->passive_services)
355+ {
356+ for (i = 0; greeter->priv->passive_services[i]; i++)
357+ {
358+ Session *session;
359+
360+ g_signal_emit (greeter, signals[CREATE_SESSION], 0, &session);
361+ greeter->priv->passive_sessions = g_list_append (greeter->priv->passive_sessions, session);
362+ g_signal_connect (G_OBJECT (session), "got-messages", G_CALLBACK (passive_messages_cb), greeter);
363+ g_signal_connect (G_OBJECT (session), "authentication-complete", G_CALLBACK (passive_complete_cb), greeter);
364+ session_set_pam_service (session, greeter->priv->passive_services[i]);
365+ session_set_do_authenticate (session, TRUE);
366+ session_set_is_interactive (session, TRUE);
367+ session_start (session);
368+ }
369+ }
370+
371 g_signal_emit (greeter, signals[CONNECTED], 0);
372 }
373
374@@ -572,6 +627,45 @@
375 }
376
377 static void
378+handle_change_authentication (Greeter *greeter, guint32 sequence_number, const gchar *service)
379+{
380+ Session *session = NULL;
381+ GList *link;
382+
383+ g_debug ("Greeter change authentication to service %s", service);
384+
385+ /* Find this session */
386+ for (link = greeter->priv->passive_sessions; link; link = link->next)
387+ {
388+ Session *s = link->data;
389+ if (strcmp (service, session_get_pam_service (s)) == 0)
390+ {
391+ session = s;
392+ break;
393+ }
394+ }
395+ if (session == NULL)
396+ {
397+ g_warning ("Greeter requested unknown service %s", service);
398+ return;
399+ }
400+
401+ reset_session (greeter);
402+
403+ greeter->priv->authentication_sequence_number = sequence_number;
404+
405+ /* Listen to this new service */
406+ greeter->priv->authentication_session = g_object_ref (session);
407+ g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter);
408+ g_signal_connect (G_OBJECT (session), "got-messages", G_CALLBACK (pam_messages_cb), greeter);
409+ g_signal_connect (G_OBJECT (session), "authentication-complete", G_CALLBACK (authentication_complete_cb), greeter);
410+ if (session_get_is_authentication_complete (session))
411+ authentication_complete_cb (session, greeter);
412+ else
413+ pam_messages_cb (session, greeter);
414+}
415+
416+static void
417 handle_continue_authentication (Greeter *greeter, gchar **secrets)
418 {
419 int messages_length;
420@@ -790,7 +884,7 @@
421 GIOStatus status;
422 int id, length, i;
423 guint32 sequence_number, n_secrets, max_secrets;
424- gchar *version, *username, *session_name, *language;
425+ gchar *version, *username, *session_name, *language, *service;
426 gchar **secrets;
427 gboolean resettable = FALSE;
428 GError *error = NULL;
429@@ -868,6 +962,12 @@
430 username = read_string (greeter, &offset);
431 handle_login_remote (greeter, session_name, username, sequence_number);
432 break;
433+ case GREETER_MESSAGE_CHANGE_AUTHENTICATION:
434+ sequence_number = read_int (greeter, &offset);
435+ service = read_string (greeter, &offset);
436+ handle_change_authentication (greeter, sequence_number, service);
437+ g_free (service);
438+ break;
439 case GREETER_MESSAGE_CONTINUE_AUTHENTICATION:
440 n_secrets = read_int (greeter, &offset);
441 max_secrets = (G_MAXUINT32 - 1) / sizeof (gchar *);
442@@ -1035,11 +1135,13 @@
443 greeter_finalize (GObject *object)
444 {
445 Greeter *self;
446+ GList *link;
447
448 self = GREETER (object);
449
450 g_free (self->priv->pam_service);
451 g_free (self->priv->autologin_pam_service);
452+ g_strfreev (self->priv->passive_services);
453 secure_free (self, self->priv->read_buffer);
454 g_hash_table_unref (self->priv->hints);
455 g_free (self->priv->remote_session);
456@@ -1049,6 +1151,13 @@
457 g_signal_handlers_disconnect_matched (self->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
458 g_object_unref (self->priv->authentication_session);
459 }
460+ for (link = self->priv->passive_sessions; link; link = link->next)
461+ {
462+ Session *session = link->data;
463+ g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
464+ g_object_unref (session);
465+ }
466+ g_list_free (self->priv->passive_sessions);
467 if (self->priv->to_greeter_channel)
468 g_io_channel_unref (self->priv->to_greeter_channel);
469 if (self->priv->from_greeter_channel)
470
471=== modified file 'src/greeter.h'
472--- src/greeter.h 2014-09-29 23:42:38 +0000
473+++ src/greeter.h 2014-10-02 07:53:03 +0000
474@@ -50,7 +50,7 @@
475
476 Greeter *greeter_new (void);
477
478-void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service);
479+void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service, gchar **passive_services);
480
481 void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest);
482
483
484=== modified file 'src/seat.c'
485--- src/seat.c 2014-09-29 23:42:38 +0000
486+++ src/seat.c 2014-10-02 07:53:03 +0000
487@@ -1186,7 +1186,8 @@
488 gchar *sessions_dir, **argv;
489 SessionConfig *session_config;
490 Greeter *greeter_session;
491- const gchar *greeter_wrapper;
492+ const gchar *greeter_wrapper, *service_list;
493+ gchar **passive_services;
494 const gchar *autologin_username;
495 int autologin_timeout;
496 gboolean autologin_guest;
497@@ -1235,9 +1236,14 @@
498 session_set_argv (SESSION (greeter_session), argv);
499 g_strfreev (argv);
500
501+ service_list = seat_get_string_property (seat, "passive-services");
502+ passive_services = service_list ? g_strsplit (service_list, " ", -1) : NULL;
503 greeter_set_pam_services (greeter_session,
504 seat_get_string_property (seat, "pam-service"),
505- seat_get_string_property (seat, "pam-autologin-service"));
506+ seat_get_string_property (seat, "pam-autologin-service"),
507+ passive_services);
508+ g_strfreev (passive_services);
509+ greeter_set_allow_guest (greeter_session, seat_get_allow_guest (seat));
510 g_signal_connect (greeter_session, GREETER_SIGNAL_CREATE_SESSION, G_CALLBACK (greeter_create_session_cb), seat);
511 g_signal_connect (greeter_session, GREETER_SIGNAL_START_SESSION, G_CALLBACK (greeter_start_session_cb), seat);
512
513
514=== modified file 'src/session.c'
515--- src/session.c 2014-09-29 23:42:38 +0000
516+++ src/session.c 2014-10-02 07:53:03 +0000
517@@ -646,6 +646,13 @@
518 }
519
520 const gchar *
521+session_get_pam_service (Session *session)
522+{
523+ g_return_val_if_fail (session != NULL, NULL);
524+ return session->priv->pam_service;
525+}
526+
527+const gchar *
528 session_get_username (Session *session)
529 {
530 g_return_val_if_fail (session != NULL, NULL);
531@@ -706,6 +713,13 @@
532 }
533
534 gboolean
535+session_get_is_authentication_complete (Session *session)
536+{
537+ g_return_val_if_fail (session != NULL, FALSE);
538+ return session->priv->authentication_complete;
539+}
540+
541+gboolean
542 session_get_is_authenticated (Session *session)
543 {
544 g_return_val_if_fail (session != NULL, FALSE);
545
546=== modified file 'src/session.h'
547--- src/session.h 2014-09-29 23:42:38 +0000
548+++ src/session.h 2014-10-02 07:53:03 +0000
549@@ -74,6 +74,8 @@
550
551 void session_set_pam_service (Session *session, const gchar *pam_service);
552
553+const gchar *session_get_pam_service (Session *session);
554+
555 void session_set_username (Session *session, const gchar *username);
556
557 void session_set_do_authenticate (Session *session, gboolean do_authenticate);
558@@ -125,6 +127,8 @@
559
560 const struct pam_message *session_get_messages (Session *session);
561
562+gboolean session_get_is_authentication_complete (Session *session);
563+
564 gboolean session_get_is_authenticated (Session *session);
565
566 int session_get_authentication_result (Session *session);
567
568=== modified file 'tests/Makefile.am'
569--- tests/Makefile.am 2014-10-02 06:51:36 +0000
570+++ tests/Makefile.am 2014-10-02 07:53:03 +0000
571@@ -36,6 +36,8 @@
572 test-autologin-guest-timeout-gobject \
573 test-change-authentication \
574 test-restart-authentication \
575+ test-fingerprint \
576+ test-smartcard \
577 test-cancel-authentication-gobject \
578 test-login-pam \
579 test-login-pam-config \
580@@ -387,6 +389,7 @@
581 scripts/dbus.conf \
582 scripts/denied.conf \
583 scripts/expired.conf \
584+ scripts/fingerprint.conf \
585 scripts/greeter-allow-guest.conf \
586 scripts/greeter-crash.conf \
587 scripts/greeter-default-session.conf \
588@@ -491,6 +494,8 @@
589 scripts/session-stderr.conf \
590 scripts/session-stderr-multi-write.conf \
591 scripts/session-stderr-backup.conf \
592+ scripts/smartcard.conf \
593+ scripts/surfaceflinger-autologin.conf \
594 scripts/switch-to-greeter.conf \
595 scripts/switch-to-greeter-disabled.conf \
596 scripts/switch-to-greeter-new-session.conf \
597
598=== added file 'tests/scripts/fingerprint.conf'
599--- tests/scripts/fingerprint.conf 1970-01-01 00:00:00 +0000
600+++ tests/scripts/fingerprint.conf 2014-10-02 07:53:03 +0000
601@@ -0,0 +1,38 @@
602+#
603+# Check can handle a fingerprint user than then requires a password
604+#
605+
606+[SeatDefaults]
607+passive-services=lightdm-fingerprint
608+
609+#?*START-DAEMON
610+#?RUNNER DAEMON-START
611+
612+# X server starts
613+#?XSERVER-0 START VT=7 SEAT=seat0
614+
615+# Daemon connects when X server is ready
616+#?*XSERVER-0 INDICATE-READY
617+#?XSERVER-0 INDICATE-READY
618+#?XSERVER-0 ACCEPT-CONNECT
619+
620+# Greeter starts
621+#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
622+#?LOGIN1 ACTIVATE-SESSION SESSION=c0
623+#?XSERVER-0 ACCEPT-CONNECT
624+#?GREETER-X-0 CONNECT-XSERVER
625+#?GREETER-X-0 CONNECT-TO-DAEMON
626+#?GREETER-X-0 CONNECTED-TO-DAEMON
627+
628+# Greeter is offered an authentication
629+#?GREETER-X-0 OFFER-AUTHENTICATION SERVICE=lightdm-fingerprint
630+#?*GREETER-X-0 CHANGE-AUTHENTICATION SERVICE=lightdm-fingerprint
631+#?GREETER-X-0 SHOW-PROMPT TEXT="Password:"
632+#?*GREETER-X-0 RESPOND TEXT="password"
633+#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=fingerprint AUTHENTICATED=TRUE
634+
635+# Cleanup
636+#?*STOP-DAEMON
637+#?GREETER-X-0 TERMINATE SIGNAL=15
638+#?XSERVER-0 TERMINATE SIGNAL=15
639+#?RUNNER DAEMON-EXIT STATUS=0
640
641=== added file 'tests/scripts/smartcard.conf'
642--- tests/scripts/smartcard.conf 1970-01-01 00:00:00 +0000
643+++ tests/scripts/smartcard.conf 2014-10-02 07:53:03 +0000
644@@ -0,0 +1,36 @@
645+#
646+# Check can handle a smartcard user that authorizes without any additional input
647+#
648+
649+[SeatDefaults]
650+passive-services=lightdm-smartcard
651+
652+#?*START-DAEMON
653+#?RUNNER DAEMON-START
654+
655+# X server starts
656+#?XSERVER-0 START VT=7 SEAT=seat0
657+
658+# Daemon connects when X server is ready
659+#?*XSERVER-0 INDICATE-READY
660+#?XSERVER-0 INDICATE-READY
661+#?XSERVER-0 ACCEPT-CONNECT
662+
663+# Greeter starts
664+#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
665+#?LOGIN1 ACTIVATE-SESSION SESSION=c0
666+#?XSERVER-0 ACCEPT-CONNECT
667+#?GREETER-X-0 CONNECT-XSERVER
668+#?GREETER-X-0 CONNECT-TO-DAEMON
669+#?GREETER-X-0 CONNECTED-TO-DAEMON
670+
671+# Greeter is offered an authentication
672+#?GREETER-X-0 OFFER-AUTHENTICATION SERVICE=lightdm-smartcard
673+#?*GREETER-X-0 CHANGE-AUTHENTICATION SERVICE=lightdm-smartcard
674+#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=smartcard AUTHENTICATED=TRUE
675+
676+# Cleanup
677+#?*STOP-DAEMON
678+#?GREETER-X-0 TERMINATE SIGNAL=15
679+#?XSERVER-0 TERMINATE SIGNAL=15
680+#?RUNNER DAEMON-EXIT STATUS=0
681
682=== modified file 'tests/src/libsystem.c'
683--- tests/src/libsystem.c 2014-09-19 03:16:14 +0000
684+++ tests/src/libsystem.c 2014-10-02 07:53:03 +0000
685@@ -910,6 +910,44 @@
686 return PAM_AUTH_ERR;
687 }
688
689+ /* Fingerprint user scans immediately and requires password */
690+ if (strcmp (pamh->service_name, "lightdm-fingerprint") == 0)
691+ {
692+ int result;
693+ struct pam_message **msg;
694+ struct pam_response *resp = NULL;
695+
696+ msg = malloc (sizeof (struct pam_message *) * 1);
697+
698+ if (pamh->user)
699+ free (pamh->user);
700+ pamh->user = strdup ("fingerprint");
701+
702+ entry = getpwnam (pamh->user);
703+ msg = malloc (sizeof (struct pam_message *));
704+ msg[0] = malloc (sizeof (struct pam_message));
705+ msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
706+ msg[0]->msg = "Password:";
707+ result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
708+ free (msg[0]);
709+ free (msg);
710+ password_matches = strcmp (entry->pw_passwd, resp[0].resp) == 0;
711+ if (resp[0].resp)
712+ free (resp[0].resp);
713+ free (resp);
714+
715+ return password_matches ? PAM_SUCCESS : PAM_AUTH_ERR;
716+ }
717+
718+ /* Smartcard user scans immediately */
719+ if (strcmp (pamh->service_name, "lightdm-smartcard") == 0)
720+ {
721+ if (pamh->user)
722+ free (pamh->user);
723+ pamh->user = strdup ("smartcard");
724+ return PAM_SUCCESS;
725+ }
726+
727 /* Prompt for username */
728 if (pamh->user == NULL)
729 {
730
731=== modified file 'tests/src/test-gobject-greeter.c'
732--- tests/src/test-gobject-greeter.c 2014-09-29 23:42:38 +0000
733+++ tests/src/test-gobject-greeter.c 2014-10-02 07:53:03 +0000
734@@ -44,6 +44,12 @@
735 }
736
737 static void
738+offer_authentication_cb (LightDMGreeter *greeter, const gchar *service)
739+{
740+ status_notify ("%s OFFER-AUTHENTICATION SERVICE=%s", greeter_id, service);
741+}
742+
743+static void
744 autologin_timer_expired_cb (LightDMGreeter *greeter)
745 {
746 }
747@@ -209,6 +215,9 @@
748 else if (strcmp (name, "RESPOND") == 0)
749 lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"));
750
751+ else if (strcmp (name, "CHANGE-AUTHENTICATION") == 0)
752+ lightdm_greeter_change_authentication (greeter, g_hash_table_lookup (params, "SERVICE"));
753+
754 else if (strcmp (name, "CANCEL-AUTHENTICATION") == 0)
755 lightdm_greeter_cancel_authentication (greeter);
756
757@@ -485,6 +494,7 @@
758 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_MESSAGE, G_CALLBACK (show_message_cb), NULL);
759 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_PROMPT, G_CALLBACK (show_prompt_cb), NULL);
760 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), NULL);
761+ g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_OFFER_AUTHENTICATION, G_CALLBACK (offer_authentication_cb), NULL);
762 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED, G_CALLBACK (autologin_timer_expired_cb), NULL);
763 if (g_key_file_get_boolean (config, "test-greeter-config", "resettable", NULL))
764 {
765
766=== modified file 'tests/src/test-runner.c'
767--- tests/src/test-runner.c 2014-10-02 02:46:13 +0000
768+++ tests/src/test-runner.c 2014-10-02 07:53:03 +0000
769@@ -2723,6 +2723,10 @@
770 {"corrupt-xauth", "password", "Corrupt Xauthority", 1032},
771 /* User to test properties */
772 {"prop-user", "", "TEST", 1033},
773+ /* This account is the user that starts by scanning a fingerprint then requiring a password */
774+ {"fingerprint", "password", "Fingerprint", 1034},
775+ /* This account is the user that authenticates by scanning a smartcard */
776+ {"smartcard", "password", "Smartcard", 1035},
777 {NULL, NULL, NULL, 0}
778 };
779 passwd_data = g_string_new ("");
780
781=== added file 'tests/test-fingerprint'
782--- tests/test-fingerprint 1970-01-01 00:00:00 +0000
783+++ tests/test-fingerprint 2014-10-02 07:53:03 +0000
784@@ -0,0 +1,2 @@
785+#!/bin/sh
786+./src/dbus-env ./src/test-runner fingerprint test-gobject-greeter
787
788=== added file 'tests/test-smartcard'
789--- tests/test-smartcard 1970-01-01 00:00:00 +0000
790+++ tests/test-smartcard 2014-10-02 07:53:03 +0000
791@@ -0,0 +1,2 @@
792+#!/bin/sh
793+./src/dbus-env ./src/test-runner smartcard test-gobject-greeter

Subscribers

People subscribed via source and target branches