2 * keyd.c - key retrieval daemon
4 * Jonathan McDowell <noodles@earth.li>
6 * Copyright 2004 Project Purple
15 #include <sys/select.h>
16 #include <sys/socket.h>
17 #include <sys/types.h>
21 #include "charfuncs.h"
26 #include "keystructs.h"
29 #include "onak-conf.h"
39 logthing(LOGTHING_CRITICAL,
40 "Failed to fork into background: %d (%s)",
45 logthing(LOGTHING_INFO, "Backgrounded as pid %d.", pid);
51 freopen("/dev/null", "r", stdin);
52 freopen("/dev/null", "w", stdout);
53 freopen("/dev/null", "w", stderr);
58 void iteratefunc(void *ctx, struct openpgp_publickey *key)
60 struct openpgp_packet_list *packets = NULL;
61 struct openpgp_packet_list *list_end = NULL;
62 struct buffer_ctx storebuf;
64 int *fd = (int *) ctx;
69 storebuf.buffer = malloc(8192);
71 logthing(LOGTHING_TRACE,
72 "Iterating over 0x%016" PRIX64 ".",
75 flatten_publickey(key,
78 write_openpgp_stream(buffer_putchar,
81 logthing(LOGTHING_TRACE,
84 ret = write(*fd, &storebuf.offset,
85 sizeof(storebuf.offset));
87 write(*fd, storebuf.buffer,
91 free(storebuf.buffer);
92 storebuf.buffer = NULL;
93 storebuf.size = storebuf.offset = 0;
94 free_packet_list(packets);
95 packets = list_end = NULL;
101 int sock_init(const char *sockname)
103 struct sockaddr_un sock;
107 fd = socket(PF_UNIX, SOCK_STREAM, 0);
109 ret = fcntl(fd, F_SETFD, 1);
113 sock.sun_family = AF_UNIX;
114 strncpy(sock.sun_path, sockname, sizeof(sock.sun_path) - 1);
116 ret = bind(fd, (struct sockaddr *) &sock, sizeof(sock));
128 uint32_t cmd = KEYD_CMD_UNKNOWN;
134 struct openpgp_publickey *key = NULL;
135 struct openpgp_packet_list *packets = NULL;
136 struct openpgp_packet_list *list_end = NULL;
137 struct buffer_ctx storebuf;
140 * Get the command from the client.
142 bytes = read(fd, &cmd, sizeof(cmd));
144 logthing(LOGTHING_DEBUG, "Read %d bytes, command: %d", bytes, cmd);
146 if (bytes != sizeof(cmd)) {
152 case KEYD_CMD_VERSION:
154 write(fd, &cmd, sizeof(cmd));
155 cmd = sizeof(keyd_version);
156 write(fd, &cmd, sizeof(cmd));
157 write(fd, &keyd_version, sizeof(keyd_version));
161 write(fd, &cmd, sizeof(cmd));
162 bytes = read(fd, &keyid, sizeof(keyid));
163 if (bytes != sizeof(keyid)) {
168 logthing(LOGTHING_INFO,
169 "Fetching 0x%" PRIX64
173 fetch_key(keyid, &key, false));
175 storebuf.size = 8192;
176 storebuf.buffer = malloc(8192);
178 flatten_publickey(key,
181 write_openpgp_stream(buffer_putchar,
184 logthing(LOGTHING_TRACE,
187 write(fd, &storebuf.offset,
188 sizeof(storebuf.offset));
189 write(fd, storebuf.buffer,
192 free(storebuf.buffer);
193 storebuf.buffer = NULL;
194 storebuf.size = storebuf.offset = 0;
195 free_packet_list(packets);
196 packets = list_end = NULL;
200 write(fd, &storebuf.offset,
201 sizeof(storebuf.offset));
205 case KEYD_CMD_GETTEXT:
207 write(fd, &cmd, sizeof(cmd));
208 bytes = read(fd, &count, sizeof(count));
209 if (bytes != sizeof(count)) {
214 search = malloc(count+1);
215 read(fd, search, count);
217 logthing(LOGTHING_INFO,
218 "Fetching %s, result: %d",
221 fetch_key_text(search, &key));
223 storebuf.size = 8192;
224 storebuf.buffer = malloc(8192);
226 flatten_publickey(key,
229 write_openpgp_stream(buffer_putchar,
232 logthing(LOGTHING_TRACE,
235 write(fd, &storebuf.offset,
236 sizeof(storebuf.offset));
237 write(fd, storebuf.buffer,
240 free(storebuf.buffer);
241 storebuf.buffer = NULL;
242 storebuf.size = storebuf.offset = 0;
243 free_packet_list(packets);
244 packets = list_end = NULL;
248 write(fd, &storebuf.offset,
249 sizeof(storebuf.offset));
255 write(fd, &cmd, sizeof(cmd));
257 bytes = read(fd, &storebuf.size,
258 sizeof(storebuf.size));
259 logthing(LOGTHING_TRACE, "Reading %d bytes.",
261 if (bytes != sizeof(storebuf.size)) {
264 if (ret == 0 && storebuf.size > 0) {
265 storebuf.buffer = malloc(storebuf.size);
267 while (bytes >= 0 && count < storebuf.size) {
269 &storebuf.buffer[count],
270 storebuf.size - count);
271 logthing(LOGTHING_TRACE,
276 read_openpgp_stream(buffer_fetchchar,
280 parse_keys(packets, &key);
281 config.dbbackend->store_key(key, false, false);
282 free_packet_list(packets);
286 free(storebuf.buffer);
287 storebuf.buffer = NULL;
288 storebuf.size = storebuf.offset = 0;
291 case KEYD_CMD_DELETE:
293 write(fd, &cmd, sizeof(cmd));
294 bytes = read(fd, &keyid, sizeof(keyid));
295 if (bytes != sizeof(keyid)) {
299 logthing(LOGTHING_INFO,
300 "Deleting 0x%" PRIX64
303 config.dbbackend->delete_key(
307 case KEYD_CMD_GETFULLKEYID:
309 write(fd, &cmd, sizeof(cmd));
310 bytes = read(fd, &keyid, sizeof(keyid));
311 if (bytes != sizeof(keyid)) {
315 keyid = config.dbbackend->getfullkeyid(keyid);
317 write(fd, &cmd, sizeof(cmd));
318 write(fd, &keyid, sizeof(keyid));
321 case KEYD_CMD_KEYITER:
323 write(fd, &cmd, sizeof(cmd));
324 config.dbbackend->iterate_keys(iteratefunc,
327 write(fd, &bytes, sizeof(bytes));
331 write(fd, &cmd, sizeof(cmd));
336 write(fd, &cmd, sizeof(cmd));
341 logthing(LOGTHING_ERROR, "Got unknown command: %d",
343 cmd = KEYD_REPLY_UNKNOWN_CMD;
344 write(fd, &cmd, sizeof(cmd));
351 int sock_close(int fd)
353 shutdown(fd, SHUT_RDWR);
357 int sock_accept(int fd)
359 struct sockaddr_un sock;
364 socklen = sizeof(sock);
365 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
367 ret = fcntl(srv, F_SETFD, 1);
371 while (!sock_do(srv)) ;
378 int main(int argc, char *argv[])
383 char *configfile = NULL;
384 bool foreground = false;
387 while ((optchar = getopt(argc, argv, "c:f")) != -1 ) {
390 configfile = strdup(optarg);
398 readconfig(configfile);
401 initlogthing("keyd", config.logfile);
402 config.use_keyd = false;
410 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
411 fd = sock_init(sockname);
417 config.dbbackend->initdb(false);
419 logthing(LOGTHING_NOTICE, "Accepting connections.");
420 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
421 logthing(LOGTHING_INFO, "Accepted connection.");
425 config.dbbackend->cleanupdb();
433 return(EXIT_SUCCESS);