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