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