1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gnome-keyring-daemon.c - main keyring daemon code.
3
4 Copyright (C) 2003 Red Hat, Inc
5
6 Gnome keyring is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 Gnome keyring is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 Author: Alexander Larsson <alexl@redhat.com>
21 Author: Stef Walter <stef@memberwebs.com>
22 */
23
24 #include "config.h"
25
26 #include "gkd-glue.h"
27 #include "gkd-main.h"
28 #include "gkd-capability.h"
29 #include "gkd-pkcs11.h"
30 #include "gkd-util.h"
31
32 #include "control/gkd-control.h"
33
34 #include "dbus/gkd-dbus.h"
35
36 #include "egg/egg-cleanup.h"
37 #include "egg/egg-error.h"
38 #include "egg/egg-libgcrypt.h"
39 #include "egg/egg-secure-memory.h"
40 #include "egg/egg-unix-credentials.h"
41
42 #include "login/gkd-login.h"
43
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <pthread.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <signal.h>
51 #include <locale.h>
52 #include <syslog.h>
53 #include <unistd.h>
54
55 #include <sys/types.h>
56 #include <sys/socket.h>
57 #include <sys/un.h>
58 #include <sys/stat.h>
59 #include <sys/wait.h>
60
61 #include <gio/gunixinputstream.h>
62 #include <gio/gunixoutputstream.h>
63 #include <glib.h>
64 #include <glib/gi18n.h>
65 #include <glib-object.h>
66 #include <glib-unix.h>
67
68 #include <gcrypt.h>
69
70 /* preset file descriptors */
71 #define STDIN 0
72 #define STDOUT 1
73 #define STDERR 2
74
75 #ifndef HAVE_SOCKLEN_T
76 typedef int socklen_t;
77 #endif
78
79 #define GKD_COMP_KEYRING "keyring"
80 #define GKD_COMP_PKCS11 "pkcs11"
81 #define GKD_COMP_SECRETS "secrets"
82 #define GKD_COMP_SSH "ssh"
83
84 EGG_SECURE_DECLARE (daemon_main);
85
86 /* -----------------------------------------------------------------------------
87 * COMMAND LINE
88 */
89
90 /* All the components to run on startup if not specified on command line */
91 #ifdef WITH_SSH
92 # ifdef WITH_GPG
93 # define DEFAULT_COMPONENTS GKD_COMP_PKCS11 "," GKD_COMP_SECRETS "," GKD_COMP_SSH "," GKD_COMP_GPG
94 # else
95 # define DEFAULT_COMPONENTS GKD_COMP_PKCS11 "," GKD_COMP_SECRETS "," GKD_COMP_SSH
96 # endif
97 #else
98 # ifdef WITH_GPG
99 # define DEFAULT_COMPONENTS GKD_COMP_PKCS11 "," GKD_COMP_SECRETS "," GKD_COMP_GPG
100 # else
101 # define DEFAULT_COMPONENTS GKD_COMP_PKCS11 "," GKD_COMP_SECRETS
102 # endif
103 #endif
104
105 /*
106 * If --login is used and then daemon is not initialized within LOGIN_TIMEOUT
107 * seconds, then we exit. See on_login_timeout() below.
108 */
109
110 #define LOGIN_TIMEOUT 120
111
112 static gchar* run_components = DEFAULT_COMPONENTS;
113 static gboolean pkcs11_started = FALSE;
114 static gboolean secrets_started = FALSE;
115 static gboolean ssh_started = FALSE;
116 static gboolean dbus_started = FALSE;
117
118 static gboolean run_foreground = FALSE;
119 static gboolean run_daemonized = FALSE;
120 static gboolean run_version = FALSE;
121 static gboolean run_for_login = FALSE;
122 static gboolean perform_unlock = FALSE;
123 static gboolean run_for_start = FALSE;
124 static gboolean run_for_replace = FALSE;
125 static gchar* login_password = NULL;
126 static gchar* control_directory = NULL;
127 static guint timeout_id = 0;
128 static gboolean initialization_completed = FALSE;
129 static GMainLoop *loop = NULL;
130 static int parent_wakeup_fd = -1;
131 static GDBusConnection *system_bus_connection = NULL;
132
133 static GOptionEntry option_entries[] = {
134 { "start", 's', 0, G_OPTION_ARG_NONE, &run_for_start,
135 "Start a dameon or initialize an already running daemon." },
136 { "replace", 'r', 0, G_OPTION_ARG_NONE, &run_for_replace,
137 "Replace the daemon for this desktop login environment." },
138 { "foreground", 'f', 0, G_OPTION_ARG_NONE, &run_foreground,
139 "Run in the foreground", NULL },
140 { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &run_daemonized,
141 "Run as a daemon", NULL },
142 { "login", 'l', 0, G_OPTION_ARG_NONE, &run_for_login,
143 "Run by PAM for a user login. Read login password from stdin", NULL },
144 { "unlock", 0, 0, G_OPTION_ARG_NONE, &perform_unlock,
145 "Prompt for login keyring password, or read from stdin", NULL },
146 { "components", 'c', 0, G_OPTION_ARG_STRING, &run_components,
147 "The optional components to run", DEFAULT_COMPONENTS },
148 { "control-directory", 'C', 0, G_OPTION_ARG_FILENAME, &control_directory,
149 "The directory for sockets and control data", NULL },
150 { "version", 'V', 0, G_OPTION_ARG_NONE, &run_version,
151 "Show the version number and exit.", NULL },
152 { NULL }
153 };
154
155 static void
parse_arguments(int * argc,char ** argv[])156 parse_arguments (int *argc, char** argv[])
157 {
158 GError *err = NULL;
159 GOptionContext *context;
160
161 context = g_option_context_new ("- The Gnome Keyring Daemon");
162 g_option_context_add_main_entries (context, option_entries, GETTEXT_PACKAGE);
163
164 if (!g_option_context_parse (context, argc, argv, &err)) {
165 g_printerr ("gnome-keyring-daemon: %s\n", egg_error_message (err));
166 g_clear_error (&err);
167 }
168
169 if (!run_components || !run_components[0]) {
170 run_components = DEFAULT_COMPONENTS;
171 } else {
172 run_components = g_strdup (run_components);
173 egg_cleanup_register (g_free, run_components);
174 }
175
176 /* Check the arguments */
177 if (run_for_login && run_for_start) {
178 g_printerr ("gnome-keyring-daemon: The --start option is incompatible with --login\n");
179 run_for_login = FALSE;
180 }
181
182 if (run_for_login && run_for_replace) {
183 g_printerr ("gnome-keyring-daemon: The --replace option is incompatible with --login\n");
184 run_for_login = FALSE;
185 }
186
187 if (run_for_start && run_for_replace) {
188 g_printerr ("gnome-keyring-daemon: The --replace option is incompatible with --start\n");
189 run_for_start = FALSE;
190 }
191
192 if (run_for_start && perform_unlock) {
193 g_printerr ("gnome-keyring-daemon: The --start option is incompatible with --unlock");
194 perform_unlock = FALSE;
195 }
196
197 if (run_for_login)
198 perform_unlock = TRUE;
199
200 g_option_context_free (context);
201 }
202
203 /* -----------------------------------------------------------------------------
204 * MEMORY
205 */
206
207 static gboolean do_warning = TRUE;
208 #define WARNING "couldn't allocate secure memory to keep passwords " \
209 "and or keys from being written to the disk"
210
211 #define ABORTMSG "The GNOME_KEYRING_PARANOID environment variable was set. " \
212 "Exiting..."
213
214
215 /*
216 * These are called from gkr-secure-memory.c to provide appropriate
217 * locking for memory between threads
218 */
219
220 G_LOCK_DEFINE_STATIC (memory_mutex);
221
222 static void
egg_memory_lock(void)223 egg_memory_lock (void)
224 {
225 G_LOCK (memory_mutex);
226 }
227
228 static void
egg_memory_unlock(void)229 egg_memory_unlock (void)
230 {
231 G_UNLOCK (memory_mutex);
232 }
233
234 static void *
egg_memory_fallback(void * p,size_t sz)235 egg_memory_fallback (void *p, size_t sz)
236 {
237 const gchar *env;
238
239 /* We were asked to free memory */
240 if (!sz) {
241 g_free (p);
242 return NULL;
243 }
244
245 /* We were asked to allocate */
246 if (!p) {
247 if (do_warning) {
248 g_message (WARNING);
249 do_warning = FALSE;
250 }
251
252 env = g_getenv ("GNOME_KEYRING_PARANOID");
253 if (env && *env)
254 g_error (ABORTMSG);
255
256 return g_malloc0 (sz);
257 }
258
259 /*
260 * Reallocation is a bit of a gray area, as we can be asked
261 * by external libraries (like libgcrypt) to reallocate a
262 * non-secure block into secure memory. We cannot satisfy
263 * this request (as we don't know the size of the original
264 * block) so we just try our best here.
265 */
266
267 return g_realloc (p, sz);
268 }
269
270 EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, egg_memory_fallback);
271
272 /* -----------------------------------------------------------------------------
273 * LOGS
274 */
275
276 static void
log_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer user_data)277 log_handler (const gchar *log_domain, GLogLevelFlags log_level,
278 const gchar *message, gpointer user_data)
279 {
280 int level;
281
282 /* Note that crit and err are the other way around in syslog */
283
284 switch (G_LOG_LEVEL_MASK & log_level) {
285 case G_LOG_LEVEL_ERROR:
286 level = LOG_CRIT;
287 break;
288 case G_LOG_LEVEL_CRITICAL:
289 level = LOG_ERR;
290 break;
291 case G_LOG_LEVEL_WARNING:
292 level = LOG_WARNING;
293 break;
294 case G_LOG_LEVEL_MESSAGE:
295 level = LOG_NOTICE;
296 break;
297 case G_LOG_LEVEL_INFO:
298 level = LOG_INFO;
299 break;
300 case G_LOG_LEVEL_DEBUG:
301 level = -1;
302 break;
303 default:
304 level = LOG_ERR;
305 break;
306 }
307
308 /* Log to syslog first */
309 if (level != -1) {
310 if (log_domain)
311 syslog (level, "%s: %s", log_domain, message);
312 else
313 syslog (level, "%s", message);
314 }
315
316 /* And then to default handler for aborting and stuff like that */
317 g_log_default_handler (log_domain, log_level, message, user_data);
318 }
319
320 static void
printerr_handler(const gchar * string)321 printerr_handler (const gchar *string)
322 {
323 /* Print to syslog and stderr */
324 syslog (LOG_WARNING, "%s", string);
325 fprintf (stderr, "%s", string);
326 }
327
328 static void
prepare_logging()329 prepare_logging ()
330 {
331 GLogLevelFlags flags = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR |
332 G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
333 G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO;
334
335 openlog ("gnome-keyring-daemon", LOG_PID, LOG_AUTH);
336
337 g_log_set_handler (NULL, flags, log_handler, NULL);
338 g_log_set_handler ("Glib", flags, log_handler, NULL);
339 g_log_set_handler ("Gtk", flags, log_handler, NULL);
340 g_log_set_handler ("Gnome", flags, log_handler, NULL);
341 g_log_set_default_handler (log_handler, NULL);
342 g_set_printerr_handler (printerr_handler);
343 }
344
345 #ifdef WITH_DEBUG
346
347 static void
dump_diagnostics(void)348 dump_diagnostics (void)
349 {
350 egg_secure_rec *records;
351 egg_secure_rec *rec;
352 unsigned int count, i;
353 GHashTable *table;
354 GHashTableIter iter;
355 gsize request = 0;
356 gsize block = 0;
357
358 g_printerr ("------------------- Secure Memory --------------------\n");
359 g_printerr (" Tag Used Space\n");
360 g_printerr ("------------------------------------------------------\n");
361
362 records = egg_secure_records (&count);
363 table = g_hash_table_new (g_str_hash, g_str_equal);
364 for (i = 0; i < count; i++) {
365 if (!records[i].tag)
366 records[i].tag = "<unused>";
367 rec = g_hash_table_lookup (table, records[i].tag);
368 if (rec == NULL)
369 g_hash_table_insert (table, (gchar *)records[i].tag, &records[i]);
370 else {
371 rec->block_length += records[i].block_length;
372 rec->request_length += records[i].request_length;
373 }
374 block += records[i].block_length;
375 request += records[i].request_length;
376 }
377
378 g_hash_table_iter_init (&iter, table);
379 while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&rec))
380 g_printerr (" %-20s %12lu %16lu\n", rec->tag,
381 (unsigned long)rec->request_length,
382 (unsigned long)rec->block_length);
383
384 if (count > 0)
385 g_printerr ("------------------------------------------------------\n");
386
387 g_printerr (" %-20s %12lu %16lu\n", "Total",
388 (unsigned long)request, (unsigned long)block);
389 g_printerr ("------------------------------------------------------\n");
390
391 g_hash_table_destroy (table);
392 free (records);
393 }
394
395 #endif /* WITH_DEBUG */
396
397 /* -----------------------------------------------------------------------------
398 * SIGNALS
399 */
400
401 void
gkd_main_quit(void)402 gkd_main_quit (void)
403 {
404 /* Always stop accepting control connections immediately */
405 gkd_control_stop ();
406 g_main_loop_quit (loop);
407 }
408
409 static gboolean
on_signal_term(gpointer user_data)410 on_signal_term (gpointer user_data)
411 {
412 gkd_main_quit ();
413 g_debug ("received signal, terminating");
414 return FALSE;
415 }
416
417 static gboolean
on_signal_usr1(gpointer user_data)418 on_signal_usr1 (gpointer user_data)
419 {
420 #ifdef WITH_DEBUG
421 dump_diagnostics ();
422 #endif
423 return TRUE;
424 }
425
426 /* -----------------------------------------------------------------------------
427 * STARTUP
428 */
429
430 static int
sane_dup2(int fd1,int fd2)431 sane_dup2 (int fd1, int fd2)
432 {
433 int ret;
434
435 retry:
436 ret = dup2 (fd1, fd2);
437 if (ret < 0 && errno == EINTR)
438 goto retry;
439
440 return ret;
441 }
442
443 static gchar*
read_login_password(int fd)444 read_login_password (int fd)
445 {
446 /* We only accept a max of 8K as the login password */
447 #define MAX_LENGTH 8192
448 #define MAX_BLOCK 256
449
450 /*
451 * When --login is specified then the login password is passed
452 * in on stdin. All data (including newlines) are part of the
453 * password. A zero length password is no password.
454 */
455
456 gchar *buf = egg_secure_alloc (MAX_BLOCK);
457 gchar *ret = NULL;
458 int r, len = 0;
459
460 for (;;) {
461 r = read (fd, buf, MAX_BLOCK);
462 if (r < 0) {
463 if (errno == EAGAIN)
464 continue;
465 egg_secure_free (ret);
466 egg_secure_free (buf);
467 return NULL;
468
469 } else if (r == 0 || len > MAX_LENGTH) {
470 break;
471
472 } else {
473 ret = egg_secure_realloc (ret, len + r + 1);
474 memset (ret + len, 0, r + 1);
475 len = len + r;
476 strncat (ret, buf, r);
477 }
478 }
479
480 egg_secure_free (buf);
481 return ret;
482 }
483
484 static void
cleanup_and_exit(int code)485 cleanup_and_exit (int code)
486 {
487 egg_cleanup_perform ();
488 exit (code);
489 }
490
491 static void
clear_login_password(void)492 clear_login_password (void)
493 {
494 if(login_password)
495 egg_secure_strfree (login_password);
496 login_password = NULL;
497 }
498
499 static void
print_environment(void)500 print_environment (void)
501 {
502 const gchar **env;
503 for (env = gkd_util_get_environment (); *env; ++env)
504 printf ("%s\n", *env);
505 fflush (stdout);
506 }
507
508 static gboolean
initialize_daemon_at(const gchar * directory)509 initialize_daemon_at (const gchar *directory)
510 {
511 gchar **ourenv, **daemonenv, **e;
512
513 /* Exchange environment variables, and try to initialize daemon */
514 ourenv = gkd_util_build_environment (GKD_UTIL_IN_ENVIRONMENT);
515 daemonenv = gkd_control_initialize (directory, run_components,
516 (const gchar**)ourenv);
517 g_strfreev (ourenv);
518
519 /* Initialization failed, start this process up as a daemon */
520 if (!daemonenv)
521 return FALSE;
522
523 /* Setup all the environment variables we were passed */
524 for (e = daemonenv; *e; ++e)
525 gkd_util_push_environment_full (*e);
526 g_strfreev (daemonenv);
527
528 return TRUE;
529 }
530
531 static gboolean
replace_daemon_at(const gchar * directory)532 replace_daemon_at (const gchar *directory)
533 {
534 gboolean ret;
535
536 /*
537 * The first control_directory is the environment one, always
538 * prefer that since it's the one that ssh will connect to
539 */
540 if (control_directory == NULL)
541 control_directory = g_strdup (directory);
542
543 ret = gkd_control_quit (directory, GKD_CONTROL_QUIET_IF_NO_PEER);
544
545 /*
546 * If we quit, wait a short time before initializing so the other
547 * daemon can quit completely
548 */
549 if (ret == TRUE)
550 g_usleep (200 * 1000); /* 200 ms in us */
551
552 /*
553 * Note that we don't return TRUE, since we want to quit all the
554 * running daemons (for this session) that may have been started
555 * by dbus or elsewhere.
556 */
557
558 return FALSE;
559 }
560
561 typedef gboolean (*DiscoverFunc) (const gchar *control_directory);
562
563 static gboolean
discover_other_daemon(DiscoverFunc callback,gboolean acquire)564 discover_other_daemon (DiscoverFunc callback, gboolean acquire)
565 {
566 const gchar *control_env;
567 gchar *control = NULL;
568 gboolean acquired = FALSE;
569 gboolean ret;
570
571 /* A pre-specified directory to control at, don't try anything else */
572 if (control_directory)
573 return (callback) (control_directory);
574
575 /* An environment variable from an already running daemon */
576 control_env = g_getenv (GKD_UTIL_ENV_CONTROL);
577 if (control_env && control_env[0]) {
578 if ((callback)(control_env))
579 return TRUE;
580 }
581
582 /* Or the default location when no evironment variable */
583 control_env = g_getenv ("XDG_RUNTIME_DIR");
584 if (control_env) {
585 control = g_build_filename (control_env, "keyring", NULL);
586 ret = (callback) (control);
587 g_free (control);
588 if (ret == TRUE)
589 return TRUE;
590 }
591
592 /* See if we can contact a daemon running, that didn't set an env variable */
593 if (acquire && !gkd_dbus_singleton_acquire (&acquired))
594 return FALSE;
595
596 /* We're the main daemon */
597 if (acquired)
598 return FALSE;
599
600 control = gkd_dbus_singleton_control ();
601 if (control) {
602 ret = (callback) (control);
603 g_free (control);
604 if (ret == TRUE)
605 return TRUE;
606 }
607
608 return FALSE;
609 }
610
611 static void
redirect_fds_after_fork(void)612 redirect_fds_after_fork (void)
613 {
614 int fd, i;
615
616 for (i = 0; i < 3; ++i) {
617 fd = open ("/dev/null", O_RDONLY);
618 sane_dup2 (fd, i);
619 close (fd);
620 }
621 }
622
623 static void
block_on_fd(int fd)624 block_on_fd (int fd)
625 {
626 unsigned char dummy;
627 read (fd, &dummy, 1);
628 }
629
630 static int
fork_and_print_environment(void)631 fork_and_print_environment (void)
632 {
633 int status;
634 pid_t pid;
635 int wakeup_fds[2] = { -1, -1 };
636
637 if (run_foreground) {
638 return -1;
639 }
640
641 if (!g_unix_open_pipe (wakeup_fds, FD_CLOEXEC, NULL))
642 exit (1);
643
644 pid = fork ();
645
646 if (pid != 0) {
647 /* Here we are in the initial process */
648 close (wakeup_fds[1]);
649
650 if (run_daemonized) {
651
652 /* Initial process, waits for intermediate child */
653 if (pid == -1)
654 exit (1);
655
656 waitpid (pid, &status, 0);
657 if (WEXITSTATUS (status) != 0)
658 exit (WEXITSTATUS (status));
659
660 } else {
661 /* Not double forking, wait for child */
662 block_on_fd (wakeup_fds[0]);
663 }
664
665 /* The initial process exits successfully */
666 exit (0);
667 }
668
669 if (run_daemonized) {
670
671 /*
672 * Become session leader of a new session, process group leader of a new
673 * process group, and detach from the controlling TTY, so that SIGHUP is
674 * not sent to this process when the previous session leader dies
675 */
676 setsid ();
677
678 /* Double fork if need to daemonize properly */
679 pid = fork ();
680
681 if (pid != 0) {
682 close (wakeup_fds[1]);
683
684 /* Here we are in the intermediate child process */
685
686 /*
687 * This process exits, so that the final child will inherit
688 * init as parent to avoid zombies
689 */
690 if (pid == -1)
691 exit (1);
692
693 /* We've done two forks. */
694 block_on_fd (wakeup_fds[0]);
695
696 /* The intermediate child exits */
697 exit (0);
698 }
699
700 }
701
702 /* Here we are in the resulting daemon or background process. */
703 return wakeup_fds[1];
704 }
705
706 static gboolean
gkr_daemon_startup_steps(const gchar * components)707 gkr_daemon_startup_steps (const gchar *components)
708 {
709 g_assert (components);
710
711 /*
712 * Startup that must run before forking.
713 * Note that we set initialized flags early so that two
714 * initializations don't overlap
715 */
716
717 #ifdef WITH_SSH
718 if (strstr (components, GKD_COMP_SSH)) {
719 if (ssh_started) {
720 g_message ("The SSH agent was already initialized");
721 } else {
722 ssh_started = TRUE;
723 if (!gkd_daemon_startup_ssh ()) {
724 ssh_started = FALSE;
725 return FALSE;
726 }
727 }
728 }
729 #endif
730
731 return TRUE;
732 }
733
734 static gboolean
gkr_daemon_initialize_steps(const gchar * components)735 gkr_daemon_initialize_steps (const gchar *components)
736 {
737 g_assert (components);
738
739 /*
740 * Startup that can run after forking.
741 * Note that we set initialized flags early so that two
742 * initializations don't overlap
743 */
744
745 if (!initialization_completed) {
746
747 /* The LANG environment variable may have changed */
748 setlocale (LC_ALL, "");
749
750 initialization_completed = TRUE;
751 if (timeout_id)
752 g_source_remove (timeout_id);
753
754 /* Initialize new style PKCS#11 components */
755 if (!gkd_pkcs11_initialize ())
756 return FALSE;
757
758 /*
759 * Unlock the login keyring if we were given a password on STDIN.
760 * If it does not exist. We create it.
761 */
762 if (login_password) {
763 if (!gkd_login_unlock (login_password))
764 g_message ("failed to unlock login keyring on startup");
765 egg_secure_strclear (login_password);
766 }
767
768 dbus_started = TRUE;
769 if (!gkd_dbus_setup ())
770 dbus_started = FALSE;
771 }
772
773 /* The Secret Service API */
774 if (strstr (components, GKD_COMP_SECRETS) || strstr (components, GKD_COMP_KEYRING)) {
775 if (secrets_started) {
776 g_message ("The Secret Service was already initialized");
777 } else {
778 if (!dbus_started) {
779 dbus_started = TRUE;
780 if (!gkd_dbus_setup ())
781 dbus_started = FALSE;
782 }
783 if (dbus_started) {
784 secrets_started = TRUE;
785 if (!gkd_dbus_secrets_startup ()) {
786 secrets_started = FALSE;
787 return FALSE;
788 }
789 }
790 }
791 }
792
793 /* The PKCS#11 remoting */
794 if (strstr (components, GKD_COMP_PKCS11)) {
795 if (pkcs11_started) {
796 g_message ("The PKCS#11 component was already initialized");
797 } else {
798 pkcs11_started = TRUE;
799 if (!gkd_pkcs11_startup_pkcs11 ()) {
800 pkcs11_started = FALSE;
801 return FALSE;
802 }
803 }
804 }
805
806 return TRUE;
807 }
808
809 void
gkd_main_complete_initialization(const gchar * components)810 gkd_main_complete_initialization (const gchar *components)
811 {
812 g_assert (components);
813
814 /*
815 * Sometimes we don't initialize the full daemon right on
816 * startup. When run with --login is one such case.
817 */
818
819 gkr_daemon_startup_steps (components);
820 gkr_daemon_initialize_steps (components);
821 }
822
823 static gboolean
on_login_timeout(gpointer data)824 on_login_timeout (gpointer data)
825 {
826 if (!initialization_completed)
827 cleanup_and_exit (0);
828 return FALSE;
829 }
830
831 static void
on_vanished_quit_loop(GDBusConnection * connection,const gchar * name,gpointer user_data)832 on_vanished_quit_loop (GDBusConnection *connection,
833 const gchar *name,
834 gpointer user_data)
835 {
836 g_main_loop_quit (user_data);
837 }
838
on_logind_session_property_get(GObject * connection,GAsyncResult * res,gpointer user_data G_GNUC_UNUSED)839 static void on_logind_session_property_get (GObject *connection,
840 GAsyncResult *res,
841 gpointer user_data G_GNUC_UNUSED)
842 {
843 GError *error = NULL;
844 GVariant *result, *resultv;
845 const gchar *state;
846 gboolean should_quit;
847
848 result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (connection), res, &error);
849
850 if (error) {
851 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
852 g_critical ("%s Couldn't get session state: %s", G_STRLOC, error->message);
853 g_error_free (error);
854 return;
855 }
856
857 g_variant_get (result, "(v)", &resultv, NULL);
858 state = g_variant_get_string (resultv, NULL);
859
860 should_quit = g_strcmp0 (state, "closing") == 0;
861
862 g_clear_pointer (&result, g_variant_unref);
863 g_clear_pointer (&resultv, g_variant_unref);
864
865 /* yes, the session is closing, so we'll quit now */
866 if (should_quit)
867 cleanup_and_exit (0);
868 }
869
on_logind_session_properties_changed(GDBusConnection * connection,const gchar * sender_name G_GNUC_UNUSED,const gchar * object_path,const gchar * interface_name G_GNUC_UNUSED,const gchar * signal_name G_GNUC_UNUSED,GVariant * parameters,gpointer user_data G_GNUC_UNUSED)870 static void on_logind_session_properties_changed (GDBusConnection *connection,
871 const gchar *sender_name G_GNUC_UNUSED,
872 const gchar *object_path,
873 const gchar *interface_name G_GNUC_UNUSED,
874 const gchar *signal_name G_GNUC_UNUSED,
875 GVariant *parameters,
876 gpointer user_data G_GNUC_UNUSED)
877 {
878 const gchar *prop_iface;
879 gboolean active;
880 GVariant* changed_properties;
881
882 g_variant_get (parameters, "(&s@a{sv}^as)", &prop_iface, &changed_properties, NULL);
883
884 if (g_variant_lookup (changed_properties, "Active", "b", &active, NULL)) {
885 if (!active) {
886 /* ok, the session went inactive, let's see if that is because
887 * it is closing */
888 g_dbus_connection_call (
889 connection,
890 "org.freedesktop.login1",
891 object_path,
892 "org.freedesktop.DBus.Properties",
893 "Get",
894 g_variant_new ("(ss)", prop_iface, "State"),
895 G_VARIANT_TYPE ("(v)"),
896 G_DBUS_CALL_FLAGS_NONE,
897 -1,
898 NULL,
899 on_logind_session_property_get,
900 NULL
901 );
902 }
903 }
904
905 g_variant_unref (changed_properties);
906 }
907
908 static void
on_logind_object_path_get(GObject * connection,GAsyncResult * res,gpointer user_data G_GNUC_UNUSED)909 on_logind_object_path_get (GObject *connection,
910 GAsyncResult *res,
911 gpointer user_data G_GNUC_UNUSED)
912 {
913 GError *error = NULL;
914 GVariant *result;
915 const gchar *object_path;
916 gchar *remote_error;
917 gboolean is_cancelled, is_name_has_no_owner;
918
919 result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (connection), res, &error);
920
921 /* If there's an error we always want to quit - but we only tell the
922 * user about it if something went wrong. Cancelling the operation or
923 * not having logind available are okay. */
924 if (error) {
925 is_cancelled = g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
926
927 remote_error = g_dbus_error_get_remote_error (error);
928 is_name_has_no_owner = g_strcmp0 (remote_error, "org.freedesktop.DBus.Error.NameHasNoOwner") == 0;
929
930 if (!is_cancelled && !is_name_has_no_owner)
931 g_critical ("%s Couldn't get object path: %s", G_STRLOC, error->message);
932
933 g_free (remote_error);
934 g_error_free (error);
935 return;
936 }
937
938 /* now we know which object path to look on, watch for
939 * PropertiesChanged. Note that, per logind's documentation, we only
940 * get notified for 'Active' changing */
941 g_variant_get (result, "(&o)", &object_path, NULL);
942
943 g_dbus_connection_signal_subscribe (
944 G_DBUS_CONNECTION (connection),
945 "org.freedesktop.login1",
946 "org.freedesktop.DBus.Properties",
947 "PropertiesChanged",
948 object_path,
949 NULL,
950 G_DBUS_SIGNAL_FLAGS_NONE,
951 on_logind_session_properties_changed,
952 NULL,
953 NULL
954 );
955
956 g_clear_pointer (&result, g_variant_unref);
957 }
958
959 static void
start_watching_logind_for_session_closure()960 start_watching_logind_for_session_closure ()
961 {
962 g_return_if_fail (system_bus_connection != NULL);
963
964 const gchar *xdg_session_id;
965
966 xdg_session_id = g_getenv ("XDG_SESSION_ID");
967
968 if (!xdg_session_id)
969 return;
970
971 /* get the right object path */
972 g_dbus_connection_call (
973 system_bus_connection,
974 "org.freedesktop.login1",
975 "/org/freedesktop/login1",
976 "org.freedesktop.login1.Manager",
977 "GetSession",
978 g_variant_new ("(s)", xdg_session_id, NULL),
979 G_VARIANT_TYPE ("(o)"),
980 G_DBUS_CALL_FLAGS_NO_AUTO_START,
981 -1,
982 NULL,
983 on_logind_object_path_get,
984 NULL
985 );
986 }
987
988 int
main(int argc,char * argv[])989 main (int argc, char *argv[])
990 {
991 /*
992 * The gnome-keyring startup is not as simple as I wish it could be.
993 *
994 * It's often started in the primordial stages of a session, where
995 * there's no DBus, and no proper X display. This is the strange world
996 * of PAM.
997 *
998 * When started with the --login option, we do as little initialization
999 * as possible. We expect a login password on the stdin, and unlock
1000 * or create the login keyring.
1001 *
1002 * Then later we expect gnome-keyring-dameon to be run again with the
1003 * --start option. This second gnome-keyring-daemon will hook the
1004 * original daemon up with environment variables necessary to initialize
1005 * itself and bring it into the session. This second daemon usually exits.
1006 *
1007 * Without either of these options, we follow a more boring and
1008 * predictable startup.
1009 */
1010
1011 GDBusConnection *connection = NULL;
1012 GError *error = NULL;
1013
1014 /*
1015 * Before we do ANYTHING, we drop privileges so we don't become
1016 * a security issue ourselves.
1017 */
1018 gkd_capability_obtain_capability_and_drop_privileges ();
1019
1020 #ifdef WITH_STRICT
1021 g_setenv ("DBUS_FATAL_WARNINGS", "1", FALSE);
1022 if (!g_getenv ("G_DEBUG"))
1023 g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
1024 #endif
1025
1026 #if !GLIB_CHECK_VERSION(2,35,0)
1027 g_type_init ();
1028 #endif
1029
1030 /* internationalisation */
1031 setlocale (LC_ALL, "");
1032
1033 #ifdef HAVE_GETTEXT
1034 bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
1035 textdomain (GETTEXT_PACKAGE);
1036 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1037 #endif
1038
1039 egg_libgcrypt_initialize ();
1040
1041 /* Send all warning or error messages to syslog */
1042 prepare_logging ();
1043
1044 parse_arguments (&argc, &argv);
1045
1046 /* The --version option. This is machine parseable output */
1047 if (run_version) {
1048 g_print ("gnome-keyring-daemon: %s\n", VERSION);
1049 g_print ("testing: %s\n",
1050 #ifdef WITH_DEBUG
1051 "enabled");
1052 #else
1053 "disabled");
1054 #endif
1055 exit (0);
1056 }
1057
1058 if (perform_unlock) {
1059 login_password = read_login_password (STDIN);
1060 atexit (clear_login_password);
1061 }
1062
1063 /* The whole forking and daemonizing dance starts here. */
1064 parent_wakeup_fd = fork_and_print_environment();
1065
1066 /* The --start option */
1067 if (run_for_start) {
1068 if (discover_other_daemon (initialize_daemon_at, TRUE)) {
1069 /*
1070 * Another daemon was initialized, print out environment,
1071 * tell parent we're done, and quit or go comatose.
1072 */
1073 print_environment ();
1074 close (parent_wakeup_fd);
1075 if (run_foreground) {
1076 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
1077 if (error) {
1078 g_warning ("Couldn't connect to session bus: %s", error->message);
1079 g_clear_error (&error);
1080 }
1081 loop = g_main_loop_new (NULL, FALSE);
1082 g_bus_watch_name (G_BUS_TYPE_SESSION, "org.gnome.keyring",
1083 G_BUS_NAME_WATCHER_FLAGS_NONE,
1084 NULL, on_vanished_quit_loop, loop, NULL);
1085 g_main_loop_run (loop);
1086 g_clear_pointer (&loop, g_main_loop_unref);
1087 g_clear_object (&connection);
1088 }
1089 cleanup_and_exit (0);
1090 }
1091
1092 /* The --replace option */
1093 } else if (run_for_replace) {
1094 discover_other_daemon (replace_daemon_at, FALSE);
1095 if (control_directory)
1096 g_message ("Replacing daemon, using directory: %s", control_directory);
1097 else
1098 g_message ("Could not find daemon to replace, staring normally");
1099 }
1100
1101 /* Initialize the main directory */
1102 gkd_util_init_master_directory (control_directory);
1103
1104 /* Initialize our daemon main loop and threading */
1105 loop = g_main_loop_new (NULL, FALSE);
1106
1107 /* Initialize our control socket */
1108 if (!gkd_control_listen ())
1109 return FALSE;
1110
1111 /* The --login option. Delayed initialization */
1112 if (run_for_login) {
1113 timeout_id = g_timeout_add_seconds (LOGIN_TIMEOUT, (GSourceFunc) on_login_timeout, NULL);
1114
1115 /* Not a login daemon. Startup stuff now.*/
1116 } else {
1117 /* These are things that can run before forking */
1118 if (!gkr_daemon_startup_steps (run_components))
1119 cleanup_and_exit (1);
1120 }
1121
1122 /* if we can get a connection to the system bus, watch it and then kill
1123 * ourselves when our session closes */
1124
1125 system_bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
1126
1127 if (system_bus_connection)
1128 start_watching_logind_for_session_closure ();
1129
1130 signal (SIGPIPE, SIG_IGN);
1131
1132 /* Print the environment and tell the parent we're done */
1133 print_environment ();
1134
1135 if (!run_foreground) {
1136 close (parent_wakeup_fd);
1137 redirect_fds_after_fork ();
1138 }
1139
1140 g_unix_signal_add (SIGTERM, on_signal_term, loop);
1141 g_unix_signal_add (SIGHUP, on_signal_term, loop);
1142 g_unix_signal_add (SIGUSR1, on_signal_usr1, loop);
1143
1144 /* Prepare logging a second time, since we may be in a different process */
1145 prepare_logging();
1146
1147 /* Remainder initialization after forking, if initialization not delayed */
1148 if (!run_for_login) {
1149 gkr_daemon_initialize_steps (run_components);
1150
1151 /*
1152 * Close stdout and so that the caller knows that we're
1153 * all initialized, (when run in foreground mode).
1154 *
1155 * However since some logging goes to stdout, redirect that
1156 * to stderr. We don't want the caller confusing that with
1157 * valid output anyway.
1158 */
1159 if (dup2 (2, 1) < 1)
1160 g_warning ("couldn't redirect stdout to stderr");
1161
1162 g_debug ("initialization complete");
1163 }
1164
1165 g_main_loop_run (loop);
1166
1167 /* This wraps everything up in order */
1168 egg_cleanup_perform ();
1169
1170 g_free (control_directory);
1171
1172 g_debug ("exiting cleanly");
1173 return 0;
1174 }
1175