2 * keyd.c - key retrieval daemon
4 * Jonathan McDowell <noodles@earth.li>
6 * Copyright 2004 Project Purple
13 #include <sys/socket.h>
14 #include <sys/types.h>
18 #include "charfuncs.h"
23 #include "keystructs.h"
26 #include "onak-conf.h"
29 void iteratefunc(void *ctx, struct openpgp_publickey *key)
31 struct openpgp_packet_list *packets = NULL;
32 struct openpgp_packet_list *list_end = NULL;
33 struct buffer_ctx storebuf;
40 storebuf.buffer = malloc(8192);
42 logthing(LOGTHING_TRACE,
43 "Iterating over 0x%016llX.",
46 flatten_publickey(key,
49 write_openpgp_stream(buffer_putchar,
52 logthing(LOGTHING_TRACE,
55 ret = write(fd, &storebuf.offset,
56 sizeof(storebuf.offset));
58 write(fd, storebuf.buffer,
62 free(storebuf.buffer);
63 storebuf.buffer = NULL;
64 storebuf.size = storebuf.offset = 0;
65 free_packet_list(packets);
66 packets = list_end = NULL;
72 int sock_init(const char *sockname)
74 struct sockaddr_un sock;
78 fd = socket(PF_UNIX, SOCK_STREAM, 0);
80 ret = fcntl(fd, F_SETFD, 1);
84 sock.sun_family = AF_UNIX;
85 strncpy(sock.sun_path, sockname, sizeof(sock.sun_path) - 1);
87 ret = bind(fd, (struct sockaddr *) &sock, sizeof(sock));
99 int cmd = KEYD_CMD_UNKNOWN;
105 struct openpgp_publickey *key = NULL;
106 struct openpgp_packet_list *packets = NULL;
107 struct openpgp_packet_list *list_end = NULL;
108 struct buffer_ctx storebuf;
111 * Get the command from the client.
113 bytes = read(fd, &cmd, sizeof(cmd));
115 logthing(LOGTHING_DEBUG, "Read %d bytes, command: %d", bytes, cmd);
117 if (bytes != sizeof(cmd)) {
123 case KEYD_CMD_VERSION:
125 write(fd, &cmd, sizeof(cmd));
126 write(fd, &keyd_version, sizeof(keyd_version));
130 write(fd, &cmd, sizeof(cmd));
131 bytes = read(fd, &keyid, sizeof(keyid));
132 if (bytes != sizeof(keyid)) {
137 logthing(LOGTHING_INFO,
138 "Fetching 0x%llX, result: %d",
141 fetch_key(keyid, &key, false));
143 storebuf.size = 8192;
144 storebuf.buffer = malloc(8192);
146 flatten_publickey(key,
149 write_openpgp_stream(buffer_putchar,
152 logthing(LOGTHING_TRACE,
155 write(fd, &storebuf.offset,
156 sizeof(storebuf.offset));
157 write(fd, storebuf.buffer,
160 free(storebuf.buffer);
161 storebuf.buffer = NULL;
162 storebuf.size = storebuf.offset = 0;
163 free_packet_list(packets);
164 packets = list_end = NULL;
168 write(fd, &storebuf.offset,
169 sizeof(storebuf.offset));
173 case KEYD_CMD_GETTEXT:
175 write(fd, &cmd, sizeof(cmd));
176 bytes = read(fd, &count, sizeof(count));
177 if (bytes != sizeof(count)) {
182 search = malloc(count+1);
183 read(fd, search, count);
185 logthing(LOGTHING_INFO,
186 "Fetching %s, result: %d",
189 fetch_key_text(search, &key));
191 storebuf.size = 8192;
192 storebuf.buffer = malloc(8192);
194 flatten_publickey(key,
197 write_openpgp_stream(buffer_putchar,
200 logthing(LOGTHING_TRACE,
203 write(fd, &storebuf.offset,
204 sizeof(storebuf.offset));
205 write(fd, storebuf.buffer,
208 free(storebuf.buffer);
209 storebuf.buffer = NULL;
210 storebuf.size = storebuf.offset = 0;
211 free_packet_list(packets);
212 packets = list_end = NULL;
216 write(fd, &storebuf.offset,
217 sizeof(storebuf.offset));
223 write(fd, &cmd, sizeof(cmd));
225 bytes = read(fd, &storebuf.size,
226 sizeof(storebuf.size));
227 logthing(LOGTHING_TRACE, "Reading %d bytes.",
229 if (bytes != sizeof(storebuf.size)) {
232 if (ret == 0 && storebuf.size > 0) {
233 storebuf.buffer = malloc(storebuf.size);
235 while (bytes >= 0 && count < storebuf.size) {
237 &storebuf.buffer[count],
238 storebuf.size - count);
239 logthing(LOGTHING_TRACE,
244 read_openpgp_stream(buffer_fetchchar,
248 parse_keys(packets, &key);
249 config.dbbackend->store_key(key, false, false);
250 free_packet_list(packets);
254 free(storebuf.buffer);
255 storebuf.buffer = NULL;
256 storebuf.size = storebuf.offset = 0;
259 case KEYD_CMD_DELETE:
261 write(fd, &cmd, sizeof(cmd));
262 bytes = read(fd, &keyid, sizeof(keyid));
263 if (bytes != sizeof(keyid)) {
267 logthing(LOGTHING_INFO,
268 "Deleting 0x%llX, result: %d",
270 config.dbbackend->delete_key(
274 case KEYD_CMD_GETFULLKEYID:
276 write(fd, &cmd, sizeof(cmd));
277 bytes = read(fd, &keyid, sizeof(keyid));
278 if (bytes != sizeof(keyid)) {
282 keyid = config.dbbackend->getfullkeyid(keyid);
283 write(fd, &keyid, sizeof(keyid));
286 case KEYD_CMD_KEYITER:
288 write(fd, &cmd, sizeof(cmd));
289 config.dbbackend->iterate_keys(iteratefunc,
292 write(fd, &bytes, sizeof(bytes));
301 logthing(LOGTHING_ERROR, "Got unknown command: %d",
303 cmd = KEYD_REPLY_UNKNOWN_CMD;
304 write(fd, &cmd, sizeof(cmd));
311 int sock_close(int fd)
313 return shutdown(fd, SHUT_RDWR);
316 int sock_accept(int fd)
318 struct sockaddr_un sock;
323 socklen = sizeof(sock);
324 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
326 ret = fcntl(srv, F_SETFD, 1);
330 while (!sock_do(srv)) ;
337 int main(int argc, char *argv[])
344 initlogthing("keyd", config.logfile);
348 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
349 fd = sock_init(sockname);
355 config.dbbackend->initdb(false);
357 logthing(LOGTHING_NOTICE, "Accepting connections.");
358 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
359 logthing(LOGTHING_INFO, "Accepted connection.");
363 config.dbbackend->cleanupdb();
371 return(EXIT_SUCCESS);