xref: /openbsd-src/usr.sbin/smtpd/smtpctl.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: smtpctl.c,v 1.151 2016/09/04 09:33:49 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
5  * Copyright (c) 2006 Gilles Chehade <gilles@poolp.org>
6  * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
7  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
8  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
9  * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
10  *
11  * Permission to use, copy, modify, and distribute this software for any
12  * purpose with or without fee is hereby granted, provided that the above
13  * copyright notice and this permission notice appear in all copies.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23 
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <sys/queue.h>
27 #include <sys/tree.h>
28 #include <sys/un.h>
29 #include <sys/wait.h>
30 #include <sys/stat.h>
31 
32 #include <err.h>
33 #include <errno.h>
34 #include <event.h>
35 #include <fts.h>
36 #include <imsg.h>
37 #include <inttypes.h>
38 #include <pwd.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <time.h>
43 #include <unistd.h>
44 #include <limits.h>
45 
46 #include "smtpd.h"
47 #include "parser.h"
48 #include "log.h"
49 
50 #define PATH_GZCAT	"/usr/bin/gzcat"
51 #define	PATH_CAT	"/bin/cat"
52 #define PATH_QUEUE	"/queue"
53 #define PATH_ENCRYPT	"/usr/bin/encrypt"
54 
55 int srv_connect(void);
56 int srv_connected(void);
57 
58 void usage(void);
59 static void show_queue_envelope(struct envelope *, int);
60 static void getflag(uint *, int, char *, char *, size_t);
61 static void display(const char *);
62 static int str_to_trace(const char *);
63 static int str_to_profile(const char *);
64 static void show_offline_envelope(uint64_t);
65 static int is_gzip_fp(FILE *);
66 static int is_encrypted_fp(FILE *);
67 static int is_encrypted_buffer(const char *);
68 static int is_gzip_buffer(const char *);
69 static FILE *offline_file(void);
70 static void sendmail_compat(int, char **);
71 
72 extern char	*__progname;
73 int		 sendmail;
74 struct smtpd	*env;
75 struct imsgbuf	*ibuf;
76 struct imsg	 imsg;
77 char		*rdata;
78 size_t		 rlen;
79 time_t		 now;
80 
81 struct queue_backend queue_backend_null;
82 struct queue_backend queue_backend_proc;
83 struct queue_backend queue_backend_ram;
84 
85 __dead void
86 usage(void)
87 {
88 	if (sendmail)
89 		fprintf(stderr, "usage: %s [-tv] [-f from] [-F name] to ...\n",
90 		    __progname);
91 	else
92 		fprintf(stderr, "usage: %s command [argument ...]\n",
93 		    __progname);
94 	exit(1);
95 }
96 
97 void stat_increment(const char *k, size_t v)
98 {
99 }
100 
101 void stat_decrement(const char *k, size_t v)
102 {
103 }
104 
105 int
106 srv_connect(void)
107 {
108 	struct sockaddr_un	s_un;
109 	int			ctl_sock, saved_errno;
110 
111 	/* connect to smtpd control socket */
112 	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
113 		err(1, "socket");
114 
115 	memset(&s_un, 0, sizeof(s_un));
116 	s_un.sun_family = AF_UNIX;
117 	(void)strlcpy(s_un.sun_path, SMTPD_SOCKET, sizeof(s_un.sun_path));
118 	if (connect(ctl_sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
119 		saved_errno = errno;
120 		close(ctl_sock);
121 		errno = saved_errno;
122 		return (0);
123 	}
124 
125 	ibuf = xcalloc(1, sizeof(struct imsgbuf), "smtpctl:srv_connect");
126 	imsg_init(ibuf, ctl_sock);
127 
128 	return (1);
129 }
130 
131 int
132 srv_connected(void)
133 {
134 	return ibuf != NULL ? 1 : 0;
135 }
136 
137 FILE *
138 offline_file(void)
139 {
140 	char	path[PATH_MAX];
141 	int	fd;
142 	FILE   *fp;
143 
144 	if (!bsnprintf(path, sizeof(path), "%s%s/%lld.XXXXXXXXXX", PATH_SPOOL,
145 		PATH_OFFLINE, (long long int) time(NULL)))
146 		err(EX_UNAVAILABLE, "snprintf");
147 
148 	if ((fd = mkstemp(path)) == -1 || (fp = fdopen(fd, "w+")) == NULL) {
149 		if (fd != -1)
150 			unlink(path);
151 		err(EX_UNAVAILABLE, "cannot create temporary file %s", path);
152 	}
153 
154 	if (fchmod(fd, 0600) == -1) {
155 		unlink(path);
156 		err(EX_SOFTWARE, "fchmod");
157 	}
158 
159 	return fp;
160 }
161 
162 
163 static void
164 srv_flush(void)
165 {
166 	if (imsg_flush(ibuf) == -1)
167 		err(1, "write error");
168 }
169 
170 static void
171 srv_send(int msg, const void *data, size_t len)
172 {
173 	if (ibuf == NULL && !srv_connect())
174 		errx(1, "smtpd doesn't seem to be running");
175 	imsg_compose(ibuf, msg, IMSG_VERSION, 0, -1, data, len);
176 }
177 
178 static void
179 srv_recv(int type)
180 {
181 	ssize_t	n;
182 
183 	srv_flush();
184 
185 	while (1) {
186 		if ((n = imsg_get(ibuf, &imsg)) == -1)
187 			errx(1, "imsg_get error");
188 		if (n) {
189 			if (imsg.hdr.type == IMSG_CTL_FAIL &&
190 			    imsg.hdr.peerid != 0 &&
191 			    imsg.hdr.peerid != IMSG_VERSION)
192 				errx(1, "incompatible smtpctl and smtpd");
193 			if (type != -1 && type != (int)imsg.hdr.type)
194 				errx(1, "bad message type");
195 			rdata = imsg.data;
196 			rlen = imsg.hdr.len - sizeof(imsg.hdr);
197 			break;
198 		}
199 
200 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
201 			errx(1, "imsg_read error");
202 		if (n == 0)
203 			errx(1, "pipe closed");
204 	}
205 }
206 
207 static void
208 srv_read(void *dst, size_t sz)
209 {
210 	if (sz == 0)
211 		return;
212 	if (rlen < sz)
213 		errx(1, "message too short");
214 	if (dst)
215 		memmove(dst, rdata, sz);
216 	rlen -= sz;
217 	rdata += sz;
218 }
219 
220 static void
221 srv_get_int(int *i)
222 {
223 	srv_read(i, sizeof(*i));
224 }
225 
226 static void
227 srv_get_time(time_t *t)
228 {
229 	srv_read(t, sizeof(*t));
230 }
231 
232 static void
233 srv_get_evpid(uint64_t *evpid)
234 {
235 	srv_read(evpid, sizeof(*evpid));
236 }
237 
238 static void
239 srv_get_string(const char **s)
240 {
241 	const char *end;
242 	size_t len;
243 
244 	if (rlen == 0)
245 		errx(1, "message too short");
246 
247 	end = memchr(rdata, 0, rlen);
248 	if (end == NULL)
249 		errx(1, "unterminated string");
250 
251 	len = end + 1 - rdata;
252 
253 	*s = rdata;
254 	rlen -= len;
255 	rdata += len;
256 }
257 
258 static void
259 srv_get_envelope(struct envelope *evp)
260 {
261 	uint64_t	 evpid;
262 	const char	*str;
263 
264 	srv_get_evpid(&evpid);
265 	srv_get_string(&str);
266 
267 	envelope_load_buffer(evp, str, strlen(str));
268 	evp->id = evpid;
269 }
270 
271 static void
272 srv_end(void)
273 {
274 	if (rlen)
275 		errx(1, "bogus data");
276 	imsg_free(&imsg);
277 }
278 
279 static int
280 srv_check_result(int verbose_)
281 {
282 	srv_recv(-1);
283 	srv_end();
284 
285 	switch (imsg.hdr.type) {
286 	case IMSG_CTL_OK:
287 		if (verbose_)
288 			printf("command succeeded\n");
289 		return (0);
290 	case IMSG_CTL_FAIL:
291 		if (verbose_) {
292 			if (rlen)
293 				printf("command failed: %s\n", rdata);
294 			else
295 				printf("command failed\n");
296 		}
297 		return (1);
298 	default:
299 		errx(1, "wrong message in response: %u", imsg.hdr.type);
300 	}
301 	return (0);
302 }
303 
304 static int
305 srv_iter_messages(uint32_t *res)
306 {
307 	static uint32_t	*msgids = NULL, from = 0;
308 	static size_t	 n, curr;
309 	static int	 done = 0;
310 
311 	if (done)
312 		return (0);
313 
314 	if (msgids == NULL) {
315 		srv_send(IMSG_CTL_LIST_MESSAGES, &from, sizeof(from));
316 		srv_recv(IMSG_CTL_LIST_MESSAGES);
317 		if (rlen == 0) {
318 			srv_end();
319 			done = 1;
320 			return (0);
321 		}
322 		msgids = malloc(rlen);
323 		n = rlen / sizeof(*msgids);
324 		srv_read(msgids, rlen);
325 		srv_end();
326 
327 		curr = 0;
328 		from = msgids[n - 1] + 1;
329 		if (from == 0)
330 			done = 1;
331 	}
332 
333 	*res = msgids[curr++];
334 	if (curr == n) {
335 		free(msgids);
336 		msgids = NULL;
337 	}
338 
339 	return (1);
340 }
341 
342 static int
343 srv_iter_envelopes(uint32_t msgid, struct envelope *evp)
344 {
345 	static uint32_t	currmsgid = 0;
346 	static uint64_t	from = 0;
347 	static int	done = 0, need_send = 1, found;
348 	int		flags;
349 	time_t		nexttry;
350 
351 	if (currmsgid != msgid) {
352 		if (currmsgid != 0 && !done)
353 			errx(1, "must finish current iteration first");
354 		currmsgid = msgid;
355 		from = msgid_to_evpid(msgid);
356 		done = 0;
357 		found = 0;
358 		need_send = 1;
359 	}
360 
361 	if (done)
362 		return (0);
363 
364     again:
365 	if (need_send) {
366 		found = 0;
367 		srv_send(IMSG_CTL_LIST_ENVELOPES, &from, sizeof(from));
368 	}
369 	need_send = 0;
370 
371 	srv_recv(IMSG_CTL_LIST_ENVELOPES);
372 	if (rlen == 0) {
373 		srv_end();
374 		if (!found || evpid_to_msgid(from) != msgid) {
375 			done = 1;
376 			return (0);
377 		}
378 		need_send = 1;
379 		goto again;
380 	}
381 
382 	srv_get_int(&flags);
383 	srv_get_time(&nexttry);
384 	srv_get_envelope(evp);
385 	srv_end();
386 
387 	evp->flags |= flags;
388 	evp->nexttry = nexttry;
389 
390 	from = evp->id + 1;
391 	found++;
392 	return (1);
393 }
394 
395 static int
396 srv_iter_evpids(uint32_t msgid, uint64_t *evpid, int *offset)
397 {
398 	static uint64_t	*evpids = NULL, *tmp;
399 	static int	 n, alloc = 0;
400 	struct envelope	 evp;
401 
402 	if (evpids == NULL) {
403 		alloc = 1000;
404 		evpids = calloc(alloc, sizeof(*evpids));
405 		if (evpids == NULL)
406 			err(1, "calloc");
407 	}
408 
409 	if (*offset == 0) {
410 		n = 0;
411 		while (srv_iter_envelopes(msgid, &evp)) {
412 			if (n == alloc) {
413 				alloc += 256;
414 				tmp = reallocarray(evpids, alloc,
415 				    sizeof(*evpids));
416 				if (tmp == NULL)
417 					err(1, "reallocarray");
418 				evpids = tmp;
419 			}
420 			evpids[n++] = evp.id;
421 		}
422 	}
423 
424 	if (*offset >= n)
425 		return (0);
426 	*evpid = evpids[*offset];
427 	*offset += 1;
428 	return (1);
429 }
430 
431 static void
432 srv_foreach_envelope(struct parameter *argv, int ctl, size_t *total, size_t *ok)
433 {
434 	uint32_t	msgid;
435 	uint64_t	evpid;
436 	int		i;
437 
438 	*total = 0;
439 	*ok = 0;
440 
441 	if (argv == NULL) {
442 		while (srv_iter_messages(&msgid)) {
443 			i = 0;
444 			while (srv_iter_evpids(msgid, &evpid, &i)) {
445 				*total += 1;
446 				srv_send(ctl, &evpid, sizeof(evpid));
447 				if (srv_check_result(0) == 0)
448 					*ok += 1;
449 			}
450 		}
451 	} else if (argv->type == P_MSGID) {
452 		i = 0;
453 		while (srv_iter_evpids(argv->u.u_msgid, &evpid, &i)) {
454 			srv_send(ctl, &evpid, sizeof(evpid));
455 			if (srv_check_result(0) == 0)
456 				*ok += 1;
457 		}
458 	} else {
459 		*total += 1;
460 		srv_send(ctl, &argv->u.u_evpid, sizeof(evpid));
461 		if (srv_check_result(0) == 0)
462 			*ok += 1;
463 	}
464 }
465 
466 static void
467 srv_show_cmd(int cmd, const void *data, size_t len)
468 {
469 	int	done = 0;
470 
471 	srv_send(cmd, data, len);
472 
473 	do {
474 		srv_recv(cmd);
475 		if (rlen) {
476 			printf("%s\n", rdata);
477 			srv_read(NULL, rlen);
478 		}
479 		else
480 			done = 1;
481 		srv_end();
482 	} while (!done);
483 }
484 
485 static int
486 do_log_brief(int argc, struct parameter *argv)
487 {
488 	int	v = 0;
489 
490 	srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v));
491 	return srv_check_result(1);
492 }
493 
494 static int
495 do_log_verbose(int argc, struct parameter *argv)
496 {
497 	int	v = TRACE_DEBUG;
498 
499 	srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v));
500 	return srv_check_result(1);
501 }
502 
503 static int
504 do_monitor(int argc, struct parameter *argv)
505 {
506 	struct stat_digest	last, digest;
507 	size_t			count;
508 
509 	memset(&last, 0, sizeof(last));
510 	count = 0;
511 
512 	while (1) {
513 		srv_send(IMSG_CTL_GET_DIGEST, NULL, 0);
514 		srv_recv(IMSG_CTL_GET_DIGEST);
515 		srv_read(&digest, sizeof(digest));
516 		srv_end();
517 
518 		if (count % 25 == 0) {
519 			if (count != 0)
520 				printf("\n");
521 			printf("--- client ---  "
522 			    "-- envelope --   "
523 			    "---- relay/delivery --- "
524 			    "------- misc -------\n"
525 			    "curr conn disc  "
526 			    "curr  enq  deq   "
527 			    "ok tmpfail prmfail loop "
528 			    "expire remove bounce\n");
529 		}
530 		printf("%4zu %4zu %4zu  "
531 		    "%4zu %4zu %4zu "
532 		    "%4zu    %4zu    %4zu %4zu   "
533 		    "%4zu   %4zu   %4zu\n",
534 		    digest.clt_connect - digest.clt_disconnect,
535 		    digest.clt_connect - last.clt_connect,
536 		    digest.clt_disconnect - last.clt_disconnect,
537 
538 		    digest.evp_enqueued - digest.evp_dequeued,
539 		    digest.evp_enqueued - last.evp_enqueued,
540 		    digest.evp_dequeued - last.evp_dequeued,
541 
542 		    digest.dlv_ok - last.dlv_ok,
543 		    digest.dlv_tempfail - last.dlv_tempfail,
544 		    digest.dlv_permfail - last.dlv_permfail,
545 		    digest.dlv_loop - last.dlv_loop,
546 
547 		    digest.evp_expired - last.evp_expired,
548 		    digest.evp_removed - last.evp_removed,
549 		    digest.evp_bounce - last.evp_bounce);
550 
551 		last = digest;
552 		count++;
553 		sleep(1);
554 	}
555 
556 	return (0);
557 }
558 
559 static int
560 do_pause_envelope(int argc, struct parameter *argv)
561 {
562 	size_t	total, ok;
563 
564 	srv_foreach_envelope(argv, IMSG_CTL_PAUSE_EVP, &total, &ok);
565 	printf("%zu envelope%s paused\n", ok, (ok > 1) ? "s" : "");
566 
567 	return (0);
568 }
569 
570 static int
571 do_pause_mda(int argc, struct parameter *argv)
572 {
573 	srv_send(IMSG_CTL_PAUSE_MDA, NULL, 0);
574 	return srv_check_result(1);
575 }
576 
577 static int
578 do_pause_mta(int argc, struct parameter *argv)
579 {
580 	srv_send(IMSG_CTL_PAUSE_MTA, NULL, 0);
581 	return srv_check_result(1);
582 }
583 
584 static int
585 do_pause_smtp(int argc, struct parameter *argv)
586 {
587 	srv_send(IMSG_CTL_PAUSE_SMTP, NULL, 0);
588 	return srv_check_result(1);
589 }
590 
591 static int
592 do_profile(int argc, struct parameter *argv)
593 {
594 	int	v;
595 
596 	v = str_to_profile(argv[0].u.u_str);
597 
598 	srv_send(IMSG_CTL_PROFILE_ENABLE, &v, sizeof(v));
599 	return srv_check_result(1);
600 }
601 
602 static int
603 do_remove(int argc, struct parameter *argv)
604 {
605 	size_t	total, ok;
606 
607 	srv_foreach_envelope(argv, IMSG_CTL_REMOVE, &total, &ok);
608 	printf("%zu envelope%s removed\n", ok, (ok > 1) ? "s" : "");
609 
610 	return (0);
611 }
612 
613 static int
614 do_resume_envelope(int argc, struct parameter *argv)
615 {
616 	size_t	total, ok;
617 
618 	srv_foreach_envelope(argv, IMSG_CTL_RESUME_EVP, &total, &ok);
619 	printf("%zu envelope%s resumed\n", ok, (ok > 1) ? "s" : "");
620 
621 	return (0);
622 }
623 
624 static int
625 do_resume_mda(int argc, struct parameter *argv)
626 {
627 	srv_send(IMSG_CTL_RESUME_MDA, NULL, 0);
628 	return srv_check_result(1);
629 }
630 
631 static int
632 do_resume_mta(int argc, struct parameter *argv)
633 {
634 	srv_send(IMSG_CTL_RESUME_MTA, NULL, 0);
635 	return srv_check_result(1);
636 }
637 
638 static int
639 do_resume_route(int argc, struct parameter *argv)
640 {
641 	uint64_t	v;
642 
643 	if (argc == 0)
644 		v = 0;
645 	else
646 		v = argv[0].u.u_routeid;
647 
648 	srv_send(IMSG_CTL_RESUME_ROUTE, &v, sizeof(v));
649 	return srv_check_result(1);
650 }
651 
652 static int
653 do_resume_smtp(int argc, struct parameter *argv)
654 {
655 	srv_send(IMSG_CTL_RESUME_SMTP, NULL, 0);
656 	return srv_check_result(1);
657 }
658 
659 static int
660 do_schedule(int argc, struct parameter *argv)
661 {
662 	size_t	total, ok;
663 
664 	srv_foreach_envelope(argv, IMSG_CTL_SCHEDULE, &total, &ok);
665 	printf("%zu envelope%s scheduled\n", ok, (ok > 1) ? "s" : "");
666 
667 	return (0);
668 }
669 
670 static int
671 do_show_envelope(int argc, struct parameter *argv)
672 {
673 	char	 buf[PATH_MAX];
674 
675 	if (!bsnprintf(buf, sizeof(buf), "%s%s/%02x/%08x/%016" PRIx64,
676 	    PATH_SPOOL,
677 	    PATH_QUEUE,
678 	    (evpid_to_msgid(argv[0].u.u_evpid) & 0xff000000) >> 24,
679 	    evpid_to_msgid(argv[0].u.u_evpid),
680 	    argv[0].u.u_evpid))
681 		errx(1, "unable to retrieve envelope");
682 
683 	display(buf);
684 
685 	return (0);
686 }
687 
688 static int
689 do_show_hoststats(int argc, struct parameter *argv)
690 {
691 	srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTSTATS, NULL, 0);
692 
693 	return (0);
694 }
695 
696 static int
697 do_show_message(int argc, struct parameter *argv)
698 {
699 	char	 buf[PATH_MAX];
700 	uint32_t msgid;
701 
702 	if (argv[0].type == P_EVPID)
703 		msgid = evpid_to_msgid(argv[0].u.u_evpid);
704 	else
705 		msgid = argv[0].u.u_msgid;
706 
707 	if (!bsnprintf(buf, sizeof(buf), "%s%s/%02x/%08x/message",
708 		PATH_SPOOL,
709 		PATH_QUEUE,
710 		(msgid & 0xff000000) >> 24,
711 		msgid))
712 		errx(1, "unable to retrieve message");
713 
714 	display(buf);
715 
716 	return (0);
717 }
718 
719 static int
720 do_show_queue(int argc, struct parameter *argv)
721 {
722 	struct envelope	 evp;
723 	uint32_t	 msgid;
724 	FTS		*fts;
725 	FTSENT		*ftse;
726 	char		*qpath[] = {"/queue", NULL};
727 	char		*tmp;
728 	uint64_t	 evpid;
729 
730 	now = time(NULL);
731 
732 	if (!srv_connect()) {
733 		log_init(1);
734 		queue_init("fs", 0);
735 		if (chroot(PATH_SPOOL) == -1 || chdir("/") == -1)
736 			err(1, "%s", PATH_SPOOL);
737 		fts = fts_open(qpath, FTS_PHYSICAL|FTS_NOCHDIR, NULL);
738 		if (fts == NULL)
739 			err(1, "%s/queue", PATH_SPOOL);
740 
741 		while ((ftse = fts_read(fts)) != NULL) {
742 			switch (ftse->fts_info) {
743 			case FTS_DP:
744 			case FTS_DNR:
745 				break;
746 			case FTS_F:
747 				tmp = NULL;
748 				evpid = strtoull(ftse->fts_name, &tmp, 16);
749 				if (tmp && *tmp != '\0')
750 					break;
751 				show_offline_envelope(evpid);
752 			}
753 		}
754 
755 		fts_close(fts);
756 		return (0);
757 	}
758 
759 	if (argc == 0) {
760 		msgid = 0;
761 		while (srv_iter_messages(&msgid))
762 			while (srv_iter_envelopes(msgid, &evp))
763 				show_queue_envelope(&evp, 1);
764 	} else if (argv[0].type == P_MSGID) {
765 		while (srv_iter_envelopes(argv[0].u.u_msgid, &evp))
766 			show_queue_envelope(&evp, 1);
767 	}
768 
769 	return (0);
770 }
771 
772 static int
773 do_show_hosts(int argc, struct parameter *argv)
774 {
775 	srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTS, NULL, 0);
776 
777 	return (0);
778 }
779 
780 static int
781 do_show_relays(int argc, struct parameter *argv)
782 {
783 	srv_show_cmd(IMSG_CTL_MTA_SHOW_RELAYS, NULL, 0);
784 
785 	return (0);
786 }
787 
788 static int
789 do_show_routes(int argc, struct parameter *argv)
790 {
791 	srv_show_cmd(IMSG_CTL_MTA_SHOW_ROUTES, NULL, 0);
792 
793 	return (0);
794 }
795 
796 static int
797 do_show_stats(int argc, struct parameter *argv)
798 {
799 	struct stat_kv	kv;
800 	time_t		duration;
801 
802 	memset(&kv, 0, sizeof kv);
803 
804 	while (1) {
805 		srv_send(IMSG_CTL_GET_STATS, &kv, sizeof kv);
806 		srv_recv(IMSG_CTL_GET_STATS);
807 		srv_read(&kv, sizeof(kv));
808 		srv_end();
809 
810 		if (kv.iter == NULL)
811 			break;
812 
813 		if (strcmp(kv.key, "uptime") == 0) {
814 			duration = time(NULL) - kv.val.u.counter;
815 			printf("uptime=%lld\n", (long long)duration);
816 			printf("uptime.human=%s\n",
817 			    duration_to_text(duration));
818 		}
819 		else {
820 			switch (kv.val.type) {
821 			case STAT_COUNTER:
822 				printf("%s=%zd\n",
823 				    kv.key, kv.val.u.counter);
824 				break;
825 			case STAT_TIMESTAMP:
826 				printf("%s=%" PRId64 "\n",
827 				    kv.key, (int64_t)kv.val.u.timestamp);
828 				break;
829 			case STAT_TIMEVAL:
830 				printf("%s=%lld.%lld\n",
831 				    kv.key, (long long)kv.val.u.tv.tv_sec,
832 				    (long long)kv.val.u.tv.tv_usec);
833 				break;
834 			case STAT_TIMESPEC:
835 				printf("%s=%lld.%06ld\n",
836 				    kv.key,
837 				    (long long)kv.val.u.ts.tv_sec * 1000000 +
838 				    kv.val.u.ts.tv_nsec / 1000000,
839 				    kv.val.u.ts.tv_nsec % 1000000);
840 				break;
841 			}
842 		}
843 	}
844 
845 	return (0);
846 }
847 
848 static int
849 do_show_status(int argc, struct parameter *argv)
850 {
851 	uint32_t	sc_flags;
852 
853 	srv_send(IMSG_CTL_SHOW_STATUS, NULL, 0);
854 	srv_recv(IMSG_CTL_SHOW_STATUS);
855 	srv_read(&sc_flags, sizeof(sc_flags));
856 	srv_end();
857 	printf("MDA %s\n",
858 	    (sc_flags & SMTPD_MDA_PAUSED) ? "paused" : "running");
859 	printf("MTA %s\n",
860 	    (sc_flags & SMTPD_MTA_PAUSED) ? "paused" : "running");
861 	printf("SMTP %s\n",
862 	    (sc_flags & SMTPD_SMTP_PAUSED) ? "paused" : "running");
863 	return (0);
864 }
865 
866 static int
867 do_trace(int argc, struct parameter *argv)
868 {
869 	int	v;
870 
871 	v = str_to_trace(argv[0].u.u_str);
872 
873 	srv_send(IMSG_CTL_TRACE_ENABLE, &v, sizeof(v));
874 	return srv_check_result(1);
875 }
876 
877 static int
878 do_unprofile(int argc, struct parameter *argv)
879 {
880 	int	v;
881 
882 	v = str_to_profile(argv[0].u.u_str);
883 
884 	srv_send(IMSG_CTL_PROFILE_DISABLE, &v, sizeof(v));
885 	return srv_check_result(1);
886 }
887 
888 static int
889 do_untrace(int argc, struct parameter *argv)
890 {
891 	int	v;
892 
893 	v = str_to_trace(argv[0].u.u_str);
894 
895 	srv_send(IMSG_CTL_TRACE_DISABLE, &v, sizeof(v));
896 	return srv_check_result(1);
897 }
898 
899 static int
900 do_update_table(int argc, struct parameter *argv)
901 {
902 	const char	*name = argv[0].u.u_str;
903 
904 	srv_send(IMSG_CTL_UPDATE_TABLE, name, strlen(name) + 1);
905 	return srv_check_result(1);
906 }
907 
908 static int
909 do_encrypt(int argc, struct parameter *argv)
910 {
911 	const char *p = NULL;
912 
913 	if (argv)
914 		p = argv[0].u.u_str;
915 	execl(PATH_ENCRYPT, "encrypt", p, (char *)NULL);
916 	errx(1, "execl");
917 }
918 
919 static int
920 do_block_mta(int argc, struct parameter *argv)
921 {
922 	struct ibuf *m;
923 
924 	if (ibuf == NULL && !srv_connect())
925 		errx(1, "smtpd doesn't seem to be running");
926 	m = imsg_create(ibuf, IMSG_CTL_MTA_BLOCK, IMSG_VERSION, 0,
927 	    sizeof(argv[0].u.u_ss) + strlen(argv[1].u.u_str) + 1);
928 	if (imsg_add(m, &argv[0].u.u_ss, sizeof(argv[0].u.u_ss)) == -1)
929 		errx(1, "imsg_add");
930 	if (imsg_add(m, argv[1].u.u_str, strlen(argv[1].u.u_str) + 1) == -1)
931 		errx(1, "imsg_add");
932 	imsg_close(ibuf, m);
933 
934 	return srv_check_result(1);
935 }
936 
937 static int
938 do_unblock_mta(int argc, struct parameter *argv)
939 {
940 	struct ibuf *m;
941 
942 	if (ibuf == NULL && !srv_connect())
943 		errx(1, "smtpd doesn't seem to be running");
944 
945 	m = imsg_create(ibuf, IMSG_CTL_MTA_UNBLOCK, IMSG_VERSION, 0,
946 	    sizeof(argv[0].u.u_ss) + strlen(argv[1].u.u_str) + 1);
947 	if (imsg_add(m, &argv[0].u.u_ss, sizeof(argv[0].u.u_ss)) == -1)
948 		errx(1, "imsg_add");
949 	if (imsg_add(m, argv[1].u.u_str, strlen(argv[1].u.u_str) + 1) == -1)
950 		errx(1, "imsg_add");
951 	imsg_close(ibuf, m);
952 
953 	return srv_check_result(1);
954 }
955 
956 static int
957 do_show_mta_block(int argc, struct parameter *argv)
958 {
959 	srv_show_cmd(IMSG_CTL_MTA_SHOW_BLOCK, NULL, 0);
960 
961 	return (0);
962 }
963 
964 static int
965 do_discover(int argc, struct parameter *argv)
966 {
967 	uint64_t evpid;
968 	uint32_t msgid;
969 	size_t	 n_evp;
970 
971 	if (ibuf == NULL && !srv_connect())
972 		errx(1, "smtpd doesn't seem to be running");
973 
974 	if (argv[0].type == P_EVPID) {
975 		evpid = argv[0].u.u_evpid;
976 		srv_send(IMSG_CTL_DISCOVER_EVPID, &evpid, sizeof evpid);
977 		srv_recv(IMSG_CTL_DISCOVER_EVPID);
978 	} else {
979 		msgid = argv[0].u.u_msgid;
980 		srv_send(IMSG_CTL_DISCOVER_MSGID, &msgid, sizeof msgid);
981 		srv_recv(IMSG_CTL_DISCOVER_MSGID);
982 	}
983 
984 	if (rlen == 0) {
985 		srv_end();
986 		return (0);
987 	} else {
988 		srv_read(&n_evp, sizeof n_evp);
989 		srv_end();
990 	}
991 
992 	printf("%zu envelope%s discovered\n", n_evp, (n_evp != 1) ? "s" : "");
993 	return (0);
994 }
995 
996 static int
997 do_uncorrupt(int argc, struct parameter *argv)
998 {
999 	uint32_t msgid;
1000 	int	 ret;
1001 
1002 	if (ibuf == NULL && !srv_connect())
1003 		errx(1, "smtpd doesn't seem to be running");
1004 
1005 	msgid = argv[0].u.u_msgid;
1006 	srv_send(IMSG_CTL_UNCORRUPT_MSGID, &msgid, sizeof msgid);
1007 	srv_recv(IMSG_CTL_UNCORRUPT_MSGID);
1008 
1009 	if (rlen == 0) {
1010 		srv_end();
1011 		return (0);
1012 	} else {
1013 		srv_read(&ret, sizeof ret);
1014 		srv_end();
1015 	}
1016 
1017 	printf("command %s\n", ret ? "succeeded" : "failed");
1018 	return (0);
1019 }
1020 
1021 int
1022 main(int argc, char **argv)
1023 {
1024 	gid_t		 gid;
1025 	char		*argv_mailq[] = { "show", "queue", NULL };
1026 
1027 	sendmail_compat(argc, argv);
1028 	if (geteuid())
1029 		errx(1, "need root privileges");
1030 
1031 	gid = getgid();
1032 	if (setresgid(gid, gid, gid) == -1)
1033 		err(1, "setresgid");
1034 
1035 	cmd_install("discover <evpid>",		do_discover);
1036 	cmd_install("discover <msgid>",		do_discover);
1037 	cmd_install("encrypt",			do_encrypt);
1038 	cmd_install("encrypt <str>",		do_encrypt);
1039 	cmd_install("pause mta from <addr> for <str>", do_block_mta);
1040 	cmd_install("resume mta from <addr> for <str>", do_unblock_mta);
1041 	cmd_install("show mta paused",		do_show_mta_block);
1042 	cmd_install("log brief",		do_log_brief);
1043 	cmd_install("log verbose",		do_log_verbose);
1044 	cmd_install("monitor",			do_monitor);
1045 	cmd_install("pause envelope <evpid>",	do_pause_envelope);
1046 	cmd_install("pause envelope <msgid>",	do_pause_envelope);
1047 	cmd_install("pause envelope all",	do_pause_envelope);
1048 	cmd_install("pause mda",		do_pause_mda);
1049 	cmd_install("pause mta",		do_pause_mta);
1050 	cmd_install("pause smtp",		do_pause_smtp);
1051 	cmd_install("profile <str>",		do_profile);
1052 	cmd_install("remove <evpid>",		do_remove);
1053 	cmd_install("remove <msgid>",		do_remove);
1054 	cmd_install("remove all",		do_remove);
1055 	cmd_install("resume envelope <evpid>",	do_resume_envelope);
1056 	cmd_install("resume envelope <msgid>",	do_resume_envelope);
1057 	cmd_install("resume envelope all",	do_resume_envelope);
1058 	cmd_install("resume mda",		do_resume_mda);
1059 	cmd_install("resume mta",		do_resume_mta);
1060 	cmd_install("resume route <routeid>",	do_resume_route);
1061 	cmd_install("resume smtp",		do_resume_smtp);
1062 	cmd_install("schedule <msgid>",		do_schedule);
1063 	cmd_install("schedule <evpid>",		do_schedule);
1064 	cmd_install("schedule all",		do_schedule);
1065 	cmd_install("show envelope <evpid>",	do_show_envelope);
1066 	cmd_install("show hoststats",		do_show_hoststats);
1067 	cmd_install("show message <msgid>",	do_show_message);
1068 	cmd_install("show message <evpid>",	do_show_message);
1069 	cmd_install("show queue",		do_show_queue);
1070 	cmd_install("show queue <msgid>",	do_show_queue);
1071 	cmd_install("show hosts",		do_show_hosts);
1072 	cmd_install("show relays",		do_show_relays);
1073 	cmd_install("show routes",		do_show_routes);
1074 	cmd_install("show stats",		do_show_stats);
1075 	cmd_install("show status",		do_show_status);
1076 	cmd_install("trace <str>",		do_trace);
1077 	cmd_install("uncorrupt <msgid>",	do_uncorrupt);
1078 	cmd_install("unprofile <str>",		do_unprofile);
1079 	cmd_install("untrace <str>",		do_untrace);
1080 	cmd_install("update table <str>",	do_update_table);
1081 
1082 	if (strcmp(__progname, "mailq") == 0)
1083 		return cmd_run(2, argv_mailq);
1084 	if (strcmp(__progname, "smtpctl") == 0)
1085 		return cmd_run(argc - 1, argv + 1);
1086 
1087 	errx(1, "unsupported mode");
1088 	return (0);
1089 }
1090 
1091 void
1092 sendmail_compat(int argc, char **argv)
1093 {
1094 	FILE	*offlinefp = NULL;
1095 	gid_t	 gid;
1096 	int	 i;
1097 
1098 	if (strcmp(__progname, "sendmail") == 0 ||
1099 	    strcmp(__progname, "send-mail") == 0) {
1100 		/*
1101 		 * determine whether we are called with flags
1102 		 * that should invoke makemap/newaliases.
1103 		 */
1104 		for (i = 1; i < argc; i++)
1105 			if (strncmp(argv[i], "-bi", 3) == 0) {
1106 				__progname = "newaliases";
1107 				exit(makemap(argc, argv));
1108 			}
1109 
1110 		if (!srv_connect())
1111 			offlinefp = offline_file();
1112 
1113 		gid = getgid();
1114 		if (setresgid(gid, gid, gid) == -1)
1115 			err(1, "setresgid");
1116 
1117 		/* we'll reduce further down the road */
1118 		if (pledge("stdio rpath wpath cpath tmppath flock "
1119 			"dns getpw recvfd", NULL) == -1)
1120 			err(1, "pledge");
1121 
1122 		sendmail = 1;
1123 		exit(enqueue(argc, argv, offlinefp));
1124 	} else if (strcmp(__progname, "makemap") == 0 ||
1125 	    strcmp(__progname, "newaliases") == 0)
1126 		exit(makemap(argc, argv));
1127 }
1128 
1129 static void
1130 show_queue_envelope(struct envelope *e, int online)
1131 {
1132 	const char	*src = "?", *agent = "?";
1133 	char		 status[128], runstate[128];
1134 
1135 	status[0] = '\0';
1136 
1137 	getflag(&e->flags, EF_BOUNCE, "bounce", status, sizeof(status));
1138 	getflag(&e->flags, EF_AUTHENTICATED, "auth", status, sizeof(status));
1139 	getflag(&e->flags, EF_INTERNAL, "internal", status, sizeof(status));
1140 	getflag(&e->flags, EF_SUSPEND, "suspend", status, sizeof(status));
1141 	getflag(&e->flags, EF_HOLD, "hold", status, sizeof(status));
1142 
1143 	if (online) {
1144 		if (e->flags & EF_PENDING)
1145 			(void)snprintf(runstate, sizeof runstate, "pending|%zd",
1146 			    (ssize_t)(e->nexttry - now));
1147 		else if (e->flags & EF_INFLIGHT)
1148 			(void)snprintf(runstate, sizeof runstate,
1149 			    "inflight|%zd", (ssize_t)(now - e->lasttry));
1150 		else
1151 			(void)snprintf(runstate, sizeof runstate, "invalid|");
1152 		e->flags &= ~(EF_PENDING|EF_INFLIGHT);
1153 	}
1154 	else
1155 		(void)strlcpy(runstate, "offline|", sizeof runstate);
1156 
1157 	if (e->flags)
1158 		errx(1, "%016" PRIx64 ": unexpected flags 0x%04x", e->id,
1159 		    e->flags);
1160 
1161 	if (status[0])
1162 		status[strlen(status) - 1] = '\0';
1163 
1164 	if (e->type == D_MDA)
1165 		agent = "mda";
1166 	else if (e->type == D_MTA)
1167 		agent = "mta";
1168 	else if (e->type == D_BOUNCE)
1169 		agent = "bounce";
1170 
1171 	if (e->ss.ss_family == AF_LOCAL)
1172 		src = "local";
1173 	else if (e->ss.ss_family == AF_INET)
1174 		src = "inet4";
1175 	else if (e->ss.ss_family == AF_INET6)
1176 		src = "inet6";
1177 
1178 	printf("%016"PRIx64
1179 	    "|%s|%s|%s|%s@%s|%s@%s|%s@%s"
1180 	    "|%zu|%zu|%zu|%zu|%s|%s\n",
1181 
1182 	    e->id,
1183 
1184 	    src,
1185 	    agent,
1186 	    status,
1187 	    e->sender.user, e->sender.domain,
1188 	    e->rcpt.user, e->rcpt.domain,
1189 	    e->dest.user, e->dest.domain,
1190 
1191 	    (size_t) e->creation,
1192 	    (size_t) (e->creation + e->expire),
1193 	    (size_t) e->lasttry,
1194 	    (size_t) e->retry,
1195 	    runstate,
1196 	    e->errorline);
1197 }
1198 
1199 static void
1200 getflag(uint *bitmap, int bit, char *bitstr, char *buf, size_t len)
1201 {
1202 	if (*bitmap & bit) {
1203 		*bitmap &= ~bit;
1204 		(void)strlcat(buf, bitstr, len);
1205 		(void)strlcat(buf, ",", len);
1206 	}
1207 }
1208 
1209 static void
1210 show_offline_envelope(uint64_t evpid)
1211 {
1212 	FILE   *fp = NULL;
1213 	char	pathname[PATH_MAX];
1214 	size_t	plen;
1215 	char   *p;
1216 	size_t	buflen;
1217 	char	buffer[sizeof(struct envelope)];
1218 
1219 	struct envelope	evp;
1220 
1221 	if (!bsnprintf(pathname, sizeof pathname,
1222 		"/queue/%02x/%08x/%016"PRIx64,
1223 		(evpid_to_msgid(evpid) & 0xff000000) >> 24,
1224 		evpid_to_msgid(evpid), evpid))
1225 		goto end;
1226 	fp = fopen(pathname, "r");
1227 	if (fp == NULL)
1228 		goto end;
1229 
1230 	buflen = fread(buffer, 1, sizeof (buffer) - 1, fp);
1231 	p = buffer;
1232 	plen = buflen;
1233 	buffer[buflen] = '\0';
1234 
1235 	if (is_encrypted_buffer(p)) {
1236 		warnx("offline encrypted queue is not supported yet");
1237 		goto end;
1238 	}
1239 
1240 	if (is_gzip_buffer(p)) {
1241 		warnx("offline compressed queue is not supported yet");
1242 		goto end;
1243 	}
1244 
1245 	if (!envelope_load_buffer(&evp, p, plen))
1246 		goto end;
1247 	evp.id = evpid;
1248 	show_queue_envelope(&evp, 0);
1249 
1250 end:
1251 	if (fp)
1252 		fclose(fp);
1253 }
1254 
1255 static void
1256 display(const char *s)
1257 {
1258 	FILE   *fp;
1259 	char   *key;
1260 	int	gzipped;
1261 	char   *gzcat_argv0 = strrchr(PATH_GZCAT, '/') + 1;
1262 
1263 	if ((fp = fopen(s, "r")) == NULL)
1264 		err(1, "fopen");
1265 
1266 	if (is_encrypted_fp(fp)) {
1267 		int	i;
1268 		int	fd;
1269 		FILE   *ofp = NULL;
1270 		char	sfn[] = "/tmp/smtpd.XXXXXXXXXX";
1271 
1272 		if ((fd = mkstemp(sfn)) == -1 ||
1273 		    (ofp = fdopen(fd, "w+")) == NULL) {
1274 			int saved_errno = errno;
1275 			if (fd != -1) {
1276 				unlink(sfn);
1277 				close(fd);
1278 			}
1279 			errc(1, saved_errno, "mkstemp");
1280 		}
1281 		unlink(sfn);
1282 
1283 		for (i = 0; i < 3; i++) {
1284 			key = getpass("key> ");
1285 			if (crypto_setup(key, strlen(key)))
1286 				break;
1287 		}
1288 		if (i == 3)
1289 			errx(1, "crypto-setup: invalid key");
1290 
1291 		if (!crypto_decrypt_file(fp, ofp)) {
1292 			printf("object is encrypted: %s\n", key);
1293 			exit(1);
1294 		}
1295 
1296 		fclose(fp);
1297 		fp = ofp;
1298 		fseek(fp, 0, SEEK_SET);
1299 	}
1300 	gzipped = is_gzip_fp(fp);
1301 
1302 	lseek(fileno(fp), 0, SEEK_SET);
1303 	(void)dup2(fileno(fp), STDIN_FILENO);
1304 	if (gzipped)
1305 		execl(PATH_GZCAT, gzcat_argv0, (char *)NULL);
1306 	else
1307 		execl(PATH_CAT, "cat", (char *)NULL);
1308 	err(1, "execl");
1309 }
1310 
1311 static int
1312 str_to_trace(const char *str)
1313 {
1314 	if (!strcmp(str, "imsg"))
1315 		return TRACE_IMSG;
1316 	if (!strcmp(str, "io"))
1317 		return TRACE_IO;
1318 	if (!strcmp(str, "smtp"))
1319 		return TRACE_SMTP;
1320 	if (!strcmp(str, "filters"))
1321 		return TRACE_FILTERS;
1322 	if (!strcmp(str, "mta"))
1323 		return TRACE_MTA;
1324 	if (!strcmp(str, "bounce"))
1325 		return TRACE_BOUNCE;
1326 	if (!strcmp(str, "scheduler"))
1327 		return TRACE_SCHEDULER;
1328 	if (!strcmp(str, "lookup"))
1329 		return TRACE_LOOKUP;
1330 	if (!strcmp(str, "stat"))
1331 		return TRACE_STAT;
1332 	if (!strcmp(str, "rules"))
1333 		return TRACE_RULES;
1334 	if (!strcmp(str, "mproc"))
1335 		return TRACE_MPROC;
1336 	if (!strcmp(str, "expand"))
1337 		return TRACE_EXPAND;
1338 	if (!strcmp(str, "all"))
1339 		return ~TRACE_DEBUG;
1340 	errx(1, "invalid trace keyword: %s", str);
1341 	return (0);
1342 }
1343 
1344 static int
1345 str_to_profile(const char *str)
1346 {
1347 	if (!strcmp(str, "imsg"))
1348 		return PROFILE_IMSG;
1349 	if (!strcmp(str, "queue"))
1350 		return PROFILE_QUEUE;
1351 	errx(1, "invalid profile keyword: %s", str);
1352 	return (0);
1353 }
1354 
1355 static int
1356 is_gzip_buffer(const char *buffer)
1357 {
1358 	uint16_t	magic;
1359 
1360 	memcpy(&magic, buffer, sizeof magic);
1361 #define	GZIP_MAGIC	0x8b1f
1362 	return (magic == GZIP_MAGIC);
1363 }
1364 
1365 static int
1366 is_gzip_fp(FILE *fp)
1367 {
1368 	uint8_t		magic[2];
1369 	int		ret = 0;
1370 
1371 	if (fread(&magic, 1, sizeof magic, fp) != sizeof magic)
1372 		goto end;
1373 
1374 	ret = is_gzip_buffer((const char *)&magic);
1375 end:
1376 	fseek(fp, 0, SEEK_SET);
1377 	return ret;
1378 }
1379 
1380 
1381 /* XXX */
1382 /*
1383  * queue supports transparent encryption.
1384  * encrypted chunks are prefixed with an API version byte
1385  * which we ensure is unambiguous with gzipped / plain
1386  * objects.
1387  */
1388 
1389 static int
1390 is_encrypted_buffer(const char *buffer)
1391 {
1392 	uint8_t	magic;
1393 
1394 	magic = *buffer;
1395 #define	ENCRYPTION_MAGIC	0x1
1396 	return (magic == ENCRYPTION_MAGIC);
1397 }
1398 
1399 static int
1400 is_encrypted_fp(FILE *fp)
1401 {
1402 	uint8_t	magic;
1403 	int	ret = 0;
1404 
1405 	if (fread(&magic, 1, sizeof magic, fp) != sizeof magic)
1406 		goto end;
1407 
1408 	ret = is_encrypted_buffer((const char *)&magic);
1409 end:
1410 	fseek(fp, 0, SEEK_SET);
1411 	return ret;
1412 }
1413