]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - src/session.c
Merge in greeter-log-file branch
[sojka/lightdm.git] / src / session.c
1 /*
2  * Copyright (C) 2010-2011 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  *
5  * This program is free software: you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License as published by the Free Software
7  * Foundation, either version 3 of the License, or (at your option) any later
8  * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
9  * license.
10  */
11
12 #include <config.h>
13
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <sys/wait.h>
19 #include <fcntl.h>
20 #include <glib/gstdio.h>
21 #include <grp.h>
22 #include <pwd.h>
23
24 #include "session.h"
25 #include "configuration.h"
26 #include "console-kit.h"
27 #include "login1.h"
28 #include "guest-account.h"
29
30 enum {
31     GOT_MESSAGES,
32     AUTHENTICATION_COMPLETE,
33     STOPPED,
34     LAST_SIGNAL
35 };
36 static guint signals[LAST_SIGNAL] = { 0 };
37
38 struct SessionPrivate
39 {
40     /* Session type */
41     gchar *session_type;
42
43     /* Display server running on */
44     DisplayServer *display_server;
45
46     /* PID of child process */
47     GPid pid;
48
49     /* Pipes to talk to child */
50     int to_child_input;
51     int from_child_output;
52     GIOChannel *from_child_channel;
53     guint from_child_watch;
54     guint child_watch;
55
56     /* User to authenticate as */
57     gchar *username;
58
59     /* TRUE if is a guest account */
60     gboolean is_guest;
61
62     /* User object that matches the current username */
63     User *user;
64
65     /* PAM service to use */
66     gchar *pam_service;
67
68     /* TRUE if should run PAM authentication phase */
69     gboolean do_authenticate;
70
71     /* TRUE if can handle PAM prompts */
72     gboolean is_interactive;
73
74     /* Messages being requested by PAM */
75     int messages_length;
76     struct pam_message *messages;
77
78     /* Authentication result from PAM */
79     gboolean authentication_started;
80     gboolean authentication_complete;
81     int authentication_result;
82     gchar *authentication_result_string;
83
84     /* File to log to */
85     gchar *log_filename;
86
87     /* Seat class */
88     gchar *class;
89
90     /* tty this session is running on */
91     gchar *tty;
92
93     /* X display connected to */
94     gchar *xdisplay;
95     XAuthority *x_authority;
96     gboolean x_authority_use_system_location;
97
98     /* Remote host this session is being controlled from */
99     gchar *remote_host_name;
100
101     /* Console kit cookie */
102     gchar *console_kit_cookie;
103
104     /* login1 session */
105     gchar *login1_session;
106
107     /* Environment to set in child */
108     GList *env;
109
110     /* Command to run in child */
111     gchar **argv;
112
113     /* True if have run command */
114     gboolean command_run;
115
116     /* TRUE if stopping this session */
117     gboolean stopping;
118 };
119
120 /* Maximum length of a string to pass between daemon and session */
121 #define MAX_STRING_LENGTH 65535
122
123 G_DEFINE_TYPE (Session, session, G_TYPE_OBJECT);
124
125 Session *
126 session_new (void)
127 {
128     return g_object_new (SESSION_TYPE, NULL);
129 }
130
131 void
132 session_set_session_type (Session *session, const gchar *session_type)
133 {
134     g_return_if_fail (session != NULL);
135     g_free (session->priv->session_type);
136     session->priv->session_type = g_strdup (session_type);
137 }
138
139 const gchar *
140 session_get_session_type (Session *session)
141 {
142     g_return_val_if_fail (session != NULL, NULL);
143     return session->priv->session_type;
144 }
145
146 void
147 session_set_pam_service (Session *session, const gchar *pam_service)
148 {
149     g_return_if_fail (session != NULL);
150     g_free (session->priv->pam_service);
151     session->priv->pam_service = g_strdup (pam_service);
152 }
153
154 void
155 session_set_username (Session *session, const gchar *username)
156 {
157     g_return_if_fail (session != NULL);
158     g_free (session->priv->username);
159     session->priv->username = g_strdup (username);
160 }
161
162 void
163 session_set_do_authenticate (Session *session, gboolean do_authenticate)
164 {
165     g_return_if_fail (session != NULL);
166     session->priv->do_authenticate = do_authenticate;
167 }
168
169 void
170 session_set_is_interactive (Session *session, gboolean is_interactive)
171 {
172     g_return_if_fail (session != NULL);
173     session->priv->is_interactive = is_interactive;
174 }
175
176 void
177 session_set_is_guest (Session *session, gboolean is_guest)
178 {
179     g_return_if_fail (session != NULL);
180     session->priv->is_guest = is_guest;
181 }
182
183 gboolean
184 session_get_is_guest (Session *session)
185 {
186     g_return_val_if_fail (session != NULL, FALSE);
187     return session->priv->is_guest;
188 }
189
190 void
191 session_set_log_file (Session *session, const gchar *filename)
192 {
193     g_return_if_fail (session != NULL);
194     g_free (session->priv->log_filename);
195     session->priv->log_filename = g_strdup (filename);
196 }
197
198 void
199 session_set_class (Session *session, const gchar *class)
200 {
201     g_return_if_fail (session != NULL);
202     g_free (session->priv->class);
203     session->priv->class = g_strdup (class);
204 }
205
206 void
207 session_set_display_server (Session *session, DisplayServer *display_server)
208 {
209     g_return_if_fail (session != NULL);
210     g_return_if_fail (display_server != NULL);
211     if (session->priv->display_server)
212         g_object_unref (session->priv->display_server);
213     session->priv->display_server = g_object_ref (display_server);
214 }
215
216 DisplayServer *
217 session_get_display_server (Session *session)
218 {
219     g_return_val_if_fail (session != NULL, NULL);
220     return session->priv->display_server;
221 }
222
223 void
224 session_set_tty (Session *session, const gchar *tty)
225 {
226     g_return_if_fail (session != NULL);
227     g_free (session->priv->tty);
228     session->priv->tty = g_strdup (tty);
229 }
230
231 void
232 session_set_xdisplay (Session *session, const gchar *xdisplay)
233 {
234     g_return_if_fail (session != NULL);
235     g_free (session->priv->xdisplay);
236     session->priv->xdisplay = g_strdup (xdisplay);
237 }
238
239 void
240 session_set_x_authority (Session *session, XAuthority *authority, gboolean use_system_location)
241 {
242     g_return_if_fail (session != NULL);
243     if (session->priv->x_authority)
244     {
245         g_object_unref (session->priv->x_authority);
246         session->priv->x_authority = NULL;
247     }
248     if (authority)
249         session->priv->x_authority = g_object_ref (authority);
250     session->priv->x_authority_use_system_location = use_system_location;
251 }
252
253 void
254 session_set_remote_host_name (Session *session, const gchar *remote_host_name)
255 {
256     g_return_if_fail (session != NULL);
257     g_free (session->priv->remote_host_name);
258     session->priv->remote_host_name = g_strdup (remote_host_name);
259 }
260
261 void
262 session_set_env (Session *session, const gchar *name, const gchar *value)
263 {
264     g_return_if_fail (session != NULL);
265     session->priv->env = g_list_append (session->priv->env, g_strdup_printf ("%s=%s", name, value));
266 }
267
268 void
269 session_set_argv (Session *session, gchar **argv)
270 {
271     g_return_if_fail (session != NULL);
272     session->priv->argv = g_strdupv (argv);
273 }
274
275 User *
276 session_get_user (Session *session)
277 {
278     g_return_val_if_fail (session != NULL, NULL);
279
280     if (session->priv->username == NULL)
281         return NULL;
282
283     if (!session->priv->user)
284         session->priv->user = accounts_get_user_by_name (session->priv->username);
285
286     return session->priv->user;
287 }
288
289 static void
290 write_data (Session *session, const void *buf, size_t count)
291 {
292     if (write (session->priv->to_child_input, buf, count) != count)
293         g_warning ("Error writing to session: %s", strerror (errno));
294 }
295
296 static void
297 write_string (Session *session, const char *value)
298 {
299     int length;
300
301     length = value ? strlen (value) : -1;
302     write_data (session, &length, sizeof (length));
303     if (value)
304         write_data (session, value, sizeof (char) * length);
305 }
306
307 static void
308 write_xauth (Session *session, XAuthority *x_authority)
309 {
310     guint16 family;
311     gsize length;
312
313     if (!x_authority)
314     {
315         write_string (session, NULL);
316         return;
317     }
318
319     write_string (session, x_authority_get_authorization_name (session->priv->x_authority));
320     family = x_authority_get_family (session->priv->x_authority);
321     write_data (session, &family, sizeof (family));
322     length = x_authority_get_address_length (session->priv->x_authority);
323     write_data (session, &length, sizeof (length));
324     write_data (session, x_authority_get_address (session->priv->x_authority), length);
325     write_string (session, x_authority_get_number (session->priv->x_authority));
326     length = x_authority_get_authorization_data_length (session->priv->x_authority);
327     write_data (session, &length, sizeof (length));
328     write_data (session, x_authority_get_authorization_data (session->priv->x_authority), length);
329 }
330
331 static ssize_t
332 read_from_child (Session *session, void *buf, size_t count)
333 {
334     ssize_t n_read;
335     n_read = read (session->priv->from_child_output, buf, count);
336     if (n_read < 0)
337         g_warning ("Error reading from session: %s", strerror (errno));
338     return n_read;
339 }
340
341 static gchar *
342 read_string_from_child (Session *session)
343 {
344     int length;
345     char *value;
346
347     if (read_from_child (session, &length, sizeof (length)) <= 0)
348         return NULL;
349     if (length < 0)
350         return NULL;
351     if (length > MAX_STRING_LENGTH)
352     {
353         g_warning ("Invalid string length %d from child", length);
354         return NULL;
355     }
356
357     value = g_malloc (sizeof (char) * (length + 1));
358     read_from_child (session, value, length);
359     value[length] = '\0';
360
361     return value;
362 }
363
364 static void
365 session_watch_cb (GPid pid, gint status, gpointer data)
366 {
367     Session *session = data;
368
369     session->priv->pid = 0;
370
371     if (WIFEXITED (status))
372         g_debug ("Session %d exited with return value %d", pid, WEXITSTATUS (status));
373     else if (WIFSIGNALED (status))
374         g_debug ("Session %d terminated with signal %d", pid, WTERMSIG (status));
375
376     /* If failed during authentication then report this as an authentication failure */
377     if (session->priv->authentication_started && !session->priv->authentication_complete)
378     {
379         g_debug ("Session %d failed during authentication", pid);
380         session->priv->authentication_complete = TRUE;
381         session->priv->authentication_result = PAM_CONV_ERR;
382         g_free (session->priv->authentication_result_string);
383         session->priv->authentication_result_string = g_strdup ("Authentication stopped before completion");
384         g_signal_emit (G_OBJECT (session), signals[AUTHENTICATION_COMPLETE], 0);
385     }
386
387     g_signal_emit (G_OBJECT (session), signals[STOPPED], 0);
388
389     /* Delete account if it is a guest one */
390     if (session->priv->is_guest)
391         guest_account_cleanup (session->priv->username);
392
393     /* Drop our reference on the child process, it has terminated */
394     g_object_unref (session);
395 }
396
397 static gboolean
398 from_child_cb (GIOChannel *source, GIOCondition condition, gpointer data)
399 {
400     Session *session = data;
401     gchar *username;
402     ssize_t n_read;
403     gboolean auth_complete;
404
405     /* Remote end gone */
406     if (condition == G_IO_HUP)
407     {
408         session->priv->from_child_watch = 0;
409         return FALSE;
410     }
411
412     /* Get the username currently being authenticated (may change during authentication) */
413     username = read_string_from_child (session);
414     if (g_strcmp0 (username, session->priv->username) != 0)
415     {
416         g_free (session->priv->username);
417         session->priv->username = username;
418         if (session->priv->user)
419             g_object_unref (session->priv->user);
420         session->priv->user = NULL;
421     }
422     else
423         g_free (username);
424
425     /* Check if authentication completed */
426     n_read = read_from_child (session, &auth_complete, sizeof (auth_complete));
427     if (n_read < 0)
428         g_debug ("Error reading from child: %s", strerror (errno));
429     if (n_read <= 0)
430     {
431         session->priv->from_child_watch = 0;
432         return FALSE;
433     }
434
435     if (auth_complete)
436     {
437         session->priv->authentication_complete = TRUE;
438         read_from_child (session, &session->priv->authentication_result, sizeof (session->priv->authentication_result));
439         g_free (session->priv->authentication_result_string);
440         session->priv->authentication_result_string = read_string_from_child (session);
441
442         g_debug ("Session %d authentication complete with return value %d: %s", session->priv->pid, session->priv->authentication_result, session->priv->authentication_result_string);
443
444         /* No longer expect any more messages */
445         session->priv->from_child_watch = 0;
446
447         g_signal_emit (G_OBJECT (session), signals[AUTHENTICATION_COMPLETE], 0);
448
449         return FALSE;
450     }
451     else
452     {
453         int i;
454
455         session->priv->messages_length = 0;
456         read_from_child (session, &session->priv->messages_length, sizeof (session->priv->messages_length));
457         session->priv->messages = calloc (session->priv->messages_length, sizeof (struct pam_message));
458         for (i = 0; i < session->priv->messages_length; i++)
459         {
460             struct pam_message *m = &session->priv->messages[i];
461             read_from_child (session, &m->msg_style, sizeof (m->msg_style));
462             m->msg = read_string_from_child (session);
463         }
464
465         g_debug ("Session %d got %d message(s) from PAM", session->priv->pid, session->priv->messages_length);
466
467         g_signal_emit (G_OBJECT (session), signals[GOT_MESSAGES], 0);
468     }
469
470     return TRUE;
471 }
472
473 gboolean
474 session_start (Session *session)
475 {
476     g_return_val_if_fail (session != NULL, FALSE);
477     g_return_val_if_fail (session->priv->display_server != NULL, FALSE);
478     return SESSION_GET_CLASS (session)->start (session);
479 }
480
481 gboolean
482 session_get_is_started (Session *session)
483 {
484     return session->priv->pid != 0;
485 }
486
487 static gboolean
488 session_real_start (Session *session)
489 {
490     int version;
491     int to_child_pipe[2], from_child_pipe[2];
492     int to_child_output, from_child_input;
493
494     g_return_val_if_fail (session->priv->pid == 0, FALSE);
495
496     display_server_setup_session (session->priv->display_server, session);
497
498     /* Create pipes to talk to the child */
499     if (pipe (to_child_pipe) < 0 || pipe (from_child_pipe) < 0)
500     {
501         g_warning ("Failed to create pipe to communicate with session process: %s", strerror (errno));
502         return FALSE;
503     }
504     to_child_output = to_child_pipe[0];
505     session->priv->to_child_input = to_child_pipe[1];
506     session->priv->from_child_output = from_child_pipe[0];
507     from_child_input = from_child_pipe[1];
508     session->priv->from_child_channel = g_io_channel_unix_new (session->priv->from_child_output);
509     session->priv->from_child_watch = g_io_add_watch (session->priv->from_child_channel, G_IO_IN | G_IO_HUP, from_child_cb, session);
510
511     /* Don't allow the daemon end of the pipes to be accessed in child processes */
512     fcntl (session->priv->to_child_input, F_SETFD, FD_CLOEXEC);
513     fcntl (session->priv->from_child_output, F_SETFD, FD_CLOEXEC);
514
515     /* Create the guest account if it is one */
516     if (session->priv->is_guest && session->priv->username == NULL)
517     {
518         session->priv->username = guest_account_setup ();
519         if (!session->priv->username)
520             return FALSE;
521     }
522
523     /* Run the child */
524     session->priv->pid = fork ();
525     if (session->priv->pid < 0)
526     {
527         g_debug ("Failed to fork session child process: %s", strerror (errno));
528         return FALSE;
529     }
530
531     if (session->priv->pid == 0)
532     {
533         /* Run us again in session child mode */
534         execlp ("lightdm",
535                 "lightdm",
536                 "--session-child",
537                 g_strdup_printf ("%d", to_child_output),
538                 g_strdup_printf ("%d", from_child_input),
539                 NULL);
540         _exit (EXIT_FAILURE);
541     }
542
543     /* Hold a reference on this object until the child process terminates so we
544      * can handle the watch callback even if it is no longer used. Otherwise a
545      * zombie process will remain */
546     g_object_ref (session);
547
548     /* Listen for session termination */
549     session->priv->authentication_started = TRUE;
550     session->priv->child_watch = g_child_watch_add (session->priv->pid, session_watch_cb, session);
551
552     /* Close the ends of the pipes we don't need */
553     close (to_child_output);
554     close (from_child_input);
555
556     /* Indicate what version of the protocol we are using */
557     version = 1;
558     write_data (session, &version, sizeof (version));
559
560     /* Send configuration */
561     write_string (session, session->priv->pam_service);
562     write_string (session, session->priv->username);
563     write_data (session, &session->priv->do_authenticate, sizeof (session->priv->do_authenticate));
564     write_data (session, &session->priv->is_interactive, sizeof (session->priv->is_interactive));
565     write_string (session, session->priv->class);
566     write_string (session, session->priv->tty);
567     write_string (session, session->priv->remote_host_name);
568     write_string (session, session->priv->xdisplay);
569     write_xauth (session, session->priv->x_authority);
570
571     g_debug ("Started session %d with service '%s', username '%s'", session->priv->pid, session->priv->pam_service, session->priv->username);
572
573     return TRUE;
574 }
575
576 const gchar *
577 session_get_username (Session *session)
578 {
579     g_return_val_if_fail (session != NULL, NULL);
580     return session->priv->username;
581 }
582
583 const gchar *
584 session_get_console_kit_cookie (Session *session)
585 {
586     g_return_val_if_fail (session != NULL, NULL);
587     return session->priv->console_kit_cookie;
588 }
589
590 void
591 session_respond (Session *session, struct pam_response *response)
592 {
593     int error = PAM_SUCCESS;
594     int i;
595
596     g_return_if_fail (session != NULL);
597
598     write_data (session, &error, sizeof (error));
599     for (i = 0; i < session->priv->messages_length; i++)
600     {
601         write_string (session, response[i].resp);
602         write_data (session, &response[i].resp_retcode, sizeof (response[i].resp_retcode));
603     }
604
605     /* Delete the old messages */
606     for (i = 0; i < session->priv->messages_length; i++)
607         g_free ((char *) session->priv->messages[i].msg);
608     g_free (session->priv->messages);
609     session->priv->messages = NULL;
610     session->priv->messages_length = 0;
611 }
612
613 void
614 session_respond_error (Session *session, int error)
615 {
616     g_return_if_fail (session != NULL);
617     g_return_if_fail (error != PAM_SUCCESS);
618
619     write_data (session, &error, sizeof (error));
620 }
621
622 int
623 session_get_messages_length (Session *session)
624 {
625     g_return_val_if_fail (session != NULL, 0);
626     return session->priv->messages_length;
627 }
628
629 const struct pam_message *
630 session_get_messages (Session *session)
631 {
632     g_return_val_if_fail (session != NULL, NULL);
633     return session->priv->messages;
634 }
635
636 gboolean
637 session_get_is_authenticated (Session *session)
638 {
639     g_return_val_if_fail (session != NULL, FALSE);
640     return session->priv->authentication_complete && session->priv->authentication_result == PAM_SUCCESS;
641 }
642
643 int
644 session_get_authentication_result (Session *session)
645 {
646     g_return_val_if_fail (session != NULL, 0);
647     return session->priv->authentication_result;
648 }
649
650 const gchar *
651 session_get_authentication_result_string (Session *session)
652 {
653     g_return_val_if_fail (session != NULL, NULL);
654     return session->priv->authentication_result_string;
655 }
656
657 void
658 session_run (Session *session)
659 {
660     g_return_if_fail (session->priv->display_server != NULL);
661     return SESSION_GET_CLASS (session)->run (session);
662 }
663
664 static void
665 session_real_run (Session *session)
666 {
667     gsize i, argc;
668     gchar *command, *x_authority_filename;
669     GList *link;
670
671     g_return_if_fail (session != NULL);
672     g_return_if_fail (!session->priv->command_run);
673     g_return_if_fail (session_get_is_authenticated (session));
674     g_return_if_fail (session->priv->argv != NULL);
675     g_return_if_fail (session->priv->pid != 0);
676
677     display_server_setup_session (session->priv->display_server, session);
678
679     session->priv->command_run = TRUE;
680
681     command = g_strjoinv (" ", session->priv->argv);
682     g_debug ("Session %d running command %s", session->priv->pid, command);
683     g_free (command);
684
685     /* Create authority location */
686     if (session->priv->x_authority_use_system_location)
687     {
688         gchar *run_dir, *dir;
689
690         run_dir = config_get_string (config_get_instance (), "LightDM", "run-directory");
691         dir = g_build_filename (run_dir, session->priv->username, NULL);
692         g_free (run_dir);
693
694         if (g_mkdir_with_parents (dir, S_IRWXU) < 0)
695             g_warning ("Failed to set create system authority dir %s: %s", dir, strerror (errno));          
696         if (getuid () == 0)
697         {
698             if (chown (dir, user_get_uid (session_get_user (session)), user_get_gid (session_get_user (session))) < 0)
699                 g_warning ("Failed to set ownership of user authority dir: %s", strerror (errno));
700         }
701
702         x_authority_filename = g_build_filename (dir, "xauthority", NULL);
703         g_free (dir);
704     }
705     else
706         x_authority_filename = g_build_filename (user_get_home_directory (session_get_user (session)), ".Xauthority", NULL);
707
708     write_string (session, session->priv->log_filename);
709     write_string (session, session->priv->tty);
710     write_string (session, x_authority_filename);
711     g_free (x_authority_filename);
712     write_string (session, session->priv->xdisplay);
713     write_xauth (session, session->priv->x_authority);
714     argc = g_list_length (session->priv->env);
715     write_data (session, &argc, sizeof (argc));
716     for (link = session->priv->env; link; link = link->next)
717         write_string (session, (gchar *) link->data);
718     argc = g_strv_length (session->priv->argv);
719     write_data (session, &argc, sizeof (argc));
720     for (i = 0; i < argc; i++)
721         write_string (session, session->priv->argv[i]);
722
723     if (login1_is_running ())
724         session->priv->login1_session = read_string_from_child (session);
725     if (!session->priv->login1_session)
726         session->priv->console_kit_cookie = read_string_from_child (session);
727 }
728
729 void
730 session_lock (Session *session)
731 {
732     g_return_if_fail (session != NULL);
733     if (getuid () == 0)
734     {
735         if (login1_is_running ())
736             login1_lock_session (session->priv->login1_session);
737         if (!session->priv->login1_session)
738             ck_lock_session (session->priv->console_kit_cookie);
739     }
740 }
741
742 void
743 session_unlock (Session *session)
744 {
745     g_return_if_fail (session != NULL);
746     if (getuid () == 0)
747     {
748         if (login1_is_running ())
749             login1_unlock_session (session->priv->login1_session);
750         if (!session->priv->login1_session)
751             ck_unlock_session (session->priv->console_kit_cookie);
752     }
753 }
754
755 void
756 session_stop (Session *session)
757 {
758     g_return_if_fail (session != NULL);
759
760     if (session->priv->stopping)
761         return;
762     session->priv->stopping = TRUE;
763
764     return SESSION_GET_CLASS (session)->stop (session);
765 }
766
767 static void
768 session_real_stop (Session *session)
769 {
770     g_return_if_fail (session != NULL);
771
772     if (session->priv->pid > 0)
773     {
774         g_debug ("Session %d: Sending SIGTERM", session->priv->pid);
775         kill (session->priv->pid, SIGTERM);
776         // FIXME: Handle timeout
777     }
778     else
779         g_signal_emit (G_OBJECT (session), signals[STOPPED], 0);
780 }
781
782 gboolean
783 session_get_is_stopping (Session *session)
784 {
785     g_return_val_if_fail (session != NULL, FALSE);
786     return session->priv->stopping;
787 }
788
789 static void
790 session_init (Session *session)
791 {
792     session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, SESSION_TYPE, SessionPrivate);
793     session->priv->log_filename = g_strdup (".xsession-errors");
794 }
795
796 static void
797 session_finalize (GObject *object)
798 {
799     Session *self = SESSION (object);
800     int i;
801
802     g_free (self->priv->session_type);
803     if (self->priv->display_server)
804         g_object_unref (self->priv->display_server);
805     if (self->priv->pid)
806         kill (self->priv->pid, SIGKILL);
807     if (self->priv->from_child_channel)
808         g_io_channel_unref (self->priv->from_child_channel);
809     if (self->priv->from_child_watch)
810         g_source_remove (self->priv->from_child_watch);
811     if (self->priv->child_watch)
812         g_source_remove (self->priv->child_watch);
813     g_free (self->priv->username);
814     if (self->priv->user)
815         g_object_unref (self->priv->user);
816     g_free (self->priv->pam_service);
817     for (i = 0; i < self->priv->messages_length; i++)
818         g_free ((char *) self->priv->messages[i].msg);
819     g_free (self->priv->messages);
820     g_free (self->priv->authentication_result_string);
821     g_free (self->priv->log_filename);
822     g_free (self->priv->class);
823     g_free (self->priv->tty);
824     g_free (self->priv->xdisplay);
825     if (self->priv->x_authority)
826         g_object_unref (self->priv->x_authority);
827     g_free (self->priv->remote_host_name);
828     g_free (self->priv->login1_session);
829     g_free (self->priv->console_kit_cookie);
830     g_list_free_full (self->priv->env, g_free);
831     g_strfreev (self->priv->argv);
832
833     G_OBJECT_CLASS (session_parent_class)->finalize (object);
834 }
835
836 static void
837 session_class_init (SessionClass *klass)
838 {
839     GObjectClass *object_class = G_OBJECT_CLASS (klass);
840
841     klass->start = session_real_start;
842     klass->run = session_real_run;
843     klass->stop = session_real_stop;
844     object_class->finalize = session_finalize;
845
846     g_type_class_add_private (klass, sizeof (SessionPrivate));
847
848     signals[GOT_MESSAGES] =
849         g_signal_new ("got-messages",
850                       G_TYPE_FROM_CLASS (klass),
851                       G_SIGNAL_RUN_LAST,
852                       G_STRUCT_OFFSET (SessionClass, got_messages),
853                       NULL, NULL,
854                       NULL,
855                       G_TYPE_NONE, 0);
856
857     signals[AUTHENTICATION_COMPLETE] =
858         g_signal_new ("authentication-complete",
859                       G_TYPE_FROM_CLASS (klass),
860                       G_SIGNAL_RUN_LAST,
861                       G_STRUCT_OFFSET (SessionClass, authentication_complete),
862                       NULL, NULL,
863                       NULL,
864                       G_TYPE_NONE, 0);
865
866     signals[STOPPED] =
867         g_signal_new ("stopped",
868                       G_TYPE_FROM_CLASS (klass),
869                       G_SIGNAL_RUN_LAST,
870                       G_STRUCT_OFFSET (SessionClass, stopped),
871                       NULL, NULL,
872                       NULL,
873                       G_TYPE_NONE, 0);
874 }