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%016llX.",
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 int 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 write(fd, &keyd_version, sizeof(keyd_version));
159 write(fd, &cmd, sizeof(cmd));
160 bytes = read(fd, &keyid, sizeof(keyid));
161 if (bytes != sizeof(keyid)) {
166 logthing(LOGTHING_INFO,
167 "Fetching 0x%llX, result: %d",
170 fetch_key(keyid, &key, false));
172 storebuf.size = 8192;
173 storebuf.buffer = malloc(8192);
175 flatten_publickey(key,
178 write_openpgp_stream(buffer_putchar,
181 logthing(LOGTHING_TRACE,
184 write(fd, &storebuf.offset,
185 sizeof(storebuf.offset));
186 write(fd, storebuf.buffer,
189 free(storebuf.buffer);
190 storebuf.buffer = NULL;
191 storebuf.size = storebuf.offset = 0;
192 free_packet_list(packets);
193 packets = list_end = NULL;
197 write(fd, &storebuf.offset,
198 sizeof(storebuf.offset));
202 case KEYD_CMD_GETTEXT:
204 write(fd, &cmd, sizeof(cmd));
205 bytes = read(fd, &count, sizeof(count));
206 if (bytes != sizeof(count)) {
211 search = malloc(count+1);
212 read(fd, search, count);
214 logthing(LOGTHING_INFO,
215 "Fetching %s, result: %d",
218 fetch_key_text(search, &key));
220 storebuf.size = 8192;
221 storebuf.buffer = malloc(8192);
223 flatten_publickey(key,
226 write_openpgp_stream(buffer_putchar,
229 logthing(LOGTHING_TRACE,
232 write(fd, &storebuf.offset,
233 sizeof(storebuf.offset));
234 write(fd, storebuf.buffer,
237 free(storebuf.buffer);
238 storebuf.buffer = NULL;
239 storebuf.size = storebuf.offset = 0;
240 free_packet_list(packets);
241 packets = list_end = NULL;
245 write(fd, &storebuf.offset,
246 sizeof(storebuf.offset));
252 write(fd, &cmd, sizeof(cmd));
254 bytes = read(fd, &storebuf.size,
255 sizeof(storebuf.size));
256 logthing(LOGTHING_TRACE, "Reading %d bytes.",
258 if (bytes != sizeof(storebuf.size)) {
261 if (ret == 0 && storebuf.size > 0) {
262 storebuf.buffer = malloc(storebuf.size);
264 while (bytes >= 0 && count < storebuf.size) {
266 &storebuf.buffer[count],
267 storebuf.size - count);
268 logthing(LOGTHING_TRACE,
273 read_openpgp_stream(buffer_fetchchar,
277 parse_keys(packets, &key);
278 config.dbbackend->store_key(key, false, false);
279 free_packet_list(packets);
283 free(storebuf.buffer);
284 storebuf.buffer = NULL;
285 storebuf.size = storebuf.offset = 0;
288 case KEYD_CMD_DELETE:
290 write(fd, &cmd, sizeof(cmd));
291 bytes = read(fd, &keyid, sizeof(keyid));
292 if (bytes != sizeof(keyid)) {
296 logthing(LOGTHING_INFO,
297 "Deleting 0x%llX, result: %d",
299 config.dbbackend->delete_key(
303 case KEYD_CMD_GETFULLKEYID:
305 write(fd, &cmd, sizeof(cmd));
306 bytes = read(fd, &keyid, sizeof(keyid));
307 if (bytes != sizeof(keyid)) {
311 keyid = config.dbbackend->getfullkeyid(keyid);
312 write(fd, &keyid, sizeof(keyid));
315 case KEYD_CMD_KEYITER:
317 write(fd, &cmd, sizeof(cmd));
318 config.dbbackend->iterate_keys(iteratefunc,
321 write(fd, &bytes, sizeof(bytes));
330 logthing(LOGTHING_ERROR, "Got unknown command: %d",
332 cmd = KEYD_REPLY_UNKNOWN_CMD;
333 write(fd, &cmd, sizeof(cmd));
340 int sock_close(int fd)
342 shutdown(fd, SHUT_RDWR);
346 int sock_accept(int fd)
348 struct sockaddr_un sock;
353 socklen = sizeof(sock);
354 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
356 ret = fcntl(srv, F_SETFD, 1);
360 while (!sock_do(srv)) ;
367 int main(int argc, char *argv[])
372 char *configfile = NULL;
373 bool foreground = false;
376 while ((optchar = getopt(argc, argv, "c:f")) != -1 ) {
379 configfile = strdup(optarg);
387 readconfig(configfile);
390 initlogthing("keyd", config.logfile);
391 config.use_keyd = false;
399 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
400 fd = sock_init(sockname);
406 config.dbbackend->initdb(false);
408 logthing(LOGTHING_NOTICE, "Accepting connections.");
409 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
410 logthing(LOGTHING_INFO, "Accepted connection.");
414 config.dbbackend->cleanupdb();
422 return(EXIT_SUCCESS);