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