xref: /openbsd-src/usr.sbin/smtpd/lka.c (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 /*	$OpenBSD: lka.c,v 1.245 2021/04/21 07:54:10 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
5  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
6  * Copyright (c) 2012 Eric Faurot <eric@faurot.net>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <sys/queue.h>
23 #include <sys/tree.h>
24 #include <sys/socket.h>
25 #include <sys/wait.h>
26 #include <sys/uio.h>
27 
28 #include <netinet/in.h>
29 
30 #include <ctype.h>
31 #include <err.h>
32 #include <errno.h>
33 #include <event.h>
34 #include <imsg.h>
35 #include <openssl/err.h>
36 #include <openssl/ssl.h>
37 #include <pwd.h>
38 #include <resolv.h>
39 #include <limits.h>
40 #include <signal.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 
46 #include "smtpd.h"
47 #include "log.h"
48 #include "ssl.h"
49 
50 static void lka_imsg(struct mproc *, struct imsg *);
51 static void lka_shutdown(void);
52 static void lka_sig_handler(int, short, void *);
53 static int lka_authenticate(const char *, const char *, const char *);
54 static int lka_credentials(const char *, const char *, char *, size_t);
55 static int lka_userinfo(const char *, const char *, struct userinfo *);
56 static int lka_addrname(const char *, const struct sockaddr *,
57     struct addrname *);
58 static int lka_mailaddrmap(const char *, const char *, const struct mailaddr *);
59 
60 static void proc_timeout(int fd, short event, void *p);
61 
62 struct event	 ev_proc_ready;
63 
64 static void
65 lka_imsg(struct mproc *p, struct imsg *imsg)
66 {
67 	struct table		*table;
68 	int			 ret;
69 	struct sockaddr_storage	 ss;
70 	struct userinfo		 userinfo;
71 	struct addrname		 addrname;
72 	struct envelope		 evp;
73 	struct mailaddr		 maddr;
74 	struct msg		 m;
75 	union lookup		 lk;
76 	char			 buf[LINE_MAX];
77 	const char		*tablename, *username, *password, *label, *procname;
78 	uint64_t		 reqid;
79 	int			 v;
80 	struct timeval		 tv;
81 	const char		*direction;
82 	const char		*rdns;
83 	const char		*command;
84 	const char		*response;
85 	const char		*ciphers;
86 	const char		*address;
87 	const char		*domain;
88 	const char		*helomethod;
89 	const char		*heloname;
90 	const char		*filter_name;
91 	const char		*result;
92 	struct sockaddr_storage	ss_src, ss_dest;
93 	int                      filter_response;
94 	int                      filter_phase;
95 	const char              *filter_param;
96 	uint32_t		 msgid;
97 	uint32_t		 subsystems;
98 	uint64_t		 evpid;
99 	size_t			 msgsz;
100 	int			 ok;
101 	int			 fcrdns;
102 
103 	if (imsg == NULL)
104 		lka_shutdown();
105 
106 	switch (imsg->hdr.type) {
107 
108 	case IMSG_GETADDRINFO:
109 	case IMSG_GETNAMEINFO:
110 	case IMSG_RES_QUERY:
111 		resolver_dispatch_request(p, imsg);
112 		return;
113 
114 	case IMSG_MTA_DNS_HOST:
115 	case IMSG_MTA_DNS_MX:
116 	case IMSG_MTA_DNS_MX_PREFERENCE:
117 		dns_imsg(p, imsg);
118 		return;
119 
120 	case IMSG_SMTP_CHECK_SENDER:
121 		m_msg(&m, imsg);
122 		m_get_id(&m, &reqid);
123 		m_get_string(&m, &tablename);
124 		m_get_string(&m, &username);
125 		m_get_mailaddr(&m, &maddr);
126 		m_end(&m);
127 
128 		ret = lka_mailaddrmap(tablename, username, &maddr);
129 
130 		m_create(p, IMSG_SMTP_CHECK_SENDER, 0, 0, -1);
131 		m_add_id(p, reqid);
132 		m_add_int(p, ret);
133 		m_close(p);
134 		return;
135 
136 	case IMSG_SMTP_EXPAND_RCPT:
137 		m_msg(&m, imsg);
138 		m_get_id(&m, &reqid);
139 		m_get_envelope(&m, &evp);
140 		m_end(&m);
141 		lka_session(reqid, &evp);
142 		return;
143 
144 	case IMSG_SMTP_LOOKUP_HELO:
145 		m_msg(&m, imsg);
146 		m_get_id(&m, &reqid);
147 		m_get_string(&m, &tablename);
148 		m_get_sockaddr(&m, (struct sockaddr *)&ss);
149 		m_end(&m);
150 
151 		ret = lka_addrname(tablename, (struct sockaddr*)&ss,
152 		    &addrname);
153 
154 		m_create(p, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1);
155 		m_add_id(p, reqid);
156 		m_add_int(p, ret);
157 		if (ret == LKA_OK)
158 			m_add_string(p, addrname.name);
159 		m_close(p);
160 		return;
161 
162 	case IMSG_SMTP_AUTHENTICATE:
163 		m_msg(&m, imsg);
164 		m_get_id(&m, &reqid);
165 		m_get_string(&m, &tablename);
166 		m_get_string(&m, &username);
167 		m_get_string(&m, &password);
168 		m_end(&m);
169 
170 		if (!tablename[0]) {
171 			m_create(p_parent, IMSG_LKA_AUTHENTICATE,
172 			    0, 0, -1);
173 			m_add_id(p_parent, reqid);
174 			m_add_string(p_parent, username);
175 			m_add_string(p_parent, password);
176 			m_close(p_parent);
177 			return;
178 		}
179 
180 		ret = lka_authenticate(tablename, username, password);
181 
182 		m_create(p, IMSG_SMTP_AUTHENTICATE, 0, 0, -1);
183 		m_add_id(p, reqid);
184 		m_add_int(p, ret);
185 		m_close(p);
186 		return;
187 
188 	case IMSG_MDA_LOOKUP_USERINFO:
189 		m_msg(&m, imsg);
190 		m_get_id(&m, &reqid);
191 		m_get_string(&m, &tablename);
192 		m_get_string(&m, &username);
193 		m_end(&m);
194 
195 		ret = lka_userinfo(tablename, username, &userinfo);
196 
197 		m_create(p, IMSG_MDA_LOOKUP_USERINFO, 0, 0, -1);
198 		m_add_id(p, reqid);
199 		m_add_int(p, ret);
200 		if (ret == LKA_OK)
201 			m_add_data(p, &userinfo, sizeof(userinfo));
202 		m_close(p);
203 		return;
204 
205 	case IMSG_MTA_LOOKUP_CREDENTIALS:
206 		m_msg(&m, imsg);
207 		m_get_id(&m, &reqid);
208 		m_get_string(&m, &tablename);
209 		m_get_string(&m, &label);
210 		m_end(&m);
211 
212 		lka_credentials(tablename, label, buf, sizeof(buf));
213 
214 		m_create(p, IMSG_MTA_LOOKUP_CREDENTIALS, 0, 0, -1);
215 		m_add_id(p, reqid);
216 		m_add_string(p, buf);
217 		m_close(p);
218 		return;
219 
220 	case IMSG_MTA_LOOKUP_SOURCE:
221 		m_msg(&m, imsg);
222 		m_get_id(&m, &reqid);
223 		m_get_string(&m, &tablename);
224 		m_end(&m);
225 
226 		table = table_find(env, tablename);
227 
228 		m_create(p, IMSG_MTA_LOOKUP_SOURCE, 0, 0, -1);
229 		m_add_id(p, reqid);
230 
231 		if (table == NULL) {
232 			log_warn("warn: source address table %s missing",
233 			    tablename);
234 			m_add_int(p, LKA_TEMPFAIL);
235 		}
236 		else {
237 			ret = table_fetch(table, K_SOURCE, &lk);
238 			if (ret == -1)
239 				m_add_int(p, LKA_TEMPFAIL);
240 			else if (ret == 0)
241 				m_add_int(p, LKA_PERMFAIL);
242 			else {
243 				m_add_int(p, LKA_OK);
244 				m_add_sockaddr(p,
245 				    (struct sockaddr *)&lk.source.addr);
246 			}
247 		}
248 		m_close(p);
249 		return;
250 
251 	case IMSG_MTA_LOOKUP_HELO:
252 		m_msg(&m, imsg);
253 		m_get_id(&m, &reqid);
254 		m_get_string(&m, &tablename);
255 		m_get_sockaddr(&m, (struct sockaddr *)&ss);
256 		m_end(&m);
257 
258 		ret = lka_addrname(tablename, (struct sockaddr*)&ss,
259 		    &addrname);
260 
261 		m_create(p, IMSG_MTA_LOOKUP_HELO, 0, 0, -1);
262 		m_add_id(p, reqid);
263 		m_add_int(p, ret);
264 		if (ret == LKA_OK)
265 			m_add_string(p, addrname.name);
266 		m_close(p);
267 		return;
268 
269 	case IMSG_MTA_LOOKUP_SMARTHOST:
270 		m_msg(&m, imsg);
271 		m_get_id(&m, &reqid);
272 		m_get_string(&m, &domain);
273 		m_get_string(&m, &tablename);
274 		m_end(&m);
275 
276 		table = table_find(env, tablename);
277 
278 		m_create(p, IMSG_MTA_LOOKUP_SMARTHOST, 0, 0, -1);
279 		m_add_id(p, reqid);
280 
281 		if (table == NULL) {
282 			log_warn("warn: smarthost table %s missing", tablename);
283 			m_add_int(p, LKA_TEMPFAIL);
284 		}
285 		else {
286 			if (domain == NULL)
287 				ret = table_fetch(table, K_RELAYHOST, &lk);
288 			else
289 				ret = table_lookup(table, K_RELAYHOST, domain, &lk);
290 
291 			if (ret == -1)
292 				m_add_int(p, LKA_TEMPFAIL);
293 			else if (ret == 0)
294 				m_add_int(p, LKA_PERMFAIL);
295 			else {
296 				m_add_int(p, LKA_OK);
297 				m_add_string(p, lk.relayhost);
298 			}
299 		}
300 		m_close(p);
301 		return;
302 
303 	case IMSG_CONF_START:
304 		return;
305 
306 	case IMSG_CONF_END:
307 		if (tracing & TRACE_TABLES)
308 			table_dump_all(env);
309 
310 		/* fork & exec tables that need it */
311 		table_open_all(env);
312 
313 		/* revoke proc & exec */
314 		if (pledge("stdio rpath inet dns getpw recvfd sendfd",
315 			NULL) == -1)
316 			err(1, "pledge");
317 
318 		/* setup proc registering task */
319 		evtimer_set(&ev_proc_ready, proc_timeout, &ev_proc_ready);
320 		tv.tv_sec = 0;
321 		tv.tv_usec = 10;
322 		evtimer_add(&ev_proc_ready, &tv);
323 		return;
324 
325 	case IMSG_LKA_OPEN_FORWARD:
326 		lka_session_forward_reply(imsg->data, imsg->fd);
327 		return;
328 
329 	case IMSG_LKA_AUTHENTICATE:
330 		imsg->hdr.type = IMSG_SMTP_AUTHENTICATE;
331 		m_forward(p_dispatcher, imsg);
332 		return;
333 
334 	case IMSG_CTL_VERBOSE:
335 		m_msg(&m, imsg);
336 		m_get_int(&m, &v);
337 		m_end(&m);
338 		log_trace_verbose(v);
339 		return;
340 
341 	case IMSG_CTL_PROFILE:
342 		m_msg(&m, imsg);
343 		m_get_int(&m, &v);
344 		m_end(&m);
345 		profiling = v;
346 		return;
347 
348 	case IMSG_CTL_UPDATE_TABLE:
349 		ret = 0;
350 		table = table_find(env, imsg->data);
351 		if (table == NULL) {
352 			log_warnx("warn: Lookup table not found: "
353 			    "\"%s\"", (char *)imsg->data);
354 		} else
355 			ret = table_update(table);
356 
357 		m_compose(p_control,
358 		    (ret == 1) ? IMSG_CTL_OK : IMSG_CTL_FAIL,
359 		    imsg->hdr.peerid, 0, -1, NULL, 0);
360 		return;
361 
362 	case IMSG_LKA_PROCESSOR_FORK:
363 		m_msg(&m, imsg);
364 		m_get_string(&m, &procname);
365 		m_get_u32(&m, &subsystems);
366 		m_end(&m);
367 
368 		m_create(p, IMSG_LKA_PROCESSOR_ERRFD, 0, 0, -1);
369 		m_add_string(p, procname);
370 		m_close(p);
371 
372 		lka_proc_forked(procname, subsystems, imsg->fd);
373 		return;
374 
375 	case IMSG_LKA_PROCESSOR_ERRFD:
376 		m_msg(&m, imsg);
377 		m_get_string(&m, &procname);
378 		m_end(&m);
379 
380 		lka_proc_errfd(procname, imsg->fd);
381 		shutdown(imsg->fd, SHUT_WR);
382 		return;
383 
384 	case IMSG_REPORT_SMTP_LINK_CONNECT:
385 		m_msg(&m, imsg);
386 		m_get_string(&m, &direction);
387 		m_get_timeval(&m, &tv);
388 		m_get_id(&m, &reqid);
389 		m_get_string(&m, &rdns);
390 		m_get_int(&m, &fcrdns);
391 		m_get_sockaddr(&m, (struct sockaddr *)&ss_src);
392 		m_get_sockaddr(&m, (struct sockaddr *)&ss_dest);
393 		m_end(&m);
394 
395 		lka_report_smtp_link_connect(direction, &tv, reqid, rdns, fcrdns, &ss_src, &ss_dest);
396 		return;
397 
398 	case IMSG_REPORT_SMTP_LINK_GREETING:
399 		m_msg(&m, imsg);
400 		m_get_string(&m, &direction);
401 		m_get_timeval(&m, &tv);
402 		m_get_id(&m, &reqid);
403 		m_get_string(&m, &domain);
404 		m_end(&m);
405 
406 		lka_report_smtp_link_greeting(direction, reqid, &tv, domain);
407 		return;
408 
409 	case IMSG_REPORT_SMTP_LINK_DISCONNECT:
410 		m_msg(&m, imsg);
411 		m_get_string(&m, &direction);
412 		m_get_timeval(&m, &tv);
413 		m_get_id(&m, &reqid);
414 		m_end(&m);
415 
416 		lka_report_smtp_link_disconnect(direction, &tv, reqid);
417 		return;
418 
419 	case IMSG_REPORT_SMTP_LINK_IDENTIFY:
420 		m_msg(&m, imsg);
421 		m_get_string(&m, &direction);
422 		m_get_timeval(&m, &tv);
423 		m_get_id(&m, &reqid);
424 		m_get_string(&m, &helomethod);
425 		m_get_string(&m, &heloname);
426 		m_end(&m);
427 
428 		lka_report_smtp_link_identify(direction, &tv, reqid, helomethod, heloname);
429 		return;
430 
431 	case IMSG_REPORT_SMTP_LINK_TLS:
432 		m_msg(&m, imsg);
433 		m_get_string(&m, &direction);
434 		m_get_timeval(&m, &tv);
435 		m_get_id(&m, &reqid);
436 		m_get_string(&m, &ciphers);
437 		m_end(&m);
438 
439 		lka_report_smtp_link_tls(direction, &tv, reqid, ciphers);
440 		return;
441 
442 	case IMSG_REPORT_SMTP_LINK_AUTH:
443 		m_msg(&m, imsg);
444 		m_get_string(&m, &direction);
445 		m_get_timeval(&m, &tv);
446 		m_get_id(&m, &reqid);
447 		m_get_string(&m, &username);
448 		m_get_string(&m, &result);
449 		m_end(&m);
450 
451 		lka_report_smtp_link_auth(direction, &tv, reqid, username, result);
452 		return;
453 
454 	case IMSG_REPORT_SMTP_TX_RESET:
455 		m_msg(&m, imsg);
456 		m_get_string(&m, &direction);
457 		m_get_timeval(&m, &tv);
458 		m_get_id(&m, &reqid);
459 		m_get_u32(&m, &msgid);
460 		m_end(&m);
461 
462 		lka_report_smtp_tx_reset(direction, &tv, reqid, msgid);
463 		return;
464 
465 	case IMSG_REPORT_SMTP_TX_BEGIN:
466 		m_msg(&m, imsg);
467 		m_get_string(&m, &direction);
468 		m_get_timeval(&m, &tv);
469 		m_get_id(&m, &reqid);
470 		m_get_u32(&m, &msgid);
471 		m_end(&m);
472 
473 		lka_report_smtp_tx_begin(direction, &tv, reqid, msgid);
474 		return;
475 
476 	case IMSG_REPORT_SMTP_TX_MAIL:
477 		m_msg(&m, imsg);
478 		m_get_string(&m, &direction);
479 		m_get_timeval(&m, &tv);
480 		m_get_id(&m, &reqid);
481 		m_get_u32(&m, &msgid);
482 		m_get_string(&m, &address);
483 		m_get_int(&m, &ok);
484 		m_end(&m);
485 
486 		lka_report_smtp_tx_mail(direction, &tv, reqid, msgid, address, ok);
487 		return;
488 
489 	case IMSG_REPORT_SMTP_TX_RCPT:
490 		m_msg(&m, imsg);
491 		m_get_string(&m, &direction);
492 		m_get_timeval(&m, &tv);
493 		m_get_id(&m, &reqid);
494 		m_get_u32(&m, &msgid);
495 		m_get_string(&m, &address);
496 		m_get_int(&m, &ok);
497 		m_end(&m);
498 
499 		lka_report_smtp_tx_rcpt(direction, &tv, reqid, msgid, address, ok);
500 		return;
501 
502 	case IMSG_REPORT_SMTP_TX_ENVELOPE:
503 		m_msg(&m, imsg);
504 		m_get_string(&m, &direction);
505 		m_get_timeval(&m, &tv);
506 		m_get_id(&m, &reqid);
507 		m_get_u32(&m, &msgid);
508 		m_get_id(&m, &evpid);
509 		m_end(&m);
510 
511 		lka_report_smtp_tx_envelope(direction, &tv, reqid, msgid, evpid);
512 		return;
513 
514 	case IMSG_REPORT_SMTP_TX_DATA:
515 		m_msg(&m, imsg);
516 		m_get_string(&m, &direction);
517 		m_get_timeval(&m, &tv);
518 		m_get_id(&m, &reqid);
519 		m_get_u32(&m, &msgid);
520 		m_get_int(&m, &ok);
521 		m_end(&m);
522 
523 		lka_report_smtp_tx_data(direction, &tv, reqid, msgid, ok);
524 		return;
525 
526 	case IMSG_REPORT_SMTP_TX_COMMIT:
527 		m_msg(&m, imsg);
528 		m_get_string(&m, &direction);
529 		m_get_timeval(&m, &tv);
530 		m_get_id(&m, &reqid);
531 		m_get_u32(&m, &msgid);
532 		m_get_size(&m, &msgsz);
533 		m_end(&m);
534 
535 		lka_report_smtp_tx_commit(direction, &tv, reqid, msgid, msgsz);
536 		return;
537 
538 	case IMSG_REPORT_SMTP_TX_ROLLBACK:
539 		m_msg(&m, imsg);
540 		m_get_string(&m, &direction);
541 		m_get_timeval(&m, &tv);
542 		m_get_id(&m, &reqid);
543 		m_get_u32(&m, &msgid);
544 		m_end(&m);
545 
546 		lka_report_smtp_tx_rollback(direction, &tv, reqid, msgid);
547 		return;
548 
549 	case IMSG_REPORT_SMTP_PROTOCOL_CLIENT:
550 		m_msg(&m, imsg);
551 		m_get_string(&m, &direction);
552 		m_get_timeval(&m, &tv);
553 		m_get_id(&m, &reqid);
554 		m_get_string(&m, &command);
555 		m_end(&m);
556 
557 		lka_report_smtp_protocol_client(direction, &tv, reqid, command);
558 		return;
559 
560 	case IMSG_REPORT_SMTP_PROTOCOL_SERVER:
561 		m_msg(&m, imsg);
562 		m_get_string(&m, &direction);
563 		m_get_timeval(&m, &tv);
564 		m_get_id(&m, &reqid);
565 		m_get_string(&m, &response);
566 		m_end(&m);
567 
568 		lka_report_smtp_protocol_server(direction, &tv, reqid, response);
569 		return;
570 
571 	case IMSG_REPORT_SMTP_FILTER_RESPONSE:
572 		m_msg(&m, imsg);
573 		m_get_string(&m, &direction);
574 		m_get_timeval(&m, &tv);
575 		m_get_id(&m, &reqid);
576 		m_get_int(&m, &filter_phase);
577 		m_get_int(&m, &filter_response);
578 		m_get_string(&m, &filter_param);
579 		m_end(&m);
580 
581 		lka_report_smtp_filter_response(direction, &tv, reqid,
582 		    filter_phase, filter_response, filter_param);
583 		return;
584 
585 	case IMSG_REPORT_SMTP_TIMEOUT:
586 		m_msg(&m, imsg);
587 		m_get_string(&m, &direction);
588 		m_get_timeval(&m, &tv);
589 		m_get_id(&m, &reqid);
590 		m_end(&m);
591 
592 		lka_report_smtp_timeout(direction, &tv, reqid);
593 		return;
594 
595 	case IMSG_FILTER_SMTP_PROTOCOL:
596 		m_msg(&m, imsg);
597 		m_get_id(&m, &reqid);
598 		m_get_int(&m, &filter_phase);
599 		m_get_string(&m, &filter_param);
600 		m_end(&m);
601 
602 		lka_filter_protocol(reqid, filter_phase, filter_param);
603 		return;
604 
605 	case IMSG_FILTER_SMTP_BEGIN:
606 		m_msg(&m, imsg);
607 		m_get_id(&m, &reqid);
608 		m_get_string(&m, &filter_name);
609 		m_end(&m);
610 
611 		lka_filter_begin(reqid, filter_name);
612 		return;
613 
614 	case IMSG_FILTER_SMTP_END:
615 		m_msg(&m, imsg);
616 		m_get_id(&m, &reqid);
617 		m_end(&m);
618 
619 		lka_filter_end(reqid);
620 		return;
621 
622 	case IMSG_FILTER_SMTP_DATA_BEGIN:
623 		m_msg(&m, imsg);
624 		m_get_id(&m, &reqid);
625 		m_end(&m);
626 
627 		lka_filter_data_begin(reqid);
628 		return;
629 
630 	case IMSG_FILTER_SMTP_DATA_END:
631 		m_msg(&m, imsg);
632 		m_get_id(&m, &reqid);
633 		m_end(&m);
634 
635 		lka_filter_data_end(reqid);
636 		return;
637 
638 	}
639 
640 	errx(1, "lka_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
641 }
642 
643 static void
644 lka_sig_handler(int sig, short event, void *p)
645 {
646 	int status;
647 	pid_t pid;
648 
649 	switch (sig) {
650 	case SIGCHLD:
651 		do {
652 			pid = waitpid(-1, &status, WNOHANG);
653 		} while (pid > 0 || (pid == -1 && errno == EINTR));
654 		break;
655 	default:
656 		fatalx("lka_sig_handler: unexpected signal");
657 	}
658 }
659 
660 void
661 lka_shutdown(void)
662 {
663 	log_debug("debug: lookup agent exiting");
664 	_exit(0);
665 }
666 
667 int
668 lka(void)
669 {
670 	struct passwd	*pw;
671 	struct event	 ev_sigchld;
672 
673 	purge_config(PURGE_LISTENERS);
674 
675 	if ((pw = getpwnam(SMTPD_USER)) == NULL)
676 		fatalx("unknown user " SMTPD_USER);
677 
678 	config_process(PROC_LKA);
679 
680 	if (initgroups(pw->pw_name, pw->pw_gid) ||
681 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
682 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
683 		fatal("lka: cannot drop privileges");
684 
685 	imsg_callback = lka_imsg;
686 	event_init();
687 
688 	signal_set(&ev_sigchld, SIGCHLD, lka_sig_handler, NULL);
689 	signal_add(&ev_sigchld, NULL);
690 	signal(SIGINT, SIG_IGN);
691 	signal(SIGTERM, SIG_IGN);
692 	signal(SIGPIPE, SIG_IGN);
693 	signal(SIGHUP, SIG_IGN);
694 
695 	config_peer(PROC_PARENT);
696 	config_peer(PROC_QUEUE);
697 	config_peer(PROC_CONTROL);
698 	config_peer(PROC_DISPATCHER);
699 
700 	/* Ignore them until we get our config */
701 	mproc_disable(p_dispatcher);
702 
703 	lka_report_init();
704 	lka_filter_init();
705 
706 	/* proc & exec will be revoked before serving requests */
707 	if (pledge("stdio rpath inet dns getpw recvfd sendfd proc exec", NULL) == -1)
708 		err(1, "pledge");
709 
710 	event_dispatch();
711 	fatalx("exited event loop");
712 
713 	return (0);
714 }
715 
716 static void
717 proc_timeout(int fd, short event, void *p)
718 {
719 	struct event	*ev = p;
720 	struct timeval	 tv;
721 
722 	if (!lka_proc_ready())
723 		goto reset;
724 
725 	lka_filter_ready();
726 	mproc_enable(p_dispatcher);
727 	return;
728 
729 reset:
730 	tv.tv_sec = 0;
731 	tv.tv_usec = 10;
732 	evtimer_add(ev, &tv);
733 }
734 
735 
736 static int
737 lka_authenticate(const char *tablename, const char *user, const char *password)
738 {
739 	struct table		*table;
740 	union lookup		 lk;
741 
742 	log_debug("debug: lka: authenticating for %s:%s", tablename, user);
743 	table = table_find(env, tablename);
744 	if (table == NULL) {
745 		log_warnx("warn: could not find table %s needed for authentication",
746 		    tablename);
747 		return (LKA_TEMPFAIL);
748 	}
749 
750 	switch (table_lookup(table, K_CREDENTIALS, user, &lk)) {
751 	case -1:
752 		log_warnx("warn: user credentials lookup fail for %s:%s",
753 		    tablename, user);
754 		return (LKA_TEMPFAIL);
755 	case 0:
756 		return (LKA_PERMFAIL);
757 	default:
758 		if (crypt_checkpass(password, lk.creds.password) == 0)
759 			return (LKA_OK);
760 		return (LKA_PERMFAIL);
761 	}
762 }
763 
764 static int
765 lka_credentials(const char *tablename, const char *label, char *dst, size_t sz)
766 {
767 	struct table		*table;
768 	union lookup		 lk;
769 	char			*buf;
770 	int			 buflen, r;
771 
772 	table = table_find(env, tablename);
773 	if (table == NULL) {
774 		log_warnx("warn: credentials table %s missing", tablename);
775 		return (LKA_TEMPFAIL);
776 	}
777 
778 	dst[0] = '\0';
779 
780 	switch (table_lookup(table, K_CREDENTIALS, label, &lk)) {
781 	case -1:
782 		log_warnx("warn: credentials lookup fail for %s:%s",
783 		    tablename, label);
784 		return (LKA_TEMPFAIL);
785 	case 0:
786 		log_warnx("warn: credentials not found for %s:%s",
787 		    tablename, label);
788 		return (LKA_PERMFAIL);
789 	default:
790 		if ((buflen = asprintf(&buf, "%c%s%c%s", '\0',
791 		    lk.creds.username, '\0', lk.creds.password)) == -1) {
792 			log_warn("warn");
793 			return (LKA_TEMPFAIL);
794 		}
795 
796 		r = base64_encode((unsigned char *)buf, buflen, dst, sz);
797 		free(buf);
798 
799 		if (r == -1) {
800 			log_warnx("warn: credentials parse error for %s:%s",
801 			    tablename, label);
802 			return (LKA_TEMPFAIL);
803 		}
804 		return (LKA_OK);
805 	}
806 }
807 
808 static int
809 lka_userinfo(const char *tablename, const char *username, struct userinfo *res)
810 {
811 	struct table	*table;
812 	union lookup	 lk;
813 
814 	log_debug("debug: lka: userinfo %s:%s", tablename, username);
815 	table = table_find(env, tablename);
816 	if (table == NULL) {
817 		log_warnx("warn: cannot find user table %s", tablename);
818 		return (LKA_TEMPFAIL);
819 	}
820 
821 	switch (table_lookup(table, K_USERINFO, username, &lk)) {
822 	case -1:
823 		log_warnx("warn: failure during userinfo lookup %s:%s",
824 		    tablename, username);
825 		return (LKA_TEMPFAIL);
826 	case 0:
827 		return (LKA_PERMFAIL);
828 	default:
829 		*res = lk.userinfo;
830 		return (LKA_OK);
831 	}
832 }
833 
834 static int
835 lka_addrname(const char *tablename, const struct sockaddr *sa,
836     struct addrname *res)
837 {
838 	struct table	*table;
839 	union lookup	 lk;
840 	const char	*source;
841 
842 	source = sa_to_text(sa);
843 
844 	log_debug("debug: lka: helo %s:%s", tablename, source);
845 	table = table_find(env, tablename);
846 	if (table == NULL) {
847 		log_warnx("warn: cannot find helo table %s", tablename);
848 		return (LKA_TEMPFAIL);
849 	}
850 
851 	switch (table_lookup(table, K_ADDRNAME, source, &lk)) {
852 	case -1:
853 		log_warnx("warn: failure during helo lookup %s:%s",
854 		    tablename, source);
855 		return (LKA_TEMPFAIL);
856 	case 0:
857 		return (LKA_PERMFAIL);
858 	default:
859 		*res = lk.addrname;
860 		return (LKA_OK);
861 	}
862 }
863 
864 static int
865 lka_mailaddrmap(const char *tablename, const char *username, const struct mailaddr *maddr)
866 {
867 	struct table	       *table;
868 	struct maddrnode       *mn;
869 	union lookup		lk;
870 	int			found;
871 
872 	log_debug("debug: lka: mailaddrmap %s:%s", tablename, username);
873 	table = table_find(env, tablename);
874 	if (table == NULL) {
875 		log_warnx("warn: cannot find mailaddrmap table %s", tablename);
876 		return (LKA_TEMPFAIL);
877 	}
878 
879 	switch (table_lookup(table, K_MAILADDRMAP, username, &lk)) {
880 	case -1:
881 		log_warnx("warn: failure during mailaddrmap lookup %s:%s",
882 		    tablename, username);
883 		return (LKA_TEMPFAIL);
884 	case 0:
885 		return (LKA_PERMFAIL);
886 	default:
887 		found = 0;
888 		TAILQ_FOREACH(mn, &lk.maddrmap->queue, entries) {
889 			if (!mailaddr_match(maddr, &mn->mailaddr))
890 				continue;
891 			found = 1;
892 			break;
893 		}
894 		maddrmap_free(lk.maddrmap);
895 		if (found)
896 			return (LKA_OK);
897 		return (LKA_PERMFAIL);
898 	}
899 	return (LKA_OK);
900 }
901