]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - tests/src/test-session.c
Allow greeters to run in-session
[sojka/lightdm.git] / tests / src / test-session.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <grp.h>
8 #include <xcb/xcb.h>
9 #include <glib.h>
10 #include <glib-object.h>
11 #include <gio/gio.h>
12 #include <glib-unix.h>
13 #include <glib/gstdio.h>
14 #include <lightdm/greeter.h>
15
16 #include "status.h"
17
18 static gchar *session_id;
19
20 static GMainLoop *loop;
21
22 static GString *open_fds;
23
24 static GKeyFile *config;
25
26 static xcb_connection_t *connection;
27
28 static LightDMGreeter *greeter = NULL;
29
30 static gboolean
31 sigint_cb (gpointer user_data)
32 {
33     status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGINT);
34     g_main_loop_quit (loop);
35     return TRUE;
36 }
37
38 static gboolean
39 sigterm_cb (gpointer user_data)
40 {
41     status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGTERM);
42     g_main_loop_quit (loop);
43     return TRUE;
44 }
45
46 static void
47 show_message_cb (LightDMGreeter *greeter, const gchar *text, LightDMMessageType type)
48 {
49     status_notify ("%s GREETER-SHOW-MESSAGE TEXT=\"%s\"", session_id, text);
50 }
51
52 static void
53 show_prompt_cb (LightDMGreeter *greeter, const gchar *text, LightDMPromptType type)
54 {
55     status_notify ("%s GREETER-SHOW-PROMPT TEXT=\"%s\"", session_id, text);
56 }
57
58 static void
59 authentication_complete_cb (LightDMGreeter *greeter)
60 {
61     if (lightdm_greeter_get_authentication_user (greeter))
62         status_notify ("%s GREETER-AUTHENTICATION-COMPLETE USERNAME=%s AUTHENTICATED=%s",
63                        session_id,
64                        lightdm_greeter_get_authentication_user (greeter),
65                        lightdm_greeter_get_is_authenticated (greeter) ? "TRUE" : "FALSE");
66     else
67         status_notify ("%s GREETER-AUTHENTICATION-COMPLETE AUTHENTICATED=%s",
68                        session_id,
69                        lightdm_greeter_get_is_authenticated (greeter) ? "TRUE" : "FALSE");
70 }
71
72 static void
73 request_cb (const gchar *name, GHashTable *params)
74 {
75     GError *error = NULL;
76
77     if (!name)
78     {
79         g_main_loop_quit (loop);
80         return;
81     }
82
83     if (strcmp (name, "LOGOUT") == 0)
84         exit (EXIT_SUCCESS);
85
86     else if (strcmp (name, "CRASH") == 0)
87         kill (getpid (), SIGSEGV);
88
89     else if (strcmp (name, "LOCK-SEAT") == 0)
90     {
91         status_notify ("%s LOCK-SEAT", session_id);
92         g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
93                                      "org.freedesktop.DisplayManager",
94                                      getenv ("XDG_SEAT_PATH"),
95                                      "org.freedesktop.DisplayManager.Seat",
96                                      "Lock",
97                                      g_variant_new ("()"),
98                                      G_VARIANT_TYPE ("()"),
99                                      G_DBUS_CALL_FLAGS_NONE,
100                                      1000,
101                                      NULL,
102                                      NULL);
103     }
104
105     else if (strcmp (name, "LOCK-SESSION") == 0)
106     {
107         status_notify ("%s LOCK-SESSION", session_id);
108         g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
109                                      "org.freedesktop.DisplayManager",
110                                      getenv ("XDG_SESSION_PATH"),
111                                      "org.freedesktop.DisplayManager.Session",
112                                      "Lock",
113                                      g_variant_new ("()"),
114                                      G_VARIANT_TYPE ("()"),
115                                      G_DBUS_CALL_FLAGS_NONE,
116                                      1000,
117                                      NULL,
118                                      NULL);
119     }
120
121     else if (strcmp (name, "LIST-GROUPS") == 0)
122     {
123         int n_groups, i;
124         gid_t *groups;
125         GString *group_list;
126
127         n_groups = getgroups (0, NULL);
128         if (n_groups < 0)
129         {
130             g_printerr ("Failed to get groups: %s", strerror (errno));
131             n_groups = 0;
132         }
133         groups = malloc (sizeof (gid_t) * n_groups);
134         n_groups = getgroups (n_groups, groups);
135         group_list = g_string_new ("");
136         for (i = 0; i < n_groups; i++)
137         {
138             struct group *group;
139
140             if (i != 0)
141                 g_string_append (group_list, ",");
142             group = getgrgid (groups[i]);
143             if (group)
144                 g_string_append (group_list, group->gr_name);
145             else
146                 g_string_append_printf (group_list, "%d", groups[i]);
147         }
148         status_notify ("%s LIST-GROUPS GROUPS=%s", session_id, group_list->str);
149         g_string_free (group_list, TRUE);
150         free (groups);
151     }
152
153     else if (strcmp (name, "READ-ENV") == 0)
154     {
155         const gchar *name = g_hash_table_lookup (params, "NAME");
156         const gchar *value = g_getenv (name);
157         status_notify ("%s READ-ENV NAME=%s VALUE=%s", session_id, name, value ? value : "");
158     }
159
160     else if (strcmp (name, "WRITE-STDOUT") == 0)
161         g_print ("%s", (const gchar *) g_hash_table_lookup (params, "TEXT"));
162
163     else if (strcmp (name, "WRITE-STDERR") == 0)
164         g_printerr ("%s", (const gchar *) g_hash_table_lookup (params, "TEXT"));
165
166     else if (strcmp (name, "READ") == 0)
167     {
168         const gchar *name = g_hash_table_lookup (params, "FILE");
169         gchar *contents = NULL;
170         GError *error = NULL;
171
172         if (g_file_get_contents (name, &contents, NULL, &error))
173             status_notify ("%s READ FILE=%s TEXT=%s", session_id, name, contents);
174         else
175             status_notify ("%s READ FILE=%s ERROR=%s", session_id, name, error->message);
176         g_free (contents);
177         g_clear_error (&error);
178     }
179
180     else if (strcmp (name, "LIST-UNKNOWN-FILE-DESCRIPTORS") == 0)
181         status_notify ("%s LIST-UNKNOWN-FILE-DESCRIPTORS FDS=%s", session_id, open_fds->str);
182
183     else if (strcmp (name, "CHECK-X-AUTHORITY") == 0)
184     {
185         gchar *xauthority;
186         GStatBuf file_info;
187         GString *mode_string;
188
189         xauthority = g_strdup (g_getenv ("XAUTHORITY"));
190         if (!xauthority)
191             xauthority = g_build_filename (g_get_home_dir (), ".Xauthority", NULL);
192
193         g_stat (xauthority, &file_info);
194         g_free (xauthority);
195
196         mode_string = g_string_new ("");
197         g_string_append_c (mode_string, file_info.st_mode & S_IRUSR ? 'r' : '-');
198         g_string_append_c (mode_string, file_info.st_mode & S_IWUSR ? 'w' : '-');
199         g_string_append_c (mode_string, file_info.st_mode & S_IXUSR ? 'x' : '-');
200         g_string_append_c (mode_string, file_info.st_mode & S_IRGRP ? 'r' : '-');
201         g_string_append_c (mode_string, file_info.st_mode & S_IWGRP ? 'w' : '-');
202         g_string_append_c (mode_string, file_info.st_mode & S_IXGRP ? 'x' : '-');
203         g_string_append_c (mode_string, file_info.st_mode & S_IROTH ? 'r' : '-');
204         g_string_append_c (mode_string, file_info.st_mode & S_IWOTH ? 'w' : '-');
205         g_string_append_c (mode_string, file_info.st_mode & S_IXOTH ? 'x' : '-');
206         status_notify ("%s CHECK-X-AUTHORITY MODE=%s", session_id, mode_string->str);
207         g_string_free (mode_string, TRUE);
208     }
209
210     else if (strcmp (name, "WRITE-SHARED-DATA") == 0)
211     {
212         const gchar *data = g_hash_table_lookup (params, "DATA");
213         gchar *dir;
214
215         dir = getenv ("XDG_GREETER_DATA_DIR");
216         if (dir)
217         {
218             gchar *path;
219             FILE *f;
220
221             path = g_build_filename (dir, "data", NULL);
222             if (!(f = fopen (path, "w")) || fprintf (f, "%s", data) < 0)
223                 status_notify ("%s WRITE-SHARED-DATA ERROR=%s", session_id, strerror (errno));
224             else
225                 status_notify ("%s WRITE-SHARED-DATA RESULT=TRUE", session_id);
226
227             if (f)
228                 fclose (f);
229             g_free (path);
230         }
231         else
232             status_notify ("%s WRITE-SHARED-DATA ERROR=NO_XDG_GREETER_DATA_DIR", session_id);
233     }
234
235     else if (strcmp (name, "READ-SHARED-DATA") == 0)
236     {
237         gchar *dir;
238
239         dir = getenv ("XDG_GREETER_DATA_DIR");
240         if (dir)
241         {
242             gchar *path;
243             gchar *contents = NULL;
244             GError *error = NULL;
245
246             path = g_build_filename (dir, "data", NULL);
247             if (g_file_get_contents (path, &contents, NULL, &error))
248                 status_notify ("%s READ-SHARED-DATA DATA=%s", session_id, contents);
249             else
250                 status_notify ("%s WRITE-SHARED-DATA ERROR=%s", session_id, error->message);
251             g_free (path);
252             g_free (contents);
253             g_clear_error (&error);
254         }
255         else
256             status_notify ("%s WRITE-SHARED-DATA ERROR=NO_XDG_GREETER_DATA_DIR", session_id);
257     }
258
259     else if (strcmp (name, "GREETER-START") == 0)
260     {
261         GError *error = NULL;
262
263         g_assert (greeter == NULL);
264         greeter = lightdm_greeter_new ();
265         g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_MESSAGE, G_CALLBACK (show_message_cb), NULL);
266         g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_SHOW_PROMPT, G_CALLBACK (show_prompt_cb), NULL);
267         g_signal_connect (greeter, LIGHTDM_GREETER_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), NULL);
268         if (lightdm_greeter_connect_to_daemon_sync (greeter, &error))
269             status_notify ("%s GREETER-STARTED", session_id);
270         else
271         {
272             status_notify ("%s GREETER-FAILED ERROR=%s", session_id, error->message);
273             g_clear_error (&error);
274         }
275     }
276
277     else if (strcmp (name, "GREETER-AUTHENTICATE") == 0)
278     {
279         if (!lightdm_greeter_authenticate (greeter, g_hash_table_lookup (params, "USERNAME"), &error))
280         {
281             status_notify ("%s FAIL-AUTHENTICATE ERROR=%s", session_id, error->message);
282             g_clear_error (&error);
283         }
284     }
285
286     else if (strcmp (name, "GREETER-RESPOND") == 0)
287     {
288         if (!lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"), &error))
289         {
290             status_notify ("%s FAIL-RESPOND ERROR=%s", session_id, error->message);
291             g_clear_error (&error);
292         }
293     }
294
295     else if (strcmp (name, "GREETER-START-SESSION") == 0)
296     {
297         if (!lightdm_greeter_start_session_sync (greeter, g_hash_table_lookup (params, "SESSION"), &error))
298         {
299             status_notify ("%s FAIL-START-SESSION ERROR=%s", session_id, error->message);
300             g_clear_error (&error);          
301         }
302     }
303 }
304
305 int
306 main (int argc, char **argv)
307 {
308     gchar *display, *xdg_seat, *xdg_vtnr, *xdg_current_desktop, *xdg_greeter_data_dir, *xdg_session_cookie, *xdg_session_class, *xdg_session_type, *xdg_session_desktop, *mir_server_host_socket, *mir_vt, *mir_id;
309     GString *status_text;
310     int fd, open_max;
311
312     display = getenv ("DISPLAY");
313     xdg_seat = getenv ("XDG_SEAT");
314     xdg_vtnr = getenv ("XDG_VTNR");
315     xdg_current_desktop = getenv ("XDG_CURRENT_DESKTOP");
316     xdg_greeter_data_dir = getenv ("XDG_GREETER_DATA_DIR");
317     xdg_session_cookie = getenv ("XDG_SESSION_COOKIE");
318     xdg_session_class = getenv ("XDG_SESSION_CLASS");
319     xdg_session_type = getenv ("XDG_SESSION_TYPE");
320     xdg_session_desktop = getenv ("XDG_SESSION_DESKTOP");
321     mir_server_host_socket = getenv ("MIR_SERVER_HOST_SOCKET");
322     mir_vt = getenv ("MIR_SERVER_VT");
323     mir_id = getenv ("MIR_SERVER_NAME");
324     if (display)
325     {
326         if (display[0] == ':')
327             session_id = g_strdup_printf ("SESSION-X-%s", display + 1);
328         else
329             session_id = g_strdup_printf ("SESSION-X-%s", display);
330     }
331     else if (mir_id)
332         session_id = g_strdup_printf ("SESSION-MIR-%s", mir_id);
333     else if (mir_server_host_socket || mir_vt)
334         session_id = g_strdup ("SESSION-MIR");
335     else if (g_strcmp0 (xdg_session_type, "wayland") == 0)
336         session_id = g_strdup ("SESSION-WAYLAND");
337     else
338         session_id = g_strdup ("SESSION-UNKNOWN");
339
340     open_fds = g_string_new ("");
341     open_max = sysconf (_SC_OPEN_MAX);
342     for (fd = STDERR_FILENO + 1; fd < open_max; fd++)
343     {
344         if (fcntl (fd, F_GETFD) >= 0)
345             g_string_append_printf (open_fds, "%d,", fd);
346     }
347     if (g_str_has_suffix (open_fds->str, ","))
348         open_fds->str[strlen (open_fds->str) - 1] = '\0';
349
350 #if !defined(GLIB_VERSION_2_36)
351     g_type_init ();
352 #endif
353
354     loop = g_main_loop_new (NULL, FALSE);
355
356     g_unix_signal_add (SIGINT, sigint_cb, NULL);
357     g_unix_signal_add (SIGTERM, sigterm_cb, NULL);
358
359     status_connect (request_cb, session_id);
360
361     status_text = g_string_new ("");
362     g_string_printf (status_text, "%s START", session_id);
363     if (xdg_seat)
364         g_string_append_printf (status_text, " XDG_SEAT=%s", xdg_seat);
365     if (xdg_vtnr)
366         g_string_append_printf (status_text, " XDG_VTNR=%s", xdg_vtnr);
367     if (xdg_current_desktop)
368         g_string_append_printf (status_text, " XDG_CURRENT_DESKTOP=%s", xdg_current_desktop);
369     if (xdg_greeter_data_dir)
370         g_string_append_printf (status_text, " XDG_GREETER_DATA_DIR=%s", xdg_greeter_data_dir);
371     if (xdg_session_cookie)
372         g_string_append_printf (status_text, " XDG_SESSION_COOKIE=%s", xdg_session_cookie);
373     if (xdg_session_class)
374         g_string_append_printf (status_text, " XDG_SESSION_CLASS=%s", xdg_session_class);
375     if (xdg_session_type)
376         g_string_append_printf (status_text, " XDG_SESSION_TYPE=%s", xdg_session_type);
377     if (xdg_session_desktop)
378         g_string_append_printf (status_text, " XDG_SESSION_DESKTOP=%s", xdg_session_desktop);
379     if (mir_vt > 0)
380         g_string_append_printf (status_text, " MIR_SERVER_VT=%s", mir_vt);
381     if (argc > 1)
382         g_string_append_printf (status_text, " NAME=%s", argv[1]);
383     g_string_append_printf (status_text, " USER=%s", getenv ("USER"));
384     status_notify ("%s", status_text->str);
385     g_string_free (status_text, TRUE);
386
387     config = g_key_file_new ();
388     g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL);
389
390     if (display)
391     {
392         connection = xcb_connect (NULL, NULL);
393         if (xcb_connection_has_error (connection))
394         {
395             status_notify ("%s CONNECT-XSERVER-ERROR", session_id);
396             return EXIT_FAILURE;
397         }
398         status_notify ("%s CONNECT-XSERVER", session_id);
399     }
400
401     g_main_loop_run (loop);
402
403     return EXIT_SUCCESS;
404 }