Line data Source code
1 : /* keybox-init.c - Initalization of the library
2 : * Copyright (C) 2001 Free Software Foundation, Inc.
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * GnuPG 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
14 : * GNU 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, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdlib.h>
22 : #include <stdio.h>
23 : #include <string.h>
24 : #include <unistd.h>
25 : #include <assert.h>
26 :
27 : #include "../common/mischelp.h"
28 : #include "keybox-defs.h"
29 :
30 : static KB_NAME kb_names;
31 :
32 :
33 : /* Register a filename for plain keybox files. Returns a pointer to
34 : be used to create a handles and so on. Returns NULL to indicate
35 : that FNAME has already been registered. */
36 : void *
37 1260 : keybox_register_file (const char *fname, int secret)
38 : {
39 : KB_NAME kr;
40 :
41 1260 : for (kr=kb_names; kr; kr = kr->next)
42 : {
43 0 : if (same_file_p (kr->fname, fname) )
44 0 : return NULL; /* Already registered. */
45 : }
46 :
47 1260 : kr = xtrymalloc (sizeof *kr + strlen (fname));
48 1260 : if (!kr)
49 0 : return NULL;
50 1260 : strcpy (kr->fname, fname);
51 1260 : kr->secret = !!secret;
52 :
53 1260 : kr->handle_table = NULL;
54 1260 : kr->handle_table_size = 0;
55 :
56 : /* kr->lockhd = NULL;*/
57 1260 : kr->is_locked = 0;
58 1260 : kr->did_full_scan = 0;
59 : /* keep a list of all issued pointers */
60 1260 : kr->next = kb_names;
61 1260 : kb_names = kr;
62 :
63 : /* create the offset table the first time a function here is used */
64 : /* if (!kb_offtbl) */
65 : /* kb_offtbl = new_offset_hash_table (); */
66 :
67 1260 : return kr;
68 : }
69 :
70 : int
71 62 : keybox_is_writable (void *token)
72 : {
73 62 : KB_NAME r = token;
74 :
75 62 : return r? !access (r->fname, W_OK) : 0;
76 : }
77 :
78 :
79 :
80 : static KEYBOX_HANDLE
81 2594 : do_keybox_new (KB_NAME resource, int secret, int for_openpgp)
82 : {
83 : KEYBOX_HANDLE hd;
84 : int idx;
85 :
86 2594 : assert (resource && !resource->secret == !secret);
87 2594 : hd = xtrycalloc (1, sizeof *hd);
88 2594 : if (hd)
89 : {
90 2594 : hd->kb = resource;
91 2594 : hd->secret = !!secret;
92 2594 : hd->for_openpgp = for_openpgp;
93 2594 : if (!resource->handle_table)
94 : {
95 820 : resource->handle_table_size = 3;
96 820 : resource->handle_table = xtrycalloc (resource->handle_table_size,
97 : sizeof *resource->handle_table);
98 820 : if (!resource->handle_table)
99 : {
100 0 : resource->handle_table_size = 0;
101 0 : xfree (hd);
102 0 : return NULL;
103 : }
104 : }
105 2877 : for (idx=0; idx < resource->handle_table_size; idx++)
106 2877 : if (!resource->handle_table[idx])
107 : {
108 2594 : resource->handle_table[idx] = hd;
109 2594 : break;
110 : }
111 2594 : if (!(idx < resource->handle_table_size))
112 : {
113 : KEYBOX_HANDLE *tmptbl;
114 : size_t newsize;
115 :
116 0 : newsize = resource->handle_table_size + 5;
117 0 : tmptbl = xtryrealloc (resource->handle_table,
118 : newsize * sizeof (*tmptbl));
119 0 : if (!tmptbl)
120 : {
121 0 : xfree (hd);
122 0 : return NULL;
123 : }
124 0 : resource->handle_table = tmptbl;
125 0 : resource->handle_table_size = newsize;
126 0 : resource->handle_table[idx] = hd;
127 0 : for (idx++; idx < resource->handle_table_size; idx++)
128 0 : resource->handle_table[idx] = NULL;
129 : }
130 : }
131 2594 : return hd;
132 : }
133 :
134 :
135 : /* Create a new handle for the resource associated with TOKEN. SECRET
136 : is just a cross-check. This is the OpenPGP version. The returned
137 : handle must be released using keybox_release. */
138 : KEYBOX_HANDLE
139 2582 : keybox_new_openpgp (void *token, int secret)
140 : {
141 2582 : KB_NAME resource = token;
142 :
143 2582 : return do_keybox_new (resource, secret, 1);
144 : }
145 :
146 : /* Create a new handle for the resource associated with TOKEN. SECRET
147 : is just a cross-check. This is the X.509 version. The returned
148 : handle must be released using keybox_release. */
149 : KEYBOX_HANDLE
150 12 : keybox_new_x509 (void *token, int secret)
151 : {
152 12 : KB_NAME resource = token;
153 :
154 12 : return do_keybox_new (resource, secret, 0);
155 : }
156 :
157 :
158 : void
159 2592 : keybox_release (KEYBOX_HANDLE hd)
160 : {
161 2592 : if (!hd)
162 2592 : return;
163 2592 : if (hd->kb->handle_table)
164 : {
165 : int idx;
166 10368 : for (idx=0; idx < hd->kb->handle_table_size; idx++)
167 7776 : if (hd->kb->handle_table[idx] == hd)
168 2592 : hd->kb->handle_table[idx] = NULL;
169 : }
170 2592 : _keybox_release_blob (hd->found.blob);
171 2592 : _keybox_release_blob (hd->saved_found.blob);
172 2592 : if (hd->fp)
173 : {
174 2515 : fclose (hd->fp);
175 2515 : hd->fp = NULL;
176 : }
177 2592 : xfree (hd->word_match.name);
178 2592 : xfree (hd->word_match.pattern);
179 2592 : xfree (hd);
180 : }
181 :
182 :
183 : /* Save the current found state in HD for later retrieval by
184 : keybox_restore_found_state. Only one state may be saved. */
185 : void
186 0 : keybox_push_found_state (KEYBOX_HANDLE hd)
187 : {
188 0 : if (hd->saved_found.blob)
189 : {
190 0 : _keybox_release_blob (hd->saved_found.blob);
191 0 : hd->saved_found.blob = NULL;
192 : }
193 0 : hd->saved_found = hd->found;
194 0 : hd->found.blob = NULL;
195 0 : }
196 :
197 :
198 : /* Restore the saved found state in HD. */
199 : void
200 0 : keybox_pop_found_state (KEYBOX_HANDLE hd)
201 : {
202 0 : if (hd->found.blob)
203 : {
204 0 : _keybox_release_blob (hd->found.blob);
205 0 : hd->found.blob = NULL;
206 : }
207 0 : hd->found = hd->saved_found;
208 0 : hd->saved_found.blob = NULL;
209 0 : }
210 :
211 :
212 : const char *
213 0 : keybox_get_resource_name (KEYBOX_HANDLE hd)
214 : {
215 0 : if (!hd || !hd->kb)
216 0 : return NULL;
217 0 : return hd->kb->fname;
218 : }
219 :
220 : int
221 6 : keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes)
222 : {
223 6 : if (!hd)
224 0 : return gpg_error (GPG_ERR_INV_HANDLE);
225 6 : hd->ephemeral = yes;
226 6 : return 0;
227 : }
228 :
229 :
230 : /* Close the file of the resource identified by HD. For consistent
231 : results this fucntion closes the files of all handles pointing to
232 : the resource identified by HD. */
233 : void
234 70 : _keybox_close_file (KEYBOX_HANDLE hd)
235 : {
236 : int idx;
237 : KEYBOX_HANDLE roverhd;
238 :
239 70 : if (!hd || !hd->kb || !hd->kb->handle_table)
240 70 : return;
241 :
242 280 : for (idx=0; idx < hd->kb->handle_table_size; idx++)
243 210 : if ((roverhd = hd->kb->handle_table[idx]))
244 : {
245 70 : if (roverhd->fp)
246 : {
247 5 : fclose (roverhd->fp);
248 5 : roverhd->fp = NULL;
249 : }
250 : }
251 70 : assert (!hd->fp);
252 : }
253 :
254 :
255 : /*
256 : * Lock the keybox at handle HD, or unlock if YES is false. Note that
257 : * we currently ignore the handle and lock all registered keyboxes.
258 : */
259 : int
260 128 : keybox_lock (KEYBOX_HANDLE hd, int yes)
261 : {
262 : /* FIXME: We need to implement it before we can use it with gpg.
263 : gpgsm does the locking in its local keydb.c driver; this should
264 : be changed as well. */
265 :
266 : (void)hd;
267 : (void)yes;
268 128 : return 0;
269 : }
|