Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2008 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #include "gkd-util.h"
24 : #include "gkd-pkcs11.h"
25 :
26 : #include "egg/egg-cleanup.h"
27 :
28 : #include "pkcs11/wrap-layer/gkm-wrap-layer.h"
29 : #include "pkcs11/rpc-layer/gkm-rpc-layer.h"
30 : #include "pkcs11/secret-store/gkm-secret-store.h"
31 : #include "pkcs11/ssh-store/gkm-ssh-store.h"
32 : #include "pkcs11/gnome2-store/gkm-gnome2-store.h"
33 : #include "pkcs11/xdg-store/gkm-xdg-store.h"
34 :
35 : #include "ssh-agent/gkd-ssh-agent-service.h"
36 :
37 : #include <string.h>
38 :
39 : /* The top level of our internal PKCS#11 module stack */
40 : static CK_FUNCTION_LIST_PTR pkcs11_roof = NULL;
41 :
42 : /* The top level of our internal PKCS#11 module stack, but below prompting */
43 : static CK_FUNCTION_LIST_PTR pkcs11_base = NULL;
44 :
45 : static void
46 27 : pkcs11_daemon_cleanup (gpointer unused)
47 : {
48 : CK_RV rv;
49 :
50 27 : g_assert (pkcs11_roof);
51 :
52 27 : gkm_rpc_layer_uninitialize ();
53 27 : rv = (pkcs11_roof->C_Finalize) (NULL);
54 :
55 27 : if (rv != CKR_OK)
56 0 : g_warning ("couldn't finalize internal PKCS#11 stack (code: %d)", (gint)rv);
57 :
58 27 : pkcs11_roof = NULL;
59 27 : }
60 :
61 : gboolean
62 27 : gkd_pkcs11_initialize (void)
63 : {
64 : CK_FUNCTION_LIST_PTR secret_store;
65 : CK_FUNCTION_LIST_PTR ssh_store;
66 : CK_FUNCTION_LIST_PTR gnome2_store;
67 : CK_FUNCTION_LIST_PTR xdg_store;
68 : CK_C_INITIALIZE_ARGS init_args;
69 : CK_RV rv;
70 :
71 : /* Secrets */
72 27 : secret_store = gkm_secret_store_get_functions ();
73 :
74 : /* SSH storage */
75 27 : ssh_store = gkm_ssh_store_get_functions ();
76 :
77 : /* Old User certificates */
78 27 : gnome2_store = gkm_gnome2_store_get_functions ();
79 :
80 : /* User certificates */
81 27 : xdg_store = gkm_xdg_store_get_functions ();
82 :
83 : /* Add all of those into the wrapper layer */
84 27 : gkm_wrap_layer_add_module (ssh_store);
85 27 : gkm_wrap_layer_add_module (secret_store);
86 27 : gkm_wrap_layer_add_module (gnome2_store);
87 27 : gkm_wrap_layer_add_module (xdg_store);
88 :
89 27 : pkcs11_roof = gkm_wrap_layer_get_functions ();
90 27 : pkcs11_base = gkm_wrap_layer_get_functions_no_prompts ();
91 :
92 27 : memset (&init_args, 0, sizeof (init_args));
93 27 : init_args.flags = CKF_OS_LOCKING_OK;
94 :
95 : #if WITH_DEBUG
96 : {
97 27 : const gchar *path = g_getenv ("GNOME_KEYRING_TEST_PATH");
98 27 : if (path && path[0])
99 27 : init_args.pReserved = g_strdup_printf ("directory=\"%s\"", path);
100 : }
101 : #endif
102 :
103 : /* Initialize the whole caboodle */
104 27 : rv = (pkcs11_roof->C_Initialize) (&init_args);
105 27 : g_free (init_args.pReserved);
106 :
107 27 : if (rv != CKR_OK) {
108 0 : g_warning ("couldn't initialize internal PKCS#11 stack (code: %d)", (gint)rv);
109 0 : return FALSE;
110 : }
111 :
112 27 : egg_cleanup_register (pkcs11_daemon_cleanup, NULL);
113 :
114 27 : return gkm_rpc_layer_initialize (pkcs11_roof);
115 : }
116 :
117 : static void
118 11 : pkcs11_rpc_cleanup (gpointer unused)
119 : {
120 11 : gkm_rpc_layer_shutdown ();
121 11 : }
122 :
123 : static gboolean
124 2 : accept_rpc_client (GIOChannel *channel, GIOCondition cond, gpointer unused)
125 : {
126 2 : if (cond == G_IO_IN)
127 2 : gkm_rpc_layer_accept ();
128 :
129 2 : return TRUE;
130 : }
131 :
132 : gboolean
133 11 : gkd_pkcs11_startup_pkcs11 (void)
134 : {
135 : GIOChannel *channel;
136 : const gchar *base_dir;
137 : int sock;
138 :
139 11 : base_dir = gkd_util_get_master_directory ();
140 11 : g_return_val_if_fail (base_dir, FALSE);
141 :
142 11 : sock = gkm_rpc_layer_startup (base_dir);
143 11 : if (sock == -1)
144 0 : return FALSE;
145 :
146 11 : channel = g_io_channel_unix_new (sock);
147 11 : g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_rpc_client, NULL);
148 11 : g_io_channel_unref (channel);
149 :
150 11 : egg_cleanup_register (pkcs11_rpc_cleanup, NULL);
151 :
152 11 : return TRUE;
153 : }
154 :
155 : CK_FUNCTION_LIST_PTR
156 25 : gkd_pkcs11_get_functions (void)
157 : {
158 25 : return pkcs11_roof;
159 : }
160 :
161 : CK_FUNCTION_LIST_PTR
162 2 : gkd_pkcs11_get_base_functions (void)
163 : {
164 2 : return pkcs11_base;
165 : }
|