2 * keyd.c - key retrieval daemon
4 * Jonathan McDowell <noodles@earth.li>
6 * Copyright 2004 Project Purple
14 #include <sys/select.h>
15 #include <sys/socket.h>
16 #include <sys/types.h>
20 #include "charfuncs.h"
25 #include "keystructs.h"
28 #include "onak-conf.h"
31 void iteratefunc(void *ctx, struct openpgp_publickey *key)
33 struct openpgp_packet_list *packets = NULL;
34 struct openpgp_packet_list *list_end = NULL;
35 struct buffer_ctx storebuf;
37 int *fd = (int *) ctx;
42 storebuf.buffer = malloc(8192);
44 logthing(LOGTHING_TRACE,
45 "Iterating over 0x%016llX.",
48 flatten_publickey(key,
51 write_openpgp_stream(buffer_putchar,
54 logthing(LOGTHING_TRACE,
57 ret = write(*fd, &storebuf.offset,
58 sizeof(storebuf.offset));
60 write(*fd, storebuf.buffer,
64 free(storebuf.buffer);
65 storebuf.buffer = NULL;
66 storebuf.size = storebuf.offset = 0;
67 free_packet_list(packets);
68 packets = list_end = NULL;
74 int sock_init(const char *sockname)
76 struct sockaddr_un sock;
80 fd = socket(PF_UNIX, SOCK_STREAM, 0);
82 ret = fcntl(fd, F_SETFD, 1);
86 sock.sun_family = AF_UNIX;
87 strncpy(sock.sun_path, sockname, sizeof(sock.sun_path) - 1);
89 ret = bind(fd, (struct sockaddr *) &sock, sizeof(sock));
101 int cmd = KEYD_CMD_UNKNOWN;
107 struct openpgp_publickey *key = NULL;
108 struct openpgp_packet_list *packets = NULL;
109 struct openpgp_packet_list *list_end = NULL;
110 struct buffer_ctx storebuf;
113 * Get the command from the client.
115 bytes = read(fd, &cmd, sizeof(cmd));
117 logthing(LOGTHING_DEBUG, "Read %d bytes, command: %d", bytes, cmd);
119 if (bytes != sizeof(cmd)) {
125 case KEYD_CMD_VERSION:
127 write(fd, &cmd, sizeof(cmd));
128 write(fd, &keyd_version, sizeof(keyd_version));
132 write(fd, &cmd, sizeof(cmd));
133 bytes = read(fd, &keyid, sizeof(keyid));
134 if (bytes != sizeof(keyid)) {
139 logthing(LOGTHING_INFO,
140 "Fetching 0x%llX, result: %d",
143 fetch_key(keyid, &key, false));
145 storebuf.size = 8192;
146 storebuf.buffer = malloc(8192);
148 flatten_publickey(key,
151 write_openpgp_stream(buffer_putchar,
154 logthing(LOGTHING_TRACE,
157 write(fd, &storebuf.offset,
158 sizeof(storebuf.offset));
159 write(fd, storebuf.buffer,
162 free(storebuf.buffer);
163 storebuf.buffer = NULL;
164 storebuf.size = storebuf.offset = 0;
165 free_packet_list(packets);
166 packets = list_end = NULL;
170 write(fd, &storebuf.offset,
171 sizeof(storebuf.offset));
175 case KEYD_CMD_GETTEXT:
177 write(fd, &cmd, sizeof(cmd));
178 bytes = read(fd, &count, sizeof(count));
179 if (bytes != sizeof(count)) {
184 search = malloc(count+1);
185 read(fd, search, count);
187 logthing(LOGTHING_INFO,
188 "Fetching %s, result: %d",
191 fetch_key_text(search, &key));
193 storebuf.size = 8192;
194 storebuf.buffer = malloc(8192);
196 flatten_publickey(key,
199 write_openpgp_stream(buffer_putchar,
202 logthing(LOGTHING_TRACE,
205 write(fd, &storebuf.offset,
206 sizeof(storebuf.offset));
207 write(fd, storebuf.buffer,
210 free(storebuf.buffer);
211 storebuf.buffer = NULL;
212 storebuf.size = storebuf.offset = 0;
213 free_packet_list(packets);
214 packets = list_end = NULL;
218 write(fd, &storebuf.offset,
219 sizeof(storebuf.offset));
225 write(fd, &cmd, sizeof(cmd));
227 bytes = read(fd, &storebuf.size,
228 sizeof(storebuf.size));
229 logthing(LOGTHING_TRACE, "Reading %d bytes.",
231 if (bytes != sizeof(storebuf.size)) {
234 if (ret == 0 && storebuf.size > 0) {
235 storebuf.buffer = malloc(storebuf.size);
237 while (bytes >= 0 && count < storebuf.size) {
239 &storebuf.buffer[count],
240 storebuf.size - count);
241 logthing(LOGTHING_TRACE,
246 read_openpgp_stream(buffer_fetchchar,
250 parse_keys(packets, &key);
251 config.dbbackend->store_key(key, false, false);
252 free_packet_list(packets);
256 free(storebuf.buffer);
257 storebuf.buffer = NULL;
258 storebuf.size = storebuf.offset = 0;
261 case KEYD_CMD_DELETE:
263 write(fd, &cmd, sizeof(cmd));
264 bytes = read(fd, &keyid, sizeof(keyid));
265 if (bytes != sizeof(keyid)) {
269 logthing(LOGTHING_INFO,
270 "Deleting 0x%llX, result: %d",
272 config.dbbackend->delete_key(
276 case KEYD_CMD_GETFULLKEYID:
278 write(fd, &cmd, sizeof(cmd));
279 bytes = read(fd, &keyid, sizeof(keyid));
280 if (bytes != sizeof(keyid)) {
284 keyid = config.dbbackend->getfullkeyid(keyid);
285 write(fd, &keyid, sizeof(keyid));
288 case KEYD_CMD_KEYITER:
290 write(fd, &cmd, sizeof(cmd));
291 config.dbbackend->iterate_keys(iteratefunc,
294 write(fd, &bytes, sizeof(bytes));
303 logthing(LOGTHING_ERROR, "Got unknown command: %d",
305 cmd = KEYD_REPLY_UNKNOWN_CMD;
306 write(fd, &cmd, sizeof(cmd));
313 int sock_close(int fd)
315 shutdown(fd, SHUT_RDWR);
319 int sock_accept(int fd)
321 struct sockaddr_un sock;
326 socklen = sizeof(sock);
327 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
329 ret = fcntl(srv, F_SETFD, 1);
333 while (!sock_do(srv)) ;
340 int main(int argc, char *argv[])
345 char *configfile = NULL;
348 while ((optchar = getopt(argc, argv, "c:")) != -1 ) {
351 configfile = strdup(optarg);
356 readconfig(configfile);
359 initlogthing("keyd", config.logfile);
363 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
364 fd = sock_init(sockname);
370 config.dbbackend->initdb(false);
372 logthing(LOGTHING_NOTICE, "Accepting connections.");
373 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
374 logthing(LOGTHING_INFO, "Accepted connection.");
378 config.dbbackend->cleanupdb();
386 return(EXIT_SUCCESS);