2 * keyd.c - key retrieval daemon
4 * Jonathan McDowell <noodles@earth.li>
6 * Copyright 2004 Project Purple
13 #include <sys/select.h>
14 #include <sys/socket.h>
15 #include <sys/types.h>
19 #include "charfuncs.h"
24 #include "keystructs.h"
27 #include "onak-conf.h"
30 void iteratefunc(void *ctx, struct openpgp_publickey *key)
32 struct openpgp_packet_list *packets = NULL;
33 struct openpgp_packet_list *list_end = NULL;
34 struct buffer_ctx storebuf;
36 int *fd = (int *) ctx;
41 storebuf.buffer = malloc(8192);
43 logthing(LOGTHING_TRACE,
44 "Iterating over 0x%016llX.",
47 flatten_publickey(key,
50 write_openpgp_stream(buffer_putchar,
53 logthing(LOGTHING_TRACE,
56 ret = write(*fd, &storebuf.offset,
57 sizeof(storebuf.offset));
59 write(*fd, storebuf.buffer,
63 free(storebuf.buffer);
64 storebuf.buffer = NULL;
65 storebuf.size = storebuf.offset = 0;
66 free_packet_list(packets);
67 packets = list_end = NULL;
73 int sock_init(const char *sockname)
75 struct sockaddr_un sock;
79 fd = socket(PF_UNIX, SOCK_STREAM, 0);
81 ret = fcntl(fd, F_SETFD, 1);
85 sock.sun_family = AF_UNIX;
86 strncpy(sock.sun_path, sockname, sizeof(sock.sun_path) - 1);
88 ret = bind(fd, (struct sockaddr *) &sock, sizeof(sock));
100 int cmd = KEYD_CMD_UNKNOWN;
106 struct openpgp_publickey *key = NULL;
107 struct openpgp_packet_list *packets = NULL;
108 struct openpgp_packet_list *list_end = NULL;
109 struct buffer_ctx storebuf;
112 * Get the command from the client.
114 bytes = read(fd, &cmd, sizeof(cmd));
116 logthing(LOGTHING_DEBUG, "Read %d bytes, command: %d", bytes, cmd);
118 if (bytes != sizeof(cmd)) {
124 case KEYD_CMD_VERSION:
126 write(fd, &cmd, sizeof(cmd));
127 write(fd, &keyd_version, sizeof(keyd_version));
131 write(fd, &cmd, sizeof(cmd));
132 bytes = read(fd, &keyid, sizeof(keyid));
133 if (bytes != sizeof(keyid)) {
138 logthing(LOGTHING_INFO,
139 "Fetching 0x%llX, result: %d",
142 fetch_key(keyid, &key, false));
144 storebuf.size = 8192;
145 storebuf.buffer = malloc(8192);
147 flatten_publickey(key,
150 write_openpgp_stream(buffer_putchar,
153 logthing(LOGTHING_TRACE,
156 write(fd, &storebuf.offset,
157 sizeof(storebuf.offset));
158 write(fd, storebuf.buffer,
161 free(storebuf.buffer);
162 storebuf.buffer = NULL;
163 storebuf.size = storebuf.offset = 0;
164 free_packet_list(packets);
165 packets = list_end = NULL;
169 write(fd, &storebuf.offset,
170 sizeof(storebuf.offset));
174 case KEYD_CMD_GETTEXT:
176 write(fd, &cmd, sizeof(cmd));
177 bytes = read(fd, &count, sizeof(count));
178 if (bytes != sizeof(count)) {
183 search = malloc(count+1);
184 read(fd, search, count);
186 logthing(LOGTHING_INFO,
187 "Fetching %s, result: %d",
190 fetch_key_text(search, &key));
192 storebuf.size = 8192;
193 storebuf.buffer = malloc(8192);
195 flatten_publickey(key,
198 write_openpgp_stream(buffer_putchar,
201 logthing(LOGTHING_TRACE,
204 write(fd, &storebuf.offset,
205 sizeof(storebuf.offset));
206 write(fd, storebuf.buffer,
209 free(storebuf.buffer);
210 storebuf.buffer = NULL;
211 storebuf.size = storebuf.offset = 0;
212 free_packet_list(packets);
213 packets = list_end = NULL;
217 write(fd, &storebuf.offset,
218 sizeof(storebuf.offset));
224 write(fd, &cmd, sizeof(cmd));
226 bytes = read(fd, &storebuf.size,
227 sizeof(storebuf.size));
228 logthing(LOGTHING_TRACE, "Reading %d bytes.",
230 if (bytes != sizeof(storebuf.size)) {
233 if (ret == 0 && storebuf.size > 0) {
234 storebuf.buffer = malloc(storebuf.size);
236 while (bytes >= 0 && count < storebuf.size) {
238 &storebuf.buffer[count],
239 storebuf.size - count);
240 logthing(LOGTHING_TRACE,
245 read_openpgp_stream(buffer_fetchchar,
249 parse_keys(packets, &key);
250 config.dbbackend->store_key(key, false, false);
251 free_packet_list(packets);
255 free(storebuf.buffer);
256 storebuf.buffer = NULL;
257 storebuf.size = storebuf.offset = 0;
260 case KEYD_CMD_DELETE:
262 write(fd, &cmd, sizeof(cmd));
263 bytes = read(fd, &keyid, sizeof(keyid));
264 if (bytes != sizeof(keyid)) {
268 logthing(LOGTHING_INFO,
269 "Deleting 0x%llX, result: %d",
271 config.dbbackend->delete_key(
275 case KEYD_CMD_GETFULLKEYID:
277 write(fd, &cmd, sizeof(cmd));
278 bytes = read(fd, &keyid, sizeof(keyid));
279 if (bytes != sizeof(keyid)) {
283 keyid = config.dbbackend->getfullkeyid(keyid);
284 write(fd, &keyid, sizeof(keyid));
287 case KEYD_CMD_KEYITER:
289 write(fd, &cmd, sizeof(cmd));
290 config.dbbackend->iterate_keys(iteratefunc,
293 write(fd, &bytes, sizeof(bytes));
302 logthing(LOGTHING_ERROR, "Got unknown command: %d",
304 cmd = KEYD_REPLY_UNKNOWN_CMD;
305 write(fd, &cmd, sizeof(cmd));
312 int sock_close(int fd)
314 shutdown(fd, SHUT_RDWR);
318 int sock_accept(int fd)
320 struct sockaddr_un sock;
325 socklen = sizeof(sock);
326 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
328 ret = fcntl(srv, F_SETFD, 1);
332 while (!sock_do(srv)) ;
339 int main(int argc, char *argv[])
346 initlogthing("keyd", config.logfile);
350 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
351 fd = sock_init(sockname);
357 config.dbbackend->initdb(false);
359 logthing(LOGTHING_NOTICE, "Accepting connections.");
360 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
361 logthing(LOGTHING_INFO, "Accepted connection.");
365 config.dbbackend->cleanupdb();
373 return(EXIT_SUCCESS);