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

Proposed by Robert Ancell
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 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

Merge with trunk

1538. By Robert Ancell

Remove cclosure that is no longer required

1539. By Robert Ancell

Merge with trunk

1540. By Robert Ancell

Merge with trunk

1541. By Robert Ancell

Merge with trunk

1542. By Robert Ancell

Remove stray files

1543. By Robert Ancell

Merge with trunk

1544. By Robert Ancell

Merge with trunk

1545. By Robert Ancell

Merge with trunk

1546. By Robert Ancell

Merge with trunk

1547. By Robert Ancell

Merge with trunk

1548. By Robert Ancell

Merge with trunk

Unmerged revisions

1548. By Robert Ancell

Merge with trunk

1547. By Robert Ancell

Merge with trunk

1546. By Robert Ancell

Merge with trunk

1545. By Robert Ancell

Merge with trunk

1544. By Robert Ancell

Merge with trunk

1543. By Robert Ancell

Merge with trunk

1542. By Robert Ancell

Remove stray files

1541. By Robert Ancell

Merge with trunk

1540. By Robert Ancell

Merge with trunk

1539. By Robert Ancell

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