Merge lp:~robert-ancell/lightdm/passive-authentication into lp:lightdm
- passive-authentication
- Merge into trunk
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 |
Related bugs: |
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.
Description of the change
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 |