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"
22 #include "keystructs.h"
25 #include "onak-conf.h"
28 int sock_init(const char *sockname)
30 struct sockaddr_un sock;
34 fd = socket(PF_UNIX, SOCK_STREAM, 0);
36 ret = fcntl(fd, F_SETFD, 1);
40 sock.sun_family = AF_UNIX;
41 strncpy(sock.sun_path, sockname, sizeof(sock.sun_path) - 1);
43 ret = bind(fd, (struct sockaddr *) &sock, sizeof(sock));
55 int cmd = KEYD_CMD_UNKNOWN;
61 struct openpgp_publickey *key = NULL;
62 struct openpgp_packet_list *packets = NULL;
63 struct openpgp_packet_list *list_end = NULL;
64 struct buffer_ctx storebuf;
67 * Get the command from the client.
69 bytes = read(fd, &cmd, sizeof(cmd));
71 logthing(LOGTHING_DEBUG, "Read %d bytes, command: %d", bytes, cmd);
73 if (bytes != sizeof(cmd)) {
79 case KEYD_CMD_VERSION:
81 write(fd, &cmd, sizeof(cmd));
82 write(fd, &keyd_version, sizeof(keyd_version));
86 write(fd, &cmd, sizeof(cmd));
87 bytes = read(fd, &keyid, sizeof(keyid));
88 if (bytes != sizeof(keyid)) {
93 logthing(LOGTHING_INFO,
94 "Fetching 0x%llX, result: %d",
96 fetch_key(keyid, &key, false));
99 storebuf.buffer = malloc(8192);
101 flatten_publickey(key,
104 write_openpgp_stream(buffer_putchar,
107 logthing(LOGTHING_TRACE,
110 write(fd, &storebuf.offset,
111 sizeof(storebuf.offset));
112 write(fd, storebuf.buffer,
115 free(storebuf.buffer);
116 storebuf.buffer = NULL;
117 storebuf.size = storebuf.offset = 0;
118 free_packet_list(packets);
119 packets = list_end = NULL;
123 write(fd, &storebuf.offset,
124 sizeof(storebuf.offset));
128 case KEYD_CMD_GETTEXT:
130 write(fd, &cmd, sizeof(cmd));
131 bytes = read(fd, &count, sizeof(count));
132 if (bytes != sizeof(count)) {
137 search = malloc(count+1);
138 read(fd, search, count);
140 logthing(LOGTHING_INFO,
141 "Fetching %s, result: %d",
143 fetch_key_text(search, &key));
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));
177 write(fd, &cmd, sizeof(cmd));
179 bytes = read(fd, &storebuf.size,
180 sizeof(storebuf.size));
181 logthing(LOGTHING_TRACE, "Reading %d bytes.",
183 if (bytes != sizeof(storebuf.size)) {
186 if (ret == 0 && storebuf.size > 0) {
187 storebuf.buffer = malloc(storebuf.size);
189 while (bytes >= 0 && count < storebuf.size) {
191 &storebuf.buffer[count],
192 storebuf.size - count);
193 logthing(LOGTHING_TRACE,
198 read_openpgp_stream(buffer_fetchchar,
202 parse_keys(packets, &key);
203 store_key(key, false, false);
204 free_packet_list(packets);
208 free(storebuf.buffer);
209 storebuf.buffer = NULL;
210 storebuf.size = storebuf.offset = 0;
213 case KEYD_CMD_DELETE:
215 write(fd, &cmd, sizeof(cmd));
216 bytes = read(fd, &keyid, sizeof(keyid));
217 if (bytes != sizeof(keyid)) {
221 logthing(LOGTHING_INFO,
222 "Deleting 0x%llX, result: %d",
224 delete_key(keyid, false));
227 case KEYD_CMD_GETFULLKEYID:
229 write(fd, &cmd, sizeof(cmd));
230 bytes = read(fd, &keyid, sizeof(keyid));
231 if (bytes != sizeof(keyid)) {
235 keyid = getfullkeyid(keyid);
236 write(fd, &keyid, sizeof(keyid));
246 logthing(LOGTHING_ERROR, "Got unknown command: %d",
248 cmd = KEYD_REPLY_UNKNOWN_CMD;
249 write(fd, &cmd, sizeof(cmd));
256 int sock_close(int fd)
258 return shutdown(fd, SHUT_RDWR);
261 int sock_accept(int fd)
263 struct sockaddr_un sock;
268 socklen = sizeof(sock);
269 srv = accept(fd, (struct sockaddr *) &sock, &socklen);
271 ret = fcntl(srv, F_SETFD, 1);
275 while (!sock_do(srv)) ;
282 int main(int argc, char *argv[])
289 initlogthing("keyd", config.logfile);
293 snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
294 fd = sock_init(sockname);
302 logthing(LOGTHING_NOTICE, "Accepting connections.");
303 while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) {
304 logthing(LOGTHING_INFO, "Accepted connection.");
316 return(EXIT_SUCCESS);