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