GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/smtpd/smtpctl/../smtpctl.c Lines: 0 662 0.0 %
Date: 2017-11-13 Branches: 0 312 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: smtpctl.c,v 1.154 2017/07/27 18:48:30 sunil 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, tmpalloc, alloc = 0;
400
	struct envelope	 evp;
401
402
	if (*offset == 0) {
403
		n = 0;
404
		while (srv_iter_envelopes(msgid, &evp)) {
405
			if (n == alloc) {
406
				tmpalloc = alloc ? (alloc * 2) : 128;
407
				tmp = recallocarray(evpids, alloc, tmpalloc,
408
				    sizeof(*evpids));
409
				if (tmp == NULL)
410
					err(1, "recallocarray");
411
				evpids = tmp;
412
				alloc = tmpalloc;
413
			}
414
			evpids[n++] = evp.id;
415
		}
416
	}
417
418
	if (*offset >= n)
419
		return (0);
420
	*evpid = evpids[*offset];
421
	*offset += 1;
422
	return (1);
423
}
424
425
static void
426
srv_foreach_envelope(struct parameter *argv, int ctl, size_t *total, size_t *ok)
427
{
428
	uint32_t	msgid;
429
	uint64_t	evpid;
430
	int		i;
431
432
	*total = 0;
433
	*ok = 0;
434
435
	if (argv == NULL) {
436
		while (srv_iter_messages(&msgid)) {
437
			i = 0;
438
			while (srv_iter_evpids(msgid, &evpid, &i)) {
439
				*total += 1;
440
				srv_send(ctl, &evpid, sizeof(evpid));
441
				if (srv_check_result(0) == 0)
442
					*ok += 1;
443
			}
444
		}
445
	} else if (argv->type == P_MSGID) {
446
		i = 0;
447
		while (srv_iter_evpids(argv->u.u_msgid, &evpid, &i)) {
448
			srv_send(ctl, &evpid, sizeof(evpid));
449
			if (srv_check_result(0) == 0)
450
				*ok += 1;
451
		}
452
	} else {
453
		*total += 1;
454
		srv_send(ctl, &argv->u.u_evpid, sizeof(evpid));
455
		if (srv_check_result(0) == 0)
456
			*ok += 1;
457
	}
458
}
459
460
static void
461
srv_show_cmd(int cmd, const void *data, size_t len)
462
{
463
	int	done = 0;
464
465
	srv_send(cmd, data, len);
466
467
	do {
468
		srv_recv(cmd);
469
		if (rlen) {
470
			printf("%s\n", rdata);
471
			srv_read(NULL, rlen);
472
		}
473
		else
474
			done = 1;
475
		srv_end();
476
	} while (!done);
477
}
478
479
static int
480
do_log_brief(int argc, struct parameter *argv)
481
{
482
	int	v = 0;
483
484
	srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v));
485
	return srv_check_result(1);
486
}
487
488
static int
489
do_log_verbose(int argc, struct parameter *argv)
490
{
491
	int	v = TRACE_DEBUG;
492
493
	srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v));
494
	return srv_check_result(1);
495
}
496
497
static int
498
do_monitor(int argc, struct parameter *argv)
499
{
500
	struct stat_digest	last, digest;
501
	size_t			count;
502
503
	memset(&last, 0, sizeof(last));
504
	count = 0;
505
506
	while (1) {
507
		srv_send(IMSG_CTL_GET_DIGEST, NULL, 0);
508
		srv_recv(IMSG_CTL_GET_DIGEST);
509
		srv_read(&digest, sizeof(digest));
510
		srv_end();
511
512
		if (count % 25 == 0) {
513
			if (count != 0)
514
				printf("\n");
515
			printf("--- client ---  "
516
			    "-- envelope --   "
517
			    "---- relay/delivery --- "
518
			    "------- misc -------\n"
519
			    "curr conn disc  "
520
			    "curr  enq  deq   "
521
			    "ok tmpfail prmfail loop "
522
			    "expire remove bounce\n");
523
		}
524
		printf("%4zu %4zu %4zu  "
525
		    "%4zu %4zu %4zu "
526
		    "%4zu    %4zu    %4zu %4zu   "
527
		    "%4zu   %4zu   %4zu\n",
528
		    digest.clt_connect - digest.clt_disconnect,
529
		    digest.clt_connect - last.clt_connect,
530
		    digest.clt_disconnect - last.clt_disconnect,
531
532
		    digest.evp_enqueued - digest.evp_dequeued,
533
		    digest.evp_enqueued - last.evp_enqueued,
534
		    digest.evp_dequeued - last.evp_dequeued,
535
536
		    digest.dlv_ok - last.dlv_ok,
537
		    digest.dlv_tempfail - last.dlv_tempfail,
538
		    digest.dlv_permfail - last.dlv_permfail,
539
		    digest.dlv_loop - last.dlv_loop,
540
541
		    digest.evp_expired - last.evp_expired,
542
		    digest.evp_removed - last.evp_removed,
543
		    digest.evp_bounce - last.evp_bounce);
544
545
		last = digest;
546
		count++;
547
		sleep(1);
548
	}
549
550
	return (0);
551
}
552
553
static int
554
do_pause_envelope(int argc, struct parameter *argv)
555
{
556
	size_t	total, ok;
557
558
	srv_foreach_envelope(argv, IMSG_CTL_PAUSE_EVP, &total, &ok);
559
	printf("%zu envelope%s paused\n", ok, (ok > 1) ? "s" : "");
560
561
	return (0);
562
}
563
564
static int
565
do_pause_mda(int argc, struct parameter *argv)
566
{
567
	srv_send(IMSG_CTL_PAUSE_MDA, NULL, 0);
568
	return srv_check_result(1);
569
}
570
571
static int
572
do_pause_mta(int argc, struct parameter *argv)
573
{
574
	srv_send(IMSG_CTL_PAUSE_MTA, NULL, 0);
575
	return srv_check_result(1);
576
}
577
578
static int
579
do_pause_smtp(int argc, struct parameter *argv)
580
{
581
	srv_send(IMSG_CTL_PAUSE_SMTP, NULL, 0);
582
	return srv_check_result(1);
583
}
584
585
static int
586
do_profile(int argc, struct parameter *argv)
587
{
588
	int	v;
589
590
	v = str_to_profile(argv[0].u.u_str);
591
592
	srv_send(IMSG_CTL_PROFILE_ENABLE, &v, sizeof(v));
593
	return srv_check_result(1);
594
}
595
596
static int
597
do_remove(int argc, struct parameter *argv)
598
{
599
	size_t	total, ok;
600
601
	srv_foreach_envelope(argv, IMSG_CTL_REMOVE, &total, &ok);
602
	printf("%zu envelope%s removed\n", ok, (ok > 1) ? "s" : "");
603
604
	return (0);
605
}
606
607
static int
608
do_resume_envelope(int argc, struct parameter *argv)
609
{
610
	size_t	total, ok;
611
612
	srv_foreach_envelope(argv, IMSG_CTL_RESUME_EVP, &total, &ok);
613
	printf("%zu envelope%s resumed\n", ok, (ok > 1) ? "s" : "");
614
615
	return (0);
616
}
617
618
static int
619
do_resume_mda(int argc, struct parameter *argv)
620
{
621
	srv_send(IMSG_CTL_RESUME_MDA, NULL, 0);
622
	return srv_check_result(1);
623
}
624
625
static int
626
do_resume_mta(int argc, struct parameter *argv)
627
{
628
	srv_send(IMSG_CTL_RESUME_MTA, NULL, 0);
629
	return srv_check_result(1);
630
}
631
632
static int
633
do_resume_route(int argc, struct parameter *argv)
634
{
635
	uint64_t	v;
636
637
	if (argc == 0)
638
		v = 0;
639
	else
640
		v = argv[0].u.u_routeid;
641
642
	srv_send(IMSG_CTL_RESUME_ROUTE, &v, sizeof(v));
643
	return srv_check_result(1);
644
}
645
646
static int
647
do_resume_smtp(int argc, struct parameter *argv)
648
{
649
	srv_send(IMSG_CTL_RESUME_SMTP, NULL, 0);
650
	return srv_check_result(1);
651
}
652
653
static int
654
do_schedule(int argc, struct parameter *argv)
655
{
656
	size_t	total, ok;
657
658
	srv_foreach_envelope(argv, IMSG_CTL_SCHEDULE, &total, &ok);
659
	printf("%zu envelope%s scheduled\n", ok, (ok > 1) ? "s" : "");
660
661
	return (0);
662
}
663
664
static int
665
do_show_envelope(int argc, struct parameter *argv)
666
{
667
	char	 buf[PATH_MAX];
668
669
	if (!bsnprintf(buf, sizeof(buf), "%s%s/%02x/%08x/%016" PRIx64,
670
	    PATH_SPOOL,
671
	    PATH_QUEUE,
672
	    (evpid_to_msgid(argv[0].u.u_evpid) & 0xff000000) >> 24,
673
	    evpid_to_msgid(argv[0].u.u_evpid),
674
	    argv[0].u.u_evpid))
675
		errx(1, "unable to retrieve envelope");
676
677
	display(buf);
678
679
	return (0);
680
}
681
682
static int
683
do_show_hoststats(int argc, struct parameter *argv)
684
{
685
	srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTSTATS, NULL, 0);
686
687
	return (0);
688
}
689
690
static int
691
do_show_message(int argc, struct parameter *argv)
692
{
693
	char	 buf[PATH_MAX];
694
	uint32_t msgid;
695
696
	if (argv[0].type == P_EVPID)
697
		msgid = evpid_to_msgid(argv[0].u.u_evpid);
698
	else
699
		msgid = argv[0].u.u_msgid;
700
701
	if (!bsnprintf(buf, sizeof(buf), "%s%s/%02x/%08x/message",
702
		PATH_SPOOL,
703
		PATH_QUEUE,
704
		(msgid & 0xff000000) >> 24,
705
		msgid))
706
		errx(1, "unable to retrieve message");
707
708
	display(buf);
709
710
	return (0);
711
}
712
713
static int
714
do_show_queue(int argc, struct parameter *argv)
715
{
716
	struct envelope	 evp;
717
	uint32_t	 msgid;
718
	FTS		*fts;
719
	FTSENT		*ftse;
720
	char		*qpath[] = {"/queue", NULL};
721
	char		*tmp;
722
	uint64_t	 evpid;
723
724
	now = time(NULL);
725
726
	if (!srv_connect()) {
727
		log_init(1, LOG_MAIL);
728
		queue_init("fs", 0);
729
		if (chroot(PATH_SPOOL) == -1 || chdir("/") == -1)
730
			err(1, "%s", PATH_SPOOL);
731
		fts = fts_open(qpath, FTS_PHYSICAL|FTS_NOCHDIR, NULL);
732
		if (fts == NULL)
733
			err(1, "%s/queue", PATH_SPOOL);
734
735
		while ((ftse = fts_read(fts)) != NULL) {
736
			switch (ftse->fts_info) {
737
			case FTS_DP:
738
			case FTS_DNR:
739
				break;
740
			case FTS_F:
741
				tmp = NULL;
742
				evpid = strtoull(ftse->fts_name, &tmp, 16);
743
				if (tmp && *tmp != '\0')
744
					break;
745
				show_offline_envelope(evpid);
746
			}
747
		}
748
749
		fts_close(fts);
750
		return (0);
751
	}
752
753
	if (argc == 0) {
754
		msgid = 0;
755
		while (srv_iter_messages(&msgid))
756
			while (srv_iter_envelopes(msgid, &evp))
757
				show_queue_envelope(&evp, 1);
758
	} else if (argv[0].type == P_MSGID) {
759
		while (srv_iter_envelopes(argv[0].u.u_msgid, &evp))
760
			show_queue_envelope(&evp, 1);
761
	}
762
763
	return (0);
764
}
765
766
static int
767
do_show_hosts(int argc, struct parameter *argv)
768
{
769
	srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTS, NULL, 0);
770
771
	return (0);
772
}
773
774
static int
775
do_show_relays(int argc, struct parameter *argv)
776
{
777
	srv_show_cmd(IMSG_CTL_MTA_SHOW_RELAYS, NULL, 0);
778
779
	return (0);
780
}
781
782
static int
783
do_show_routes(int argc, struct parameter *argv)
784
{
785
	srv_show_cmd(IMSG_CTL_MTA_SHOW_ROUTES, NULL, 0);
786
787
	return (0);
788
}
789
790
static int
791
do_show_stats(int argc, struct parameter *argv)
792
{
793
	struct stat_kv	kv;
794
	time_t		duration;
795
796
	memset(&kv, 0, sizeof kv);
797
798
	while (1) {
799
		srv_send(IMSG_CTL_GET_STATS, &kv, sizeof kv);
800
		srv_recv(IMSG_CTL_GET_STATS);
801
		srv_read(&kv, sizeof(kv));
802
		srv_end();
803
804
		if (kv.iter == NULL)
805
			break;
806
807
		if (strcmp(kv.key, "uptime") == 0) {
808
			duration = time(NULL) - kv.val.u.counter;
809
			printf("uptime=%lld\n", (long long)duration);
810
			printf("uptime.human=%s\n",
811
			    duration_to_text(duration));
812
		}
813
		else {
814
			switch (kv.val.type) {
815
			case STAT_COUNTER:
816
				printf("%s=%zd\n",
817
				    kv.key, kv.val.u.counter);
818
				break;
819
			case STAT_TIMESTAMP:
820
				printf("%s=%" PRId64 "\n",
821
				    kv.key, (int64_t)kv.val.u.timestamp);
822
				break;
823
			case STAT_TIMEVAL:
824
				printf("%s=%lld.%lld\n",
825
				    kv.key, (long long)kv.val.u.tv.tv_sec,
826
				    (long long)kv.val.u.tv.tv_usec);
827
				break;
828
			case STAT_TIMESPEC:
829
				printf("%s=%lld.%06ld\n",
830
				    kv.key,
831
				    (long long)kv.val.u.ts.tv_sec * 1000000 +
832
				    kv.val.u.ts.tv_nsec / 1000000,
833
				    kv.val.u.ts.tv_nsec % 1000000);
834
				break;
835
			}
836
		}
837
	}
838
839
	return (0);
840
}
841
842
static int
843
do_show_status(int argc, struct parameter *argv)
844
{
845
	uint32_t	sc_flags;
846
847
	srv_send(IMSG_CTL_SHOW_STATUS, NULL, 0);
848
	srv_recv(IMSG_CTL_SHOW_STATUS);
849
	srv_read(&sc_flags, sizeof(sc_flags));
850
	srv_end();
851
	printf("MDA %s\n",
852
	    (sc_flags & SMTPD_MDA_PAUSED) ? "paused" : "running");
853
	printf("MTA %s\n",
854
	    (sc_flags & SMTPD_MTA_PAUSED) ? "paused" : "running");
855
	printf("SMTP %s\n",
856
	    (sc_flags & SMTPD_SMTP_PAUSED) ? "paused" : "running");
857
	return (0);
858
}
859
860
static int
861
do_trace(int argc, struct parameter *argv)
862
{
863
	int	v;
864
865
	v = str_to_trace(argv[0].u.u_str);
866
867
	srv_send(IMSG_CTL_TRACE_ENABLE, &v, sizeof(v));
868
	return srv_check_result(1);
869
}
870
871
static int
872
do_unprofile(int argc, struct parameter *argv)
873
{
874
	int	v;
875
876
	v = str_to_profile(argv[0].u.u_str);
877
878
	srv_send(IMSG_CTL_PROFILE_DISABLE, &v, sizeof(v));
879
	return srv_check_result(1);
880
}
881
882
static int
883
do_untrace(int argc, struct parameter *argv)
884
{
885
	int	v;
886
887
	v = str_to_trace(argv[0].u.u_str);
888
889
	srv_send(IMSG_CTL_TRACE_DISABLE, &v, sizeof(v));
890
	return srv_check_result(1);
891
}
892
893
static int
894
do_update_table(int argc, struct parameter *argv)
895
{
896
	const char	*name = argv[0].u.u_str;
897
898
	srv_send(IMSG_CTL_UPDATE_TABLE, name, strlen(name) + 1);
899
	return srv_check_result(1);
900
}
901
902
static int
903
do_encrypt(int argc, struct parameter *argv)
904
{
905
	const char *p = NULL;
906
907
	if (argv)
908
		p = argv[0].u.u_str;
909
	execl(PATH_ENCRYPT, "encrypt", p, (char *)NULL);
910
	errx(1, "execl");
911
}
912
913
static int
914
do_block_mta(int argc, struct parameter *argv)
915
{
916
	struct ibuf *m;
917
918
	if (ibuf == NULL && !srv_connect())
919
		errx(1, "smtpd doesn't seem to be running");
920
	m = imsg_create(ibuf, IMSG_CTL_MTA_BLOCK, IMSG_VERSION, 0,
921
	    sizeof(argv[0].u.u_ss) + strlen(argv[1].u.u_str) + 1);
922
	if (imsg_add(m, &argv[0].u.u_ss, sizeof(argv[0].u.u_ss)) == -1)
923
		errx(1, "imsg_add");
924
	if (imsg_add(m, argv[1].u.u_str, strlen(argv[1].u.u_str) + 1) == -1)
925
		errx(1, "imsg_add");
926
	imsg_close(ibuf, m);
927
928
	return srv_check_result(1);
929
}
930
931
static int
932
do_unblock_mta(int argc, struct parameter *argv)
933
{
934
	struct ibuf *m;
935
936
	if (ibuf == NULL && !srv_connect())
937
		errx(1, "smtpd doesn't seem to be running");
938
939
	m = imsg_create(ibuf, IMSG_CTL_MTA_UNBLOCK, IMSG_VERSION, 0,
940
	    sizeof(argv[0].u.u_ss) + strlen(argv[1].u.u_str) + 1);
941
	if (imsg_add(m, &argv[0].u.u_ss, sizeof(argv[0].u.u_ss)) == -1)
942
		errx(1, "imsg_add");
943
	if (imsg_add(m, argv[1].u.u_str, strlen(argv[1].u.u_str) + 1) == -1)
944
		errx(1, "imsg_add");
945
	imsg_close(ibuf, m);
946
947
	return srv_check_result(1);
948
}
949
950
static int
951
do_show_mta_block(int argc, struct parameter *argv)
952
{
953
	srv_show_cmd(IMSG_CTL_MTA_SHOW_BLOCK, NULL, 0);
954
955
	return (0);
956
}
957
958
static int
959
do_discover(int argc, struct parameter *argv)
960
{
961
	uint64_t evpid;
962
	uint32_t msgid;
963
	size_t	 n_evp;
964
965
	if (ibuf == NULL && !srv_connect())
966
		errx(1, "smtpd doesn't seem to be running");
967
968
	if (argv[0].type == P_EVPID) {
969
		evpid = argv[0].u.u_evpid;
970
		srv_send(IMSG_CTL_DISCOVER_EVPID, &evpid, sizeof evpid);
971
		srv_recv(IMSG_CTL_DISCOVER_EVPID);
972
	} else {
973
		msgid = argv[0].u.u_msgid;
974
		srv_send(IMSG_CTL_DISCOVER_MSGID, &msgid, sizeof msgid);
975
		srv_recv(IMSG_CTL_DISCOVER_MSGID);
976
	}
977
978
	if (rlen == 0) {
979
		srv_end();
980
		return (0);
981
	} else {
982
		srv_read(&n_evp, sizeof n_evp);
983
		srv_end();
984
	}
985
986
	printf("%zu envelope%s discovered\n", n_evp, (n_evp != 1) ? "s" : "");
987
	return (0);
988
}
989
990
static int
991
do_uncorrupt(int argc, struct parameter *argv)
992
{
993
	uint32_t msgid;
994
	int	 ret;
995
996
	if (ibuf == NULL && !srv_connect())
997
		errx(1, "smtpd doesn't seem to be running");
998
999
	msgid = argv[0].u.u_msgid;
1000
	srv_send(IMSG_CTL_UNCORRUPT_MSGID, &msgid, sizeof msgid);
1001
	srv_recv(IMSG_CTL_UNCORRUPT_MSGID);
1002
1003
	if (rlen == 0) {
1004
		srv_end();
1005
		return (0);
1006
	} else {
1007
		srv_read(&ret, sizeof ret);
1008
		srv_end();
1009
	}
1010
1011
	printf("command %s\n", ret ? "succeeded" : "failed");
1012
	return (0);
1013
}
1014
1015
int
1016
main(int argc, char **argv)
1017
{
1018
	gid_t		 gid;
1019
	char		*argv_mailq[] = { "show", "queue", NULL };
1020
1021
	sendmail_compat(argc, argv);
1022
	if (geteuid())
1023
		errx(1, "need root privileges");
1024
1025
	gid = getgid();
1026
	if (setresgid(gid, gid, gid) == -1)
1027
		err(1, "setresgid");
1028
1029
	cmd_install("discover <evpid>",		do_discover);
1030
	cmd_install("discover <msgid>",		do_discover);
1031
	cmd_install("encrypt",			do_encrypt);
1032
	cmd_install("encrypt <str>",		do_encrypt);
1033
	cmd_install("pause mta from <addr> for <str>", do_block_mta);
1034
	cmd_install("resume mta from <addr> for <str>", do_unblock_mta);
1035
	cmd_install("show mta paused",		do_show_mta_block);
1036
	cmd_install("log brief",		do_log_brief);
1037
	cmd_install("log verbose",		do_log_verbose);
1038
	cmd_install("monitor",			do_monitor);
1039
	cmd_install("pause envelope <evpid>",	do_pause_envelope);
1040
	cmd_install("pause envelope <msgid>",	do_pause_envelope);
1041
	cmd_install("pause envelope all",	do_pause_envelope);
1042
	cmd_install("pause mda",		do_pause_mda);
1043
	cmd_install("pause mta",		do_pause_mta);
1044
	cmd_install("pause smtp",		do_pause_smtp);
1045
	cmd_install("profile <str>",		do_profile);
1046
	cmd_install("remove <evpid>",		do_remove);
1047
	cmd_install("remove <msgid>",		do_remove);
1048
	cmd_install("remove all",		do_remove);
1049
	cmd_install("resume envelope <evpid>",	do_resume_envelope);
1050
	cmd_install("resume envelope <msgid>",	do_resume_envelope);
1051
	cmd_install("resume envelope all",	do_resume_envelope);
1052
	cmd_install("resume mda",		do_resume_mda);
1053
	cmd_install("resume mta",		do_resume_mta);
1054
	cmd_install("resume route <routeid>",	do_resume_route);
1055
	cmd_install("resume smtp",		do_resume_smtp);
1056
	cmd_install("schedule <msgid>",		do_schedule);
1057
	cmd_install("schedule <evpid>",		do_schedule);
1058
	cmd_install("schedule all",		do_schedule);
1059
	cmd_install("show envelope <evpid>",	do_show_envelope);
1060
	cmd_install("show hoststats",		do_show_hoststats);
1061
	cmd_install("show message <msgid>",	do_show_message);
1062
	cmd_install("show message <evpid>",	do_show_message);
1063
	cmd_install("show queue",		do_show_queue);
1064
	cmd_install("show queue <msgid>",	do_show_queue);
1065
	cmd_install("show hosts",		do_show_hosts);
1066
	cmd_install("show relays",		do_show_relays);
1067
	cmd_install("show routes",		do_show_routes);
1068
	cmd_install("show stats",		do_show_stats);
1069
	cmd_install("show status",		do_show_status);
1070
	cmd_install("trace <str>",		do_trace);
1071
	cmd_install("uncorrupt <msgid>",	do_uncorrupt);
1072
	cmd_install("unprofile <str>",		do_unprofile);
1073
	cmd_install("untrace <str>",		do_untrace);
1074
	cmd_install("update table <str>",	do_update_table);
1075
1076
	if (strcmp(__progname, "mailq") == 0)
1077
		return cmd_run(2, argv_mailq);
1078
	if (strcmp(__progname, "smtpctl") == 0)
1079
		return cmd_run(argc - 1, argv + 1);
1080
1081
	errx(1, "unsupported mode");
1082
	return (0);
1083
}
1084
1085
void
1086
sendmail_compat(int argc, char **argv)
1087
{
1088
	FILE	*offlinefp = NULL;
1089
	gid_t	 gid;
1090
	int	 i;
1091
1092
	if (strcmp(__progname, "sendmail") == 0 ||
1093
	    strcmp(__progname, "send-mail") == 0) {
1094
		/*
1095
		 * determine whether we are called with flags
1096
		 * that should invoke makemap/newaliases.
1097
		 */
1098
		for (i = 1; i < argc; i++)
1099
			if (strncmp(argv[i], "-bi", 3) == 0)
1100
				exit(makemap(P_NEWALIASES, argc, argv));
1101
1102
		if (!srv_connect())
1103
			offlinefp = offline_file();
1104
1105
		gid = getgid();
1106
		if (setresgid(gid, gid, gid) == -1)
1107
			err(1, "setresgid");
1108
1109
		/* we'll reduce further down the road */
1110
		if (pledge("stdio rpath wpath cpath tmppath flock "
1111
			"dns getpw recvfd", NULL) == -1)
1112
			err(1, "pledge");
1113
1114
		sendmail = 1;
1115
		exit(enqueue(argc, argv, offlinefp));
1116
	} else if (strcmp(__progname, "makemap") == 0)
1117
		exit(makemap(P_MAKEMAP, argc, argv));
1118
	else if (strcmp(__progname, "newaliases") == 0)
1119
		exit(makemap(P_NEWALIASES, argc, argv));
1120
}
1121
1122
static void
1123
show_queue_envelope(struct envelope *e, int online)
1124
{
1125
	const char	*src = "?", *agent = "?";
1126
	char		 status[128], runstate[128];
1127
1128
	status[0] = '\0';
1129
1130
	getflag(&e->flags, EF_BOUNCE, "bounce", status, sizeof(status));
1131
	getflag(&e->flags, EF_AUTHENTICATED, "auth", status, sizeof(status));
1132
	getflag(&e->flags, EF_INTERNAL, "internal", status, sizeof(status));
1133
	getflag(&e->flags, EF_SUSPEND, "suspend", status, sizeof(status));
1134
	getflag(&e->flags, EF_HOLD, "hold", status, sizeof(status));
1135
1136
	if (online) {
1137
		if (e->flags & EF_PENDING)
1138
			(void)snprintf(runstate, sizeof runstate, "pending|%zd",
1139
			    (ssize_t)(e->nexttry - now));
1140
		else if (e->flags & EF_INFLIGHT)
1141
			(void)snprintf(runstate, sizeof runstate,
1142
			    "inflight|%zd", (ssize_t)(now - e->lasttry));
1143
		else
1144
			(void)snprintf(runstate, sizeof runstate, "invalid|");
1145
		e->flags &= ~(EF_PENDING|EF_INFLIGHT);
1146
	}
1147
	else
1148
		(void)strlcpy(runstate, "offline|", sizeof runstate);
1149
1150
	if (e->flags)
1151
		errx(1, "%016" PRIx64 ": unexpected flags 0x%04x", e->id,
1152
		    e->flags);
1153
1154
	if (status[0])
1155
		status[strlen(status) - 1] = '\0';
1156
1157
	if (e->type == D_MDA)
1158
		agent = "mda";
1159
	else if (e->type == D_MTA)
1160
		agent = "mta";
1161
	else if (e->type == D_BOUNCE)
1162
		agent = "bounce";
1163
1164
	if (e->ss.ss_family == AF_LOCAL)
1165
		src = "local";
1166
	else if (e->ss.ss_family == AF_INET)
1167
		src = "inet4";
1168
	else if (e->ss.ss_family == AF_INET6)
1169
		src = "inet6";
1170
1171
	printf("%016"PRIx64
1172
	    "|%s|%s|%s|%s@%s|%s@%s|%s@%s"
1173
	    "|%zu|%zu|%zu|%zu|%s|%s\n",
1174
1175
	    e->id,
1176
1177
	    src,
1178
	    agent,
1179
	    status,
1180
	    e->sender.user, e->sender.domain,
1181
	    e->rcpt.user, e->rcpt.domain,
1182
	    e->dest.user, e->dest.domain,
1183
1184
	    (size_t) e->creation,
1185
	    (size_t) (e->creation + e->expire),
1186
	    (size_t) e->lasttry,
1187
	    (size_t) e->retry,
1188
	    runstate,
1189
	    e->errorline);
1190
}
1191
1192
static void
1193
getflag(uint *bitmap, int bit, char *bitstr, char *buf, size_t len)
1194
{
1195
	if (*bitmap & bit) {
1196
		*bitmap &= ~bit;
1197
		(void)strlcat(buf, bitstr, len);
1198
		(void)strlcat(buf, ",", len);
1199
	}
1200
}
1201
1202
static void
1203
show_offline_envelope(uint64_t evpid)
1204
{
1205
	FILE   *fp = NULL;
1206
	char	pathname[PATH_MAX];
1207
	size_t	plen;
1208
	char   *p;
1209
	size_t	buflen;
1210
	char	buffer[sizeof(struct envelope)];
1211
1212
	struct envelope	evp;
1213
1214
	if (!bsnprintf(pathname, sizeof pathname,
1215
		"/queue/%02x/%08x/%016"PRIx64,
1216
		(evpid_to_msgid(evpid) & 0xff000000) >> 24,
1217
		evpid_to_msgid(evpid), evpid))
1218
		goto end;
1219
	fp = fopen(pathname, "r");
1220
	if (fp == NULL)
1221
		goto end;
1222
1223
	buflen = fread(buffer, 1, sizeof (buffer) - 1, fp);
1224
	p = buffer;
1225
	plen = buflen;
1226
	buffer[buflen] = '\0';
1227
1228
	if (is_encrypted_buffer(p)) {
1229
		warnx("offline encrypted queue is not supported yet");
1230
		goto end;
1231
	}
1232
1233
	if (is_gzip_buffer(p)) {
1234
		warnx("offline compressed queue is not supported yet");
1235
		goto end;
1236
	}
1237
1238
	if (!envelope_load_buffer(&evp, p, plen))
1239
		goto end;
1240
	evp.id = evpid;
1241
	show_queue_envelope(&evp, 0);
1242
1243
end:
1244
	if (fp)
1245
		fclose(fp);
1246
}
1247
1248
static void
1249
display(const char *s)
1250
{
1251
	FILE   *fp;
1252
	char   *key;
1253
	int	gzipped;
1254
	char   *gzcat_argv0 = strrchr(PATH_GZCAT, '/') + 1;
1255
1256
	if ((fp = fopen(s, "r")) == NULL)
1257
		err(1, "fopen");
1258
1259
	if (is_encrypted_fp(fp)) {
1260
		int	i;
1261
		int	fd;
1262
		FILE   *ofp = NULL;
1263
		char	sfn[] = "/tmp/smtpd.XXXXXXXXXX";
1264
1265
		if ((fd = mkstemp(sfn)) == -1 ||
1266
		    (ofp = fdopen(fd, "w+")) == NULL) {
1267
			int saved_errno = errno;
1268
			if (fd != -1) {
1269
				unlink(sfn);
1270
				close(fd);
1271
			}
1272
			errc(1, saved_errno, "mkstemp");
1273
		}
1274
		unlink(sfn);
1275
1276
		for (i = 0; i < 3; i++) {
1277
			key = getpass("key> ");
1278
			if (crypto_setup(key, strlen(key)))
1279
				break;
1280
		}
1281
		if (i == 3)
1282
			errx(1, "crypto-setup: invalid key");
1283
1284
		if (!crypto_decrypt_file(fp, ofp)) {
1285
			printf("object is encrypted: %s\n", key);
1286
			exit(1);
1287
		}
1288
1289
		fclose(fp);
1290
		fp = ofp;
1291
		fseek(fp, 0, SEEK_SET);
1292
	}
1293
	gzipped = is_gzip_fp(fp);
1294
1295
	lseek(fileno(fp), 0, SEEK_SET);
1296
	(void)dup2(fileno(fp), STDIN_FILENO);
1297
	if (gzipped)
1298
		execl(PATH_GZCAT, gzcat_argv0, (char *)NULL);
1299
	else
1300
		execl(PATH_CAT, "cat", (char *)NULL);
1301
	err(1, "execl");
1302
}
1303
1304
static int
1305
str_to_trace(const char *str)
1306
{
1307
	if (!strcmp(str, "imsg"))
1308
		return TRACE_IMSG;
1309
	if (!strcmp(str, "io"))
1310
		return TRACE_IO;
1311
	if (!strcmp(str, "smtp"))
1312
		return TRACE_SMTP;
1313
	if (!strcmp(str, "filters"))
1314
		return TRACE_FILTERS;
1315
	if (!strcmp(str, "mta"))
1316
		return TRACE_MTA;
1317
	if (!strcmp(str, "bounce"))
1318
		return TRACE_BOUNCE;
1319
	if (!strcmp(str, "scheduler"))
1320
		return TRACE_SCHEDULER;
1321
	if (!strcmp(str, "lookup"))
1322
		return TRACE_LOOKUP;
1323
	if (!strcmp(str, "stat"))
1324
		return TRACE_STAT;
1325
	if (!strcmp(str, "rules"))
1326
		return TRACE_RULES;
1327
	if (!strcmp(str, "mproc"))
1328
		return TRACE_MPROC;
1329
	if (!strcmp(str, "expand"))
1330
		return TRACE_EXPAND;
1331
	if (!strcmp(str, "all"))
1332
		return ~TRACE_DEBUG;
1333
	errx(1, "invalid trace keyword: %s", str);
1334
	return (0);
1335
}
1336
1337
static int
1338
str_to_profile(const char *str)
1339
{
1340
	if (!strcmp(str, "imsg"))
1341
		return PROFILE_IMSG;
1342
	if (!strcmp(str, "queue"))
1343
		return PROFILE_QUEUE;
1344
	errx(1, "invalid profile keyword: %s", str);
1345
	return (0);
1346
}
1347
1348
static int
1349
is_gzip_buffer(const char *buffer)
1350
{
1351
	uint16_t	magic;
1352
1353
	memcpy(&magic, buffer, sizeof magic);
1354
#define	GZIP_MAGIC	0x8b1f
1355
	return (magic == GZIP_MAGIC);
1356
}
1357
1358
static int
1359
is_gzip_fp(FILE *fp)
1360
{
1361
	uint8_t		magic[2];
1362
	int		ret = 0;
1363
1364
	if (fread(&magic, 1, sizeof magic, fp) != sizeof magic)
1365
		goto end;
1366
1367
	ret = is_gzip_buffer((const char *)&magic);
1368
end:
1369
	fseek(fp, 0, SEEK_SET);
1370
	return ret;
1371
}
1372
1373
1374
/* XXX */
1375
/*
1376
 * queue supports transparent encryption.
1377
 * encrypted chunks are prefixed with an API version byte
1378
 * which we ensure is unambiguous with gzipped / plain
1379
 * objects.
1380
 */
1381
1382
static int
1383
is_encrypted_buffer(const char *buffer)
1384
{
1385
	uint8_t	magic;
1386
1387
	magic = *buffer;
1388
#define	ENCRYPTION_MAGIC	0x1
1389
	return (magic == ENCRYPTION_MAGIC);
1390
}
1391
1392
static int
1393
is_encrypted_fp(FILE *fp)
1394
{
1395
	uint8_t	magic;
1396
	int	ret = 0;
1397
1398
	if (fread(&magic, 1, sizeof magic, fp) != sizeof magic)
1399
		goto end;
1400
1401
	ret = is_encrypted_buffer((const char *)&magic);
1402
end:
1403
	fseek(fp, 0, SEEK_SET);
1404
	return ret;
1405
}