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",
140 fetch_key(keyid, &key, false));
142 storebuf.size = 8192;
143 storebuf.buffer = malloc(8192);
145 flatten_publickey(key,
148 write_openpgp_stream(buffer_putchar,
151 logthing(LOGTHING_TRACE,
154 write(fd, &storebuf.offset,
155 sizeof(storebuf.offset));
156 write(fd, storebuf.buffer,
159 free(storebuf.buffer);
160 storebuf.buffer = NULL;
161 storebuf.size = storebuf.offset = 0;
162 free_packet_list(packets);
163 packets = list_end = NULL;
167 write(fd, &storebuf.offset,
168 sizeof(storebuf.offset));
172 case KEYD_CMD_GETTEXT:
174 write(fd, &cmd, sizeof(cmd));
175 bytes = read(fd, &count, sizeof(count));
176 if (bytes != sizeof(count)) {
181 search = malloc(count+1);
182 read(fd, search, count);
184 logthing(LOGTHING_INFO,
185 "Fetching %s, result: %d",
187 fetch_key_text(search, &key));
189 storebuf.size = 8192;
190 storebuf.buffer = malloc(8192);
192 flatten_publickey(key,
195 write_openpgp_stream(buffer_putchar,
198 logthing(LOGTHING_TRACE,
201 write(fd, &storebuf.offset,
202 sizeof(storebuf.offset));
203 write(fd, storebuf.buffer,
206 free(storebuf.buffer);
207 storebuf.buffer = NULL;
208 storebuf.size = storebuf.offset = 0;
209 free_packet_list(packets);
210 packets = list_end = NULL;
214 write(fd, &storebuf.offset,
215 sizeof(storebuf.offset));
221 write(fd, &cmd, sizeof(cmd));
223 bytes = read(fd, &storebuf.size,
224 sizeof(storebuf.size));
225 logthing(LOGTHING_TRACE, "Reading %d bytes.",
227 if (bytes != sizeof(storebuf.size)) {
230 if (ret == 0 && storebuf.size > 0) {
231 storebuf.buffer = malloc(storebuf.size);
233 while (bytes >= 0 && count < storebuf.size) {
235 &storebuf.buffer[count],
236 storebuf.size - count);
237 logthing(LOGTHING_TRACE,
242 read_openpgp_stream(buffer_fetchchar,
246 parse_keys(packets, &key);
247 store_key(key, false, false);
248 free_packet_list(packets);
252 free(storebuf.buffer);
253 storebuf.buffer = NULL;
254 storebuf.size = storebuf.offset = 0;
257 case KEYD_CMD_DELETE:
259 write(fd, &cmd, sizeof(cmd));
260 bytes = read(fd, &keyid, sizeof(keyid));
261 if (bytes != sizeof(keyid)) {
265 logthing(LOGTHING_INFO,
266 "Deleting 0x%llX, result: %d",
268 delete_key(keyid, false));
271 case KEYD_CMD_GETFULLKEYID:
273 write(fd, &cmd, sizeof(cmd));
274 bytes = read(fd, &keyid, sizeof(keyid));
275 if (bytes != sizeof(keyid)) {
279 keyid = getfullkeyid(keyid);
280 write(fd, &keyid, sizeof(keyid));
283 case KEYD_CMD_KEYITER:
285 write(fd, &cmd, sizeof(cmd));
286 iterate_keys(iteratefunc, (void *) fd);
288 write(fd, &bytes, sizeof(bytes));
297 logthing(LOGTHING_ERROR, "Got unknown command: %d",
299 cmd = KEYD_REPLY_UNKNOWN_CMD;
300 write(fd, &cmd, sizeof(cmd));
307 int sock_close(int fd)
309 return shutdown(fd, SHUT_RDWR);
312 int sock_accept(int fd)
314 struct sockaddr_un sock;
319 socklen = sizeof(sock);
320 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
322 ret = fcntl(srv, F_SETFD, 1);
326 while (!sock_do(srv)) ;
333 int main(int argc, char *argv[])
340 initlogthing("keyd", config.logfile);
344 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
345 fd = sock_init(sockname);
353 logthing(LOGTHING_NOTICE, "Accepting connections.");
354 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
355 logthing(LOGTHING_INFO, "Accepted connection.");
367 return(EXIT_SUCCESS);