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
=== modified file 'data/lightdm.conf'
--- data/lightdm.conf 2014-09-10 03:33:25 +0000
+++ data/lightdm.conf 2014-10-02 07:53:03 +0000
@@ -68,6 +68,7 @@
68# greeter-setup-script = Script to run when starting a greeter (runs as root)68# greeter-setup-script = Script to run when starting a greeter (runs as root)
69# session-setup-script = Script to run when starting a user session (runs as root)69# session-setup-script = Script to run when starting a user session (runs as root)
70# session-cleanup-script = Script to run when quitting a user session (runs as root)70# session-cleanup-script = Script to run when quitting a user session (runs as root)
71# passive-services = PAM services to run which are triggered by external events (e.g. fingerprint, smartcard)
71# autologin-guest = True to log in as guest by default72# autologin-guest = True to log in as guest by default
72# autologin-user = User to log in with by default (overrides autologin-guest)73# autologin-user = User to log in with by default (overrides autologin-guest)
73# autologin-user-timeout = Number of seconds to wait before loading default user74# autologin-user-timeout = Number of seconds to wait before loading default user
@@ -109,6 +110,7 @@
109#greeter-setup-script=110#greeter-setup-script=
110#session-setup-script=111#session-setup-script=
111#session-cleanup-script=112#session-cleanup-script=
113#passive-services=
112#autologin-guest=false114#autologin-guest=false
113#autologin-user=115#autologin-user=
114#autologin-user-timeout=0116#autologin-user-timeout=0
115117
=== modified file 'liblightdm-gobject/greeter.c'
--- liblightdm-gobject/greeter.c 2014-09-29 23:42:38 +0000
+++ liblightdm-gobject/greeter.c 2014-10-02 07:53:03 +0000
@@ -41,6 +41,7 @@
41 AUTOLOGIN_TIMER_EXPIRED,41 AUTOLOGIN_TIMER_EXPIRED,
42 IDLE,42 IDLE,
43 RESET,43 RESET,
44 OFFER_AUTHENTICATION,
44 LAST_SIGNAL45 LAST_SIGNAL
45};46};
46static guint signals[LAST_SIGNAL] = { 0 };47static guint signals[LAST_SIGNAL] = { 0 };
@@ -107,6 +108,7 @@
107 GREETER_MESSAGE_SET_LANGUAGE,108 GREETER_MESSAGE_SET_LANGUAGE,
108 GREETER_MESSAGE_AUTHENTICATE_REMOTE,109 GREETER_MESSAGE_AUTHENTICATE_REMOTE,
109 GREETER_MESSAGE_ENSURE_SHARED_DIR,110 GREETER_MESSAGE_ENSURE_SHARED_DIR,
111 GREETER_MESSAGE_CHANGE_AUTHENTICATION,
110} GreeterMessage;112} GreeterMessage;
111113
112/* Messages from the server to the greeter */114/* Messages from the server to the greeter */
@@ -119,6 +121,7 @@
119 SERVER_MESSAGE_SHARED_DIR_RESULT,121 SERVER_MESSAGE_SHARED_DIR_RESULT,
120 SERVER_MESSAGE_IDLE,122 SERVER_MESSAGE_IDLE,
121 SERVER_MESSAGE_RESET,123 SERVER_MESSAGE_RESET,
124 SERVER_MESSAGE_OFFER_AUTHENTICATION,
122} ServerMessage;125} ServerMessage;
123126
124/* Request sent to server */127/* Request sent to server */
@@ -509,6 +512,20 @@
509}512}
510513
511static void514static void
515handle_offer_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
516{
517 gchar *service;
518
519 service = read_string (message, message_length, offset);
520
521 g_debug ("Offering authentication with service %s", service);
522
523 g_signal_emit (G_OBJECT (greeter), signals[OFFER_AUTHENTICATION], 0, service);
524
525 g_free (service);
526}
527
528static void
512handle_idle (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)529handle_idle (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
513{530{
514 g_signal_emit (G_OBJECT (greeter), signals[IDLE], 0);531 g_signal_emit (G_OBJECT (greeter), signals[IDLE], 0);
@@ -595,6 +612,9 @@
595 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:612 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
596 handle_prompt_authentication (greeter, message, message_length, &offset);613 handle_prompt_authentication (greeter, message, message_length, &offset);
597 break;614 break;
615 case SERVER_MESSAGE_OFFER_AUTHENTICATION:
616 handle_offer_authentication (greeter, message, message_length, &offset);
617 break;
598 case SERVER_MESSAGE_END_AUTHENTICATION:618 case SERVER_MESSAGE_END_AUTHENTICATION:
599 handle_end_authentication (greeter, message, message_length, &offset);619 handle_end_authentication (greeter, message, message_length, &offset);
600 break;620 break;
@@ -1212,6 +1232,40 @@
1212}1232}
12131233
1214/**1234/**
1235 * lightdm_greeter_change_authentication:
1236 * @greeter: A #LightDMGreeter
1237 * @service: The service to change to (as received from ::offer-authentication)
1238 *
1239 * Sets the requested service as the active authentication.
1240 **/
1241void
1242lightdm_greeter_change_authentication (LightDMGreeter *greeter, const gchar *service)
1243{
1244 LightDMGreeterPrivate *priv;
1245 guint8 message[MAX_MESSAGE_LENGTH];
1246 gsize offset = 0;
1247
1248 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1249
1250 priv = GET_PRIVATE (greeter);
1251
1252 g_return_if_fail (priv->connected);
1253
1254 priv->cancelling_authentication = FALSE;
1255 priv->authenticate_sequence_number++;
1256 priv->in_authentication = TRUE;
1257 priv->is_authenticated = FALSE;
1258 g_free (priv->authentication_user);
1259 priv->authentication_user = NULL;
1260
1261 g_debug ("Changing to authentication service %s...", service);
1262 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CHANGE_AUTHENTICATION, int_length () + string_length (service), &offset);
1263 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1264 write_string (message, MAX_MESSAGE_LENGTH, service, &offset);
1265 send_message (greeter, message, offset);
1266}
1267
1268/**
1215 * lightdm_greeter_respond:1269 * lightdm_greeter_respond:
1216 * @greeter: A #LightDMGreeter1270 * @greeter: A #LightDMGreeter
1217 * @response: Response to a prompt1271 * @response: Response to a prompt
@@ -1866,6 +1920,27 @@
1866 G_TYPE_NONE, 0);1920 G_TYPE_NONE, 0);
18671921
1868 /**1922 /**
1923 * LightDMGreeter::offer-authentication:
1924 * @greeter: A #LightDMGreeter
1925 * @service: The service that can be changed to
1926 *
1927 * The ::offer-authentication signal gets emitted when an uninitiated
1928 * authentication starts, for example a smartcard or fingerprint is
1929 * presented.
1930 *
1931 * If this authentication can be used the application should then call
1932 * lightdm_greeter_change_authentication().
1933 **/
1934 signals[OFFER_AUTHENTICATION] =
1935 g_signal_new ("offer-authentication",
1936 G_TYPE_FROM_CLASS (klass),
1937 G_SIGNAL_RUN_LAST,
1938 G_STRUCT_OFFSET (LightDMGreeterClass, offer_authentication),
1939 NULL, NULL,
1940 NULL,
1941 G_TYPE_NONE, 1, G_TYPE_STRING);
1942
1943 /**
1869 * LightDMGreeter::idle:1944 * LightDMGreeter::idle:
1870 * @greeter: A #LightDMGreeter1945 * @greeter: A #LightDMGreeter
1871 *1946 *
18721947
=== modified file 'liblightdm-gobject/lightdm/greeter.h'
--- liblightdm-gobject/lightdm/greeter.h 2014-09-29 23:42:38 +0000
+++ liblightdm-gobject/lightdm/greeter.h 2014-10-02 07:53:03 +0000
@@ -29,6 +29,7 @@
29#define LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED "autologin-timer-expired"29#define LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED "autologin-timer-expired"
30#define LIGHTDM_GREETER_SIGNAL_IDLE "idle"30#define LIGHTDM_GREETER_SIGNAL_IDLE "idle"
31#define LIGHTDM_GREETER_SIGNAL_RESET "reset"31#define LIGHTDM_GREETER_SIGNAL_RESET "reset"
32#define LIGHTDM_GREETER_SIGNAL_OFFER_AUTHENTICATION "offer-authentication"
3233
33/**34/**
34 * LightDMPromptType:35 * LightDMPromptType:
@@ -67,12 +68,12 @@
67 void (*autologin_timer_expired)(LightDMGreeter *greeter);68 void (*autologin_timer_expired)(LightDMGreeter *greeter);
68 void (*idle)(LightDMGreeter *greeter);69 void (*idle)(LightDMGreeter *greeter);
69 void (*reset)(LightDMGreeter *greeter);70 void (*reset)(LightDMGreeter *greeter);
71 void (*offer_authentication) (LightDMGreeter *greeter, const gchar *service);
7072
71 /* Reserved */73 /* Reserved */
72 void (*reserved1) (void);74 void (*reserved1) (void);
73 void (*reserved2) (void);75 void (*reserved2) (void);
74 void (*reserved3) (void);76 void (*reserved3) (void);
75 void (*reserved4) (void);
76} LightDMGreeterClass;77} LightDMGreeterClass;
7778
78GType lightdm_greeter_get_type (void);79GType lightdm_greeter_get_type (void);
@@ -123,6 +124,8 @@
123124
124void lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username);125void lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username);
125126
127void lightdm_greeter_change_authentication (LightDMGreeter *greeter, const gchar *service);
128
126void lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response);129void lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response);
127130
128void lightdm_greeter_cancel_authentication (LightDMGreeter *greeter);131void lightdm_greeter_cancel_authentication (LightDMGreeter *greeter);
129132
=== modified file 'liblightdm-qt/QLightDM/greeter.h'
--- liblightdm-qt/QLightDM/greeter.h 2014-09-19 03:16:14 +0000
+++ liblightdm-qt/QLightDM/greeter.h 2014-10-02 07:53:03 +0000
@@ -77,6 +77,7 @@
77 void authenticateAsGuest();77 void authenticateAsGuest();
78 void authenticateAutologin();78 void authenticateAutologin();
79 void authenticateRemote(const QString &session=QString(), const QString &username=QString());79 void authenticateRemote(const QString &session=QString(), const QString &username=QString());
80 void changeAuthentication(const QString &service);
80 void respond(const QString &response);81 void respond(const QString &response);
81 void cancelAuthentication();82 void cancelAuthentication();
82 void setLanguage (const QString &language);83 void setLanguage (const QString &language);
@@ -91,6 +92,7 @@
91 void autologinTimerExpired();92 void autologinTimerExpired();
92 void idle();93 void idle();
93 void reset();94 void reset();
95 void offerAuthentication(QString service);
9496
95private:97private:
96 GreeterPrivate *d_ptr;98 GreeterPrivate *d_ptr;
9799
=== modified file 'liblightdm-qt/greeter.cpp'
--- liblightdm-qt/greeter.cpp 2014-09-29 23:42:38 +0000
+++ liblightdm-qt/greeter.cpp 2014-10-02 07:53:03 +0000
@@ -35,7 +35,7 @@
35 static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data);35 static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data);
36 static void cb_idle(LightDMGreeter *greeter, gpointer data);36 static void cb_idle(LightDMGreeter *greeter, gpointer data);
37 static void cb_reset(LightDMGreeter *greeter, gpointer data);37 static void cb_reset(LightDMGreeter *greeter, gpointer data);
3838 static void cb_offerAuthentication(LightDMGreeter *greeter, const gchar *service, gpointer data);
39private:39private:
40 Q_DECLARE_PUBLIC(Greeter)40 Q_DECLARE_PUBLIC(Greeter)
41};41};
@@ -54,6 +54,7 @@
54 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED, G_CALLBACK (cb_autoLoginExpired), this);54 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED, G_CALLBACK (cb_autoLoginExpired), this);
55 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_IDLE, G_CALLBACK (cb_idle), this);55 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_IDLE, G_CALLBACK (cb_idle), this);
56 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_RESET, G_CALLBACK (cb_reset), this);56 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_RESET, G_CALLBACK (cb_reset), this);
57 g_signal_connect (ldmGreeter, LIGHTDM_GREETER_SIGNAL_OFFER_AUTHENTICATION, G_CALLBACK (cb_offerAuthentication), this);
57}58}
5859
59void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data)60void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data)
@@ -106,6 +107,14 @@
106 Q_EMIT that->q_func()->reset();107 Q_EMIT that->q_func()->reset();
107}108}
108109
110void GreeterPrivate::cb_offerAuthentication(LightDMGreeter *greeter, const gchar *service, gpointer data)
111{
112 Q_UNUSED(greeter);
113 GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
114 QString service_string = QString::fromUtf8(service);
115 Q_EMIT that->q_func()->offerAuthentication(service_string);
116}
117
109Greeter::Greeter(QObject *parent) :118Greeter::Greeter(QObject *parent) :
110 QObject(parent),119 QObject(parent),
111 d_ptr(new GreeterPrivate(this))120 d_ptr(new GreeterPrivate(this))
@@ -154,6 +163,12 @@
154 lightdm_greeter_authenticate_remote(d->ldmGreeter, session.toLocal8Bit().data(), username.toLocal8Bit().data());163 lightdm_greeter_authenticate_remote(d->ldmGreeter, session.toLocal8Bit().data(), username.toLocal8Bit().data());
155}164}
156165
166void Greeter::changeAuthentication(const QString &service)
167{
168 Q_D(Greeter);
169 lightdm_greeter_change_authentication(d->ldmGreeter, service.toLocal8Bit().data());
170}
171
157void Greeter::respond(const QString &response)172void Greeter::respond(const QString &response)
158{173{
159 Q_D(Greeter);174 Q_D(Greeter);
160175
=== modified file 'src/greeter.c'
--- src/greeter.c 2014-09-29 23:42:38 +0000
+++ src/greeter.c 2014-10-02 07:53:03 +0000
@@ -40,6 +40,9 @@
40 gchar *pam_service;40 gchar *pam_service;
41 gchar *autologin_pam_service;41 gchar *autologin_pam_service;
4242
43 /* PAM services to that are triggered by external events */
44 gchar **passive_services;
45
43 /* Buffer for data read from greeter */46 /* Buffer for data read from greeter */
44 guint8 *read_buffer;47 guint8 *read_buffer;
45 gsize n_read;48 gsize n_read;
@@ -63,6 +66,9 @@
63 /* PAM session being constructed by the greeter */66 /* PAM session being constructed by the greeter */
64 Session *authentication_session;67 Session *authentication_session;
6568
69 /* Background sessions being authenticated by the greeter */
70 GList *passive_sessions;
71
66 /* TRUE if a the greeter can handle a reset; else we will just kill it instead */72 /* TRUE if a the greeter can handle a reset; else we will just kill it instead */
67 gboolean resettable;73 gboolean resettable;
6874
@@ -95,6 +101,7 @@
95 GREETER_MESSAGE_SET_LANGUAGE,101 GREETER_MESSAGE_SET_LANGUAGE,
96 GREETER_MESSAGE_AUTHENTICATE_REMOTE,102 GREETER_MESSAGE_AUTHENTICATE_REMOTE,
97 GREETER_MESSAGE_ENSURE_SHARED_DIR,103 GREETER_MESSAGE_ENSURE_SHARED_DIR,
104 GREETER_MESSAGE_CHANGE_AUTHENTICATION,
98} GreeterMessage;105} GreeterMessage;
99106
100/* Messages from the server to the greeter */107/* Messages from the server to the greeter */
@@ -107,6 +114,7 @@
107 SERVER_MESSAGE_SHARED_DIR_RESULT,114 SERVER_MESSAGE_SHARED_DIR_RESULT,
108 SERVER_MESSAGE_IDLE,115 SERVER_MESSAGE_IDLE,
109 SERVER_MESSAGE_RESET,116 SERVER_MESSAGE_RESET,
117 SERVER_MESSAGE_OFFER_AUTHENTICATION,
110} ServerMessage;118} ServerMessage;
111119
112static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);120static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);
@@ -118,12 +126,13 @@
118}126}
119127
120void128void
121greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service)129greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service, gchar **passive_services)
122{130{
123 g_free (greeter->priv->pam_service);131 g_free (greeter->priv->pam_service);
124 greeter->priv->pam_service = g_strdup (pam_service);132 greeter->priv->pam_service = g_strdup (pam_service);
125 g_free (greeter->priv->autologin_pam_service);133 g_free (greeter->priv->autologin_pam_service);
126 greeter->priv->autologin_pam_service = g_strdup (autologin_pam_service);134 greeter->priv->autologin_pam_service = g_strdup (autologin_pam_service);
135 greeter->priv->passive_services = g_strdupv (passive_services);
127}136}
128137
129void138void
@@ -258,6 +267,33 @@
258}267}
259268
260static void269static void
270offer_service (Greeter *greeter, const gchar *service)
271{
272 guint8 message[MAX_MESSAGE_LENGTH];
273 gsize offset = 0;
274 guint32 length;
275
276 g_debug ("Greeter offering authentication with service %s", service);
277
278 length = string_length (service);
279 write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_OFFER_AUTHENTICATION, length, &offset);
280 write_string (message, MAX_MESSAGE_LENGTH, service, &offset);
281 write_message (greeter, message, offset);
282}
283
284static void
285passive_messages_cb (Session *session, Greeter *greeter)
286{
287 offer_service (greeter, session_get_pam_service (session));
288}
289
290static void
291passive_complete_cb (Session *session, Greeter *greeter)
292{
293 offer_service (greeter, session_get_pam_service (session));
294}
295
296static void
261handle_connect (Greeter *greeter, const gchar *version, gboolean resettable)297handle_connect (Greeter *greeter, const gchar *version, gboolean resettable)
262{298{
263 guint8 message[MAX_MESSAGE_LENGTH];299 guint8 message[MAX_MESSAGE_LENGTH];
@@ -265,6 +301,7 @@
265 guint32 length;301 guint32 length;
266 GHashTableIter iter;302 GHashTableIter iter;
267 gpointer key, value;303 gpointer key, value;
304 int i;
268305
269 l_debug (greeter, "Greeter connected version=%s resettable=%s", version, resettable ? "true" : "false");306 l_debug (greeter, "Greeter connected version=%s resettable=%s", version, resettable ? "true" : "false");
270307
@@ -285,6 +322,24 @@
285 }322 }
286 write_message (greeter, message, offset);323 write_message (greeter, message, offset);
287324
325 /* Start background authentications */
326 if (greeter->priv->passive_services)
327 {
328 for (i = 0; greeter->priv->passive_services[i]; i++)
329 {
330 Session *session;
331
332 g_signal_emit (greeter, signals[CREATE_SESSION], 0, &session);
333 greeter->priv->passive_sessions = g_list_append (greeter->priv->passive_sessions, session);
334 g_signal_connect (G_OBJECT (session), "got-messages", G_CALLBACK (passive_messages_cb), greeter);
335 g_signal_connect (G_OBJECT (session), "authentication-complete", G_CALLBACK (passive_complete_cb), greeter);
336 session_set_pam_service (session, greeter->priv->passive_services[i]);
337 session_set_do_authenticate (session, TRUE);
338 session_set_is_interactive (session, TRUE);
339 session_start (session);
340 }
341 }
342
288 g_signal_emit (greeter, signals[CONNECTED], 0);343 g_signal_emit (greeter, signals[CONNECTED], 0);
289}344}
290345
@@ -572,6 +627,45 @@
572}627}
573628
574static void629static void
630handle_change_authentication (Greeter *greeter, guint32 sequence_number, const gchar *service)
631{
632 Session *session = NULL;
633 GList *link;
634
635 g_debug ("Greeter change authentication to service %s", service);
636
637 /* Find this session */
638 for (link = greeter->priv->passive_sessions; link; link = link->next)
639 {
640 Session *s = link->data;
641 if (strcmp (service, session_get_pam_service (s)) == 0)
642 {
643 session = s;
644 break;
645 }
646 }
647 if (session == NULL)
648 {
649 g_warning ("Greeter requested unknown service %s", service);
650 return;
651 }
652
653 reset_session (greeter);
654
655 greeter->priv->authentication_sequence_number = sequence_number;
656
657 /* Listen to this new service */
658 greeter->priv->authentication_session = g_object_ref (session);
659 g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter);
660 g_signal_connect (G_OBJECT (session), "got-messages", G_CALLBACK (pam_messages_cb), greeter);
661 g_signal_connect (G_OBJECT (session), "authentication-complete", G_CALLBACK (authentication_complete_cb), greeter);
662 if (session_get_is_authentication_complete (session))
663 authentication_complete_cb (session, greeter);
664 else
665 pam_messages_cb (session, greeter);
666}
667
668static void
575handle_continue_authentication (Greeter *greeter, gchar **secrets)669handle_continue_authentication (Greeter *greeter, gchar **secrets)
576{670{
577 int messages_length;671 int messages_length;
@@ -790,7 +884,7 @@
790 GIOStatus status;884 GIOStatus status;
791 int id, length, i;885 int id, length, i;
792 guint32 sequence_number, n_secrets, max_secrets;886 guint32 sequence_number, n_secrets, max_secrets;
793 gchar *version, *username, *session_name, *language;887 gchar *version, *username, *session_name, *language, *service;
794 gchar **secrets;888 gchar **secrets;
795 gboolean resettable = FALSE;889 gboolean resettable = FALSE;
796 GError *error = NULL;890 GError *error = NULL;
@@ -868,6 +962,12 @@
868 username = read_string (greeter, &offset);962 username = read_string (greeter, &offset);
869 handle_login_remote (greeter, session_name, username, sequence_number);963 handle_login_remote (greeter, session_name, username, sequence_number);
870 break;964 break;
965 case GREETER_MESSAGE_CHANGE_AUTHENTICATION:
966 sequence_number = read_int (greeter, &offset);
967 service = read_string (greeter, &offset);
968 handle_change_authentication (greeter, sequence_number, service);
969 g_free (service);
970 break;
871 case GREETER_MESSAGE_CONTINUE_AUTHENTICATION:971 case GREETER_MESSAGE_CONTINUE_AUTHENTICATION:
872 n_secrets = read_int (greeter, &offset);972 n_secrets = read_int (greeter, &offset);
873 max_secrets = (G_MAXUINT32 - 1) / sizeof (gchar *);973 max_secrets = (G_MAXUINT32 - 1) / sizeof (gchar *);
@@ -1035,11 +1135,13 @@
1035greeter_finalize (GObject *object)1135greeter_finalize (GObject *object)
1036{1136{
1037 Greeter *self;1137 Greeter *self;
1138 GList *link;
10381139
1039 self = GREETER (object);1140 self = GREETER (object);
10401141
1041 g_free (self->priv->pam_service);1142 g_free (self->priv->pam_service);
1042 g_free (self->priv->autologin_pam_service);1143 g_free (self->priv->autologin_pam_service);
1144 g_strfreev (self->priv->passive_services);
1043 secure_free (self, self->priv->read_buffer);1145 secure_free (self, self->priv->read_buffer);
1044 g_hash_table_unref (self->priv->hints);1146 g_hash_table_unref (self->priv->hints);
1045 g_free (self->priv->remote_session);1147 g_free (self->priv->remote_session);
@@ -1049,6 +1151,13 @@
1049 g_signal_handlers_disconnect_matched (self->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);1151 g_signal_handlers_disconnect_matched (self->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
1050 g_object_unref (self->priv->authentication_session);1152 g_object_unref (self->priv->authentication_session);
1051 }1153 }
1154 for (link = self->priv->passive_sessions; link; link = link->next)
1155 {
1156 Session *session = link->data;
1157 g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
1158 g_object_unref (session);
1159 }
1160 g_list_free (self->priv->passive_sessions);
1052 if (self->priv->to_greeter_channel)1161 if (self->priv->to_greeter_channel)
1053 g_io_channel_unref (self->priv->to_greeter_channel);1162 g_io_channel_unref (self->priv->to_greeter_channel);
1054 if (self->priv->from_greeter_channel)1163 if (self->priv->from_greeter_channel)
10551164
=== modified file 'src/greeter.h'
--- src/greeter.h 2014-09-29 23:42:38 +0000
+++ src/greeter.h 2014-10-02 07:53:03 +0000
@@ -50,7 +50,7 @@
5050
51Greeter *greeter_new (void);51Greeter *greeter_new (void);
5252
53void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service);53void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service, gchar **passive_services);
5454
55void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest);55void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest);
5656
5757
=== modified file 'src/seat.c'
--- src/seat.c 2014-09-29 23:42:38 +0000
+++ src/seat.c 2014-10-02 07:53:03 +0000
@@ -1186,7 +1186,8 @@
1186 gchar *sessions_dir, **argv;1186 gchar *sessions_dir, **argv;
1187 SessionConfig *session_config;1187 SessionConfig *session_config;
1188 Greeter *greeter_session;1188 Greeter *greeter_session;
1189 const gchar *greeter_wrapper;1189 const gchar *greeter_wrapper, *service_list;
1190 gchar **passive_services;
1190 const gchar *autologin_username;1191 const gchar *autologin_username;
1191 int autologin_timeout;1192 int autologin_timeout;
1192 gboolean autologin_guest;1193 gboolean autologin_guest;
@@ -1235,9 +1236,14 @@
1235 session_set_argv (SESSION (greeter_session), argv);1236 session_set_argv (SESSION (greeter_session), argv);
1236 g_strfreev (argv);1237 g_strfreev (argv);
12371238
1239 service_list = seat_get_string_property (seat, "passive-services");
1240 passive_services = service_list ? g_strsplit (service_list, " ", -1) : NULL;
1238 greeter_set_pam_services (greeter_session,1241 greeter_set_pam_services (greeter_session,
1239 seat_get_string_property (seat, "pam-service"),1242 seat_get_string_property (seat, "pam-service"),
1240 seat_get_string_property (seat, "pam-autologin-service"));1243 seat_get_string_property (seat, "pam-autologin-service"),
1244 passive_services);
1245 g_strfreev (passive_services);
1246 greeter_set_allow_guest (greeter_session, seat_get_allow_guest (seat));
1241 g_signal_connect (greeter_session, GREETER_SIGNAL_CREATE_SESSION, G_CALLBACK (greeter_create_session_cb), seat);1247 g_signal_connect (greeter_session, GREETER_SIGNAL_CREATE_SESSION, G_CALLBACK (greeter_create_session_cb), seat);
1242 g_signal_connect (greeter_session, GREETER_SIGNAL_START_SESSION, G_CALLBACK (greeter_start_session_cb), seat);1248 g_signal_connect (greeter_session, GREETER_SIGNAL_START_SESSION, G_CALLBACK (greeter_start_session_cb), seat);
12431249
12441250
=== modified file 'src/session.c'
--- src/session.c 2014-09-29 23:42:38 +0000
+++ src/session.c 2014-10-02 07:53:03 +0000
@@ -646,6 +646,13 @@
646}646}
647647
648const gchar *648const gchar *
649session_get_pam_service (Session *session)
650{
651 g_return_val_if_fail (session != NULL, NULL);
652 return session->priv->pam_service;
653}
654
655const gchar *
649session_get_username (Session *session)656session_get_username (Session *session)
650{657{
651 g_return_val_if_fail (session != NULL, NULL);658 g_return_val_if_fail (session != NULL, NULL);
@@ -706,6 +713,13 @@
706}713}
707714
708gboolean715gboolean
716session_get_is_authentication_complete (Session *session)
717{
718 g_return_val_if_fail (session != NULL, FALSE);
719 return session->priv->authentication_complete;
720}
721
722gboolean
709session_get_is_authenticated (Session *session)723session_get_is_authenticated (Session *session)
710{724{
711 g_return_val_if_fail (session != NULL, FALSE);725 g_return_val_if_fail (session != NULL, FALSE);
712726
=== modified file 'src/session.h'
--- src/session.h 2014-09-29 23:42:38 +0000
+++ src/session.h 2014-10-02 07:53:03 +0000
@@ -74,6 +74,8 @@
7474
75void session_set_pam_service (Session *session, const gchar *pam_service);75void session_set_pam_service (Session *session, const gchar *pam_service);
7676
77const gchar *session_get_pam_service (Session *session);
78
77void session_set_username (Session *session, const gchar *username);79void session_set_username (Session *session, const gchar *username);
7880
79void session_set_do_authenticate (Session *session, gboolean do_authenticate);81void session_set_do_authenticate (Session *session, gboolean do_authenticate);
@@ -125,6 +127,8 @@
125127
126const struct pam_message *session_get_messages (Session *session);128const struct pam_message *session_get_messages (Session *session);
127129
130gboolean session_get_is_authentication_complete (Session *session);
131
128gboolean session_get_is_authenticated (Session *session);132gboolean session_get_is_authenticated (Session *session);
129133
130int session_get_authentication_result (Session *session);134int session_get_authentication_result (Session *session);
131135
=== modified file 'tests/Makefile.am'
--- tests/Makefile.am 2014-10-02 06:51:36 +0000
+++ tests/Makefile.am 2014-10-02 07:53:03 +0000
@@ -36,6 +36,8 @@
36 test-autologin-guest-timeout-gobject \36 test-autologin-guest-timeout-gobject \
37 test-change-authentication \37 test-change-authentication \
38 test-restart-authentication \38 test-restart-authentication \
39 test-fingerprint \
40 test-smartcard \
39 test-cancel-authentication-gobject \41 test-cancel-authentication-gobject \
40 test-login-pam \42 test-login-pam \
41 test-login-pam-config \43 test-login-pam-config \
@@ -387,6 +389,7 @@
387 scripts/dbus.conf \389 scripts/dbus.conf \
388 scripts/denied.conf \390 scripts/denied.conf \
389 scripts/expired.conf \391 scripts/expired.conf \
392 scripts/fingerprint.conf \
390 scripts/greeter-allow-guest.conf \393 scripts/greeter-allow-guest.conf \
391 scripts/greeter-crash.conf \394 scripts/greeter-crash.conf \
392 scripts/greeter-default-session.conf \395 scripts/greeter-default-session.conf \
@@ -491,6 +494,8 @@
491 scripts/session-stderr.conf \494 scripts/session-stderr.conf \
492 scripts/session-stderr-multi-write.conf \495 scripts/session-stderr-multi-write.conf \
493 scripts/session-stderr-backup.conf \496 scripts/session-stderr-backup.conf \
497 scripts/smartcard.conf \
498 scripts/surfaceflinger-autologin.conf \
494 scripts/switch-to-greeter.conf \499 scripts/switch-to-greeter.conf \
495 scripts/switch-to-greeter-disabled.conf \500 scripts/switch-to-greeter-disabled.conf \
496 scripts/switch-to-greeter-new-session.conf \501 scripts/switch-to-greeter-new-session.conf \
497502
=== added file 'tests/scripts/fingerprint.conf'
--- tests/scripts/fingerprint.conf 1970-01-01 00:00:00 +0000
+++ tests/scripts/fingerprint.conf 2014-10-02 07:53:03 +0000
@@ -0,0 +1,38 @@
1#
2# Check can handle a fingerprint user than then requires a password
3#
4
5[SeatDefaults]
6passive-services=lightdm-fingerprint
7
8#?*START-DAEMON
9#?RUNNER DAEMON-START
10
11# X server starts
12#?XSERVER-0 START VT=7 SEAT=seat0
13
14# Daemon connects when X server is ready
15#?*XSERVER-0 INDICATE-READY
16#?XSERVER-0 INDICATE-READY
17#?XSERVER-0 ACCEPT-CONNECT
18
19# Greeter starts
20#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
21#?LOGIN1 ACTIVATE-SESSION SESSION=c0
22#?XSERVER-0 ACCEPT-CONNECT
23#?GREETER-X-0 CONNECT-XSERVER
24#?GREETER-X-0 CONNECT-TO-DAEMON
25#?GREETER-X-0 CONNECTED-TO-DAEMON
26
27# Greeter is offered an authentication
28#?GREETER-X-0 OFFER-AUTHENTICATION SERVICE=lightdm-fingerprint
29#?*GREETER-X-0 CHANGE-AUTHENTICATION SERVICE=lightdm-fingerprint
30#?GREETER-X-0 SHOW-PROMPT TEXT="Password:"
31#?*GREETER-X-0 RESPOND TEXT="password"
32#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=fingerprint AUTHENTICATED=TRUE
33
34# Cleanup
35#?*STOP-DAEMON
36#?GREETER-X-0 TERMINATE SIGNAL=15
37#?XSERVER-0 TERMINATE SIGNAL=15
38#?RUNNER DAEMON-EXIT STATUS=0
039
=== added file 'tests/scripts/smartcard.conf'
--- tests/scripts/smartcard.conf 1970-01-01 00:00:00 +0000
+++ tests/scripts/smartcard.conf 2014-10-02 07:53:03 +0000
@@ -0,0 +1,36 @@
1#
2# Check can handle a smartcard user that authorizes without any additional input
3#
4
5[SeatDefaults]
6passive-services=lightdm-smartcard
7
8#?*START-DAEMON
9#?RUNNER DAEMON-START
10
11# X server starts
12#?XSERVER-0 START VT=7 SEAT=seat0
13
14# Daemon connects when X server is ready
15#?*XSERVER-0 INDICATE-READY
16#?XSERVER-0 INDICATE-READY
17#?XSERVER-0 ACCEPT-CONNECT
18
19# Greeter starts
20#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
21#?LOGIN1 ACTIVATE-SESSION SESSION=c0
22#?XSERVER-0 ACCEPT-CONNECT
23#?GREETER-X-0 CONNECT-XSERVER
24#?GREETER-X-0 CONNECT-TO-DAEMON
25#?GREETER-X-0 CONNECTED-TO-DAEMON
26
27# Greeter is offered an authentication
28#?GREETER-X-0 OFFER-AUTHENTICATION SERVICE=lightdm-smartcard
29#?*GREETER-X-0 CHANGE-AUTHENTICATION SERVICE=lightdm-smartcard
30#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=smartcard AUTHENTICATED=TRUE
31
32# Cleanup
33#?*STOP-DAEMON
34#?GREETER-X-0 TERMINATE SIGNAL=15
35#?XSERVER-0 TERMINATE SIGNAL=15
36#?RUNNER DAEMON-EXIT STATUS=0
037
=== modified file 'tests/src/libsystem.c'
--- tests/src/libsystem.c 2014-09-19 03:16:14 +0000
+++ tests/src/libsystem.c 2014-10-02 07:53:03 +0000
@@ -910,6 +910,44 @@
910 return PAM_AUTH_ERR;910 return PAM_AUTH_ERR;
911 }911 }
912912
913 /* Fingerprint user scans immediately and requires password */
914 if (strcmp (pamh->service_name, "lightdm-fingerprint") == 0)
915 {
916 int result;
917 struct pam_message **msg;
918 struct pam_response *resp = NULL;
919
920 msg = malloc (sizeof (struct pam_message *) * 1);
921
922 if (pamh->user)
923 free (pamh->user);
924 pamh->user = strdup ("fingerprint");
925
926 entry = getpwnam (pamh->user);
927 msg = malloc (sizeof (struct pam_message *));
928 msg[0] = malloc (sizeof (struct pam_message));
929 msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
930 msg[0]->msg = "Password:";
931 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
932 free (msg[0]);
933 free (msg);
934 password_matches = strcmp (entry->pw_passwd, resp[0].resp) == 0;
935 if (resp[0].resp)
936 free (resp[0].resp);
937 free (resp);
938
939 return password_matches ? PAM_SUCCESS : PAM_AUTH_ERR;
940 }
941
942 /* Smartcard user scans immediately */
943 if (strcmp (pamh->service_name, "lightdm-smartcard") == 0)
944 {
945 if (pamh->user)
946 free (pamh->user);
947 pamh->user = strdup ("smartcard");
948 return PAM_SUCCESS;
949 }
950
913 /* Prompt for username */951 /* Prompt for username */
914 if (pamh->user == NULL)952 if (pamh->user == NULL)
915 {953 {
916954
=== modified file 'tests/src/test-gobject-greeter.c'
--- tests/src/test-gobject-greeter.c 2014-09-29 23:42:38 +0000
+++ tests/src/test-gobject-greeter.c 2014-10-02 07:53:03 +0000
@@ -44,6 +44,12 @@
44}44}
4545
46static void46static void
47offer_authentication_cb (LightDMGreeter *greeter, const gchar *service)
48{
49 status_notify ("%s OFFER-AUTHENTICATION SERVICE=%s", greeter_id, service);
50}
51
52static void
47autologin_timer_expired_cb (LightDMGreeter *greeter)53autologin_timer_expired_cb (LightDMGreeter *greeter)
48{54{
49}55}
@@ -209,6 +215,9 @@
209 else if (strcmp (name, "RESPOND") == 0)215 else if (strcmp (name, "RESPOND") == 0)
210 lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"));216 lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"));
211217
218 else if (strcmp (name, "CHANGE-AUTHENTICATION") == 0)
219 lightdm_greeter_change_authentication (greeter, g_hash_table_lookup (params, "SERVICE"));
220
212 else if (strcmp (name, "CANCEL-AUTHENTICATION") == 0)221 else if (strcmp (name, "CANCEL-AUTHENTICATION") == 0)
213 lightdm_greeter_cancel_authentication (greeter);222 lightdm_greeter_cancel_authentication (greeter);
214223
@@ -485,6 +494,7 @@
485 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_MESSAGE, G_CALLBACK (show_message_cb), NULL);494 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_MESSAGE, G_CALLBACK (show_message_cb), NULL);
486 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_PROMPT, G_CALLBACK (show_prompt_cb), NULL);495 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_PROMPT, G_CALLBACK (show_prompt_cb), NULL);
487 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), NULL);496 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), NULL);
497 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_OFFER_AUTHENTICATION, G_CALLBACK (offer_authentication_cb), NULL);
488 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED, G_CALLBACK (autologin_timer_expired_cb), NULL);498 g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED, G_CALLBACK (autologin_timer_expired_cb), NULL);
489 if (g_key_file_get_boolean (config, "test-greeter-config", "resettable", NULL))499 if (g_key_file_get_boolean (config, "test-greeter-config", "resettable", NULL))
490 {500 {
491501
=== modified file 'tests/src/test-runner.c'
--- tests/src/test-runner.c 2014-10-02 02:46:13 +0000
+++ tests/src/test-runner.c 2014-10-02 07:53:03 +0000
@@ -2723,6 +2723,10 @@
2723 {"corrupt-xauth", "password", "Corrupt Xauthority", 1032},2723 {"corrupt-xauth", "password", "Corrupt Xauthority", 1032},
2724 /* User to test properties */2724 /* User to test properties */
2725 {"prop-user", "", "TEST", 1033},2725 {"prop-user", "", "TEST", 1033},
2726 /* This account is the user that starts by scanning a fingerprint then requiring a password */
2727 {"fingerprint", "password", "Fingerprint", 1034},
2728 /* This account is the user that authenticates by scanning a smartcard */
2729 {"smartcard", "password", "Smartcard", 1035},
2726 {NULL, NULL, NULL, 0}2730 {NULL, NULL, NULL, 0}
2727 };2731 };
2728 passwd_data = g_string_new ("");2732 passwd_data = g_string_new ("");
27292733
=== added file 'tests/test-fingerprint'
--- tests/test-fingerprint 1970-01-01 00:00:00 +0000
+++ tests/test-fingerprint 2014-10-02 07:53:03 +0000
@@ -0,0 +1,2 @@
1#!/bin/sh
2./src/dbus-env ./src/test-runner fingerprint test-gobject-greeter
03
=== added file 'tests/test-smartcard'
--- tests/test-smartcard 1970-01-01 00:00:00 +0000
+++ tests/test-smartcard 2014-10-02 07:53:03 +0000
@@ -0,0 +1,2 @@
1#!/bin/sh
2./src/dbus-env ./src/test-runner smartcard test-gobject-greeter

Subscribers

People subscribed via source and target branches