]> the.earth.li Git - onak.git/blob - keydb_file.c
Skip signature hash verification for X509 signatures
[onak.git] / keydb_file.c
1 /*
2  * keydb.c - Routines to store and fetch keys.
3  *
4  * Copyright 2002-2004 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 51
17  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <sys/types.h>
21 #include <sys/uio.h>
22 #include <dirent.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #include "charfuncs.h"
31 #include "keydb.h"
32 #include "keyid.h"
33 #include "keystructs.h"
34 #include "ll.h"
35 #include "log.h"
36 #include "mem.h"
37 #include "onak-conf.h"
38 #include "parsekey.h"
39
40 /**
41  *      initdb - Initialize the key database.
42  *
43  *      This is just a no-op for flat file access.
44  */
45 static void file_initdb(bool readonly)
46 {
47 }
48
49 /**
50  *      cleanupdb - De-initialize the key database.
51  *
52  *      This is just a no-op for flat file access.
53  */
54 static void file_cleanupdb(void)
55 {
56 }
57
58 /**
59  *      starttrans - Start a transaction.
60  *
61  *      This is just a no-op for flat file access.
62  */
63 static bool file_starttrans(void)
64 {
65         return true;
66 }
67
68 /**
69  *      endtrans - End a transaction.
70  *
71  *      This is just a no-op for flat file access.
72  */
73 static void file_endtrans(void)
74 {
75         return;
76 }
77
78 /**
79  *      fetch_key_id - Given a keyid fetch the key from storage.
80  *      @keyid: The keyid to fetch.
81  *      @publickey: A pointer to a structure to return the key in.
82  *      @intrans: If we're already in a transaction.
83  *
84  *      We use the hex representation of the keyid as the filename to fetch the
85  *      key from. The key is stored in the file as a binary OpenPGP stream of
86  *      packets, so we can just use read_openpgp_stream() to read the packets
87  *      in and then parse_keys() to parse the packets into a publickey
88  *      structure.
89  */
90 static int file_fetch_key_id(uint64_t keyid,
91                 struct openpgp_publickey **publickey,
92                 bool intrans)
93 {
94         struct openpgp_packet_list *packets = NULL;
95         char keyfile[1024];
96         int fd = -1;
97
98         snprintf(keyfile, 1023, "%s/0x%" PRIX64, config.db_dir,
99                         keyid & 0xFFFFFFFF);
100         fd = open(keyfile, O_RDONLY); // | O_SHLOCK);
101
102         if (fd > -1) {
103                 read_openpgp_stream(file_fetchchar, &fd, &packets, 0);
104                 parse_keys(packets, publickey);
105                 free_packet_list(packets);
106                 packets = NULL;
107                 close(fd);
108         }
109
110         return (fd > -1);
111 }
112
113 /**
114  *      store_key - Takes a key and stores it.
115  *      @publickey: A pointer to the public key to store.
116  *      @intrans: If we're already in a transaction.
117  *      @update: If true the key exists and should be updated.
118  *
119  *      Again we just use the hex representation of the keyid as the filename
120  *      to store the key to. We flatten the public key to a list of OpenPGP
121  *      packets and then use write_openpgp_stream() to write the stream out to
122  *      the file.
123  */
124 static int file_store_key(struct openpgp_publickey *publickey, bool intrans,
125                 bool update)
126 {
127         struct openpgp_packet_list *packets = NULL;
128         struct openpgp_packet_list *list_end = NULL;
129         struct openpgp_publickey *next = NULL;
130         char keyfile[1024];
131         int fd = -1;
132         uint64_t keyid;
133
134         if (get_keyid(publickey, &keyid) != ONAK_E_OK) {
135                 logthing(LOGTHING_ERROR, "Couldn't find key ID for key.");
136                 return 0;
137         }
138         snprintf(keyfile, 1023, "%s/0x%" PRIX64, config.db_dir,
139                         keyid & 0xFFFFFFFF);
140         fd = open(keyfile, O_WRONLY | O_CREAT, 0664); // | O_EXLOCK);
141
142         if (fd > -1) {
143                 next = publickey -> next;
144                 publickey -> next = NULL;
145                 flatten_publickey(publickey, &packets, &list_end);
146                 publickey -> next = next;
147                 
148                 write_openpgp_stream(file_putchar, &fd, packets);
149                 close(fd);
150                 free_packet_list(packets);
151                 packets = NULL;
152         }
153
154         return (fd > -1);
155 }
156
157 /**
158  *      delete_key - Given a keyid delete the key from storage.
159  *      @keyid: The keyid to delete.
160  *      @intrans: If we're already in a transaction.
161  *
162  *      This function deletes a public key from whatever storage mechanism we
163  *      are using. Returns 0 if the key existed.
164  */
165 static int file_delete_key(uint64_t keyid, bool intrans)
166 {
167         char keyfile[1024];
168
169         snprintf(keyfile, 1023, "%s/0x%" PRIX64, config.db_dir,
170                         keyid & 0xFFFFFFFF);
171
172         return unlink(keyfile);
173 }
174
175 /**
176  *      fetch_key_text - Trys to find the keys that contain the supplied text.
177  *      @search: The text to search for.
178  *      @publickey: A pointer to a structure to return the key in.
179  *
180  *      This function searches for the supplied text and returns the keys that
181  *      contain it.
182  *
183  *      TODO: Write for flat file access. Some sort of grep?
184  */
185 static int file_fetch_key_text(const char *search,
186                 struct openpgp_publickey **publickey)
187 {
188         return 0;
189 }
190
191 /**
192  *      iterate_keys - call a function once for each key in the db.
193  *      @iterfunc: The function to call.
194  *      @ctx: A context pointer
195  *
196  *      Calls iterfunc once for each key in the database. ctx is passed
197  *      unaltered to iterfunc. This function is intended to aid database dumps
198  *      and statistic calculations.
199  *
200  *      Returns the number of keys we iterated over.
201  */
202 static int file_iterate_keys(void (*iterfunc)(void *ctx,
203                 struct openpgp_publickey *key), void *ctx)
204 {
205         int                         numkeys = 0;
206         struct openpgp_packet_list *packets = NULL;
207         struct openpgp_publickey   *key = NULL;
208         DIR                        *dir;
209         char                        keyfile[1024];
210         int                         fd = -1;
211         struct dirent              *curfile = NULL;
212
213         dir = opendir(config.db_dir);
214
215         if (dir != NULL) {
216                 while ((curfile = readdir(dir)) != NULL) {
217                         if (curfile->d_name[0] == '0' &&
218                                         curfile->d_name[1] == 'x') {
219                                 snprintf(keyfile, 1023, "%s/%s",
220                                                 config.db_dir,
221                                                 curfile->d_name);
222                                 fd = open(keyfile, O_RDONLY);
223
224                                 if (fd > -1) {
225                                         read_openpgp_stream(file_fetchchar,
226                                                         &fd,
227                                                         &packets,
228                                                         0);
229                                         parse_keys(packets, &key);
230
231                                         iterfunc(ctx, key);
232
233                                         free_publickey(key);
234                                         key = NULL;
235                                         free_packet_list(packets);
236                                         packets = NULL;
237                                         close(fd);
238                                 }
239                                 numkeys++;
240                         }
241                 }
242                 
243                 closedir(dir);
244                 dir = NULL;
245         }
246
247         return numkeys;
248 }
249
250 /*
251  * Include the basic keydb routines.
252  */
253 #define NEED_KEYID2UID 1
254 #define NEED_GETKEYSIGS 1
255 #define NEED_GETFULLKEYID 1
256 #define NEED_UPDATEKEYS 1
257 #define NEED_GET_FP 1
258 #include "keydb.c"
259
260 struct dbfuncs keydb_file_funcs = {
261         .initdb                 = file_initdb,
262         .cleanupdb              = file_cleanupdb,
263         .starttrans             = file_starttrans,
264         .endtrans               = file_endtrans,
265         .fetch_key_id           = file_fetch_key_id,
266         .fetch_key_fp           = generic_fetch_key_fp,
267         .fetch_key_text         = file_fetch_key_text,
268         .store_key              = file_store_key,
269         .update_keys            = generic_update_keys,
270         .delete_key             = file_delete_key,
271         .getkeysigs             = generic_getkeysigs,
272         .cached_getkeysigs      = generic_cached_getkeysigs,
273         .keyid2uid              = generic_keyid2uid,
274         .getfullkeyid           = generic_getfullkeyid,
275         .iterate_keys           = file_iterate_keys,
276 };