1 /* 2 * Copyright (c) 1998-2010, 2012-2014 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14 #include <sendmail.h> 15 #if MILTER 16 # include <libmilter/mfapi.h> 17 # include <libmilter/mfdef.h> 18 #endif 19 20 SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.1016 2013-11-22 20:51:56 ca Exp $") 21 22 #include <sm/sendmail.h> 23 #if _FFR_8BITENVADDR 24 # include <sm/ixlen.h> 25 #endif 26 #include <sm/time.h> 27 #include <sm/fdset.h> 28 29 #if SASL || STARTTLS 30 # include <tls.h> 31 # include "sfsasl.h" 32 #endif 33 #if SASL 34 # define ENC64LEN(l) (((l) + 2) * 4 / 3 + 1) 35 static int saslmechs __P((sasl_conn_t *, char **)); 36 #endif 37 #if STARTTLS 38 # include <openssl/err.h> 39 40 static SSL_CTX *srv_ctx = NULL; /* TLS server context */ 41 static SSL *srv_ssl = NULL; /* per connection context */ 42 static tlsi_ctx_T tlsi_ctx; /* TLS information context */ 43 44 static bool tls_ok_srv = false; 45 46 # define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \ 47 bitset(SRV_VRFY_CLT, features)) 48 #endif /* STARTTLS */ 49 50 #if _FFR_DM_ONE 51 static bool NotFirstDelivery = false; 52 #endif 53 54 /* server features */ 55 #define SRV_NONE 0x0000 /* none... */ 56 #define SRV_OFFER_TLS 0x0001 /* offer STARTTLS */ 57 #define SRV_VRFY_CLT 0x0002 /* request a cert */ 58 #define SRV_OFFER_AUTH 0x0004 /* offer AUTH */ 59 #define SRV_OFFER_ETRN 0x0008 /* offer ETRN */ 60 #define SRV_OFFER_VRFY 0x0010 /* offer VRFY (not yet used) */ 61 #define SRV_OFFER_EXPN 0x0020 /* offer EXPN */ 62 #define SRV_OFFER_VERB 0x0040 /* offer VERB */ 63 #define SRV_OFFER_DSN 0x0080 /* offer DSN */ 64 #if PIPELINING 65 # define SRV_OFFER_PIPE 0x0100 /* offer PIPELINING */ 66 # if _FFR_NO_PIPE 67 # define SRV_NO_PIPE 0x0200 /* disable PIPELINING, sleep if used */ 68 # endif 69 #endif /* PIPELINING */ 70 #define SRV_REQ_AUTH 0x0400 /* require AUTH */ 71 #define SRV_REQ_SEC 0x0800 /* require security - equiv to AuthOptions=p */ 72 #define SRV_TMP_FAIL 0x1000 /* ruleset caused a temporary failure */ 73 #if USE_EAI 74 # define SRV_OFFER_EAI 0x2000 /* offer SMTPUTF8 */ 75 #endif 76 #define SRV_NO_HTTP_CMD 0x4000 /* always reject HTTP commands */ 77 78 static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int)); 79 80 #define STOP_ATTACK ((time_t) -1) 81 static time_t checksmtpattack __P((volatile unsigned int *, unsigned int, 82 bool, char *, ENVELOPE *)); 83 static void printvrfyaddr __P((ADDRESS *, bool, bool)); 84 static char *skipword __P((char *volatile, char *)); 85 static void setup_smtpd_io __P((void)); 86 87 #if SASL 88 # ifndef MAX_AUTH_USER_LEN 89 # define MAX_AUTH_USER_LEN 256 90 # endif 91 # ifndef MAX_AUTH_LOG_LEN 92 # define MAX_AUTH_LOG_LEN 64 93 # endif 94 static void get_sasl_user __P((char *, unsigned int, const char *, char *out, size_t)); 95 # define RESET_AUTH_FAIL_LOG_USER \ 96 do \ 97 { \ 98 (void) memset(auth_user, 0, sizeof(auth_user)); \ 99 (void) memset(auth_user_tmp, 0, sizeof(auth_user_tmp)); \ 100 auth_user_len = 0; \ 101 } while (0) 102 # define SET_AUTH_USER_TMP(s, len) \ 103 do \ 104 { \ 105 auth_user_len = SM_MIN(len, MAX_AUTH_USER_LEN-1); \ 106 (void) memcpy(auth_user_tmp, s, auth_user_len); \ 107 } while (0) 108 # define SET_AUTH_USER \ 109 get_sasl_user(auth_user_tmp, auth_user_len, auth_type, auth_user, sizeof(auth_user)) 110 # define SET_AUTH_USER_CONDITIONALLY \ 111 if ('\0' == auth_user[0]) \ 112 SET_AUTH_USER; 113 # define LOG_AUTH_FAIL_USER ", user=", (int)MAX_AUTH_LOG_LEN, auth_user 114 # if SASL >= 20000 115 static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, 116 char *_remoteip, char *_localip, 117 char *_auth_id, sasl_ssf_t *_ext_ssf)); 118 119 # define RESET_SASLCONN \ 120 do \ 121 { \ 122 RESET_AUTH_FAIL_LOG_USER; \ 123 result = reset_saslconn(&conn, AuthRealm, remoteip, \ 124 localip, auth_id, &ext_ssf); \ 125 if (result != SASL_OK) \ 126 sasl_ok = false; \ 127 } while (0) 128 129 # else /* SASL >= 20000 */ 130 static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, 131 struct sockaddr_in *_saddr_r, 132 struct sockaddr_in *_saddr_l, 133 sasl_external_properties_t *_ext_ssf)); 134 # define RESET_SASLCONN \ 135 do \ 136 { \ 137 RESET_AUTH_FAIL_LOG_USER; \ 138 result = reset_saslconn(&conn, AuthRealm, &saddr_r, \ 139 &saddr_l, &ext_ssf); \ 140 if (result != SASL_OK) \ 141 sasl_ok = false; \ 142 } while (0) 143 144 # endif /* SASL >= 20000 */ 145 #endif /* SASL */ 146 147 #if !defined(RESET_AUTH_FAIL_LOG_USER) 148 # define RESET_AUTH_FAIL_LOG_USER 149 #endif 150 151 extern ENVELOPE BlankEnvelope; 152 153 #define NBADRCPTS \ 154 do \ 155 { \ 156 char buf[16]; \ 157 (void) sm_snprintf(buf, sizeof(buf), "%d", \ 158 BadRcptThrottle > 0 && n_badrcpts > BadRcptThrottle \ 159 ? n_badrcpts - 1 : n_badrcpts); \ 160 macdefine(&e->e_macro, A_TEMP, macid("{nbadrcpts}"), buf); \ 161 } while (0) 162 163 #define SKIP_SPACE(s) while (SM_ISSPACE(*s)) \ 164 (s)++ 165 166 #if USE_EAI 167 /* 168 ** ADDR_IS_ASCII -- check whether an address is 100% printable ASCII 169 ** 170 ** Parameters: 171 ** a -- an address (or other string) 172 ** 173 ** Returns: 174 ** TRUE if a is non-NULL and points to only printable ASCII 175 ** FALSE if a is NULL and points to printable ASCII 176 ** FALSE if a is non-NULL and points to something containing 8-bittery 177 */ 178 179 bool 180 addr_is_ascii(a) 181 const char *a; 182 { 183 while (a != NULL && *a != '\0' && *a >= ' ' && (unsigned char)*a < 127) 184 a++; 185 return (a != NULL && *a == '\0'); 186 } 187 188 # define CHECK_UTF8_ADDR(a, q) \ 189 do \ 190 { \ 191 q = NULL; \ 192 if (addr_is_ascii(a)) \ 193 break; \ 194 if (!SMTPUTF8) \ 195 break; \ 196 if (!e->e_smtputf8) \ 197 q = "553 5.6.7 Address requires SMTPUTF8"; \ 198 else \ 199 { \ 200 char str[MAXNAME]; \ 201 dequote_internal_chars(a, str, sizeof(str)); \ 202 if (!utf8_valid(str, strlen(str)) && SMTPUTF8 <= 1) \ 203 q = "553 5.6.7 Address not valid UTF8"; \ 204 } \ 205 } while (0) 206 #endif /* USE_EAI */ 207 208 /* 209 ** PARSE_ESMTP_ARGS -- parse ESMTP arguments (for MAIL, RCPT) 210 ** 211 ** Parameters: 212 ** e -- the envelope 213 ** addr_st -- address (RCPT only) 214 ** p -- read buffer 215 ** delimptr -- current position in read buffer 216 ** which -- MAIL/RCPT 217 ** args -- arguments (output) 218 ** esmtp_args -- function to process a single ESMTP argument 219 ** 220 ** Returns: 221 ** none 222 */ 223 224 void 225 parse_esmtp_args(e, addr_st, p, delimptr, which, args, esmtp_args) 226 ENVELOPE *e; 227 ADDRESS *addr_st; 228 char *p; 229 char *delimptr; 230 char *which; 231 char *args[]; 232 esmtp_args_F esmtp_args; 233 { 234 int argno; 235 236 argno = 0; 237 if (args != NULL) 238 args[argno++] = p; 239 p = delimptr; 240 while (p != NULL && *p != '\0') 241 { 242 char *kp; 243 char *vp = NULL; 244 char *equal = NULL; 245 246 /* locate the beginning of the keyword */ 247 SKIP_SPACE(p); 248 if (*p == '\0') 249 break; 250 kp = p; 251 252 /* skip to the value portion */ 253 while ((isascii(*p) && isalnum(*p)) || *p == '-') 254 p++; 255 if (*p == '=') 256 { 257 equal = p; 258 *p++ = '\0'; 259 vp = p; 260 261 /* skip to the end of the value */ 262 while (*p != '\0' && *p != ' ' && 263 !(isascii(*p) && iscntrl(*p)) && 264 *p != '=') 265 p++; 266 } 267 268 if (*p != '\0') 269 *p++ = '\0'; 270 271 if (tTd(19, 1)) 272 sm_dprintf("%s: got arg %s=\"%s\"\n", which, kp, 273 vp == NULL ? "<null>" : vp); 274 275 esmtp_args(addr_st, kp, vp, e); 276 if (equal != NULL) 277 *equal = '='; 278 if (args != NULL) 279 args[argno] = kp; 280 argno++; 281 if (argno >= MAXSMTPARGS - 1) 282 usrerr("501 5.5.4 Too many parameters"); 283 if (Errors > 0) 284 break; 285 } 286 if (args != NULL) 287 args[argno] = NULL; 288 } 289 290 #if _FFR_ADD_BCC 291 292 /* 293 ** ADDRCPT -- Add a rcpt to sendq list 294 ** 295 ** Parameters: 296 ** rcpt -- rcpt [i] 297 ** sendq -- a pointer to the head of a queue to put 298 ** these people into. 299 ** e -- the envelope in which to add these recipients. 300 ** 301 ** Returns: 302 ** The number of addresses added to the list. 303 */ 304 305 static int 306 addrcpt(rcpt, sendq, e) 307 char *rcpt; 308 ADDRESS **sendq; 309 ENVELOPE *e; 310 { 311 int r; 312 char *oldto; 313 ADDRESS *a; 314 315 SM_REQUIRE(rcpt != NULL); 316 SM_REQUIRE(sendq != NULL); 317 SM_REQUIRE(e != NULL); 318 oldto = e->e_to; 319 if (tTd(25, 1)) 320 sm_dprintf("addrcpt: rcpt=%s\n", rcpt); 321 r = Errors; 322 a = NULL; 323 SM_TRY 324 { 325 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e b"); 326 /* XXX rcpt must be [i] */ 327 a = parseaddr(rcpt, NULLADDR, RF_COPYALL, ' ', NULL, e, true); 328 if (a == NULL) 329 return 0; 330 331 a->q_flags &= ~Q_PINGFLAGS; 332 a->q_flags |= QINTBCC; 333 a->q_owner = "<>"; 334 335 /* disable alias expansion? */ 336 a = recipient(a, sendq, 0, e); 337 } 338 SM_FINALLY 339 { 340 e->e_to = oldto; 341 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); 342 } 343 SM_END_TRY 344 if (tTd(25, 1)) 345 sm_dprintf("addrcpt: rcpt=%s, flags=%#lx\n", rcpt, 346 a != NULL ? a->q_flags : 0); 347 Errors = r; 348 return 1; 349 } 350 351 /* 352 ** ADDBCC -- Maybe create a copy of an e-mail 353 ** 354 ** Parameters: 355 ** a -- current RCPT 356 ** e -- the envelope. 357 ** 358 ** Returns: 359 ** nothing 360 ** 361 ** Side Effects: 362 ** rscheck() can trigger an "exception" 363 */ 364 365 static void 366 addbcc(a, e) 367 ADDRESS *a; 368 ENVELOPE *e; 369 { 370 int nobcc; 371 char *newrcpt, empty[1]; 372 373 if (!AddBcc) 374 return; 375 376 nobcc = false; 377 empty[0] = '\0'; 378 newrcpt = empty; 379 380 nobcc = rscheck("bcc", a->q_paddr, NULL, e, RSF_ADDR, 12, NULL, NOQID, 381 NULL, &newrcpt); 382 if (tTd(25, 1)) 383 sm_dprintf("addbcc: nobcc=%d, Errors=%d, newrcpt=<%s>\n", nobcc, Errors, newrcpt); 384 if (nobcc != EX_OK || Errors > 0 || *newrcpt == '\0') 385 return; 386 387 (void) addrcpt(newrcpt, &e->e_sendqueue, e); 388 return; 389 } 390 #else /* _FFR_ADD_BCC */ 391 # define addbcc(a, e) 392 #endif /* _FFR_ADD_BCC */ 393 394 #if _FFR_RCPTFLAGS 395 /* 396 ** RCPTMODS -- Perform rcpt modifications if requested 397 ** 398 ** Parameters: 399 ** rcpt -- current RCPT 400 ** e -- the envelope. 401 ** 402 ** Returns: 403 ** nothing. 404 */ 405 406 void 407 rcptmods(rcpt, e) 408 ADDRESS *rcpt; 409 ENVELOPE *e; 410 { 411 char *fl; 412 413 SM_REQUIRE(rcpt != NULL); 414 SM_REQUIRE(e != NULL); 415 416 fl = macvalue(macid("{rcpt_flags}"), e); 417 if (SM_IS_EMPTY(fl)) 418 return; 419 if (tTd(25, 1)) 420 sm_dprintf("rcptmods: rcpt=%s, flags=%s\n", rcpt->q_paddr, fl); 421 422 /* parse flags */ 423 for ( ; *fl != '\0'; ++fl) 424 { 425 switch (*fl) 426 { 427 case 'n': 428 rcpt->q_flags &= ~Q_PINGFLAGS; 429 rcpt->q_flags |= QINTBCC; 430 rcpt->q_owner = "<>"; 431 break; 432 433 case 'N': 434 rcpt->q_flags &= ~Q_PINGFLAGS; 435 rcpt->q_owner = "<>"; 436 break; 437 438 case QDYNMAILFLG: 439 rcpt->q_flags |= QDYNMAILER; 440 newmodmailer(rcpt, *fl); 441 break; 442 443 default: 444 sm_syslog(LOG_INFO, e->e_id, 445 "rcpt=%s, rcpt_flags=%s, status=unknown", 446 rcpt->q_paddr, fl); 447 break; 448 } 449 } 450 451 /* reset macro to avoid confusion later on */ 452 macdefine(&e->e_macro, A_PERM, macid("{rcpt_flags}"), NULL); 453 454 } 455 #else /* _FFR_RCPTFLAGS */ 456 # define rcptmods(a, e) 457 #endif /* _FFR_RCPTFLAGS */ 458 459 /* 460 ** SMTP -- run the SMTP protocol. 461 ** 462 ** Parameters: 463 ** nullserver -- if non-NULL, rejection message for 464 ** (almost) all SMTP commands. 465 ** d_flags -- daemon flags 466 ** e -- the envelope. 467 ** 468 ** Returns: 469 ** never. 470 ** 471 ** Side Effects: 472 ** Reads commands from the input channel and processes them. 473 */ 474 475 /* 476 ** Notice: The smtp server doesn't have a session context like the client 477 ** side has (mci). Therefore some data (session oriented) is allocated 478 ** or assigned to the "wrong" structure (esp. STARTTLS, AUTH). 479 ** This should be fixed in a successor version. 480 */ 481 482 struct cmd 483 { 484 char *cmd_name; /* command name */ 485 int cmd_code; /* internal code, see below */ 486 }; 487 488 /* values for cmd_code */ 489 #define CMDERROR 0 /* bad command */ 490 #define CMDMAIL 1 /* mail -- designate sender */ 491 #define CMDRCPT 2 /* rcpt -- designate recipient */ 492 #define CMDDATA 3 /* data -- send message text */ 493 #define CMDRSET 4 /* rset -- reset state */ 494 #define CMDVRFY 5 /* vrfy -- verify address */ 495 #define CMDEXPN 6 /* expn -- expand address */ 496 #define CMDNOOP 7 /* noop -- do nothing */ 497 #define CMDQUIT 8 /* quit -- close connection and die */ 498 #define CMDHELO 9 /* helo -- be polite */ 499 #define CMDHELP 10 /* help -- give usage info */ 500 #define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */ 501 #define CMDETRN 12 /* etrn -- flush queue */ 502 #if SASL 503 # define CMDAUTH 13 /* auth -- SASL authenticate */ 504 #endif 505 #if STARTTLS 506 # define CMDSTLS 14 /* STARTTLS -- start TLS session */ 507 #endif 508 /* non-standard commands */ 509 #define CMDVERB 17 /* verb -- go into verbose mode */ 510 /* unimplemented commands from RFC 821 */ 511 #define CMDUNIMPL 19 /* unimplemented rfc821 commands */ 512 /* use this to catch and log "door handle" attempts on your system */ 513 #define CMDLOGBOGUS 23 /* bogus command that should be logged */ 514 /* debugging-only commands, only enabled if SMTPDEBUG is defined */ 515 #define CMDDBGQSHOW 24 /* showq -- show send queue */ 516 #define CMDDBGDEBUG 25 /* debug -- set debug mode */ 517 518 /* 519 ** Note: If you change this list, remember to update 'helpfile' 520 */ 521 522 static struct cmd CmdTab[] = 523 { 524 { "mail", CMDMAIL }, 525 { "rcpt", CMDRCPT }, 526 { "data", CMDDATA }, 527 { "rset", CMDRSET }, 528 { "vrfy", CMDVRFY }, 529 { "expn", CMDEXPN }, 530 { "help", CMDHELP }, 531 { "noop", CMDNOOP }, 532 { "quit", CMDQUIT }, 533 { "helo", CMDHELO }, 534 { "ehlo", CMDEHLO }, 535 { "etrn", CMDETRN }, 536 { "verb", CMDVERB }, 537 { "send", CMDUNIMPL }, 538 { "saml", CMDUNIMPL }, 539 { "soml", CMDUNIMPL }, 540 { "turn", CMDUNIMPL }, 541 #if SASL 542 { "auth", CMDAUTH, }, 543 #endif 544 #if STARTTLS 545 { "starttls", CMDSTLS, }, 546 #endif 547 /* remaining commands are here only to trap and log attempts to use them */ 548 { "showq", CMDDBGQSHOW }, 549 { "debug", CMDDBGDEBUG }, 550 { "wiz", CMDLOGBOGUS }, 551 552 { NULL, CMDERROR } 553 }; 554 555 static char *CurSmtpClient; /* who's at the other end of channel */ 556 557 #ifndef MAXBADCOMMANDS 558 # define MAXBADCOMMANDS 25 /* maximum number of bad commands */ 559 #endif 560 #ifndef MAXHELOCOMMANDS 561 # define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */ 562 #endif 563 #ifndef MAXVRFYCOMMANDS 564 # define MAXVRFYCOMMANDS 6 /* max VRFY/EXPN commands before slowdown */ 565 #endif 566 #ifndef MAXETRNCOMMANDS 567 # define MAXETRNCOMMANDS 8 /* max ETRN commands before slowdown */ 568 #endif 569 #ifndef MAXTIMEOUT 570 # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */ 571 #endif 572 573 /* 574 ** Maximum shift value to compute timeout for bad commands. 575 ** This introduces an upper limit of 2^MAXSHIFT for the timeout. 576 */ 577 578 #ifndef MAXSHIFT 579 # define MAXSHIFT 8 580 #endif 581 #if MAXSHIFT > 31 582 # ERROR "MAXSHIFT > 31 is invalid" 583 #endif 584 585 586 #if MAXBADCOMMANDS > 0 587 # define STOP_IF_ATTACK(r) do \ 588 { \ 589 if ((r) == STOP_ATTACK) \ 590 goto stopattack; \ 591 } while (0) 592 593 #else /* MAXBADCOMMANDS > 0 */ 594 # define STOP_IF_ATTACK(r) r 595 #endif /* MAXBADCOMMANDS > 0 */ 596 597 598 #if SM_HEAP_CHECK 599 static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp", 600 "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $"); 601 #endif 602 603 typedef struct 604 { 605 bool sm_gotmail; /* mail command received */ 606 unsigned int sm_nrcpts; /* number of successful RCPT commands */ 607 bool sm_discard; 608 #if MILTER 609 bool sm_milterize; 610 bool sm_milterlist; /* any filters in the list? */ 611 milters_T sm_milters; 612 613 /* e_nrcpts from envelope before recipient() call */ 614 unsigned int sm_e_nrcpts_orig; 615 #endif /* MILTER */ 616 char *sm_quarmsg; /* carry quarantining across messages */ 617 } SMTP_T; 618 619 static bool smtp_data __P((SMTP_T *, ENVELOPE *)); 620 621 #define MSG_TEMPFAIL "451 4.3.2 Please try again later" 622 623 #if MILTER 624 # define MILTER_ABORT(e) milter_abort((e)) 625 626 # define MILTER_REPLY(str) \ 627 { \ 628 int savelogusrerrs = LogUsrErrs; \ 629 \ 630 milter_cmd_fail = true; \ 631 switch (state) \ 632 { \ 633 case SMFIR_SHUTDOWN: \ 634 if (MilterLogLevel > 3) \ 635 { \ 636 sm_syslog(LOG_INFO, e->e_id, \ 637 "Milter: %s=%s, reject=421, errormode=4", \ 638 str, addr); \ 639 LogUsrErrs = false; \ 640 } \ 641 { \ 642 bool tsave = QuickAbort; \ 643 \ 644 QuickAbort = false; \ 645 usrerr("421 4.3.0 closing connection"); \ 646 QuickAbort = tsave; \ 647 e->e_sendqueue = NULL; \ 648 goto doquit; \ 649 } \ 650 break; \ 651 case SMFIR_REPLYCODE: \ 652 if (MilterLogLevel > 3) \ 653 { \ 654 sm_syslog(LOG_INFO, e->e_id, \ 655 "Milter: %s=%s, reject=%s", \ 656 str, addr, response); \ 657 LogUsrErrs = false; \ 658 } \ 659 if (strncmp(response, "421 ", 4) == 0 \ 660 || strncmp(response, "421-", 4) == 0) \ 661 { \ 662 bool tsave = QuickAbort; \ 663 \ 664 QuickAbort = false; \ 665 usrerr(response); \ 666 QuickAbort = tsave; \ 667 e->e_sendqueue = NULL; \ 668 goto doquit; \ 669 } \ 670 else \ 671 usrerr(response); \ 672 break; \ 673 \ 674 case SMFIR_REJECT: \ 675 if (MilterLogLevel > 3) \ 676 { \ 677 sm_syslog(LOG_INFO, e->e_id, \ 678 "Milter: %s=%s, reject=550 5.7.1 Command rejected", \ 679 str, addr); \ 680 LogUsrErrs = false; \ 681 } \ 682 usrerr("550 5.7.1 Command rejected"); \ 683 break; \ 684 \ 685 case SMFIR_DISCARD: \ 686 if (MilterLogLevel > 3) \ 687 sm_syslog(LOG_INFO, e->e_id, \ 688 "Milter: %s=%s, discard", \ 689 str, addr); \ 690 e->e_flags |= EF_DISCARD; \ 691 milter_cmd_fail = false; \ 692 break; \ 693 \ 694 case SMFIR_TEMPFAIL: \ 695 if (MilterLogLevel > 3) \ 696 { \ 697 sm_syslog(LOG_INFO, e->e_id, \ 698 "Milter: %s=%s, reject=%s", \ 699 str, addr, MSG_TEMPFAIL); \ 700 LogUsrErrs = false; \ 701 } \ 702 usrerr(MSG_TEMPFAIL); \ 703 break; \ 704 default: \ 705 milter_cmd_fail = false; \ 706 break; \ 707 } \ 708 LogUsrErrs = savelogusrerrs; \ 709 if (response != NULL) \ 710 sm_free(response); /* XXX */ \ 711 } 712 713 #else /* MILTER */ 714 # define MILTER_ABORT(e) 715 #endif /* MILTER */ 716 717 /* clear all SMTP state (for HELO/EHLO/RSET) */ 718 #define CLEAR_STATE(cmd) \ 719 do \ 720 { \ 721 /* abort milter filters */ \ 722 MILTER_ABORT(e); \ 723 \ 724 if (smtp.sm_nrcpts > 0) \ 725 { \ 726 logundelrcpts(e, cmd, 10, false); \ 727 smtp.sm_nrcpts = 0; \ 728 macdefine(&e->e_macro, A_PERM, \ 729 macid("{nrcpts}"), "0"); \ 730 } \ 731 \ 732 e->e_sendqueue = NULL; \ 733 e->e_flags |= EF_CLRQUEUE; \ 734 \ 735 if (tTd(92, 2)) \ 736 sm_dprintf("CLEAR_STATE: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",\ 737 e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);\ 738 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) \ 739 logsender(e, NULL); \ 740 e->e_flags &= ~EF_LOGSENDER; \ 741 \ 742 /* clean up a bit */ \ 743 smtp.sm_gotmail = false; \ 744 SuprErrs = true; \ 745 (void) dropenvelope(e, true, false); \ 746 sm_rpool_free(e->e_rpool); \ 747 e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \ 748 CurEnv = e; \ 749 e->e_features = features; \ 750 \ 751 /* put back discard bit */ \ 752 if (smtp.sm_discard) \ 753 e->e_flags |= EF_DISCARD; \ 754 \ 755 /* restore connection quarantining */ \ 756 if (smtp.sm_quarmsg == NULL) \ 757 { \ 758 e->e_quarmsg = NULL; \ 759 macdefine(&e->e_macro, A_PERM, \ 760 macid("{quarantine}"), ""); \ 761 } \ 762 else \ 763 { \ 764 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 765 smtp.sm_quarmsg); \ 766 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ 767 e->e_quarmsg); \ 768 } \ 769 } while (0) 770 771 /* sleep to flatten out connection load */ 772 #define MIN_DELAY_LOG 15 /* wait before logging this again */ 773 774 /* is it worth setting the process title for 1s? */ 775 #define DELAY_CONN(cmd) \ 776 if (DelayLA > 0 && (CurrentLA = getla()) >= DelayLA) \ 777 { \ 778 time_t dnow; \ 779 \ 780 sm_setproctitle(true, e, \ 781 "%s: %s: delaying %s: load average: %d", \ 782 qid_printname(e), CurSmtpClient, \ 783 cmd, DelayLA); \ 784 if (LogLevel > 8 && (dnow = curtime()) > log_delay) \ 785 { \ 786 sm_syslog(LOG_INFO, e->e_id, \ 787 "delaying=%s, load average=%d >= %d", \ 788 cmd, CurrentLA, DelayLA); \ 789 log_delay = dnow + MIN_DELAY_LOG; \ 790 } \ 791 (void) sleep(1); \ 792 sm_setproctitle(true, e, "%s %s: %.80s", \ 793 qid_printname(e), CurSmtpClient, inp); \ 794 } 795 796 /* 797 ** Determine the correct protocol keyword to use in the 798 ** Received: header, following RFC 3848. 799 */ 800 801 #if !STARTTLS 802 # define tls_active false 803 #endif 804 #if SASL 805 # define auth_active (authenticating == SASL_IS_AUTH) 806 #else 807 # define auth_active false 808 #endif 809 #if USE_EAI 810 #define GET_PROTOCOL() \ 811 (e->e_smtputf8 \ 812 ? (auth_active \ 813 ? (tls_active ? "UTF8SMTPSA" : "UTF8SMTPA") \ 814 : (tls_active ? "UTF8SMTPS" : "UTF8SMTP")) \ 815 : (auth_active \ 816 ? (tls_active ? "ESMTPSA" : "ESMTPA") \ 817 : (tls_active ? "ESMTPS" : "ESMTP"))) 818 #else /* USE_EAI */ 819 #define GET_PROTOCOL() \ 820 (auth_active \ 821 ? (tls_active ? "ESMTPSA" : "ESMTPA") \ 822 : (tls_active ? "ESMTPS" : "ESMTP")) 823 #endif /* USE_EAI */ 824 825 static bool SevenBitInput_Saved; /* saved version of SevenBitInput */ 826 827 #if _FFR_NOREFLECT 828 # define SHOWCMDINREPLY(inp) (bitset(PRIV_NOREFLECTION, PrivacyFlags) ? \ 829 "(suppressed)" : inp) 830 # define SHOWSHRTCMDINREPLY(inp) (bitset(PRIV_NOREFLECTION, PrivacyFlags) ? \ 831 "(suppressed)" : shortenstring(inp, MAXSHORTSTR)) 832 #else 833 # define SHOWCMDINREPLY(inp) inp 834 # define SHOWSHRTCMDINREPLY(inp) shortenstring(inp, MAXSHORTSTR) 835 #endif 836 837 void 838 smtp(nullserver, d_flags, e) 839 char *volatile nullserver; 840 BITMAP256 d_flags; 841 register ENVELOPE *volatile e; 842 { 843 register char *volatile p; 844 register struct cmd *volatile c = NULL; 845 char *cmd; 846 auto ADDRESS *vrfyqueue; 847 ADDRESS *a; 848 volatile bool gothello; /* helo command received */ 849 bool vrfy; /* set if this is a vrfy command */ 850 char *volatile protocol; /* sending protocol */ 851 char *volatile sendinghost; /* sending hostname */ 852 char *volatile peerhostname; /* name of SMTP peer or "localhost" */ 853 auto char *delimptr; 854 char *id; 855 volatile unsigned int n_badcmds = 0; /* count of bad commands */ 856 volatile unsigned int n_badrcpts = 0; /* number of rejected RCPT */ 857 volatile unsigned int n_verifies = 0; /* count of VRFY/EXPN */ 858 volatile unsigned int n_etrn = 0; /* count of ETRN */ 859 volatile unsigned int n_noop = 0; /* count of NOOP/VERB/etc */ 860 volatile unsigned int n_helo = 0; /* count of HELO/EHLO */ 861 bool ok; 862 volatile bool first; 863 volatile bool tempfail = false; 864 volatile time_t wt; /* timeout after too many commands */ 865 volatile time_t previous; /* time after checksmtpattack() */ 866 volatile bool lognullconnection = true; 867 register char *q; 868 SMTP_T smtp; 869 char *addr; 870 char *greetcode = "220"; 871 const char *greetmsg = "not accepting messages"; 872 char *hostname; /* my hostname ($j) */ 873 QUEUE_CHAR *new; 874 char *args[MAXSMTPARGS]; 875 char inp[MAXINPLINE]; 876 #if MAXINPLINE < MAXLINE 877 # ERROR "MAXINPLINE must NOT be less than MAXLINE" 878 #endif 879 char cmdbuf[MAXLINE]; 880 #if SASL 881 sasl_conn_t *conn; 882 volatile bool sasl_ok; 883 volatile unsigned int n_auth = 0; /* count of AUTH commands */ 884 bool ismore; 885 int result; 886 volatile int authenticating; 887 char *user; 888 char *in, *out2; 889 char auth_user[MAX_AUTH_USER_LEN], auth_user_tmp[MAX_AUTH_USER_LEN]; 890 unsigned int auth_user_len; 891 # if SASL >= 20000 892 char *auth_id = NULL; 893 const char *out; 894 sasl_ssf_t ext_ssf; 895 char localip[60], remoteip[60]; 896 # else /* SASL >= 20000 */ 897 char *out; 898 const char *errstr; 899 sasl_external_properties_t ext_ssf; 900 struct sockaddr_in saddr_l; 901 struct sockaddr_in saddr_r; 902 # endif /* SASL >= 20000 */ 903 sasl_security_properties_t ssp; 904 sasl_ssf_t *ssf; 905 unsigned int inlen, out2len; 906 unsigned int outlen; 907 char *volatile auth_type; 908 char *mechlist; 909 volatile unsigned int n_mechs; 910 unsigned int len; 911 #endif /* SASL */ 912 int r; 913 #if STARTTLS 914 int rfd, wfd; 915 volatile bool tls_active = false; 916 volatile bool smtps = bitnset(D_SMTPS, d_flags); 917 bool saveQuickAbort; 918 bool saveSuprErrs; 919 time_t tlsstart; 920 int ssl_err, tlsret; 921 int save_errno; 922 extern int TLSsslidx; 923 #endif /* STARTTLS */ 924 volatile unsigned int features; 925 #if PIPELINING 926 # if _FFR_NO_PIPE 927 int np_log = 0; 928 # endif 929 #endif 930 volatile time_t log_delay = (time_t) 0; 931 #if MILTER 932 volatile bool milter_cmd_done, milter_cmd_safe; 933 volatile bool milter_rcpt_added, milter_cmd_fail; 934 ADDRESS addr_st; 935 # define p_addr_st &addr_st 936 #else /* MILTER */ 937 # define p_addr_st NULL 938 #endif /* MILTER */ 939 size_t inplen; 940 #if _FFR_BADRCPT_SHUTDOWN 941 int n_badrcpts_adj; 942 #endif 943 944 RESET_AUTH_FAIL_LOG_USER; 945 SevenBitInput_Saved = SevenBitInput; 946 smtp.sm_nrcpts = 0; 947 #if MILTER 948 smtp.sm_milterize = (nullserver == NULL); 949 smtp.sm_milterlist = false; 950 addr = NULL; 951 #endif 952 953 /* setup I/O fd correctly for the SMTP server */ 954 setup_smtpd_io(); 955 956 #if SM_HEAP_CHECK 957 if (sm_debug_active(&DebugLeakSmtp, 1)) 958 { 959 sm_heap_newgroup(); 960 sm_dprintf("smtp() heap group #%d\n", sm_heap_group()); 961 } 962 #endif /* SM_HEAP_CHECK */ 963 964 /* XXX the rpool should be set when e is initialized in main() */ 965 e->e_rpool = sm_rpool_new_x(NULL); 966 e->e_macro.mac_rpool = e->e_rpool; 967 968 settime(e); 969 sm_getla(); 970 peerhostname = RealHostName; 971 if (peerhostname == NULL) 972 peerhostname = "localhost"; 973 CurHostName = peerhostname; 974 CurSmtpClient = macvalue('_', e); 975 if (CurSmtpClient == NULL) 976 CurSmtpClient = CurHostName; 977 978 /* check_relay may have set discard bit, save for later */ 979 smtp.sm_discard = bitset(EF_DISCARD, e->e_flags); 980 981 #if PIPELINING 982 /* auto-flush output when reading input */ 983 (void) sm_io_autoflush(InChannel, OutChannel); 984 #endif 985 986 sm_setproctitle(true, e, "server %s startup", CurSmtpClient); 987 988 /* Set default features for server. */ 989 features = ((bitset(PRIV_NOETRN, PrivacyFlags) || 990 bitnset(D_NOETRN, d_flags)) ? SRV_NONE : SRV_OFFER_ETRN) 991 | (bitnset(D_AUTHREQ, d_flags) ? SRV_REQ_AUTH : SRV_NONE) 992 | (bitset(PRIV_NOEXPN, PrivacyFlags) ? SRV_NONE 993 : (SRV_OFFER_EXPN 994 | (bitset(PRIV_NOVERB, PrivacyFlags) 995 ? SRV_NONE : SRV_OFFER_VERB))) 996 | ((bitset(PRIV_NORECEIPTS, PrivacyFlags) || !SendMIMEErrors) 997 ? SRV_NONE : SRV_OFFER_DSN) 998 #if SASL 999 | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH) 1000 | (bitset(SASL_SEC_NOPLAINTEXT, SASLOpts) ? SRV_REQ_SEC 1001 : SRV_NONE) 1002 #endif /* SASL */ 1003 #if PIPELINING 1004 | SRV_OFFER_PIPE 1005 #endif 1006 #if STARTTLS 1007 | (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS) 1008 | (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE 1009 : SRV_VRFY_CLT) 1010 #endif 1011 #if USE_EAI 1012 | (SMTPUTF8 ? SRV_OFFER_EAI : 0) 1013 #endif 1014 ; 1015 if (nullserver == NULL) 1016 { 1017 features = srvfeatures(e, CurSmtpClient, features); 1018 if (bitset(SRV_TMP_FAIL, features)) 1019 { 1020 if (LogLevel > 4) 1021 sm_syslog(LOG_ERR, NOQID, 1022 "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled", 1023 CurSmtpClient); 1024 nullserver = "450 4.3.0 Please try again later."; 1025 } 1026 else 1027 { 1028 #if PIPELINING 1029 # if _FFR_NO_PIPE 1030 if (bitset(SRV_NO_PIPE, features)) 1031 { 1032 /* for consistency */ 1033 features &= ~SRV_OFFER_PIPE; 1034 } 1035 # endif /* _FFR_NO_PIPE */ 1036 #endif /* PIPELINING */ 1037 #if SASL 1038 if (bitset(SRV_REQ_SEC, features)) 1039 SASLOpts |= SASL_SEC_NOPLAINTEXT; 1040 else 1041 SASLOpts &= ~SASL_SEC_NOPLAINTEXT; 1042 #endif /* SASL */ 1043 } 1044 } 1045 else if (strncmp(nullserver, "421 ", 4) == 0) 1046 { 1047 /* Can't use ("%s", ...) due to message() requirements */ 1048 message(nullserver); 1049 goto doquit; 1050 } 1051 1052 e->e_features = features; 1053 hostname = macvalue('j', e); 1054 #if SASL 1055 if (AuthRealm == NULL) 1056 AuthRealm = hostname; 1057 sasl_ok = bitset(SRV_OFFER_AUTH, features); 1058 n_mechs = 0; 1059 authenticating = SASL_NOT_AUTH; 1060 1061 /* SASL server new connection */ 1062 if (sasl_ok) 1063 { 1064 # if SASL >= 20000 1065 result = sasl_server_new("smtp", AuthRealm, NULL, NULL, NULL, 1066 NULL, 0, &conn); 1067 # elif SASL > 10505 1068 /* use empty realm: only works in SASL > 1.5.5 */ 1069 result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn); 1070 # else /* SASL >= 20000 */ 1071 /* use no realm -> realm is set to hostname by SASL lib */ 1072 result = sasl_server_new("smtp", AuthRealm, NULL, NULL, 0, 1073 &conn); 1074 # endif /* SASL >= 20000 */ 1075 sasl_ok = result == SASL_OK; 1076 if (!sasl_ok) 1077 { 1078 if (LogLevel > 9) 1079 sm_syslog(LOG_WARNING, NOQID, 1080 "AUTH error: sasl_server_new failed=%d", 1081 result); 1082 } 1083 } 1084 if (sasl_ok) 1085 { 1086 /* 1087 ** SASL set properties for sasl 1088 ** set local/remote IP 1089 ** XXX Cyrus SASL v1 only supports IPv4 1090 ** 1091 ** XXX where exactly are these used/required? 1092 ** Kerberos_v4 1093 */ 1094 1095 # if SASL >= 20000 1096 localip[0] = remoteip[0] = '\0'; 1097 # if NETINET || NETINET6 1098 in = macvalue(macid("{daemon_family}"), e); 1099 if (in != NULL && ( 1100 # if NETINET6 1101 strcmp(in, "inet6") == 0 || 1102 # endif 1103 strcmp(in, "inet") == 0)) 1104 { 1105 SOCKADDR_LEN_T addrsize; 1106 SOCKADDR saddr_l; 1107 SOCKADDR saddr_r; 1108 1109 addrsize = sizeof(saddr_r); 1110 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD, 1111 NULL), 1112 (struct sockaddr *) &saddr_r, 1113 &addrsize) == 0) 1114 { 1115 if (iptostring(&saddr_r, addrsize, 1116 remoteip, sizeof(remoteip))) 1117 { 1118 sasl_setprop(conn, SASL_IPREMOTEPORT, 1119 remoteip); 1120 } 1121 addrsize = sizeof(saddr_l); 1122 if (getsockname(sm_io_getinfo(InChannel, 1123 SM_IO_WHAT_FD, 1124 NULL), 1125 (struct sockaddr *) &saddr_l, 1126 &addrsize) == 0) 1127 { 1128 if (iptostring(&saddr_l, addrsize, 1129 localip, 1130 sizeof(localip))) 1131 { 1132 sasl_setprop(conn, 1133 SASL_IPLOCALPORT, 1134 localip); 1135 } 1136 } 1137 } 1138 } 1139 # endif /* NETINET || NETINET6 */ 1140 # else /* SASL >= 20000 */ 1141 # if NETINET 1142 in = macvalue(macid("{daemon_family}"), e); 1143 if (in != NULL && strcmp(in, "inet") == 0) 1144 { 1145 SOCKADDR_LEN_T addrsize; 1146 1147 addrsize = sizeof(struct sockaddr_in); 1148 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD, 1149 NULL), 1150 (struct sockaddr *)&saddr_r, 1151 &addrsize) == 0) 1152 { 1153 sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r); 1154 addrsize = sizeof(struct sockaddr_in); 1155 if (getsockname(sm_io_getinfo(InChannel, 1156 SM_IO_WHAT_FD, 1157 NULL), 1158 (struct sockaddr *)&saddr_l, 1159 &addrsize) == 0) 1160 sasl_setprop(conn, SASL_IP_LOCAL, 1161 &saddr_l); 1162 } 1163 } 1164 # endif /* NETINET */ 1165 # endif /* SASL >= 20000 */ 1166 1167 auth_type = NULL; 1168 mechlist = NULL; 1169 user = NULL; 1170 # if 0 1171 macdefine(&BlankEnvelope.e_macro, A_PERM, 1172 macid("{auth_author}"), NULL); 1173 # endif 1174 1175 /* set properties */ 1176 (void) memset(&ssp, '\0', sizeof(ssp)); 1177 1178 /* XXX should these be options settable via .cf ? */ 1179 /* ssp.min_ssf = 0; is default due to memset() */ 1180 ssp.max_ssf = MaxSLBits; 1181 ssp.maxbufsize = MAXOUTLEN; 1182 ssp.security_flags = SASLOpts & SASL_SEC_MASK; 1183 sasl_ok = sasl_setprop(conn, SASL_SEC_PROPS, &ssp) == SASL_OK; 1184 1185 if (sasl_ok) 1186 { 1187 /* 1188 ** external security strength factor; 1189 ** currently we have none so zero 1190 */ 1191 1192 # if SASL >= 20000 1193 ext_ssf = 0; 1194 auth_id = NULL; 1195 sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL, 1196 &ext_ssf) == SASL_OK) && 1197 (sasl_setprop(conn, SASL_AUTH_EXTERNAL, 1198 auth_id) == SASL_OK)); 1199 # else /* SASL >= 20000 */ 1200 ext_ssf.ssf = 0; 1201 ext_ssf.auth_id = NULL; 1202 sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL, 1203 &ext_ssf) == SASL_OK; 1204 # endif /* SASL >= 20000 */ 1205 } 1206 if (sasl_ok) 1207 n_mechs = saslmechs(conn, &mechlist); 1208 } 1209 #endif /* SASL */ 1210 1211 (void) set_tls_rd_tmo(TimeOuts.to_nextcommand); 1212 1213 #if MILTER 1214 if (smtp.sm_milterize) 1215 { 1216 char state; 1217 1218 /* initialize mail filter connection */ 1219 smtp.sm_milterlist = milter_init(e, &state, &smtp.sm_milters); 1220 switch (state) 1221 { 1222 case SMFIR_REJECT: 1223 if (MilterLogLevel > 3) 1224 sm_syslog(LOG_INFO, e->e_id, 1225 "Milter: initialization failed, rejecting commands"); 1226 greetcode = "554"; 1227 nullserver = "Command rejected"; 1228 smtp.sm_milterize = false; 1229 break; 1230 1231 case SMFIR_TEMPFAIL: 1232 if (MilterLogLevel > 3) 1233 sm_syslog(LOG_INFO, e->e_id, 1234 "Milter: initialization failed, temp failing commands"); 1235 tempfail = true; 1236 smtp.sm_milterize = false; 1237 break; 1238 1239 case SMFIR_SHUTDOWN: 1240 if (MilterLogLevel > 3) 1241 sm_syslog(LOG_INFO, e->e_id, 1242 "Milter: initialization failed, closing connection"); 1243 tempfail = true; 1244 smtp.sm_milterize = false; 1245 message("421 4.7.0 %s closing connection", 1246 MyHostName); 1247 1248 /* arrange to ignore send list */ 1249 e->e_sendqueue = NULL; 1250 lognullconnection = false; 1251 goto doquit; 1252 } 1253 } 1254 1255 if (smtp.sm_milterlist && smtp.sm_milterize && 1256 !bitset(EF_DISCARD, e->e_flags)) 1257 { 1258 char state; 1259 char *response; 1260 1261 q = macvalue(macid("{client_name}"), e); 1262 SM_ASSERT(q != NULL || OpMode == MD_SMTP); 1263 if (q == NULL) 1264 q = "localhost"; 1265 response = milter_connect(q, RealHostAddr, e, &state); 1266 switch (state) 1267 { 1268 # if _FFR_MILTER_CONNECT_REPLYCODE 1269 case SMFIR_REPLYCODE: 1270 if (*response == '5') 1271 { 1272 if (MilterLogLevel > 3) 1273 sm_syslog(LOG_INFO, e->e_id, 1274 "Milter: connect: host=%s, addr=%s, reject=%s", 1275 peerhostname, 1276 anynet_ntoa(&RealHostAddr), 1277 response); 1278 greetcode = "554"; /* Required by 2821 3.1 */ 1279 nullserver = newstr(response); 1280 if (strlen(nullserver) > 4) 1281 { 1282 int skip; 1283 1284 greetmsg = nullserver + 4; 1285 1286 /* skip over enhanced status code */ 1287 skip = isenhsc(greetmsg, ' '); 1288 if (skip > 0) 1289 greetmsg += skip + 1; 1290 } 1291 smtp.sm_milterize = false; 1292 break; 1293 } 1294 else if (strncmp(response, "421 ", 4) == 0) 1295 { 1296 int skip; 1297 const char *msg = response + 4; 1298 1299 if (MilterLogLevel > 3) 1300 sm_syslog(LOG_INFO, e->e_id, 1301 "Milter: connect: host=%s, addr=%s, shutdown=%s", 1302 peerhostname, 1303 anynet_ntoa(&RealHostAddr), 1304 response); 1305 tempfail = true; 1306 smtp.sm_milterize = false; 1307 1308 /* skip over enhanced status code */ 1309 skip = isenhsc(msg, ' '); 1310 if (skip > 0) 1311 msg += skip + 1; 1312 message("421 %s %s", MyHostName, msg); 1313 1314 /* arrange to ignore send list */ 1315 e->e_sendqueue = NULL; 1316 goto doquit; 1317 } 1318 else 1319 { 1320 if (MilterLogLevel > 3) 1321 sm_syslog(LOG_INFO, e->e_id, 1322 "Milter: connect: host=%s, addr=%s, temp failing commands=%s", 1323 peerhostname, 1324 anynet_ntoa(&RealHostAddr), 1325 response); 1326 /*tempfail = true;*/ 1327 smtp.sm_milterize = false; 1328 nullserver = newstr(response); 1329 break; 1330 } 1331 1332 # else /* _FFR_MILTER_CONNECT_REPLYCODE */ 1333 case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */ 1334 # endif /* _FFR_MILTER_CONNECT_REPLYCODE */ 1335 case SMFIR_REJECT: 1336 if (MilterLogLevel > 3) 1337 sm_syslog(LOG_INFO, e->e_id, 1338 "Milter: connect: host=%s, addr=%s, rejecting commands", 1339 peerhostname, 1340 anynet_ntoa(&RealHostAddr)); 1341 greetcode = "554"; 1342 nullserver = "Command rejected"; 1343 smtp.sm_milterize = false; 1344 break; 1345 1346 case SMFIR_TEMPFAIL: 1347 if (MilterLogLevel > 3) 1348 sm_syslog(LOG_INFO, e->e_id, 1349 "Milter: connect: host=%s, addr=%s, temp failing commands", 1350 peerhostname, 1351 anynet_ntoa(&RealHostAddr)); 1352 tempfail = true; 1353 smtp.sm_milterize = false; 1354 break; 1355 1356 case SMFIR_SHUTDOWN: 1357 if (MilterLogLevel > 3) 1358 sm_syslog(LOG_INFO, e->e_id, 1359 "Milter: connect: host=%s, addr=%s, shutdown", 1360 peerhostname, 1361 anynet_ntoa(&RealHostAddr)); 1362 tempfail = true; 1363 smtp.sm_milterize = false; 1364 message("421 4.7.0 %s closing connection", 1365 MyHostName); 1366 1367 /* arrange to ignore send list */ 1368 e->e_sendqueue = NULL; 1369 goto doquit; 1370 } 1371 if (response != NULL) 1372 sm_free(response); 1373 } 1374 #endif /* MILTER */ 1375 1376 /* 1377 ** Broken proxies and SMTP slammers 1378 ** push data without waiting, catch them 1379 */ 1380 1381 if ( 1382 #if STARTTLS 1383 !smtps && 1384 #endif 1385 *greetcode == '2' && nullserver == NULL) 1386 { 1387 time_t msecs = 0; 1388 char **pvp; 1389 char pvpbuf[PSBUFSIZE]; 1390 1391 /* Ask the rulesets how long to pause */ 1392 pvp = NULL; 1393 r = rscap("greet_pause", peerhostname, 1394 anynet_ntoa(&RealHostAddr), e, 1395 &pvp, pvpbuf, sizeof(pvpbuf)); 1396 if (r == EX_OK && pvp != NULL && pvp[0] != NULL && 1397 (pvp[0][0] & 0377) == CANONNET && pvp[1] != NULL) 1398 { 1399 msecs = strtol(pvp[1], NULL, 10); 1400 } 1401 1402 if (msecs > 0) 1403 { 1404 int fd; 1405 fd_set readfds; 1406 struct timeval timeout; 1407 struct timeval bp, ep, tp; /* {begin,end,total}pause */ 1408 int eoftest; 1409 1410 /* pause for a moment */ 1411 timeout.tv_sec = msecs / 1000; 1412 timeout.tv_usec = (msecs % 1000) * 1000; 1413 1414 /* Obey RFC 2821: 4.3.5.2: 220 timeout of 5 minutes */ 1415 if (timeout.tv_sec >= 300) 1416 { 1417 timeout.tv_sec = 300; 1418 timeout.tv_usec = 0; 1419 } 1420 1421 /* check if data is on the socket during the pause */ 1422 fd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL); 1423 FD_ZERO(&readfds); 1424 SM_FD_SET(fd, &readfds); 1425 gettimeofday(&bp, NULL); 1426 if (select(fd + 1, FDSET_CAST &readfds, 1427 NULL, NULL, &timeout) > 0 && 1428 FD_ISSET(fd, &readfds) && 1429 (eoftest = sm_io_getc(InChannel, SM_TIME_DEFAULT)) 1430 != SM_IO_EOF) 1431 { 1432 sm_io_ungetc(InChannel, SM_TIME_DEFAULT, 1433 eoftest); 1434 gettimeofday(&ep, NULL); 1435 timersub(&ep, &bp, &tp); 1436 greetcode = "554"; 1437 nullserver = "Command rejected"; 1438 sm_syslog(LOG_INFO, e->e_id, 1439 "rejecting commands from %s [%s] due to pre-greeting traffic after %d seconds", 1440 peerhostname, 1441 anynet_ntoa(&RealHostAddr), 1442 (int) tp.tv_sec + 1443 (tp.tv_usec >= 500000 ? 1 : 0) 1444 ); 1445 } 1446 } 1447 } 1448 1449 #if STARTTLS 1450 /* If this an smtps connection, start TLS now */ 1451 if (smtps) 1452 { 1453 if (!tls_ok_srv || srv_ctx == NULL) 1454 { 1455 sm_syslog(LOG_ERR, e->e_id, 1456 "smtps: TLS not available, exiting"); 1457 exit(EX_CONFIG); 1458 } 1459 Errors = 0; 1460 first = true; 1461 gothello = false; 1462 smtp.sm_gotmail = false; 1463 goto starttls; 1464 } 1465 1466 greeting: 1467 1468 #endif /* STARTTLS */ 1469 1470 /* output the first line, inserting "ESMTP" as second word */ 1471 if (*greetcode == '5') 1472 (void) sm_snprintf(inp, sizeof(inp), "%s %s", hostname, 1473 greetmsg); 1474 else 1475 expand(SmtpGreeting, inp, sizeof(inp), e); 1476 1477 p = strchr(inp, '\n'); 1478 if (p != NULL) 1479 *p++ = '\0'; 1480 id = strchr(inp, ' '); 1481 if (id == NULL) 1482 id = &inp[strlen(inp)]; 1483 if (p == NULL) 1484 (void) sm_snprintf(cmdbuf, sizeof(cmdbuf), 1485 "%s %%.*s ESMTP%%s", greetcode); 1486 else 1487 (void) sm_snprintf(cmdbuf, sizeof(cmdbuf), 1488 "%s-%%.*s ESMTP%%s", greetcode); 1489 message(cmdbuf, (int) (id - inp), inp, id); 1490 1491 /* output remaining lines */ 1492 while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL) 1493 { 1494 *p++ = '\0'; 1495 if (SM_ISSPACE(*id)) 1496 id++; 1497 (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, "-%s"); 1498 message(cmdbuf, id); 1499 } 1500 if (id != NULL) 1501 { 1502 if (SM_ISSPACE(*id)) 1503 id++; 1504 (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, " %s"); 1505 message(cmdbuf, id); 1506 } 1507 1508 protocol = NULL; 1509 sendinghost = macvalue('s', e); 1510 1511 /* If quarantining by a connect/ehlo action, save between messages */ 1512 if (e->e_quarmsg == NULL) 1513 smtp.sm_quarmsg = NULL; 1514 else 1515 smtp.sm_quarmsg = newstr(e->e_quarmsg); 1516 1517 /* sendinghost's storage must outlive the current envelope */ 1518 if (sendinghost != NULL) 1519 sendinghost = sm_strdup_x(sendinghost); 1520 first = true; 1521 gothello = false; 1522 smtp.sm_gotmail = false; 1523 for (;;) 1524 { 1525 SM_TRY 1526 { 1527 QuickAbort = false; 1528 HoldErrs = false; 1529 SuprErrs = false; 1530 LogUsrErrs = false; 1531 OnlyOneError = true; 1532 e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS); 1533 #if MILTER 1534 milter_cmd_fail = false; 1535 #endif 1536 1537 /* setup for the read */ 1538 e->e_to = NULL; 1539 Errors = 0; 1540 FileName = NULL; 1541 (void) sm_io_flush(smioout, SM_TIME_DEFAULT); 1542 1543 /* read the input line */ 1544 SmtpPhase = "server cmd read"; 1545 sm_setproctitle(true, e, "server %s cmd read", CurSmtpClient); 1546 1547 /* handle errors */ 1548 if (sm_io_error(OutChannel) || 1549 (p = sfgets(inp, sizeof(inp), InChannel, 1550 TimeOuts.to_nextcommand, SmtpPhase)) == NULL) 1551 { 1552 char *d; 1553 1554 d = macvalue(macid("{daemon_name}"), e); 1555 if (d == NULL) 1556 d = "stdin"; 1557 /* end of file, just die */ 1558 disconnect(1, e); 1559 1560 #if MILTER 1561 /* close out milter filters */ 1562 milter_quit(e); 1563 #endif 1564 1565 message("421 4.4.1 %s Lost input channel from %s", 1566 MyHostName, CurSmtpClient); 1567 if (LogLevel > (smtp.sm_gotmail ? 1 : 19)) 1568 sm_syslog(LOG_NOTICE, e->e_id, 1569 "lost input channel from %s to %s after %s", 1570 CurSmtpClient, d, 1571 (c == NULL || c->cmd_name == NULL) ? "startup" : c->cmd_name); 1572 /* 1573 ** If have not accepted mail (DATA), do not bounce 1574 ** bad addresses back to sender. 1575 */ 1576 1577 if (bitset(EF_CLRQUEUE, e->e_flags)) 1578 e->e_sendqueue = NULL; 1579 goto doquit; 1580 } 1581 1582 /* also used by "proxy" check below */ 1583 inplen = strlen(inp); 1584 #if SASL 1585 /* 1586 ** SMTP AUTH requires accepting any length, 1587 ** at least for challenge/response. However, not imposing 1588 ** a limit is a bad idea (denial of service). 1589 */ 1590 1591 if (authenticating != SASL_PROC_AUTH 1592 && sm_strncasecmp(inp, "AUTH ", 5) != 0 1593 && inplen > MAXLINE) 1594 { 1595 message("421 4.7.0 %s Command too long, possible attack %s", 1596 MyHostName, CurSmtpClient); 1597 sm_syslog(LOG_INFO, e->e_id, 1598 "%s: SMTP violation, input too long: %lu", 1599 CurSmtpClient, (unsigned long) inplen); 1600 goto doquit; 1601 } 1602 #endif /* SASL */ 1603 1604 if (first || bitset(SRV_NO_HTTP_CMD, features)) 1605 { 1606 size_t cmdlen; 1607 int idx; 1608 char *http_cmd; 1609 static char *http_cmds[] = { "GET", "POST", 1610 "CONNECT", "USER", NULL }; 1611 1612 for (idx = 0; (http_cmd = http_cmds[idx]) != NULL; 1613 idx++) 1614 { 1615 cmdlen = strlen(http_cmd); 1616 if (cmdlen < inplen && 1617 sm_strncasecmp(inp, http_cmd, cmdlen) == 0 && 1618 SM_ISSPACE(inp[cmdlen])) 1619 { 1620 /* Open proxy, drop it */ 1621 message("421 4.7.0 %s %s %s", 1622 MyHostName, 1623 first ? "Rejecting open proxy" 1624 : "HTTP command", 1625 CurSmtpClient); 1626 sm_syslog(LOG_INFO, e->e_id, 1627 "%s: probable open proxy: command=%.40s", 1628 CurSmtpClient, inp); 1629 goto doquit; 1630 } 1631 } 1632 first = false; 1633 } 1634 1635 /* clean up end of line */ 1636 fixcrlf(inp, true); 1637 1638 #if PIPELINING 1639 # if _FFR_NO_PIPE 1640 /* 1641 ** if there is more input and pipelining is disabled: 1642 ** delay ... (and maybe discard the input?) 1643 ** XXX this doesn't really work, at least in tests using 1644 ** telnet SM_IO_IS_READABLE only returns 1 if there were 1645 ** more than 2 input lines available. 1646 */ 1647 1648 if (bitset(SRV_NO_PIPE, features) && 1649 sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0) 1650 { 1651 if (++np_log < 3) 1652 sm_syslog(LOG_INFO, NOQID, 1653 "unauthorized PIPELINING, sleeping, relay=%.100s", 1654 CurSmtpClient); 1655 sleep(1); 1656 } 1657 1658 # endif /* _FFR_NO_PIPE */ 1659 #endif /* PIPELINING */ 1660 1661 #if SASL 1662 if (authenticating == SASL_PROC_AUTH) 1663 { 1664 # if 0 1665 if (*inp == '\0') 1666 { 1667 authenticating = SASL_NOT_AUTH; 1668 message("501 5.5.2 missing input"); 1669 RESET_SASLCONN; 1670 continue; 1671 } 1672 # endif /* 0 */ 1673 if (*inp == '*' && *(inp + 1) == '\0') 1674 { 1675 authenticating = SASL_NOT_AUTH; 1676 1677 /* RFC 2554 4. */ 1678 message("501 5.0.0 AUTH aborted"); 1679 RESET_SASLCONN; 1680 continue; 1681 } 1682 1683 /* could this be shorter? XXX */ 1684 # if SASL >= 20000 1685 in = xalloc(strlen(inp) + 1); 1686 result = sasl_decode64(inp, strlen(inp), in, 1687 strlen(inp), &inlen); 1688 # else /* SASL >= 20000 */ 1689 out = xalloc(strlen(inp)); 1690 result = sasl_decode64(inp, strlen(inp), out, &outlen); 1691 # endif /* SASL >= 20000 */ 1692 if (result != SASL_OK) 1693 { 1694 authenticating = SASL_NOT_AUTH; 1695 1696 /* RFC 2554 4. */ 1697 message("501 5.5.4 cannot decode AUTH parameter %s", 1698 inp); 1699 # if SASL >= 20000 1700 sm_free(in); 1701 # endif 1702 RESET_SASLCONN; 1703 continue; 1704 } 1705 1706 # if SASL >= 20000 1707 SET_AUTH_USER_TMP(in, inlen); 1708 result = sasl_server_step(conn, in, inlen, 1709 &out, &outlen); 1710 sm_free(in); 1711 # else /* SASL >= 20000 */ 1712 SET_AUTH_USER_TMP(out, outlen); 1713 result = sasl_server_step(conn, out, outlen, 1714 &out, &outlen, &errstr); 1715 # endif /* SASL >= 20000 */ 1716 1717 /* get an OK if we're done */ 1718 if (result == SASL_OK) 1719 { 1720 authenticated: 1721 message("235 2.0.0 OK Authenticated"); 1722 authenticating = SASL_IS_AUTH; 1723 macdefine(&BlankEnvelope.e_macro, A_TEMP, 1724 macid("{auth_type}"), auth_type); 1725 1726 # if SASL >= 20000 1727 user = macvalue(macid("{auth_authen}"), e); 1728 1729 /* get security strength (features) */ 1730 result = sasl_getprop(conn, SASL_SSF, 1731 (const void **) &ssf); 1732 # else /* SASL >= 20000 */ 1733 result = sasl_getprop(conn, SASL_USERNAME, 1734 (void **)&user); 1735 if (result != SASL_OK) 1736 { 1737 user = ""; 1738 macdefine(&BlankEnvelope.e_macro, 1739 A_PERM, 1740 macid("{auth_authen}"), NULL); 1741 } 1742 else 1743 { 1744 macdefine(&BlankEnvelope.e_macro, 1745 A_TEMP, 1746 macid("{auth_authen}"), 1747 xtextify(user, "<>\")")); 1748 } 1749 1750 # if 0 1751 /* get realm? */ 1752 sasl_getprop(conn, SASL_REALM, (void **) &data); 1753 # endif 1754 1755 /* get security strength (features) */ 1756 result = sasl_getprop(conn, SASL_SSF, 1757 (void **) &ssf); 1758 # endif /* SASL >= 20000 */ 1759 if (result != SASL_OK) 1760 { 1761 macdefine(&BlankEnvelope.e_macro, 1762 A_PERM, 1763 macid("{auth_ssf}"), "0"); 1764 ssf = NULL; 1765 } 1766 else 1767 { 1768 char pbuf[8]; 1769 1770 (void) sm_snprintf(pbuf, sizeof(pbuf), 1771 "%u", *ssf); 1772 macdefine(&BlankEnvelope.e_macro, 1773 A_TEMP, 1774 macid("{auth_ssf}"), pbuf); 1775 if (tTd(95, 8)) 1776 sm_dprintf("AUTH auth_ssf: %u\n", 1777 *ssf); 1778 } 1779 1780 protocol = GET_PROTOCOL(); 1781 1782 /* 1783 ** Only switch to encrypted connection 1784 ** if a security layer has been negotiated 1785 */ 1786 1787 if (ssf != NULL && *ssf > 0) 1788 { 1789 int tmo; 1790 1791 /* 1792 ** Convert I/O layer to use SASL. 1793 ** If the call fails, the connection 1794 ** is aborted. 1795 */ 1796 1797 tmo = TimeOuts.to_datablock * 1000; 1798 if (sfdcsasl(&InChannel, &OutChannel, 1799 conn, tmo) == 0) 1800 { 1801 /* restart dialogue */ 1802 n_helo = 0; 1803 # if PIPELINING 1804 (void) sm_io_autoflush(InChannel, 1805 OutChannel); 1806 # endif /* PIPELINING */ 1807 } 1808 else 1809 syserr("503 5.3.3 SASL TLS failed"); 1810 } 1811 1812 /* NULL pointer ok since it's our function */ 1813 if (LogLevel > 8) 1814 sm_syslog(LOG_INFO, NOQID, 1815 "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d", 1816 CurSmtpClient, 1817 shortenstring(user, 128), 1818 auth_type, *ssf); 1819 } 1820 else if (result == SASL_CONTINUE) 1821 { 1822 SET_AUTH_USER; 1823 1824 len = ENC64LEN(outlen); 1825 out2 = xalloc(len); 1826 result = sasl_encode64(out, outlen, out2, len, 1827 &out2len); 1828 if (result != SASL_OK) 1829 { 1830 /* correct code? XXX */ 1831 /* 454 Temp. authentication failure */ 1832 message("454 4.5.4 Internal error: unable to encode64"); 1833 if (LogLevel > 5) 1834 sm_syslog(LOG_WARNING, e->e_id, 1835 "AUTH encode64 error [%d for \"%s\"], relay=%.100s", 1836 result, out, 1837 CurSmtpClient); 1838 /* start over? */ 1839 authenticating = SASL_NOT_AUTH; 1840 } 1841 else 1842 { 1843 message("334 %s", out2); 1844 if (tTd(95, 2)) 1845 sm_dprintf("AUTH continue: msg='%s' len=%u\n", 1846 out2, out2len); 1847 } 1848 # if SASL >= 20000 1849 sm_free(out2); 1850 # endif 1851 } 1852 else 1853 { 1854 1855 # if SASL >= 20000 1856 # define SASLERR sasl_errdetail(conn) 1857 # else 1858 # define SASLERR errstr == NULL ? "" : errstr 1859 # endif 1860 #define LOGAUTHFAIL \ 1861 do \ 1862 { \ 1863 SET_AUTH_USER_CONDITIONALLY \ 1864 message("535 5.7.0 authentication failed"); \ 1865 if (LogLevel >= 9) \ 1866 sm_syslog(LOG_WARNING, e->e_id, \ 1867 "AUTH failure (%s): %s (%d) %s%s%.*s, relay=%.100s", \ 1868 (auth_type != NULL) ? auth_type : "unknown", \ 1869 sasl_errstring(result, NULL, NULL), \ 1870 result, \ 1871 SASLERR, \ 1872 LOG_AUTH_FAIL_USER, \ 1873 CurSmtpClient); \ 1874 RESET_SASLCONN; \ 1875 } while (0) 1876 1877 1878 LOGAUTHFAIL; 1879 authenticating = SASL_NOT_AUTH; 1880 } 1881 } 1882 else 1883 { 1884 /* don't want to do any of this if authenticating */ 1885 #endif /* SASL */ 1886 1887 /* echo command to transcript */ 1888 if (e->e_xfp != NULL) 1889 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 1890 "<<< %s\n", inp); 1891 1892 if (LogLevel > 14) 1893 sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp); 1894 1895 /* break off command */ 1896 for (p = inp; SM_ISSPACE(*p); p++) 1897 continue; 1898 cmd = cmdbuf; 1899 while (*p != '\0' && 1900 !(SM_ISSPACE(*p)) && 1901 cmd < &cmdbuf[sizeof(cmdbuf) - 2]) 1902 *cmd++ = *p++; 1903 *cmd = '\0'; 1904 1905 /* throw away leading whitespace */ 1906 SKIP_SPACE(p); 1907 1908 /* decode command */ 1909 for (c = CmdTab; c->cmd_name != NULL; c++) 1910 { 1911 if (SM_STRCASEEQ(c->cmd_name, cmdbuf)) 1912 break; 1913 } 1914 1915 /* reset errors */ 1916 errno = 0; 1917 1918 /* check whether a "non-null" command has been used */ 1919 switch (c->cmd_code) 1920 { 1921 #if SASL 1922 case CMDAUTH: 1923 /* avoid information leak; take first two words? */ 1924 q = "AUTH"; 1925 break; 1926 #endif /* SASL */ 1927 1928 case CMDMAIL: 1929 case CMDEXPN: 1930 case CMDVRFY: 1931 case CMDETRN: 1932 lognullconnection = false; 1933 /* FALLTHROUGH */ 1934 default: 1935 q = inp; 1936 break; 1937 } 1938 1939 if (e->e_id == NULL) 1940 sm_setproctitle(true, e, "%s: %.80s", 1941 CurSmtpClient, q); 1942 else 1943 sm_setproctitle(true, e, "%s %s: %.80s", 1944 qid_printname(e), 1945 CurSmtpClient, q); 1946 1947 /* 1948 ** Process command. 1949 ** 1950 ** If we are running as a null server, return 550 1951 ** to almost everything. 1952 */ 1953 1954 if (nullserver != NULL || bitnset(D_ETRNONLY, d_flags)) 1955 { 1956 switch (c->cmd_code) 1957 { 1958 case CMDQUIT: 1959 case CMDHELO: 1960 case CMDEHLO: 1961 case CMDNOOP: 1962 case CMDRSET: 1963 case CMDERROR: 1964 /* process normally */ 1965 break; 1966 1967 case CMDETRN: 1968 if (bitnset(D_ETRNONLY, d_flags) && 1969 nullserver == NULL) 1970 break; 1971 DELAY_CONN("ETRN"); 1972 /* FALLTHROUGH */ 1973 1974 default: 1975 #if MAXBADCOMMANDS > 0 1976 /* theoretically this could overflow */ 1977 if (nullserver != NULL && 1978 ++n_badcmds > MAXBADCOMMANDS) 1979 { 1980 message("421 4.7.0 %s Too many bad commands; closing connection", 1981 MyHostName); 1982 1983 /* arrange to ignore send list */ 1984 e->e_sendqueue = NULL; 1985 goto doquit; 1986 } 1987 #endif /* MAXBADCOMMANDS > 0 */ 1988 if (nullserver != NULL) 1989 { 1990 if (ISSMTPREPLY(nullserver)) 1991 { 1992 /* Can't use ("%s", ...) due to usrerr() requirements */ 1993 usrerr(nullserver); 1994 } 1995 else 1996 { 1997 usrerr("550 5.0.0 %s", 1998 nullserver); 1999 } 2000 } 2001 else 2002 usrerr("452 4.4.5 Insufficient disk space; try again later"); 2003 continue; 2004 } 2005 } 2006 2007 switch (c->cmd_code) 2008 { 2009 #if SASL 2010 case CMDAUTH: /* sasl */ 2011 DELAY_CONN("AUTH"); 2012 if (!sasl_ok || n_mechs <= 0) 2013 { 2014 message("503 5.3.3 AUTH not available"); 2015 break; 2016 } 2017 if (authenticating == SASL_IS_AUTH) 2018 { 2019 message("503 5.5.0 Already Authenticated"); 2020 break; 2021 } 2022 if (smtp.sm_gotmail) 2023 { 2024 message("503 5.5.0 AUTH not permitted during a mail transaction"); 2025 break; 2026 } 2027 if (tempfail) 2028 { 2029 if (LogLevel > 9) 2030 sm_syslog(LOG_INFO, e->e_id, 2031 "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)", 2032 p, CurSmtpClient); 2033 usrerr("454 4.3.0 Please try again later"); 2034 break; 2035 } 2036 2037 ismore = false; 2038 2039 /* crude way to avoid crack attempts */ 2040 STOP_IF_ATTACK(checksmtpattack(&n_auth, n_mechs + 1, 2041 true, "AUTH", e)); 2042 2043 /* make sure mechanism (p) is a valid string */ 2044 for (q = p; *q != '\0' && isascii(*q); q++) 2045 { 2046 if (isspace(*q)) 2047 { 2048 *q = '\0'; 2049 while (*++q != '\0' && SM_ISSPACE(*q)) 2050 continue; 2051 *(q - 1) = '\0'; 2052 ismore = (*q != '\0'); 2053 break; 2054 } 2055 } 2056 2057 if (*p == '\0') 2058 { 2059 message("501 5.5.2 AUTH mechanism must be specified"); 2060 break; 2061 } 2062 2063 /* check whether mechanism is available */ 2064 if (iteminlist(p, mechlist, " ") == NULL) 2065 { 2066 message("504 5.3.3 AUTH mechanism %.32s not available", 2067 p); 2068 break; 2069 } 2070 2071 /* 2072 ** RFC 2554 4. 2073 ** Unlike a zero-length client answer to a 2074 ** 334 reply, a zero- length initial response 2075 ** is sent as a single equals sign ("="). 2076 */ 2077 2078 if (ismore && *q == '=' && *(q + 1) == '\0') 2079 { 2080 /* will be free()d, don't use in=""; */ 2081 in = xalloc(1); 2082 *in = '\0'; 2083 inlen = 0; 2084 } 2085 else if (ismore) 2086 { 2087 /* could this be shorter? XXX */ 2088 # if SASL >= 20000 2089 in = xalloc(strlen(q) + 1); 2090 result = sasl_decode64(q, strlen(q), in, 2091 strlen(q), &inlen); 2092 # else /* SASL >= 20000 */ 2093 in = sm_rpool_malloc(e->e_rpool, strlen(q)); 2094 result = sasl_decode64(q, strlen(q), in, 2095 &inlen); 2096 # endif /* SASL >= 20000 */ 2097 2098 if (result != SASL_OK) 2099 { 2100 message("501 5.5.4 cannot BASE64 decode '%s'", 2101 q); 2102 if (LogLevel > 5) 2103 sm_syslog(LOG_WARNING, e->e_id, 2104 "AUTH decode64 error [%d for \"%s\"], relay=%.100s", 2105 result, q, 2106 CurSmtpClient); 2107 /* start over? */ 2108 authenticating = SASL_NOT_AUTH; 2109 # if SASL >= 20000 2110 sm_free(in); 2111 # endif 2112 in = NULL; 2113 inlen = 0; 2114 break; 2115 } 2116 SET_AUTH_USER_TMP(in, inlen); 2117 } 2118 else 2119 { 2120 in = NULL; 2121 inlen = 0; 2122 } 2123 2124 /* see if that auth type exists */ 2125 # if SASL >= 20000 2126 result = sasl_server_start(conn, p, in, inlen, 2127 &out, &outlen); 2128 SM_FREE(in); 2129 # else /* SASL >= 20000 */ 2130 result = sasl_server_start(conn, p, in, inlen, 2131 &out, &outlen, &errstr); 2132 # endif /* SASL >= 20000 */ 2133 2134 if (p != NULL) 2135 auth_type = newstr(p); 2136 if (result != SASL_OK && result != SASL_CONTINUE) 2137 { 2138 LOGAUTHFAIL; 2139 break; 2140 } 2141 2142 if (result == SASL_OK) 2143 { 2144 /* ugly, but same code */ 2145 goto authenticated; 2146 /* authenticated by the initial response */ 2147 } 2148 2149 SET_AUTH_USER; 2150 2151 /* len is at least 2 */ 2152 len = ENC64LEN(outlen); 2153 out2 = xalloc(len); 2154 result = sasl_encode64(out, outlen, out2, len, 2155 &out2len); 2156 2157 if (result != SASL_OK) 2158 { 2159 message("454 4.5.4 Temporary authentication failure"); 2160 if (LogLevel > 5) 2161 sm_syslog(LOG_WARNING, e->e_id, 2162 "AUTH encode64 error [%d for \"%s\"]", 2163 result, out); 2164 2165 /* start over? */ 2166 authenticating = SASL_NOT_AUTH; 2167 RESET_SASLCONN; 2168 } 2169 else 2170 { 2171 message("334 %s", out2); 2172 authenticating = SASL_PROC_AUTH; 2173 } 2174 # if SASL >= 20000 2175 sm_free(out2); 2176 # endif 2177 break; 2178 #endif /* SASL */ 2179 2180 #if STARTTLS 2181 case CMDSTLS: /* starttls */ 2182 DELAY_CONN("STARTTLS"); 2183 if (*p != '\0') 2184 { 2185 message("501 5.5.2 Syntax error (no parameters allowed)"); 2186 break; 2187 } 2188 if (!bitset(SRV_OFFER_TLS, features)) 2189 { 2190 message("503 5.5.0 TLS not available"); 2191 break; 2192 } 2193 starttls: 2194 if (!tls_ok_srv) 2195 { 2196 message("454 4.3.3 TLS not available after start"); 2197 break; 2198 } 2199 if (smtp.sm_gotmail) 2200 { 2201 message("503 5.5.0 TLS not permitted during a mail transaction"); 2202 break; 2203 } 2204 if (tempfail) 2205 { 2206 if (LogLevel > 9) 2207 sm_syslog(LOG_INFO, e->e_id, 2208 "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)", 2209 p, CurSmtpClient); 2210 usrerr("454 4.7.0 Please try again later"); 2211 break; 2212 } 2213 if (!TLS_set_engine(SSLEngine, false)) 2214 { 2215 sm_syslog(LOG_ERR, NOQID, 2216 "STARTTLS=server, engine=%s, TLS_set_engine=failed", 2217 SSLEngine); 2218 tls_ok_srv = false; 2219 message("454 4.3.3 TLS not available right now"); 2220 break; 2221 } 2222 # if TLS_NO_RSA 2223 /* 2224 ** XXX do we need a temp key ? 2225 */ 2226 # endif 2227 2228 # if TLS_VRFY_PER_CTX 2229 /* 2230 ** Note: this sets the verification globally 2231 ** (per SSL_CTX) 2232 ** it's ok since it applies only to one transaction 2233 */ 2234 2235 TLS_VERIFY_CLIENT(); 2236 # endif /* TLS_VRFY_PER_CTX */ 2237 2238 #define SMTLSFAILED \ 2239 do { \ 2240 SM_SSL_FREE(srv_ssl); \ 2241 goto tls_done; \ 2242 } while (0) 2243 2244 if (srv_ssl != NULL) 2245 SSL_clear(srv_ssl); 2246 else if ((srv_ssl = SSL_new(srv_ctx)) == NULL) 2247 { 2248 message("454 4.3.3 TLS not available: error generating SSL handle"); 2249 tlslogerr(LOG_WARNING, 8, "server"); 2250 goto tls_done; 2251 } 2252 if (get_tls_se_features(e, srv_ssl, &tlsi_ctx, true) 2253 != EX_OK) 2254 { 2255 /* do not offer too much info to client */ 2256 message("454 4.3.3 TLS curently not available"); 2257 SMTLSFAILED; 2258 } 2259 r = SSL_set_ex_data(srv_ssl, TLSsslidx, &tlsi_ctx); 2260 if (0 == r) 2261 { 2262 if (LogLevel > 5) 2263 { 2264 sm_syslog(LOG_ERR, NOQID, 2265 "STARTTLS=server, error: SSL_set_ex_data failed=%d", 2266 r); 2267 tlslogerr(LOG_WARNING, 9, "server"); 2268 } 2269 SMTLSFAILED; 2270 } 2271 2272 # if !TLS_VRFY_PER_CTX 2273 /* 2274 ** this could be used if it were possible to set 2275 ** verification per SSL (connection) 2276 ** not just per SSL_CTX (global) 2277 */ 2278 2279 TLS_VERIFY_CLIENT(); 2280 # endif /* !TLS_VRFY_PER_CTX */ 2281 2282 rfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL); 2283 wfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL); 2284 2285 if (rfd < 0 || wfd < 0 || 2286 SSL_set_rfd(srv_ssl, rfd) <= 0 || 2287 SSL_set_wfd(srv_ssl, wfd) <= 0) 2288 { 2289 message("454 4.3.3 TLS not available: error set fd"); 2290 SMTLSFAILED; 2291 } 2292 if (!smtps) 2293 message("220 2.0.0 Ready to start TLS"); 2294 # if PIPELINING 2295 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT); 2296 # endif 2297 2298 SSL_set_accept_state(srv_ssl); 2299 2300 tlsstart = curtime(); 2301 2302 ssl_err = SSL_ERROR_WANT_READ; 2303 save_errno = 0; 2304 do 2305 { 2306 tlsret = tls_retry(srv_ssl, rfd, wfd, tlsstart, 2307 TimeOuts.to_starttls, ssl_err, 2308 "server"); 2309 if (tlsret <= 0) 2310 { 2311 if (LogLevel > 5) 2312 { 2313 unsigned long l; 2314 const char *sr; 2315 2316 l = ERR_peek_error(); 2317 sr = ERR_reason_error_string(l); 2318 2319 sm_syslog(LOG_WARNING, NOQID, 2320 "STARTTLS=server, error: accept failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d, relay=%.100s", 2321 r, sr == NULL ? "unknown" 2322 : sr, 2323 ssl_err, save_errno, 2324 tlsret, CurSmtpClient); 2325 tlslogerr(LOG_WARNING, 9, "server"); 2326 } 2327 tls_ok_srv = false; 2328 SM_SSL_FREE(srv_ssl); 2329 2330 /* 2331 ** according to the next draft of 2332 ** RFC 2487 the connection should 2333 ** be dropped 2334 ** 2335 ** arrange to ignore any current 2336 ** send list 2337 */ 2338 2339 e->e_sendqueue = NULL; 2340 goto doquit; 2341 } 2342 2343 r = SSL_accept(srv_ssl); 2344 save_errno = 0; 2345 if (r <= 0) 2346 ssl_err = SSL_get_error(srv_ssl, r); 2347 } while (r <= 0); 2348 2349 /* ignore return code for now, it's in {verify} */ 2350 (void) tls_get_info(srv_ssl, true, 2351 CurSmtpClient, 2352 &BlankEnvelope.e_macro, 2353 bitset(SRV_VRFY_CLT, features)); 2354 2355 /* 2356 ** call Stls_client to find out whether 2357 ** to accept the connection from the client 2358 */ 2359 2360 saveQuickAbort = QuickAbort; 2361 saveSuprErrs = SuprErrs; 2362 SuprErrs = true; 2363 QuickAbort = false; 2364 if (rscheck("tls_client", 2365 macvalue(macid("{verify}"), e), 2366 "STARTTLS", e, 2367 RSF_RMCOMM|RSF_COUNT, 2368 5, NULL, NOQID, NULL, NULL) != EX_OK || 2369 Errors > 0) 2370 { 2371 extern char MsgBuf[]; 2372 2373 if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf)) 2374 nullserver = newstr(MsgBuf); 2375 else 2376 nullserver = "503 5.7.0 Authentication required."; 2377 } 2378 QuickAbort = saveQuickAbort; 2379 SuprErrs = saveSuprErrs; 2380 2381 tls_ok_srv = false; /* don't offer STARTTLS again */ 2382 first = true; 2383 n_helo = 0; 2384 # if SASL 2385 if (sasl_ok) 2386 { 2387 int cipher_bits; 2388 bool verified; 2389 char *s, *v, *c; 2390 2391 s = macvalue(macid("{cipher_bits}"), e); 2392 v = macvalue(macid("{verify}"), e); 2393 c = macvalue(macid("{cert_subject}"), e); 2394 verified = (v != NULL && strcmp(v, "OK") == 0); 2395 if (s != NULL && (cipher_bits = atoi(s)) > 0) 2396 { 2397 # if SASL >= 20000 2398 ext_ssf = cipher_bits; 2399 auth_id = verified ? c : NULL; 2400 sasl_ok = ((sasl_setprop(conn, 2401 SASL_SSF_EXTERNAL, 2402 &ext_ssf) == SASL_OK) && 2403 (sasl_setprop(conn, 2404 SASL_AUTH_EXTERNAL, 2405 auth_id) == SASL_OK)); 2406 # else /* SASL >= 20000 */ 2407 ext_ssf.ssf = cipher_bits; 2408 ext_ssf.auth_id = verified ? c : NULL; 2409 sasl_ok = sasl_setprop(conn, 2410 SASL_SSF_EXTERNAL, 2411 &ext_ssf) == SASL_OK; 2412 # endif /* SASL >= 20000 */ 2413 mechlist = NULL; 2414 if (sasl_ok) 2415 n_mechs = saslmechs(conn, 2416 &mechlist); 2417 } 2418 } 2419 # endif /* SASL */ 2420 2421 /* switch to secure connection */ 2422 if (sfdctls(&InChannel, &OutChannel, srv_ssl) == 0) 2423 { 2424 tls_active = true; 2425 # if PIPELINING 2426 (void) sm_io_autoflush(InChannel, OutChannel); 2427 # endif 2428 } 2429 else 2430 { 2431 /* 2432 ** XXX this is an internal error 2433 ** how to deal with it? 2434 ** we can't generate an error message 2435 ** since the other side switched to an 2436 ** encrypted layer, but we could not... 2437 ** just "hang up"? 2438 */ 2439 2440 nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer"; 2441 syserr("STARTTLS: can't switch to encrypted layer"); 2442 } 2443 tls_done: 2444 if (smtps) 2445 { 2446 if (tls_active) 2447 goto greeting; 2448 else 2449 goto doquit; 2450 } 2451 break; 2452 #endif /* STARTTLS */ 2453 2454 case CMDHELO: /* hello -- introduce yourself */ 2455 case CMDEHLO: /* extended hello */ 2456 DELAY_CONN("EHLO"); 2457 if (c->cmd_code == CMDEHLO) 2458 { 2459 protocol = GET_PROTOCOL(); 2460 SmtpPhase = "server EHLO"; 2461 } 2462 else 2463 { 2464 protocol = "SMTP"; 2465 SmtpPhase = "server HELO"; 2466 } 2467 2468 /* avoid denial-of-service */ 2469 STOP_IF_ATTACK(checksmtpattack(&n_helo, MAXHELOCOMMANDS, 2470 true, "HELO/EHLO", e)); 2471 2472 #if 0 2473 /* RFC2821 4.1.4 allows duplicate HELO/EHLO */ 2474 /* check for duplicate HELO/EHLO per RFC 1651 4.2 */ 2475 if (gothello) 2476 { 2477 usrerr("503 %s Duplicate HELO/EHLO", 2478 MyHostName); 2479 break; 2480 } 2481 #endif /* 0 */ 2482 2483 /* check for valid domain name (re 1123 5.2.5) */ 2484 if (*p == '\0' && !AllowBogusHELO) 2485 { 2486 usrerr("501 %s requires domain address", 2487 cmdbuf); 2488 break; 2489 } 2490 2491 /* check for long domain name (hides Received: info) */ 2492 if (strlen(p) > MAXNAME) /* EAI:ok:EHLO name must be ASCII */ 2493 { 2494 usrerr("501 Invalid domain name"); 2495 if (LogLevel > 9) 2496 sm_syslog(LOG_INFO, CurEnv->e_id, 2497 "invalid domain name (too long) from %s", 2498 CurSmtpClient); 2499 break; 2500 } 2501 2502 ok = true; 2503 for (q = p; *q != '\0'; q++) 2504 { 2505 if (!isascii(*q)) 2506 break; 2507 if (isalnum(*q)) 2508 continue; 2509 if (isspace(*q)) 2510 { 2511 *q = '\0'; 2512 2513 /* only complain if strict check */ 2514 ok = AllowBogusHELO; 2515 2516 /* allow trailing whitespace */ 2517 while (!ok && *++q != '\0' && 2518 isspace(*q)) 2519 ; 2520 if (*q == '\0') 2521 ok = true; 2522 break; 2523 } 2524 if (strchr("[].-_#:", *q) == NULL) 2525 break; 2526 } 2527 2528 if (*q == '\0' && ok) 2529 { 2530 q = "pleased to meet you"; 2531 sendinghost = sm_strdup_x(p); 2532 } 2533 else if (!AllowBogusHELO) 2534 { 2535 usrerr("501 Invalid domain name"); 2536 if (LogLevel > 9) 2537 sm_syslog(LOG_INFO, CurEnv->e_id, 2538 "invalid domain name (%s) from %.100s", 2539 p, CurSmtpClient); 2540 break; 2541 } 2542 else 2543 { 2544 q = "accepting invalid domain name"; 2545 } 2546 2547 if (gothello || smtp.sm_gotmail) 2548 CLEAR_STATE(cmdbuf); 2549 2550 #if MILTER 2551 if (smtp.sm_milterlist && smtp.sm_milterize && 2552 !bitset(EF_DISCARD, e->e_flags)) 2553 { 2554 char state; 2555 char *response; 2556 2557 response = milter_helo(p, e, &state); 2558 switch (state) 2559 { 2560 case SMFIR_REJECT: 2561 if (MilterLogLevel > 3) 2562 sm_syslog(LOG_INFO, e->e_id, 2563 "Milter: helo=%s, reject=Command rejected", 2564 p); 2565 nullserver = "Command rejected"; 2566 smtp.sm_milterize = false; 2567 break; 2568 2569 case SMFIR_TEMPFAIL: 2570 if (MilterLogLevel > 3) 2571 sm_syslog(LOG_INFO, e->e_id, 2572 "Milter: helo=%s, reject=%s", 2573 p, MSG_TEMPFAIL); 2574 tempfail = true; 2575 smtp.sm_milterize = false; 2576 break; 2577 2578 case SMFIR_REPLYCODE: 2579 if (MilterLogLevel > 3) 2580 sm_syslog(LOG_INFO, e->e_id, 2581 "Milter: helo=%s, reject=%s", 2582 p, response); 2583 if (strncmp(response, "421 ", 4) != 0 2584 && strncmp(response, "421-", 4) != 0) 2585 { 2586 nullserver = newstr(response); 2587 smtp.sm_milterize = false; 2588 break; 2589 } 2590 /* FALLTHROUGH */ 2591 2592 case SMFIR_SHUTDOWN: 2593 if (MilterLogLevel > 3 && 2594 response == NULL) 2595 sm_syslog(LOG_INFO, e->e_id, 2596 "Milter: helo=%s, reject=421 4.7.0 %s closing connection", 2597 p, MyHostName); 2598 tempfail = true; 2599 smtp.sm_milterize = false; 2600 if (response != NULL) 2601 { 2602 /* Can't use ("%s", ...) due to usrerr() requirements */ 2603 usrerr(response); 2604 } 2605 else 2606 { 2607 message("421 4.7.0 %s closing connection", 2608 MyHostName); 2609 } 2610 /* arrange to ignore send list */ 2611 e->e_sendqueue = NULL; 2612 lognullconnection = false; 2613 goto doquit; 2614 } 2615 if (response != NULL) 2616 sm_free(response); 2617 2618 /* 2619 ** If quarantining by a connect/ehlo action, 2620 ** save between messages 2621 */ 2622 2623 if (smtp.sm_quarmsg == NULL && 2624 e->e_quarmsg != NULL) 2625 smtp.sm_quarmsg = newstr(e->e_quarmsg); 2626 } 2627 #endif /* MILTER */ 2628 gothello = true; 2629 2630 /* print HELO response message */ 2631 if (c->cmd_code != CMDEHLO) 2632 { 2633 message("250 %s Hello %s, %s", 2634 MyHostName, CurSmtpClient, q); 2635 break; 2636 } 2637 2638 message("250-%s Hello %s, %s", 2639 MyHostName, CurSmtpClient, q); 2640 2641 /* offer ENHSC even for nullserver */ 2642 if (nullserver != NULL) 2643 { 2644 message("250 ENHANCEDSTATUSCODES"); 2645 break; 2646 } 2647 2648 /* 2649 ** print EHLO features list 2650 ** 2651 ** Note: If you change this list, 2652 ** remember to update 'helpfile' 2653 */ 2654 2655 message("250-ENHANCEDSTATUSCODES"); 2656 #if PIPELINING 2657 if (bitset(SRV_OFFER_PIPE, features)) 2658 message("250-PIPELINING"); 2659 #endif 2660 if (bitset(SRV_OFFER_EXPN, features)) 2661 { 2662 message("250-EXPN"); 2663 if (bitset(SRV_OFFER_VERB, features)) 2664 message("250-VERB"); 2665 } 2666 #if MIME8TO7 2667 message("250-8BITMIME"); 2668 #endif 2669 if (MaxMessageSize > 0) 2670 message("250-SIZE %ld", MaxMessageSize); 2671 else 2672 message("250-SIZE"); 2673 #if DSN 2674 if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features)) 2675 message("250-DSN"); 2676 #endif 2677 #if USE_EAI 2678 if (bitset(SRV_OFFER_EAI, features)) 2679 message("250-SMTPUTF8"); 2680 #endif 2681 if (bitset(SRV_OFFER_ETRN, features)) 2682 message("250-ETRN"); 2683 #if SASL 2684 if (sasl_ok && mechlist != NULL && *mechlist != '\0') 2685 message("250-AUTH %s", mechlist); 2686 #endif 2687 #if STARTTLS 2688 if (tls_ok_srv && bitset(SRV_OFFER_TLS, features)) 2689 message("250-STARTTLS"); 2690 #endif 2691 if (DeliverByMin > 0) 2692 message("250-DELIVERBY %ld", 2693 (long) DeliverByMin); 2694 else if (DeliverByMin == 0) 2695 message("250-DELIVERBY"); 2696 2697 /* < 0: no deliver-by */ 2698 2699 message("250 HELP"); 2700 break; 2701 2702 case CMDMAIL: /* mail -- designate sender */ 2703 SmtpPhase = "server MAIL"; 2704 DELAY_CONN("MAIL"); 2705 2706 /* check for validity of this command */ 2707 if (!gothello && bitset(PRIV_NEEDMAILHELO, PrivacyFlags)) 2708 { 2709 usrerr("503 5.0.0 Polite people say HELO first"); 2710 break; 2711 } 2712 if (smtp.sm_gotmail) 2713 { 2714 usrerr("503 5.5.0 Sender already specified"); 2715 break; 2716 } 2717 #if SASL 2718 if (bitset(SRV_REQ_AUTH, features) && 2719 authenticating != SASL_IS_AUTH) 2720 { 2721 usrerr("530 5.7.0 Authentication required"); 2722 break; 2723 } 2724 #endif /* SASL */ 2725 2726 p = skipword(p, "from"); 2727 if (p == NULL) 2728 break; 2729 if (tempfail) 2730 { 2731 if (LogLevel > 9) 2732 sm_syslog(LOG_INFO, e->e_id, 2733 "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)", 2734 p, CurSmtpClient); 2735 /* Can't use ("%s", ...) due to usrerr() requirements */ 2736 usrerr(MSG_TEMPFAIL); 2737 break; 2738 } 2739 2740 /* make sure we know who the sending host is */ 2741 if (sendinghost == NULL) 2742 sendinghost = peerhostname; 2743 2744 2745 #if SM_HEAP_CHECK 2746 if (sm_debug_active(&DebugLeakSmtp, 1)) 2747 { 2748 sm_heap_newgroup(); 2749 sm_dprintf("smtp() heap group #%d\n", 2750 sm_heap_group()); 2751 } 2752 #endif /* SM_HEAP_CHECK */ 2753 2754 if (Errors > 0) 2755 goto undo_no_pm; 2756 if (!gothello) 2757 { 2758 auth_warning(e, "%s didn't use HELO protocol", 2759 CurSmtpClient); 2760 } 2761 #ifdef PICKY_HELO_CHECK 2762 if (sm_strcasecmp(sendinghost, peerhostname) != 0 && 2763 (sm_strcasecmp(peerhostname, "localhost") != 0 || 2764 sm_strcasecmp(sendinghost, MyHostName) != 0)) 2765 { 2766 auth_warning(e, "Host %s claimed to be %s", 2767 CurSmtpClient, sendinghost); 2768 } 2769 #endif /* PICKY_HELO_CHECK */ 2770 2771 if (protocol == NULL) 2772 protocol = "SMTP"; 2773 macdefine(&e->e_macro, A_PERM, 'r', protocol); 2774 macdefine(&e->e_macro, A_PERM, 's', sendinghost); 2775 2776 if (Errors > 0) 2777 goto undo_no_pm; 2778 smtp.sm_nrcpts = 0; 2779 n_badrcpts = 0; 2780 macdefine(&e->e_macro, A_PERM, macid("{ntries}"), "0"); 2781 macdefine(&e->e_macro, A_PERM, macid("{nrcpts}"), "0"); 2782 macdefine(&e->e_macro, A_PERM, macid("{nbadrcpts}"), 2783 "0"); 2784 e->e_flags |= EF_CLRQUEUE; 2785 sm_setproctitle(true, e, "%s %s: %.80s", 2786 qid_printname(e), 2787 CurSmtpClient, inp); 2788 2789 /* do the processing */ 2790 SM_TRY 2791 { 2792 extern char *FullName; 2793 #if _FFR_8BITENVADDR 2794 char *origp; 2795 char iaddr[MAXLINE * 2]; 2796 int len; 2797 #else 2798 # define origp p 2799 #endif 2800 2801 QuickAbort = true; 2802 SM_FREE(FullName); 2803 #if _FFR_8BITENVADDR 2804 len = sizeof(iaddr); 2805 origp = p; 2806 2807 /* HACK!!!! p is more than the address! */ 2808 p = quote_internal_chars(p, iaddr, &len, NULL); 2809 #endif 2810 2811 /* must parse sender first */ 2812 delimptr = NULL; 2813 setsender(p, e, &delimptr, ' ', false); 2814 if (delimptr != NULL && *delimptr != '\0') 2815 { 2816 *delimptr++ = '\0'; 2817 #if _FFR_8BITENVADDR 2818 len = sizeof(iaddr) - (delimptr - iaddr); 2819 (void) dequote_internal_chars(delimptr, delimptr, len); 2820 #endif 2821 } 2822 if (Errors > 0) 2823 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2824 2825 /* Successfully set e_from, allow logging */ 2826 e->e_flags |= EF_LOGSENDER; 2827 2828 /* put resulting triple from parseaddr() into macros */ 2829 if (e->e_from.q_mailer != NULL) 2830 macdefine(&e->e_macro, A_PERM, 2831 macid("{mail_mailer}"), 2832 e->e_from.q_mailer->m_name); 2833 else 2834 macdefine(&e->e_macro, A_PERM, 2835 macid("{mail_mailer}"), NULL); 2836 if (e->e_from.q_host != NULL) 2837 macdefine(&e->e_macro, A_PERM, 2838 macid("{mail_host}"), 2839 e->e_from.q_host); 2840 else 2841 macdefine(&e->e_macro, A_PERM, 2842 macid("{mail_host}"), "localhost"); 2843 if (e->e_from.q_user != NULL) 2844 macdefine(&e->e_macro, A_PERM, 2845 macid("{mail_addr}"), 2846 e->e_from.q_user); 2847 else 2848 macdefine(&e->e_macro, A_PERM, 2849 macid("{mail_addr}"), NULL); 2850 if (Errors > 0) 2851 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2852 2853 /* check for possible spoofing */ 2854 if (RealUid != 0 && OpMode == MD_SMTP && 2855 !wordinclass(RealUserName, 't') && 2856 (!bitnset(M_LOCALMAILER, 2857 e->e_from.q_mailer->m_flags) || 2858 strcmp(e->e_from.q_user, RealUserName) != 0)) 2859 { 2860 auth_warning(e, "%s owned process doing -bs", 2861 RealUserName); 2862 } 2863 2864 /* reset to default value */ 2865 SevenBitInput = SevenBitInput_Saved; 2866 2867 /* now parse ESMTP arguments */ 2868 e->e_msgsize = 0; 2869 addr = p; 2870 parse_esmtp_args(e, NULL, origp, delimptr, "MAIL", args, 2871 mail_esmtp_args); 2872 if (Errors > 0) 2873 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2874 2875 #if USE_EAI 2876 if (e->e_smtputf8) 2877 { 2878 protocol = GET_PROTOCOL(); 2879 macdefine(&e->e_macro, A_PERM, 'r', protocol); 2880 } 2881 2882 /* UTF8 addresses are only legal with SMTPUTF8 */ 2883 /* XXX different error if SMTPUTF8 is not enabled? */ 2884 CHECK_UTF8_ADDR(e->e_from.q_paddr, q); 2885 if (q != NULL) 2886 { 2887 usrerr(q); 2888 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2889 } 2890 #endif 2891 2892 #if SASL 2893 # if _FFR_AUTH_PASSING 2894 /* set the default AUTH= if the sender didn't */ 2895 if (e->e_auth_param == NULL) 2896 { 2897 /* XXX only do this for an MSA? */ 2898 e->e_auth_param = macvalue(macid("{auth_authen}"), 2899 e); 2900 if (e->e_auth_param == NULL) 2901 e->e_auth_param = "<>"; 2902 2903 /* 2904 ** XXX should we invoke Strust_auth now? 2905 ** authorizing as the client that just 2906 ** authenticated, so we'll trust implicitly 2907 */ 2908 } 2909 # endif /* _FFR_AUTH_PASSING */ 2910 #endif /* SASL */ 2911 2912 /* do config file checking of the sender */ 2913 macdefine(&e->e_macro, A_PERM, 2914 macid("{addr_type}"), "e s"); 2915 #if _FFR_MAIL_MACRO 2916 /* make the "real" sender address available */ 2917 macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"), 2918 e->e_from.q_paddr); 2919 #endif 2920 if (rscheck("check_mail", addr, 2921 NULL, e, RSF_RMCOMM|RSF_COUNT, 3, 2922 NULL, e->e_id, NULL, NULL) != EX_OK || 2923 Errors > 0) 2924 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2925 macdefine(&e->e_macro, A_PERM, 2926 macid("{addr_type}"), NULL); 2927 2928 if (MaxMessageSize > 0 && 2929 (e->e_msgsize > MaxMessageSize || 2930 e->e_msgsize < 0)) 2931 { 2932 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)", 2933 MaxMessageSize); 2934 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2935 } 2936 2937 /* 2938 ** XXX always check whether there is at least one fs 2939 ** with enough space? 2940 ** However, this may not help much: the queue group 2941 ** selection may later on select a FS that hasn't 2942 ** enough space. 2943 */ 2944 2945 if ((NumFileSys == 1 || NumQueue == 1) && 2946 !enoughdiskspace(e->e_msgsize, e) 2947 #if _FFR_ANY_FREE_FS 2948 && !filesys_free(e->e_msgsize) 2949 #endif 2950 ) 2951 { 2952 /* 2953 ** We perform this test again when the 2954 ** queue directory is selected, in collect. 2955 */ 2956 2957 usrerr("452 4.4.5 Insufficient disk space; try again later"); 2958 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2959 } 2960 if (Errors > 0) 2961 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2962 2963 LogUsrErrs = true; 2964 #if MILTER 2965 if (smtp.sm_milterlist && smtp.sm_milterize && 2966 !bitset(EF_DISCARD, e->e_flags)) 2967 { 2968 char state; 2969 char *response; 2970 2971 response = milter_envfrom(args, e, &state); 2972 MILTER_REPLY("from"); 2973 } 2974 #endif /* MILTER */ 2975 if (Errors > 0) 2976 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 2977 2978 message("250 2.1.0 Sender ok"); 2979 smtp.sm_gotmail = true; 2980 } 2981 SM_EXCEPT(exc, "[!F]*") 2982 { 2983 /* 2984 ** An error occurred while processing a MAIL command. 2985 ** Jump to the common error handling code. 2986 */ 2987 2988 sm_exc_free(exc); 2989 goto undo_no_pm; 2990 } 2991 SM_END_TRY 2992 break; 2993 2994 undo_no_pm: 2995 e->e_flags &= ~EF_PM_NOTIFY; 2996 undo: 2997 break; 2998 2999 case CMDRCPT: /* rcpt -- designate recipient */ 3000 DELAY_CONN("RCPT"); 3001 macdefine(&e->e_macro, A_PERM, 3002 macid("{rcpt_mailer}"), NULL); 3003 macdefine(&e->e_macro, A_PERM, 3004 macid("{rcpt_host}"), NULL); 3005 macdefine(&e->e_macro, A_PERM, 3006 macid("{rcpt_addr}"), NULL); 3007 #if MILTER 3008 (void) memset(&addr_st, '\0', sizeof(addr_st)); 3009 a = NULL; 3010 milter_rcpt_added = false; 3011 smtp.sm_e_nrcpts_orig = e->e_nrcpts; 3012 #endif 3013 #if _FFR_BADRCPT_SHUTDOWN 3014 /* 3015 ** hack to deal with hack, see below: 3016 ** n_badrcpts is increased if limit is reached. 3017 */ 3018 3019 n_badrcpts_adj = (BadRcptThrottle > 0 && 3020 n_badrcpts > BadRcptThrottle && 3021 LogLevel > 5) 3022 ? n_badrcpts - 1 : n_badrcpts; 3023 if (BadRcptShutdown > 0 && 3024 n_badrcpts_adj >= BadRcptShutdown && 3025 (BadRcptShutdownGood == 0 || 3026 smtp.sm_nrcpts == 0 || 3027 (n_badrcpts_adj * 100 / 3028 (smtp.sm_nrcpts + n_badrcpts) >= 3029 BadRcptShutdownGood))) 3030 { 3031 if (LogLevel > 5) 3032 sm_syslog(LOG_INFO, e->e_id, 3033 "%s: Possible SMTP RCPT flood, shutting down connection.", 3034 CurSmtpClient); 3035 message("421 4.7.0 %s Too many bad recipients; closing connection", 3036 MyHostName); 3037 3038 /* arrange to ignore any current send list */ 3039 e->e_sendqueue = NULL; 3040 goto doquit; 3041 } 3042 #endif /* _FFR_BADRCPT_SHUTDOWN */ 3043 if (BadRcptThrottle > 0 && 3044 n_badrcpts >= BadRcptThrottle) 3045 { 3046 if (LogLevel > 5 && 3047 n_badrcpts == BadRcptThrottle) 3048 { 3049 sm_syslog(LOG_INFO, e->e_id, 3050 "%s: Possible SMTP RCPT flood, throttling.", 3051 CurSmtpClient); 3052 3053 /* To avoid duplicated message */ 3054 n_badrcpts++; 3055 } 3056 NBADRCPTS; 3057 3058 /* 3059 ** Don't use exponential backoff for now. 3060 ** Some systems will open more connections 3061 ** and actually overload the receiver even 3062 ** more. 3063 */ 3064 3065 (void) sleep(BadRcptThrottleDelay); 3066 } 3067 if (!smtp.sm_gotmail) 3068 { 3069 usrerr("503 5.0.0 Need MAIL before RCPT"); 3070 break; 3071 } 3072 SmtpPhase = "server RCPT"; 3073 SM_TRY 3074 { 3075 #if _FFR_8BITENVADDR 3076 char iaddr[MAXLINE * 2]; 3077 int len; 3078 char *origp; 3079 #endif 3080 3081 QuickAbort = true; 3082 LogUsrErrs = true; 3083 3084 /* limit flooding of our machine */ 3085 if (MaxRcptPerMsg > 0 && 3086 smtp.sm_nrcpts >= MaxRcptPerMsg) 3087 { 3088 /* sleep(1); / * slow down? */ 3089 usrerr("452 4.5.3 Too many recipients"); 3090 goto rcpt_done; 3091 } 3092 3093 if (!SM_IS_INTERACTIVE(e->e_sendmode) 3094 #if _FFR_DM_ONE 3095 && (NotFirstDelivery || SM_DM_ONE != e->e_sendmode) 3096 #endif 3097 ) 3098 e->e_flags |= EF_VRFYONLY; 3099 3100 #if MILTER 3101 /* 3102 ** Do not expand recipients at RCPT time (in the call 3103 ** to recipient()) if a milter can delete or reject 3104 ** a RCPT. If they are expanded, it is impossible 3105 ** for removefromlist() to figure out the expanded 3106 ** members of the original recipient and mark them 3107 ** as QS_DONTSEND. 3108 */ 3109 3110 if (smtp.sm_milterlist && smtp.sm_milterize && 3111 !bitset(EF_DISCARD, e->e_flags) && 3112 (smtp.sm_milters.mis_flags & 3113 (MIS_FL_DEL_RCPT|MIS_FL_REJ_RCPT)) != 0) 3114 e->e_flags |= EF_VRFYONLY; 3115 milter_cmd_done = false; 3116 milter_cmd_safe = false; 3117 #endif /* MILTER */ 3118 3119 p = skipword(p, "to"); 3120 if (p == NULL) 3121 goto rcpt_done; 3122 macdefine(&e->e_macro, A_PERM, 3123 macid("{addr_type}"), "e r"); 3124 #if _FFR_8BITENVADDR 3125 len = sizeof(iaddr); 3126 origp = p; 3127 3128 /* HACK!!!! p is more than the address! */ 3129 p = quote_internal_chars(p, iaddr, &len, NULL); 3130 #endif 3131 a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr, 3132 e, true); 3133 macdefine(&e->e_macro, A_PERM, 3134 macid("{addr_type}"), NULL); 3135 if (Errors > 0) 3136 goto rcpt_done; 3137 if (a == NULL) 3138 { 3139 usrerr("501 5.0.0 Missing recipient"); 3140 goto rcpt_done; 3141 } 3142 #if USE_EAI 3143 CHECK_UTF8_ADDR(a->q_paddr, q); 3144 if (q != NULL) 3145 { 3146 usrerr(q); 3147 goto rcpt_done; 3148 } 3149 #endif 3150 3151 if (delimptr != NULL && *delimptr != '\0') 3152 { 3153 *delimptr++ = '\0'; 3154 #if _FFR_8BITENVADDR 3155 len = sizeof(iaddr) - (delimptr - iaddr); 3156 (void) dequote_internal_chars(delimptr, delimptr, len); 3157 #endif 3158 } 3159 3160 /* put resulting triple from parseaddr() into macros */ 3161 if (a->q_mailer != NULL) 3162 macdefine(&e->e_macro, A_PERM, 3163 macid("{rcpt_mailer}"), 3164 a->q_mailer->m_name); 3165 else 3166 macdefine(&e->e_macro, A_PERM, 3167 macid("{rcpt_mailer}"), NULL); 3168 if (a->q_host != NULL) 3169 macdefine(&e->e_macro, A_PERM, 3170 macid("{rcpt_host}"), a->q_host); 3171 else 3172 macdefine(&e->e_macro, A_PERM, 3173 macid("{rcpt_host}"), "localhost"); 3174 if (a->q_user != NULL) 3175 macdefine(&e->e_macro, A_PERM, 3176 macid("{rcpt_addr}"), a->q_user); 3177 else 3178 macdefine(&e->e_macro, A_PERM, 3179 macid("{rcpt_addr}"), NULL); 3180 if (Errors > 0) 3181 goto rcpt_done; 3182 3183 /* now parse ESMTP arguments */ 3184 addr = sm_rpool_strdup_x(e->e_rpool, p); 3185 parse_esmtp_args(e, a, origp, delimptr, "RCPT", args, 3186 rcpt_esmtp_args); 3187 if (Errors > 0) 3188 goto rcpt_done; 3189 3190 #if MILTER 3191 /* 3192 ** rscheck() can trigger an "exception" 3193 ** in which case the execution continues at 3194 ** SM_EXCEPT(exc, "[!F]*") 3195 ** This means milter_cmd_safe is not set 3196 ** and hence milter is not invoked. 3197 ** Would it be "safe" to change that, i.e., use 3198 ** milter_cmd_safe = true; 3199 ** here so a milter is informed (if requested) 3200 ** about RCPTs that are rejected by check_rcpt? 3201 */ 3202 # if _FFR_MILTER_CHECK_REJECTIONS_TOO 3203 milter_cmd_safe = true; 3204 # endif 3205 #endif 3206 3207 /* do config file checking of the recipient */ 3208 macdefine(&e->e_macro, A_PERM, 3209 macid("{addr_type}"), "e r"); 3210 if (rscheck("check_rcpt", addr, 3211 NULL, e, RSF_RMCOMM|RSF_COUNT, 3, 3212 NULL, e->e_id, p_addr_st, NULL) != EX_OK || 3213 Errors > 0) 3214 goto rcpt_done; 3215 macdefine(&e->e_macro, A_PERM, 3216 macid("{addr_type}"), NULL); 3217 3218 /* If discarding, don't bother to verify user */ 3219 if (bitset(EF_DISCARD, e->e_flags)) 3220 a->q_state = QS_VERIFIED; 3221 #if MILTER 3222 milter_cmd_safe = true; 3223 #endif 3224 3225 addbcc(a, e); 3226 rcptmods(a, e); 3227 3228 /* save in recipient list after ESMTP mods */ 3229 a = recipient(a, &e->e_sendqueue, 0, e); 3230 /* may trigger exception... */ 3231 3232 #if MILTER 3233 milter_rcpt_added = true; 3234 #endif 3235 3236 if(!(Errors > 0) && QS_IS_BADADDR(a->q_state)) 3237 { 3238 /* punt -- should keep message in ADDRESS.... */ 3239 usrerr("550 5.1.1 Addressee unknown"); 3240 } 3241 3242 #if MILTER 3243 rcpt_done: 3244 if (smtp.sm_milterlist && smtp.sm_milterize && 3245 !bitset(EF_DISCARD, e->e_flags)) 3246 { 3247 char state; 3248 char *response; 3249 3250 /* how to get the error codes? */ 3251 if (Errors > 0) 3252 { 3253 macdefine(&e->e_macro, A_PERM, 3254 macid("{rcpt_mailer}"), 3255 "error"); 3256 if (a != NULL && 3257 a->q_status != NULL && 3258 a->q_rstatus != NULL) 3259 { 3260 macdefine(&e->e_macro, A_PERM, 3261 macid("{rcpt_host}"), 3262 a->q_status); 3263 macdefine(&e->e_macro, A_PERM, 3264 macid("{rcpt_addr}"), 3265 a->q_rstatus); 3266 } 3267 else 3268 { 3269 if (addr_st.q_host != NULL) 3270 macdefine(&e->e_macro, 3271 A_PERM, 3272 macid("{rcpt_host}"), 3273 addr_st.q_host); 3274 if (addr_st.q_user != NULL) 3275 macdefine(&e->e_macro, 3276 A_PERM, 3277 macid("{rcpt_addr}"), 3278 addr_st.q_user); 3279 } 3280 } 3281 3282 response = milter_envrcpt(args, e, &state, 3283 Errors > 0); 3284 milter_cmd_done = true; 3285 MILTER_REPLY("to"); 3286 } 3287 #endif /* MILTER */ 3288 3289 /* no errors during parsing, but might be a duplicate */ 3290 e->e_to = a->q_paddr; 3291 if (!(Errors > 0) && !QS_IS_BADADDR(a->q_state)) 3292 { 3293 if (smtp.sm_nrcpts == 0) 3294 initsys(e); 3295 message("250 2.1.5 Recipient ok%s", 3296 QS_IS_QUEUEUP(a->q_state) ? 3297 " (will queue)" : ""); 3298 smtp.sm_nrcpts++; 3299 } 3300 3301 /* Is this needed? */ 3302 #if !MILTER 3303 rcpt_done: 3304 #endif 3305 3306 macdefine(&e->e_macro, A_PERM, 3307 macid("{rcpt_mailer}"), NULL); 3308 macdefine(&e->e_macro, A_PERM, 3309 macid("{rcpt_host}"), NULL); 3310 macdefine(&e->e_macro, A_PERM, 3311 macid("{rcpt_addr}"), NULL); 3312 macdefine(&e->e_macro, A_PERM, 3313 macid("{dsn_notify}"), NULL); 3314 3315 if (Errors > 0) 3316 { 3317 ++n_badrcpts; 3318 NBADRCPTS; 3319 } 3320 } 3321 SM_EXCEPT(exc, "[!F]*") 3322 { 3323 /* An exception occurred while processing RCPT */ 3324 e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY); 3325 ++n_badrcpts; 3326 NBADRCPTS; 3327 #if MILTER 3328 if (smtp.sm_milterlist && smtp.sm_milterize && 3329 !bitset(EF_DISCARD, e->e_flags) && 3330 !milter_cmd_done && milter_cmd_safe) 3331 { 3332 char state; 3333 char *response; 3334 3335 macdefine(&e->e_macro, A_PERM, 3336 macid("{rcpt_mailer}"), "error"); 3337 3338 /* how to get the error codes? */ 3339 if (addr_st.q_host != NULL) 3340 macdefine(&e->e_macro, A_PERM, 3341 macid("{rcpt_host}"), 3342 addr_st.q_host); 3343 else if (a != NULL && a->q_status != NULL) 3344 macdefine(&e->e_macro, A_PERM, 3345 macid("{rcpt_host}"), 3346 a->q_status); 3347 3348 if (addr_st.q_user != NULL) 3349 macdefine(&e->e_macro, A_PERM, 3350 macid("{rcpt_addr}"), 3351 addr_st.q_user); 3352 else if (a != NULL && a->q_rstatus != NULL) 3353 macdefine(&e->e_macro, A_PERM, 3354 macid("{rcpt_addr}"), 3355 a->q_rstatus); 3356 3357 response = milter_envrcpt(args, e, &state, 3358 true); 3359 milter_cmd_done = true; 3360 MILTER_REPLY("to"); 3361 macdefine(&e->e_macro, A_PERM, 3362 macid("{rcpt_mailer}"), NULL); 3363 macdefine(&e->e_macro, A_PERM, 3364 macid("{rcpt_host}"), NULL); 3365 macdefine(&e->e_macro, A_PERM, 3366 macid("{rcpt_addr}"), NULL); 3367 } 3368 if (smtp.sm_milterlist && smtp.sm_milterize && 3369 milter_rcpt_added && milter_cmd_done && 3370 milter_cmd_fail) 3371 { 3372 (void) removefromlist(addr, &e->e_sendqueue, e); 3373 milter_cmd_fail = false; 3374 if (smtp.sm_e_nrcpts_orig < e->e_nrcpts) 3375 e->e_nrcpts = smtp.sm_e_nrcpts_orig; 3376 } 3377 #endif /* MILTER */ 3378 } 3379 SM_END_TRY 3380 break; 3381 3382 case CMDDATA: /* data -- text of mail */ 3383 DELAY_CONN("DATA"); 3384 if (!smtp_data(&smtp, e)) 3385 goto doquit; 3386 break; 3387 3388 case CMDRSET: /* rset -- reset state */ 3389 if (tTd(94, 100)) 3390 message("451 4.0.0 Test failure"); 3391 else 3392 message("250 2.0.0 Reset state"); 3393 CLEAR_STATE(cmdbuf); 3394 break; 3395 3396 case CMDVRFY: /* vrfy -- verify address */ 3397 case CMDEXPN: /* expn -- expand address */ 3398 vrfy = c->cmd_code == CMDVRFY; 3399 DELAY_CONN(vrfy ? "VRFY" : "EXPN"); 3400 if (tempfail) 3401 { 3402 if (LogLevel > 9) 3403 sm_syslog(LOG_INFO, e->e_id, 3404 "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)", 3405 vrfy ? "VRFY" : "EXPN", 3406 p, CurSmtpClient); 3407 3408 /* RFC 821 doesn't allow 4xy reply code */ 3409 usrerr("550 5.7.1 Please try again later"); 3410 break; 3411 } 3412 wt = checksmtpattack(&n_verifies, MAXVRFYCOMMANDS, 3413 false, vrfy ? "VRFY" : "EXPN", e); 3414 STOP_IF_ATTACK(wt); 3415 previous = curtime(); 3416 if ((vrfy && bitset(PRIV_NOVRFY, PrivacyFlags)) || 3417 (!vrfy && !bitset(SRV_OFFER_EXPN, features))) 3418 { 3419 if (vrfy) 3420 message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)"); 3421 else 3422 message("502 5.7.0 Sorry, we do not allow this operation"); 3423 if (LogLevel > 5) 3424 sm_syslog(LOG_INFO, e->e_id, 3425 "%s: %s [rejected]", 3426 CurSmtpClient, 3427 shortenstring(inp, MAXSHORTSTR)); 3428 break; 3429 } 3430 else if (!gothello && 3431 bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO, 3432 PrivacyFlags)) 3433 { 3434 usrerr("503 5.0.0 I demand that you introduce yourself first"); 3435 break; 3436 } 3437 if (Errors > 0) 3438 break; 3439 if (LogLevel > 5) 3440 sm_syslog(LOG_INFO, e->e_id, "%s: %s", 3441 CurSmtpClient, 3442 shortenstring(inp, MAXSHORTSTR)); 3443 SM_TRY 3444 { 3445 QuickAbort = true; 3446 vrfyqueue = NULL; 3447 if (vrfy) 3448 e->e_flags |= EF_VRFYONLY; 3449 while (*p != '\0' && SM_ISSPACE(*p)) 3450 p++; 3451 if (*p == '\0') 3452 { 3453 usrerr("501 5.5.2 Argument required"); 3454 } 3455 else 3456 { 3457 /* do config file checking of the address */ 3458 if (rscheck(vrfy ? "check_vrfy" : "check_expn", 3459 p, NULL, e, RSF_RMCOMM, 3, NULL, 3460 NOQID, NULL, NULL) != EX_OK || 3461 Errors > 0) 3462 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 3463 (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e); 3464 } 3465 if (wt > 0) 3466 { 3467 time_t t; 3468 3469 t = wt - (curtime() - previous); 3470 if (t > 0) 3471 (void) sleep(t); 3472 } 3473 if (Errors > 0) 3474 sm_exc_raisenew_x(&EtypeQuickAbort, 1); 3475 if (vrfyqueue == NULL) 3476 { 3477 usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN"); 3478 } 3479 while (vrfyqueue != NULL) 3480 { 3481 if (!QS_IS_UNDELIVERED(vrfyqueue->q_state)) 3482 { 3483 vrfyqueue = vrfyqueue->q_next; 3484 continue; 3485 } 3486 3487 /* see if there is more in the vrfy list */ 3488 a = vrfyqueue; 3489 while ((a = a->q_next) != NULL && 3490 (!QS_IS_UNDELIVERED(a->q_state))) 3491 continue; 3492 printvrfyaddr(vrfyqueue, a == NULL, vrfy); 3493 vrfyqueue = a; 3494 } 3495 } 3496 SM_EXCEPT(exc, "[!F]*") 3497 { 3498 /* 3499 ** An exception occurred while processing VRFY/EXPN 3500 */ 3501 3502 sm_exc_free(exc); 3503 goto undo; 3504 } 3505 SM_END_TRY 3506 break; 3507 3508 case CMDETRN: /* etrn -- force queue flush */ 3509 DELAY_CONN("ETRN"); 3510 3511 /* Don't leak queue information via debug flags */ 3512 if (!bitset(SRV_OFFER_ETRN, features) || UseMSP || 3513 (RealUid != 0 && RealUid != TrustedUid && 3514 OpMode == MD_SMTP)) 3515 { 3516 /* different message for MSA ? */ 3517 message("502 5.7.0 Sorry, we do not allow this operation"); 3518 if (LogLevel > 5) 3519 sm_syslog(LOG_INFO, e->e_id, 3520 "%s: %s [rejected]", 3521 CurSmtpClient, 3522 shortenstring(inp, MAXSHORTSTR)); 3523 break; 3524 } 3525 if (tempfail) 3526 { 3527 if (LogLevel > 9) 3528 sm_syslog(LOG_INFO, e->e_id, 3529 "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)", 3530 p, CurSmtpClient); 3531 /* Can't use ("%s", ...) due to usrerr() requirements */ 3532 usrerr(MSG_TEMPFAIL); 3533 break; 3534 } 3535 3536 if (strlen(p) <= 0) 3537 { 3538 usrerr("500 5.5.2 Parameter required"); 3539 break; 3540 } 3541 3542 /* crude way to avoid denial-of-service attacks */ 3543 STOP_IF_ATTACK(checksmtpattack(&n_etrn, MAXETRNCOMMANDS, 3544 true, "ETRN", e)); 3545 3546 /* 3547 ** Do config file checking of the parameter. 3548 ** Even though we have srv_features now, we still 3549 ** need this ruleset because the former is called 3550 ** when the connection has been established, while 3551 ** this ruleset is called when the command is 3552 ** actually issued and therefore has all information 3553 ** available to make a decision. 3554 */ 3555 3556 if (rscheck("check_etrn", p, NULL, e, RSF_RMCOMM, 3, 3557 NULL, NOQID, NULL, NULL) != EX_OK || 3558 Errors > 0) 3559 break; 3560 3561 if (LogLevel > 5) 3562 sm_syslog(LOG_INFO, e->e_id, 3563 "%s: ETRN %s", CurSmtpClient, 3564 shortenstring(p, MAXSHORTSTR)); 3565 3566 id = p; 3567 if (*id == '#') 3568 { 3569 int i, qgrp; 3570 3571 id++; 3572 qgrp = name2qid(id); 3573 if (!ISVALIDQGRP(qgrp)) 3574 { 3575 usrerr("459 4.5.4 Queue %s unknown", 3576 id); 3577 break; 3578 } 3579 for (i = 0; i < NumQueue && Queue[i] != NULL; 3580 i++) 3581 Queue[i]->qg_nextrun = (time_t) -1; 3582 Queue[qgrp]->qg_nextrun = 0; 3583 ok = run_work_group(Queue[qgrp]->qg_wgrp, 3584 RWG_FORK|RWG_FORCE); 3585 if (ok && Errors == 0) 3586 message("250 2.0.0 Queuing for queue group %s started", id); 3587 break; 3588 } 3589 3590 if (*id == '@') 3591 id++; 3592 else 3593 *--id = '@'; 3594 3595 new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR)); 3596 if (new == NULL) 3597 { 3598 syserr("500 5.5.0 ETRN out of memory"); 3599 break; 3600 } 3601 new->queue_match = id; 3602 new->queue_negate = false; 3603 new->queue_next = NULL; 3604 QueueLimitRecipient = new; 3605 ok = runqueue(true, false, false, true); 3606 sm_free(QueueLimitRecipient); /* XXX */ 3607 QueueLimitRecipient = NULL; 3608 if (ok && Errors == 0) 3609 message("250 2.0.0 Queuing for node %s started", p); 3610 break; 3611 3612 case CMDHELP: /* help -- give user info */ 3613 DELAY_CONN("HELP"); 3614 help(p, e); 3615 break; 3616 3617 #define CHECK_OTHER(type) do \ 3618 { \ 3619 bool saveQuickAbort = QuickAbort; \ 3620 extern char MsgBuf[]; \ 3621 int rsc; \ 3622 QuickAbort = false; \ 3623 if ((rsc = rscheck("check_other", inp, type, e, \ 3624 RSF_UNSTRUCTURED, 3, NULL, NOQID, NULL, NULL)) \ 3625 != EX_OK || \ 3626 Errors > 0) \ 3627 { \ 3628 if (strncmp(MsgBuf, "421 ", 4) == 0) \ 3629 { \ 3630 e->e_sendqueue = NULL; \ 3631 goto doquit; \ 3632 } \ 3633 } \ 3634 QuickAbort = saveQuickAbort; \ 3635 } while (0) 3636 3637 case CMDNOOP: /* noop -- do nothing */ 3638 DELAY_CONN("NOOP"); 3639 STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands, 3640 true, "NOOP", e)); 3641 CHECK_OTHER("2"); 3642 message("250 2.0.0 OK"); 3643 break; 3644 3645 case CMDQUIT: /* quit -- leave mail */ 3646 message("221 2.0.0 %s closing connection", MyHostName); 3647 #if PIPELINING 3648 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT); 3649 #endif 3650 3651 if (smtp.sm_nrcpts > 0) 3652 logundelrcpts(e, "aborted by sender", 9, false); 3653 3654 /* arrange to ignore any current send list */ 3655 e->e_sendqueue = NULL; 3656 3657 #if STARTTLS 3658 /* shutdown TLS connection */ 3659 if (tls_active) 3660 { 3661 (void) endtls(&srv_ssl, "server"); 3662 tls_active = false; 3663 } 3664 #endif /* STARTTLS */ 3665 #if SASL 3666 if (authenticating == SASL_IS_AUTH) 3667 { 3668 sasl_dispose(&conn); 3669 authenticating = SASL_NOT_AUTH; 3670 /* XXX sasl_done(); this is a child */ 3671 } 3672 #endif /* SASL */ 3673 3674 doquit: 3675 /* avoid future 050 messages */ 3676 disconnect(1, e); 3677 3678 #if MILTER 3679 /* close out milter filters */ 3680 milter_quit(e); 3681 #endif 3682 3683 if (tTd(92, 2)) 3684 sm_dprintf("QUIT: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", 3685 e->e_id, 3686 bitset(EF_LOGSENDER, e->e_flags), 3687 LogLevel); 3688 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 3689 logsender(e, NULL); 3690 e->e_flags &= ~EF_LOGSENDER; 3691 3692 if (lognullconnection && LogLevel > 5 && 3693 nullserver == NULL) 3694 { 3695 char *d; 3696 3697 d = macvalue(macid("{daemon_name}"), e); 3698 if (d == NULL) 3699 d = "stdin"; 3700 3701 /* 3702 ** even though this id is "bogus", it makes 3703 ** it simpler to "grep" related events, e.g., 3704 ** timeouts for the same connection. 3705 */ 3706 3707 sm_syslog(LOG_INFO, e->e_id, 3708 "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s", 3709 CurSmtpClient, d); 3710 } 3711 if (tTd(93, 100)) 3712 { 3713 /* return to handle next connection */ 3714 #if SM_HEAP_CHECK 3715 # define SM_HC_TRIGGER "heapdump" 3716 if (sm_debug_active(&SmHeapCheck, 2) 3717 && access(SM_HC_TRIGGER, F_OK) == 0 3718 ) 3719 { 3720 SM_FILE_T *out; 3721 3722 remove(SM_HC_TRIGGER); 3723 out = sm_io_open(SmFtStdio, 3724 SM_TIME_DEFAULT, SM_HC_TRIGGER ".heap", 3725 SM_IO_APPEND, NULL); 3726 if (out != NULL) 3727 { 3728 (void) sm_io_fprintf(out, SM_TIME_DEFAULT, "----------------------\n"); 3729 sm_heap_report(out, 3730 sm_debug_level(&SmHeapCheck) - 1); 3731 (void) sm_io_close(out, SM_TIME_DEFAULT); 3732 } 3733 } 3734 #endif /* SM_HEAP_CHECK */ 3735 return; 3736 } 3737 finis(true, true, ExitStat); 3738 /* NOTREACHED */ 3739 3740 /* just to avoid bogus warning from some compilers */ 3741 exit(EX_OSERR); 3742 3743 case CMDVERB: /* set verbose mode */ 3744 DELAY_CONN("VERB"); 3745 if (!bitset(SRV_OFFER_EXPN, features) || 3746 !bitset(SRV_OFFER_VERB, features)) 3747 { 3748 /* this would give out the same info */ 3749 message("502 5.7.0 Verbose unavailable"); 3750 break; 3751 } 3752 STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands, 3753 true, "VERB", e)); 3754 CHECK_OTHER("2"); 3755 Verbose = 1; 3756 set_delivery_mode(SM_DELIVER, e); 3757 message("250 2.0.0 Verbose mode"); 3758 break; 3759 3760 #if SMTPDEBUG 3761 case CMDDBGQSHOW: /* show queues */ 3762 CHECK_OTHER("2"); 3763 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3764 "Send Queue="); 3765 printaddr(smioout, e->e_sendqueue, true); 3766 break; 3767 3768 case CMDDBGDEBUG: /* set debug mode */ 3769 CHECK_OTHER("2"); 3770 tTsetup(tTdvect, sizeof(tTdvect), "0-99.1"); 3771 tTflag(p); 3772 message("200 2.0.0 Debug set"); 3773 break; 3774 3775 #else /* SMTPDEBUG */ 3776 case CMDDBGQSHOW: /* show queues */ 3777 case CMDDBGDEBUG: /* set debug mode */ 3778 #endif /* SMTPDEBUG */ 3779 case CMDLOGBOGUS: /* bogus command */ 3780 DELAY_CONN("Bogus"); 3781 if (LogLevel > 0) 3782 sm_syslog(LOG_CRIT, e->e_id, 3783 "\"%s\" command from %s (%.100s)", 3784 c->cmd_name, CurSmtpClient, 3785 anynet_ntoa(&RealHostAddr)); 3786 /* FALLTHROUGH */ 3787 3788 case CMDERROR: /* unknown command */ 3789 #if MAXBADCOMMANDS > 0 3790 if (++n_badcmds > MAXBADCOMMANDS) 3791 { 3792 stopattack: 3793 message("421 4.7.0 %s Too many bad commands; closing connection", 3794 MyHostName); 3795 3796 /* arrange to ignore any current send list */ 3797 e->e_sendqueue = NULL; 3798 goto doquit; 3799 } 3800 #endif /* MAXBADCOMMANDS > 0 */ 3801 3802 #if MILTER && SMFI_VERSION > 2 3803 if (smtp.sm_milterlist && smtp.sm_milterize && 3804 !bitset(EF_DISCARD, e->e_flags)) 3805 { 3806 char state; 3807 char *response; 3808 3809 if (MilterLogLevel > 9) 3810 sm_syslog(LOG_INFO, e->e_id, 3811 "Sending \"%s\" to Milter", inp); 3812 response = milter_unknown(inp, e, &state); 3813 MILTER_REPLY("unknown"); 3814 if (state == SMFIR_REPLYCODE || 3815 state == SMFIR_REJECT || 3816 state == SMFIR_TEMPFAIL || 3817 state == SMFIR_SHUTDOWN) 3818 { 3819 /* MILTER_REPLY already gave an error */ 3820 break; 3821 } 3822 } 3823 #endif /* MILTER && SMFI_VERSION > 2 */ 3824 3825 CHECK_OTHER("5"); 3826 usrerr("500 5.5.1 Command unrecognized: \"%s\"", 3827 SHOWSHRTCMDINREPLY(inp)); 3828 break; 3829 3830 case CMDUNIMPL: 3831 DELAY_CONN("Unimpl"); 3832 CHECK_OTHER("5"); 3833 usrerr("502 5.5.1 Command not implemented: \"%s\"", 3834 SHOWSHRTCMDINREPLY(inp)); 3835 break; 3836 3837 default: 3838 DELAY_CONN("default"); 3839 CHECK_OTHER("5"); 3840 errno = 0; 3841 syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code); 3842 break; 3843 } 3844 #if SASL 3845 } 3846 #endif 3847 } 3848 SM_EXCEPT(exc, "[!F]*") 3849 { 3850 /* 3851 ** The only possible exception is "E:mta.quickabort". 3852 ** There is nothing to do except fall through and loop. 3853 */ 3854 } 3855 SM_END_TRY 3856 } 3857 } 3858 /* 3859 ** SMTP_DATA -- implement the SMTP DATA command. 3860 ** 3861 ** Parameters: 3862 ** smtp -- status of SMTP connection. 3863 ** e -- envelope. 3864 ** 3865 ** Returns: 3866 ** true iff SMTP session can continue. 3867 ** 3868 ** Side Effects: 3869 ** possibly sends message. 3870 */ 3871 3872 static bool 3873 smtp_data(smtp, e) 3874 SMTP_T *smtp; 3875 ENVELOPE *e; 3876 { 3877 #if MILTER 3878 bool milteraccept; 3879 #endif 3880 bool aborting; 3881 bool doublequeue; 3882 bool rv = true; 3883 ADDRESS *a; 3884 ENVELOPE *ee; 3885 char *id; 3886 char *oldid; 3887 unsigned int features; 3888 char buf[32]; 3889 3890 SmtpPhase = "server DATA"; 3891 if (!smtp->sm_gotmail) 3892 { 3893 usrerr("503 5.0.0 Need MAIL command"); 3894 return true; 3895 } 3896 else if (smtp->sm_nrcpts <= 0) 3897 { 3898 usrerr("503 5.0.0 Need RCPT (recipient)"); 3899 return true; 3900 } 3901 (void) sm_snprintf(buf, sizeof(buf), "%u", smtp->sm_nrcpts); 3902 if (rscheck("check_data", buf, NULL, e, 3903 RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL, 3904 e->e_id, NULL, NULL) != EX_OK) 3905 return true; 3906 3907 #if MILTER && SMFI_VERSION > 3 3908 if (smtp->sm_milterlist && smtp->sm_milterize && 3909 !bitset(EF_DISCARD, e->e_flags)) 3910 { 3911 char state; 3912 char *response; 3913 int savelogusrerrs = LogUsrErrs; 3914 3915 response = milter_data_cmd(e, &state); 3916 switch (state) 3917 { 3918 case SMFIR_REPLYCODE: 3919 if (MilterLogLevel > 3) 3920 { 3921 sm_syslog(LOG_INFO, e->e_id, 3922 "Milter: cmd=data, reject=%s", 3923 response); 3924 LogUsrErrs = false; 3925 } 3926 # if _FFR_MILTER_ENHSC 3927 if (ISSMTPCODE(response)) 3928 (void) extenhsc(response + 4, ' ', e->e_enhsc); 3929 # endif 3930 3931 /* Can't use ("%s", ...) due to usrerr() requirements */ 3932 usrerr(response); 3933 if (strncmp(response, "421 ", 4) == 0 3934 || strncmp(response, "421-", 4) == 0) 3935 { 3936 e->e_sendqueue = NULL; 3937 return false; 3938 } 3939 return true; 3940 3941 case SMFIR_REJECT: 3942 if (MilterLogLevel > 3) 3943 { 3944 sm_syslog(LOG_INFO, e->e_id, 3945 "Milter: cmd=data, reject=550 5.7.1 Command rejected"); 3946 LogUsrErrs = false; 3947 } 3948 # if _FFR_MILTER_ENHSC 3949 (void) sm_strlcpy(e->e_enhsc, "5.7.1", 3950 sizeof(e->e_enhsc)); 3951 # endif 3952 usrerr("550 5.7.1 Command rejected"); 3953 return true; 3954 3955 case SMFIR_DISCARD: 3956 if (MilterLogLevel > 3) 3957 sm_syslog(LOG_INFO, e->e_id, 3958 "Milter: cmd=data, discard"); 3959 e->e_flags |= EF_DISCARD; 3960 break; 3961 3962 case SMFIR_TEMPFAIL: 3963 if (MilterLogLevel > 3) 3964 { 3965 sm_syslog(LOG_INFO, e->e_id, 3966 "Milter: cmd=data, reject=%s", 3967 MSG_TEMPFAIL); 3968 LogUsrErrs = false; 3969 } 3970 # if _FFR_MILTER_ENHSC 3971 (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc); 3972 # endif 3973 /* Can't use ("%s", ...) due to usrerr() requirements */ 3974 usrerr(MSG_TEMPFAIL); 3975 return true; 3976 3977 case SMFIR_SHUTDOWN: 3978 if (MilterLogLevel > 3) 3979 { 3980 sm_syslog(LOG_INFO, e->e_id, 3981 "Milter: cmd=data, reject=421 4.7.0 %s closing connection", 3982 MyHostName); 3983 LogUsrErrs = false; 3984 } 3985 usrerr("421 4.7.0 %s closing connection", MyHostName); 3986 e->e_sendqueue = NULL; 3987 return false; 3988 } 3989 LogUsrErrs = savelogusrerrs; 3990 if (response != NULL) 3991 sm_free(response); /* XXX */ 3992 } 3993 #endif /* MILTER && SMFI_VERSION > 3 */ 3994 3995 /* put back discard bit */ 3996 if (smtp->sm_discard) 3997 e->e_flags |= EF_DISCARD; 3998 3999 /* check to see if we need to re-expand aliases */ 4000 /* also reset QS_BADADDR on already-diagnosted addrs */ 4001 doublequeue = false; 4002 for (a = e->e_sendqueue; a != NULL; a = a->q_next) 4003 { 4004 if (QS_IS_VERIFIED(a->q_state) && 4005 !bitset(EF_DISCARD, e->e_flags)) 4006 { 4007 /* need to re-expand aliases */ 4008 doublequeue = true; 4009 } 4010 if (QS_IS_BADADDR(a->q_state)) 4011 { 4012 /* make this "go away" */ 4013 a->q_state = QS_DONTSEND; 4014 } 4015 } 4016 4017 /* collect the text of the message */ 4018 SmtpPhase = "collect"; 4019 buffer_errors(); 4020 4021 collect(InChannel, true, NULL, e, true); 4022 4023 /* redefine message size */ 4024 (void) sm_snprintf(buf, sizeof(buf), "%ld", PRT_NONNEGL(e->e_msgsize)); 4025 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf); 4026 4027 /* rscheck() will set Errors or EF_DISCARD if it trips */ 4028 (void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT, 4029 3, NULL, e->e_id, NULL, NULL); 4030 4031 #if MILTER 4032 milteraccept = true; 4033 if (smtp->sm_milterlist && smtp->sm_milterize && 4034 Errors <= 0 && 4035 !bitset(EF_DISCARD, e->e_flags)) 4036 { 4037 char state; 4038 char *response; 4039 4040 response = milter_data(e, &state); 4041 switch (state) 4042 { 4043 case SMFIR_REPLYCODE: 4044 if (MilterLogLevel > 3) 4045 sm_syslog(LOG_INFO, e->e_id, 4046 "Milter: data, reject=%s", 4047 response); 4048 milteraccept = false; 4049 # if _FFR_MILTER_ENHSC 4050 if (ISSMTPCODE(response)) 4051 (void) extenhsc(response + 4, ' ', e->e_enhsc); 4052 # endif 4053 /* Can't use ("%s", ...) due to usrerr() requirements */ 4054 usrerr(response); 4055 if (strncmp(response, "421 ", 4) == 0 4056 || strncmp(response, "421-", 4) == 0) 4057 rv = false; 4058 break; 4059 4060 case SMFIR_REJECT: 4061 milteraccept = false; 4062 if (MilterLogLevel > 3) 4063 sm_syslog(LOG_INFO, e->e_id, 4064 "Milter: data, reject=554 5.7.1 Command rejected"); 4065 usrerr("554 5.7.1 Command rejected"); 4066 break; 4067 4068 case SMFIR_DISCARD: 4069 if (MilterLogLevel > 3) 4070 sm_syslog(LOG_INFO, e->e_id, 4071 "Milter: data, discard"); 4072 milteraccept = false; 4073 e->e_flags |= EF_DISCARD; 4074 break; 4075 4076 case SMFIR_TEMPFAIL: 4077 if (MilterLogLevel > 3) 4078 sm_syslog(LOG_INFO, e->e_id, 4079 "Milter: data, reject=%s", 4080 MSG_TEMPFAIL); 4081 milteraccept = false; 4082 # if _FFR_MILTER_ENHSC 4083 (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc); 4084 # endif 4085 /* Can't use ("%s", ...) due to usrerr() requirements */ 4086 usrerr(MSG_TEMPFAIL); 4087 break; 4088 4089 case SMFIR_SHUTDOWN: 4090 if (MilterLogLevel > 3) 4091 sm_syslog(LOG_INFO, e->e_id, 4092 "Milter: data, reject=421 4.7.0 %s closing connection", 4093 MyHostName); 4094 milteraccept = false; 4095 usrerr("421 4.7.0 %s closing connection", MyHostName); 4096 rv = false; 4097 break; 4098 } 4099 if (response != NULL) 4100 sm_free(response); 4101 } 4102 4103 /* Milter may have changed message size */ 4104 (void) sm_snprintf(buf, sizeof(buf), "%ld", PRT_NONNEGL(e->e_msgsize)); 4105 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf); 4106 4107 /* abort message filters that didn't get the body & log msg is OK */ 4108 if (smtp->sm_milterlist && smtp->sm_milterize) 4109 { 4110 milter_abort(e); 4111 if (milteraccept && MilterLogLevel > 9) 4112 sm_syslog(LOG_INFO, e->e_id, "Milter accept: message"); 4113 } 4114 4115 /* 4116 ** If SuperSafe is SAFE_REALLY_POSTMILTER, and we don't have milter or 4117 ** milter accepted message, sync it now 4118 ** 4119 ** XXX This is almost a copy of the code in collect(): put it into 4120 ** a function that is called from both places? 4121 */ 4122 4123 if (milteraccept && SuperSafe == SAFE_REALLY_POSTMILTER) 4124 { 4125 int afd; 4126 SM_FILE_T *volatile df; 4127 char *dfname; 4128 4129 df = e->e_dfp; 4130 dfname = queuename(e, DATAFL_LETTER); 4131 if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0 4132 && errno != EINVAL) 4133 { 4134 int save_errno; 4135 4136 save_errno = errno; 4137 if (save_errno == EEXIST) 4138 { 4139 struct stat st; 4140 int dfd; 4141 4142 if (stat(dfname, &st) < 0) 4143 st.st_size = -1; 4144 errno = EEXIST; 4145 syserr("@collect: bfcommit(%s): already on disk, size=%ld", 4146 dfname, (long) st.st_size); 4147 dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); 4148 if (dfd >= 0) 4149 dumpfd(dfd, true, true); 4150 } 4151 errno = save_errno; 4152 dferror(df, "bfcommit", e); 4153 flush_errors(true); 4154 finis(save_errno != EEXIST, true, ExitStat); 4155 } 4156 else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0) 4157 { 4158 dferror(df, "sm_io_getinfo", e); 4159 flush_errors(true); 4160 finis(true, true, ExitStat); 4161 /* NOTREACHED */ 4162 } 4163 else if (fsync(afd) < 0) 4164 { 4165 dferror(df, "fsync", e); 4166 flush_errors(true); 4167 finis(true, true, ExitStat); 4168 /* NOTREACHED */ 4169 } 4170 else if (sm_io_close(df, SM_TIME_DEFAULT) < 0) 4171 { 4172 dferror(df, "sm_io_close", e); 4173 flush_errors(true); 4174 finis(true, true, ExitStat); 4175 /* NOTREACHED */ 4176 } 4177 4178 /* Now reopen the df file */ 4179 e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, 4180 SM_IO_RDONLY, NULL); 4181 if (e->e_dfp == NULL) 4182 { 4183 /* we haven't acked receipt yet, so just chuck this */ 4184 syserr("@Cannot reopen %s", dfname); 4185 finis(true, true, ExitStat); 4186 /* NOTREACHED */ 4187 } 4188 } 4189 #endif /* MILTER */ 4190 4191 /* Check if quarantining stats should be updated */ 4192 if (e->e_quarmsg != NULL) 4193 markstats(e, NULL, STATS_QUARANTINE); 4194 4195 /* 4196 ** If a header/body check (header checks or milter) 4197 ** set EF_DISCARD, don't queueup the message -- 4198 ** that would lose the EF_DISCARD bit and deliver 4199 ** the message. 4200 */ 4201 4202 if (bitset(EF_DISCARD, e->e_flags)) 4203 doublequeue = false; 4204 4205 aborting = Errors > 0; 4206 if (!(aborting || bitset(EF_DISCARD, e->e_flags)) && 4207 (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) && 4208 !split_by_recipient(e)) 4209 aborting = bitset(EF_FATALERRS, e->e_flags); 4210 4211 if (aborting) 4212 { 4213 ADDRESS *q; 4214 4215 /* Log who the mail would have gone to */ 4216 logundelrcpts(e, e->e_message, 8, false); 4217 4218 /* 4219 ** If something above refused the message, we still haven't 4220 ** accepted responsibility for it. Don't send DSNs. 4221 */ 4222 4223 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 4224 q->q_flags &= ~Q_PINGFLAGS; 4225 4226 flush_errors(true); 4227 buffer_errors(); 4228 goto abortmessage; 4229 } 4230 4231 /* from now on, we have to operate silently */ 4232 buffer_errors(); 4233 4234 #if 0 4235 /* 4236 ** Clear message, it may contain an error from the SMTP dialogue. 4237 ** This error must not show up in the queue. 4238 ** Some error message should show up, e.g., alias database 4239 ** not available, but others shouldn't, e.g., from check_rcpt. 4240 */ 4241 4242 e->e_message = NULL; 4243 #endif /* 0 */ 4244 4245 /* 4246 ** Arrange to send to everyone. 4247 ** If sending to multiple people, mail back 4248 ** errors rather than reporting directly. 4249 ** In any case, don't mail back errors for 4250 ** anything that has happened up to 4251 ** now (the other end will do this). 4252 ** Truncate our transcript -- the mail has gotten 4253 ** to us successfully, and if we have 4254 ** to mail this back, it will be easier 4255 ** on the reader. 4256 ** Then send to everyone. 4257 ** Finally give a reply code. If an error has 4258 ** already been given, don't mail a 4259 ** message back. 4260 ** We goose error returns by clearing error bit. 4261 */ 4262 4263 SmtpPhase = "delivery"; 4264 (void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL); 4265 id = e->e_id; 4266 4267 #if NAMED_BIND 4268 _res.retry = TimeOuts.res_retry[RES_TO_FIRST]; 4269 _res.retrans = TimeOuts.res_retrans[RES_TO_FIRST]; 4270 #endif 4271 4272 #if _FFR_PROXY 4273 if (SM_PROXY_REQ == e->e_sendmode) 4274 { 4275 /* is proxy mode possible? */ 4276 if (e->e_sibling == NULL && e->e_nrcpts == 1 4277 && smtp->sm_nrcpts == 1 4278 && (a = e->e_sendqueue) != NULL && a->q_next == NULL) 4279 { 4280 a->q_flags &= ~(QPINGONFAILURE|QPINGONSUCCESS| 4281 QPINGONDELAY); 4282 e->e_errormode = EM_QUIET; 4283 e->e_sendmode = SM_PROXY; 4284 } 4285 else 4286 { 4287 if (tTd(87, 2)) 4288 { 4289 a = e->e_sendqueue; 4290 sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, sm_nrcpts=%d, sendqueue=%p, next=%p\n", 4291 e->e_sendmode, e, e->e_sibling, e->e_nrcpts, 4292 smtp->sm_nrcpts, a, 4293 (a == NULL) ? (void *)0 : a->q_next); 4294 } 4295 4296 /* switch to interactive mode */ 4297 e->e_sendmode = SM_DELIVER; 4298 if (LogLevel > 9) 4299 sm_syslog(LOG_DEBUG, e->e_id, 4300 "proxy mode requested but not possible"); 4301 } 4302 } 4303 #endif /* _FFR_PROXY */ 4304 4305 #if _FFR_DMTRIGGER 4306 if (SM_TRIGGER == e->e_sendmode) 4307 doublequeue = true; 4308 #endif 4309 for (ee = e; ee != NULL; ee = ee->e_sibling) 4310 { 4311 /* make sure we actually do delivery */ 4312 ee->e_flags &= ~EF_CLRQUEUE; 4313 4314 /* from now on, operate silently */ 4315 ee->e_errormode = EM_MAIL; 4316 4317 if (doublequeue) 4318 { 4319 unsigned int qup_flags; 4320 4321 qup_flags = QUP_FL_MSYNC; 4322 #if _FFR_DMTRIGGER 4323 if (IS_SM_TRIGGER(ee->e_sendmode)) 4324 qup_flags |= QUP_FL_UNLOCK; 4325 #endif 4326 /* make sure it is in the queue */ 4327 queueup(ee, qup_flags); 4328 } 4329 else 4330 { 4331 int mode; 4332 4333 /* send to all recipients */ 4334 mode = SM_DEFAULT; 4335 #if _FFR_DM_ONE 4336 if (SM_DM_ONE == e->e_sendmode) 4337 { 4338 if (NotFirstDelivery) 4339 { 4340 mode = SM_QUEUE; 4341 e->e_sendmode = SM_QUEUE; 4342 } 4343 else 4344 { 4345 mode = SM_FORK; 4346 NotFirstDelivery = true; 4347 } 4348 } 4349 #endif /* _FFR_DM_ONE */ 4350 sendall(ee, mode); 4351 } 4352 ee->e_to = NULL; 4353 } 4354 4355 /* put back id for SMTP logging in putoutmsg() */ 4356 oldid = CurEnv->e_id; 4357 CurEnv->e_id = id; 4358 4359 #if _FFR_PROXY 4360 a = e->e_sendqueue; 4361 if (tTd(87, 1)) 4362 { 4363 sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, msg=%s, sendqueue=%p, next=%p, state=%d, SmtpError=%s, rcode=%d, renhsc=%s, text=%s\n", 4364 e->e_sendmode, e, e->e_sibling, e->e_nrcpts, e->e_message, a, 4365 (a == NULL) ? (void *)0 : a->q_next, 4366 (a == NULL) ? -1 : a->q_state, SmtpError, e->e_rcode, 4367 e->e_renhsc, e->e_text); 4368 } 4369 4370 if (SM_PROXY == e->e_sendmode && a->q_state != QS_SENT && 4371 a->q_state != QS_VERIFIED) /* discarded! */ 4372 { 4373 char *m, *errtext; 4374 char replycode[4]; 4375 char enhsc[10]; 4376 int offset; 4377 4378 #define NN_MSG(e) (((e)->e_message != NULL) ? (e)->e_message : "") 4379 m = e->e_message; 4380 #define SM_MSG_DEFERRED "Deferred: " 4381 if (m != NULL && strncmp(SM_MSG_DEFERRED, m, 4382 sizeof(SM_MSG_DEFERRED) - 1) == 0) 4383 m += sizeof(SM_MSG_DEFERRED) - 1; 4384 offset = extsc(m, ' ', replycode, enhsc); 4385 4386 if (tTd(87, 2)) 4387 { 4388 sm_dprintf("srv: SmtpError=%s, rcode=%d, renhsc=%s, replycode=%s, enhsc=%s, offset=%d\n", 4389 SmtpError, e->e_rcode, e->e_renhsc, 4390 replycode, enhsc, offset); 4391 } 4392 4393 #define DIG2CHAR(d) ((d) + '0') 4394 if (e->e_rcode != 0 && (replycode[0] == '\0' || 4395 replycode[0] == DIG2CHAR(REPLYTYPE(e->e_rcode)))) 4396 { 4397 replycode[0] = DIG2CHAR(REPLYTYPE(e->e_rcode)); 4398 replycode[1] = DIG2CHAR(REPLYCLASS(e->e_rcode)); 4399 replycode[2] = DIG2CHAR(REPLYMINOR(e->e_rcode)); 4400 replycode[3] = '\0'; 4401 if (e->e_renhsc[0] == replycode[0]) 4402 sm_strlcpy(enhsc, e->e_renhsc, sizeof(enhsc)); 4403 if (offset < 0) 4404 offset = 0; 4405 } 4406 if (e->e_text != NULL) 4407 { 4408 (void) strreplnonprt(e->e_text, '_'); 4409 errtext = e->e_text; 4410 } 4411 else 4412 errtext = m + offset; 4413 4414 if (replycode[0] != '\0' && enhsc[0] != '\0') 4415 emessage(replycode, enhsc, "%s", errtext); 4416 else if (replycode[0] != '\0') 4417 emessage(replycode, smtptodsn(atoi(replycode)), 4418 "%s", errtext); 4419 else if (QS_IS_TEMPFAIL(a->q_state)) 4420 { 4421 if (m != NULL) 4422 message("450 4.5.1 %s", m); 4423 else 4424 message("450 4.5.1 Temporary error"); 4425 } 4426 else 4427 { 4428 if (m != NULL) 4429 message("550 5.5.1 %s", m); 4430 else 4431 message("550 5.0.0 Permanent error"); 4432 } 4433 } 4434 else 4435 { 4436 #endif /* _FFR_PROXY */ 4437 /* issue success message */ 4438 #if _FFR_MSG_ACCEPT 4439 if (MessageAccept != NULL && *MessageAccept != '\0') 4440 { 4441 char msg[MAXLINE]; 4442 4443 expand(MessageAccept, msg, sizeof(msg), e); 4444 message("250 2.0.0 %s", msg); 4445 } 4446 else 4447 #endif /* _FFR_MSG_ACCEPT */ 4448 /* "else" in #if code above */ 4449 message("250 2.0.0 %s Message accepted for delivery", id); 4450 #if _FFR_PROXY 4451 } 4452 #endif 4453 CurEnv->e_id = oldid; 4454 4455 /* if we just queued, poke it */ 4456 if (doublequeue) 4457 { 4458 bool anything_to_send = false; 4459 4460 sm_getla(); 4461 for (ee = e; ee != NULL; ee = ee->e_sibling) 4462 { 4463 #if _FFR_DMTRIGGER 4464 if (SM_TRIGGER == ee->e_sendmode) 4465 { 4466 sm_syslog(LOG_DEBUG, ee->e_id, 4467 "smtp: doublequeue, mode=%c", ee->e_sendmode); 4468 ee->e_sendmode = SM_DELIVER; 4469 4470 /* close all the queue files */ 4471 /* almost the same as below */ 4472 closexscript(ee); 4473 SM_CLOSE_FP(ee->e_dfp); 4474 continue; 4475 } 4476 #endif /* _FFR_DMTRIGGER */ 4477 if (WILL_BE_QUEUED(ee->e_sendmode)) 4478 continue; 4479 if (shouldqueue(ee->e_msgpriority, ee->e_ctime)) 4480 { 4481 ee->e_sendmode = SM_QUEUE; 4482 continue; 4483 } 4484 else if (QueueMode != QM_QUARANTINE && 4485 ee->e_quarmsg != NULL) 4486 { 4487 ee->e_sendmode = SM_QUEUE; 4488 continue; 4489 } 4490 anything_to_send = true; 4491 4492 /* close all the queue files */ 4493 closexscript(ee); 4494 SM_CLOSE_FP(ee->e_dfp); 4495 unlockqueue(ee); 4496 } 4497 if (anything_to_send) 4498 { 4499 #if PIPELINING 4500 /* 4501 ** XXX if we don't do this, we get 250 twice 4502 ** because it is also flushed in the child. 4503 */ 4504 4505 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT); 4506 #endif /* PIPELINING */ 4507 #if _FFR_DMTRIGGER 4508 sm_syslog(LOG_DEBUG, e->e_id, "smtp: doublequeue=send"); 4509 #endif 4510 (void) doworklist(e, true, true); 4511 } 4512 } 4513 4514 abortmessage: 4515 if (tTd(92, 2)) 4516 sm_dprintf("abortmessage: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", 4517 e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); 4518 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 4519 logsender(e, NULL); 4520 e->e_flags &= ~EF_LOGSENDER; 4521 4522 /* clean up a bit */ 4523 smtp->sm_gotmail = false; 4524 4525 /* 4526 ** Call dropenvelope if and only if the envelope is *not* 4527 ** being processed by the child process forked by doworklist(). 4528 */ 4529 4530 if (aborting || bitset(EF_DISCARD, e->e_flags)) 4531 (void) dropenvelope(e, true, false); 4532 else 4533 { 4534 for (ee = e; ee != NULL; ee = ee->e_sibling) 4535 { 4536 if (!doublequeue && 4537 QueueMode != QM_QUARANTINE && 4538 ee->e_quarmsg != NULL) 4539 { 4540 (void) dropenvelope(ee, true, false); 4541 continue; 4542 } 4543 if (WILL_BE_QUEUED(ee->e_sendmode)) 4544 (void) dropenvelope(ee, true, false); 4545 } 4546 } 4547 4548 CurEnv = e; 4549 features = e->e_features; 4550 sm_rpool_free(e->e_rpool); 4551 newenvelope(e, e, sm_rpool_new_x(NULL)); 4552 e->e_flags = BlankEnvelope.e_flags; 4553 e->e_features = features; 4554 4555 /* restore connection quarantining */ 4556 if (smtp->sm_quarmsg == NULL) 4557 { 4558 e->e_quarmsg = NULL; 4559 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); 4560 } 4561 else 4562 { 4563 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg); 4564 macdefine(&e->e_macro, A_PERM, 4565 macid("{quarantine}"), e->e_quarmsg); 4566 } 4567 return rv; 4568 } 4569 /* 4570 ** LOGUNDELRCPTS -- log undelivered (or all) recipients. 4571 ** 4572 ** Parameters: 4573 ** e -- envelope. 4574 ** msg -- message for Stat= 4575 ** level -- log level. 4576 ** all -- log all recipients. 4577 ** 4578 ** Returns: 4579 ** none. 4580 ** 4581 ** Side Effects: 4582 ** logs undelivered (or all) recipients 4583 */ 4584 4585 void 4586 logundelrcpts(e, msg, level, all) 4587 ENVELOPE *e; 4588 char *msg; 4589 int level; 4590 bool all; 4591 { 4592 ADDRESS *a; 4593 4594 if (LogLevel <= level || msg == NULL || *msg == '\0') 4595 return; 4596 4597 /* Clear $h so relay= doesn't get mislogged by logdelivery() */ 4598 macdefine(&e->e_macro, A_PERM, 'h', NULL); 4599 4600 /* Log who the mail would have gone to */ 4601 for (a = e->e_sendqueue; a != NULL; a = a->q_next) 4602 { 4603 if (!QS_IS_UNDELIVERED(a->q_state) && !all) 4604 continue; 4605 e->e_to = a->q_paddr; 4606 logdelivery(NULL, NULL, 4607 #if _FFR_MILTER_ENHSC 4608 (a->q_status == NULL && e->e_enhsc[0] != '\0') 4609 ? e->e_enhsc : 4610 #endif 4611 /* not yet documented or tested */ 4612 #if _FFR_USE_E_STATUS 4613 (NULL == a->q_status) ? e->e_status : 4614 #endif 4615 a->q_status, 4616 msg, NULL, (time_t) 0, e, a, EX_OK /* ??? */); 4617 } 4618 e->e_to = NULL; 4619 } 4620 /* 4621 ** CHECKSMTPATTACK -- check for denial-of-service attack by repetition 4622 ** 4623 ** Parameters: 4624 ** pcounter -- pointer to a counter for this command. 4625 ** maxcount -- maximum value for this counter before we 4626 ** slow down. 4627 ** waitnow -- sleep now (in this routine)? 4628 ** cname -- command name for logging. 4629 ** e -- the current envelope. 4630 ** 4631 ** Returns: 4632 ** time to wait, 4633 ** STOP_ATTACK if twice as many commands as allowed and 4634 ** MaxChildren > 0. 4635 ** 4636 ** Side Effects: 4637 ** Slows down if we seem to be under attack. 4638 */ 4639 4640 static time_t 4641 checksmtpattack(pcounter, maxcount, waitnow, cname, e) 4642 volatile unsigned int *pcounter; 4643 unsigned int maxcount; 4644 bool waitnow; 4645 char *cname; 4646 ENVELOPE *e; 4647 { 4648 if (maxcount <= 0) /* no limit */ 4649 return (time_t) 0; 4650 4651 if (++(*pcounter) >= maxcount) 4652 { 4653 unsigned int shift; 4654 time_t s; 4655 4656 if (*pcounter == maxcount && LogLevel > 5) 4657 { 4658 sm_syslog(LOG_INFO, e->e_id, 4659 "%s: possible SMTP attack: command=%.40s, count=%u", 4660 CurSmtpClient, cname, *pcounter); 4661 } 4662 shift = *pcounter - maxcount; 4663 s = 1 << shift; 4664 if (shift > MAXSHIFT || s >= MAXTIMEOUT || s <= 0) 4665 s = MAXTIMEOUT; 4666 4667 #define IS_ATTACK(s) ((MaxChildren > 0 && *pcounter >= maxcount * 2) \ 4668 ? STOP_ATTACK : (time_t) s) 4669 4670 /* sleep at least 1 second before returning */ 4671 (void) sleep(*pcounter / maxcount); 4672 s -= *pcounter / maxcount; 4673 if (s >= MAXTIMEOUT || s < 0) 4674 s = MAXTIMEOUT; 4675 if (waitnow && s > 0) 4676 { 4677 (void) sleep(s); 4678 return IS_ATTACK(0); 4679 } 4680 return IS_ATTACK(s); 4681 } 4682 return (time_t) 0; 4683 } 4684 /* 4685 ** SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server 4686 ** 4687 ** Parameters: 4688 ** none. 4689 ** 4690 ** Returns: 4691 ** nothing. 4692 ** 4693 ** Side Effects: 4694 ** may change I/O fd. 4695 */ 4696 4697 static void 4698 setup_smtpd_io() 4699 { 4700 int inchfd, outchfd, outfd; 4701 4702 inchfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL); 4703 outchfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL); 4704 outfd = sm_io_getinfo(smioout, SM_IO_WHAT_FD, NULL); 4705 if (outchfd != outfd) 4706 { 4707 /* arrange for debugging output to go to remote host */ 4708 (void) dup2(outchfd, outfd); 4709 } 4710 4711 /* 4712 ** if InChannel and OutChannel are stdin/stdout 4713 ** and connected to ttys 4714 ** and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT, 4715 ** then "chain" them together. 4716 */ 4717 4718 if (inchfd == STDIN_FILENO && outchfd == STDOUT_FILENO && 4719 isatty(inchfd) && isatty(outchfd)) 4720 { 4721 int inmode, outmode; 4722 4723 inmode = fcntl(inchfd, F_GETFL, 0); 4724 if (inmode == -1) 4725 { 4726 if (LogLevel > 11) 4727 sm_syslog(LOG_INFO, NOQID, 4728 "fcntl(inchfd, F_GETFL) failed: %s", 4729 sm_errstring(errno)); 4730 return; 4731 } 4732 outmode = fcntl(outchfd, F_GETFL, 0); 4733 if (outmode == -1) 4734 { 4735 if (LogLevel > 11) 4736 sm_syslog(LOG_INFO, NOQID, 4737 "fcntl(outchfd, F_GETFL) failed: %s", 4738 sm_errstring(errno)); 4739 return; 4740 } 4741 if (bitset(O_NONBLOCK, inmode) || 4742 bitset(O_NONBLOCK, outmode) || 4743 fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1) 4744 return; 4745 outmode = fcntl(outchfd, F_GETFL, 0); 4746 if (outmode != -1 && bitset(O_NONBLOCK, outmode)) 4747 { 4748 /* changing InChannel also changes OutChannel */ 4749 sm_io_automode(OutChannel, InChannel); 4750 if (tTd(97, 4) && LogLevel > 9) 4751 sm_syslog(LOG_INFO, NOQID, 4752 "set automode for I (%d)/O (%d) in SMTP server", 4753 inchfd, outchfd); 4754 } 4755 4756 /* undo change of inchfd */ 4757 (void) fcntl(inchfd, F_SETFL, inmode); 4758 } 4759 } 4760 /* 4761 ** SKIPWORD -- skip a fixed word. 4762 ** 4763 ** Parameters: 4764 ** p -- place to start looking. 4765 ** w -- word to skip. 4766 ** 4767 ** Returns: 4768 ** p following w. 4769 ** NULL on error. 4770 ** 4771 ** Side Effects: 4772 ** clobbers the p data area. 4773 */ 4774 4775 static char * 4776 skipword(p, w) 4777 register char *volatile p; 4778 char *w; 4779 { 4780 register char *q; 4781 char *firstp = p; 4782 4783 /* find beginning of word */ 4784 SKIP_SPACE(p); 4785 q = p; 4786 4787 /* find end of word */ 4788 while (*p != '\0' && *p != ':' && !(SM_ISSPACE(*p))) 4789 p++; 4790 while (SM_ISSPACE(*p)) 4791 *p++ = '\0'; 4792 if (*p != ':') 4793 { 4794 syntax: 4795 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"", 4796 SHOWSHRTCMDINREPLY(firstp)); 4797 return NULL; 4798 } 4799 *p++ = '\0'; 4800 SKIP_SPACE(p); 4801 4802 if (*p == '\0') 4803 goto syntax; 4804 4805 /* see if the input word matches desired word */ 4806 if (sm_strcasecmp(q, w)) 4807 goto syntax; 4808 4809 return p; 4810 } 4811 4812 /* 4813 ** RESET_MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line 4814 ** 4815 ** Parameters: 4816 ** e -- the envelope. 4817 ** 4818 ** Returns: 4819 ** none. 4820 */ 4821 4822 void 4823 reset_mail_esmtp_args(e) 4824 ENVELOPE *e; 4825 { 4826 /* "size": no reset */ 4827 4828 /* "body" */ 4829 SevenBitInput = SevenBitInput_Saved; 4830 e->e_bodytype = NULL; 4831 4832 /* "envid" */ 4833 e->e_envid = NULL; 4834 macdefine(&e->e_macro, A_PERM, macid("{dsn_envid}"), NULL); 4835 4836 /* "ret" */ 4837 e->e_flags &= ~(EF_RET_PARAM|EF_NO_BODY_RETN); 4838 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), NULL); 4839 4840 #if SASL 4841 /* "auth" */ 4842 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), NULL); 4843 e->e_auth_param = ""; 4844 # if _FFR_AUTH_PASSING 4845 macdefine(&BlankEnvelope.e_macro, A_PERM, 4846 macid("{auth_author}"), NULL); 4847 # endif 4848 #endif /* SASL */ 4849 4850 /* "by" */ 4851 e->e_deliver_by = 0; 4852 e->e_dlvr_flag = 0; 4853 } 4854 4855 /* 4856 ** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line 4857 ** 4858 ** Parameters: 4859 ** a -- address (unused, for compatibility with rcpt_esmtp_args) 4860 ** kp -- the parameter key. 4861 ** vp -- the value of that parameter. 4862 ** e -- the envelope. 4863 ** 4864 ** Returns: 4865 ** none. 4866 */ 4867 4868 void 4869 mail_esmtp_args(a, kp, vp, e) 4870 ADDRESS *a; 4871 char *kp; 4872 char *vp; 4873 ENVELOPE *e; 4874 { 4875 if (SM_STRCASEEQ(kp, "size")) 4876 { 4877 if (vp == NULL) 4878 { 4879 usrerr("501 5.5.2 SIZE requires a value"); 4880 /* NOTREACHED */ 4881 } 4882 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp); 4883 errno = 0; 4884 e->e_msgsize = strtol(vp, (char **) NULL, 10); 4885 if (e->e_msgsize == LONG_MAX && errno == ERANGE) 4886 { 4887 usrerr("552 5.2.3 Message size exceeds maximum value"); 4888 /* NOTREACHED */ 4889 } 4890 if (e->e_msgsize < 0) 4891 { 4892 usrerr("552 5.2.3 Message size invalid"); 4893 /* NOTREACHED */ 4894 } 4895 } 4896 else if (SM_STRCASEEQ(kp, "body")) 4897 { 4898 if (vp == NULL) 4899 { 4900 usrerr("501 5.5.2 BODY requires a value"); 4901 /* NOTREACHED */ 4902 } 4903 else if (SM_STRCASEEQ(vp, "8bitmime")) 4904 { 4905 SevenBitInput = false; 4906 } 4907 else if (SM_STRCASEEQ(vp, "7bit")) 4908 { 4909 SevenBitInput = true; 4910 } 4911 else 4912 { 4913 usrerr("501 5.5.4 Unknown BODY type %s", 4914 SHOWCMDINREPLY(vp)); 4915 /* NOTREACHED */ 4916 } 4917 e->e_bodytype = sm_rpool_strdup_x(e->e_rpool, vp); 4918 } 4919 else if (SM_STRCASEEQ(kp, "envid")) 4920 { 4921 if (!bitset(SRV_OFFER_DSN, e->e_features)) 4922 { 4923 usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN"); 4924 /* NOTREACHED */ 4925 } 4926 if (vp == NULL) 4927 { 4928 usrerr("501 5.5.2 ENVID requires a value"); 4929 /* NOTREACHED */ 4930 } 4931 if (!xtextok(vp)) 4932 { 4933 usrerr("501 5.5.4 Syntax error in ENVID parameter value"); 4934 /* NOTREACHED */ 4935 } 4936 if (e->e_envid != NULL) 4937 { 4938 usrerr("501 5.5.0 Duplicate ENVID parameter"); 4939 /* NOTREACHED */ 4940 } 4941 e->e_envid = sm_rpool_strdup_x(e->e_rpool, vp); 4942 macdefine(&e->e_macro, A_PERM, 4943 macid("{dsn_envid}"), e->e_envid); 4944 } 4945 else if (SM_STRCASEEQ(kp, "ret")) 4946 { 4947 if (!bitset(SRV_OFFER_DSN, e->e_features)) 4948 { 4949 usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN"); 4950 /* NOTREACHED */ 4951 } 4952 if (vp == NULL) 4953 { 4954 usrerr("501 5.5.2 RET requires a value"); 4955 /* NOTREACHED */ 4956 } 4957 if (bitset(EF_RET_PARAM, e->e_flags)) 4958 { 4959 usrerr("501 5.5.0 Duplicate RET parameter"); 4960 /* NOTREACHED */ 4961 } 4962 e->e_flags |= EF_RET_PARAM; 4963 if (SM_STRCASEEQ(vp, "hdrs")) 4964 e->e_flags |= EF_NO_BODY_RETN; 4965 else if (sm_strcasecmp(vp, "full") != 0) 4966 { 4967 usrerr("501 5.5.2 Bad argument \"%s\" to RET", 4968 SHOWCMDINREPLY(vp)); 4969 /* NOTREACHED */ 4970 } 4971 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp); 4972 } 4973 #if SASL 4974 else if (SM_STRCASEEQ(kp, "auth")) 4975 { 4976 int len; 4977 char *q; 4978 char *auth_param; /* the value of the AUTH=x */ 4979 bool saveQuickAbort = QuickAbort; 4980 bool saveSuprErrs = SuprErrs; 4981 bool saveExitStat = ExitStat; 4982 4983 if (vp == NULL) 4984 { 4985 usrerr("501 5.5.2 AUTH= requires a value"); 4986 /* NOTREACHED */ 4987 } 4988 if (e->e_auth_param != NULL) 4989 { 4990 usrerr("501 5.5.0 Duplicate AUTH parameter"); 4991 /* NOTREACHED */ 4992 } 4993 if ((q = strchr(vp, ' ')) != NULL) 4994 len = q - vp + 1; 4995 else 4996 len = strlen(vp) + 1; 4997 auth_param = xalloc(len); 4998 (void) sm_strlcpy(auth_param, vp, len); 4999 if (!xtextok(auth_param)) 5000 { 5001 usrerr("501 5.5.4 Syntax error in AUTH parameter value"); 5002 /* just a warning? */ 5003 /* NOTREACHED */ 5004 } 5005 5006 /* XXX define this always or only if trusted? */ 5007 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), 5008 auth_param); 5009 5010 /* 5011 ** call Strust_auth to find out whether 5012 ** auth_param is acceptable (trusted) 5013 ** we shouldn't trust it if not authenticated 5014 ** (required by RFC, leave it to ruleset?) 5015 */ 5016 5017 SuprErrs = true; 5018 QuickAbort = false; 5019 if (strcmp(auth_param, "<>") != 0 && 5020 (rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM, 9, 5021 NULL, NOQID, NULL, NULL) != EX_OK || Errors > 0)) 5022 { 5023 if (tTd(95, 8)) 5024 { 5025 q = e->e_auth_param; 5026 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n", 5027 auth_param, (q == NULL) ? "" : q); 5028 } 5029 5030 /* not trusted */ 5031 e->e_auth_param = "<>"; 5032 # if _FFR_AUTH_PASSING 5033 macdefine(&BlankEnvelope.e_macro, A_PERM, 5034 macid("{auth_author}"), NULL); 5035 # endif 5036 } 5037 else 5038 { 5039 if (tTd(95, 8)) 5040 sm_dprintf("auth=\"%.100s\" trusted\n", auth_param); 5041 e->e_auth_param = sm_rpool_strdup_x(e->e_rpool, 5042 auth_param); 5043 } 5044 sm_free(auth_param); /* XXX */ 5045 5046 /* reset values */ 5047 Errors = 0; 5048 QuickAbort = saveQuickAbort; 5049 SuprErrs = saveSuprErrs; 5050 ExitStat = saveExitStat; 5051 } 5052 #endif /* SASL */ 5053 #define PRTCHAR(c) ((isascii(c) && isprint(c)) ? (c) : '?') 5054 5055 /* 5056 ** "by" is only accepted if DeliverByMin >= 0. 5057 ** We maybe could add this to the list of server_features. 5058 */ 5059 5060 else if (SM_STRCASEEQ(kp, "by") && DeliverByMin >= 0) 5061 { 5062 char *s; 5063 5064 if (vp == NULL) 5065 { 5066 usrerr("501 5.5.2 BY= requires a value"); 5067 /* NOTREACHED */ 5068 } 5069 errno = 0; 5070 e->e_deliver_by = strtol(vp, &s, 10); 5071 if (e->e_deliver_by == LONG_MIN || 5072 e->e_deliver_by == LONG_MAX || 5073 e->e_deliver_by > 999999999l || 5074 e->e_deliver_by < -999999999l) 5075 { 5076 usrerr("501 5.5.2 BY=%s out of range", 5077 SHOWCMDINREPLY(vp)); 5078 /* NOTREACHED */ 5079 } 5080 if (s == NULL || *s != ';') 5081 { 5082 usrerr("501 5.5.2 BY= missing ';'"); 5083 /* NOTREACHED */ 5084 } 5085 e->e_dlvr_flag = 0; 5086 ++s; /* XXX: spaces allowed? */ 5087 SKIP_SPACE(s); 5088 switch (tolower(*s)) 5089 { 5090 case 'n': 5091 e->e_dlvr_flag = DLVR_NOTIFY; 5092 break; 5093 case 'r': 5094 e->e_dlvr_flag = DLVR_RETURN; 5095 if (e->e_deliver_by <= 0) 5096 { 5097 usrerr("501 5.5.4 mode R requires BY time > 0"); 5098 /* NOTREACHED */ 5099 } 5100 if (DeliverByMin > 0 && e->e_deliver_by > 0 && 5101 e->e_deliver_by < DeliverByMin) 5102 { 5103 usrerr("555 5.5.2 time %ld less than %ld", 5104 e->e_deliver_by, (long) DeliverByMin); 5105 /* NOTREACHED */ 5106 } 5107 break; 5108 default: 5109 usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s)); 5110 /* NOTREACHED */ 5111 } 5112 ++s; /* XXX: spaces allowed? */ 5113 SKIP_SPACE(s); 5114 switch (tolower(*s)) 5115 { 5116 case 't': 5117 e->e_dlvr_flag |= DLVR_TRACE; 5118 break; 5119 case '\0': 5120 break; 5121 default: 5122 usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s)); 5123 /* NOTREACHED */ 5124 } 5125 5126 /* XXX: check whether more characters follow? */ 5127 } 5128 #if USE_EAI 5129 else if (SM_STRCASEEQ(kp, "smtputf8")) 5130 { 5131 if (!bitset(SRV_OFFER_EAI, e->e_features)) 5132 { 5133 usrerr("504 5.7.0 Sorry, SMTPUTF8 not supported"); 5134 /* NOTREACHED */ 5135 } 5136 e->e_smtputf8 = true; 5137 } 5138 #endif 5139 else 5140 { 5141 usrerr("555 5.5.4 %s parameter unrecognized", 5142 SHOWCMDINREPLY(kp)); 5143 /* NOTREACHED */ 5144 } 5145 } 5146 5147 /* 5148 ** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line 5149 ** 5150 ** Parameters: 5151 ** a -- the address corresponding to the To: parameter. 5152 ** kp -- the parameter key. 5153 ** vp -- the value of that parameter. 5154 ** e -- the envelope. 5155 ** 5156 ** Returns: 5157 ** none. 5158 */ 5159 5160 void 5161 rcpt_esmtp_args(a, kp, vp, e) 5162 ADDRESS *a; 5163 char *kp; 5164 char *vp; 5165 ENVELOPE *e; 5166 { 5167 if (SM_STRCASEEQ(kp, "notify")) 5168 { 5169 char *p; 5170 5171 if (!bitset(SRV_OFFER_DSN, e->e_features)) 5172 { 5173 usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN"); 5174 /* NOTREACHED */ 5175 } 5176 if (vp == NULL) 5177 { 5178 usrerr("501 5.5.2 NOTIFY requires a value"); 5179 /* NOTREACHED */ 5180 } 5181 a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY); 5182 a->q_flags |= QHASNOTIFY; 5183 macdefine(&e->e_macro, A_TEMP, macid("{dsn_notify}"), vp); 5184 5185 if (SM_STRCASEEQ(vp, "never")) 5186 return; 5187 for (p = vp; p != NULL; vp = p) 5188 { 5189 char *s; 5190 5191 s = p = strchr(p, ','); 5192 if (p != NULL) 5193 *p++ = '\0'; 5194 if (SM_STRCASEEQ(vp, "success")) 5195 a->q_flags |= QPINGONSUCCESS; 5196 else if (SM_STRCASEEQ(vp, "failure")) 5197 a->q_flags |= QPINGONFAILURE; 5198 else if (SM_STRCASEEQ(vp, "delay")) 5199 a->q_flags |= QPINGONDELAY; 5200 else 5201 { 5202 usrerr("501 5.5.4 Bad argument \"%s\" to NOTIFY", 5203 SHOWCMDINREPLY(vp)); 5204 /* NOTREACHED */ 5205 } 5206 if (s != NULL) 5207 *s = ','; 5208 } 5209 } 5210 else if (SM_STRCASEEQ(kp, "orcpt")) 5211 { 5212 char *p; 5213 5214 if (!bitset(SRV_OFFER_DSN, e->e_features)) 5215 { 5216 usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN"); 5217 /* NOTREACHED */ 5218 } 5219 if (vp == NULL) 5220 { 5221 usrerr("501 5.5.2 ORCPT requires a value"); 5222 /* NOTREACHED */ 5223 } 5224 if (a->q_orcpt != NULL) 5225 { 5226 usrerr("501 5.5.0 Duplicate ORCPT parameter"); 5227 /* NOTREACHED */ 5228 } 5229 p = strchr(vp, ';'); 5230 if (p == NULL) 5231 { 5232 usrerr("501 5.5.4 Syntax error in ORCPT parameter value"); 5233 /* NOTREACHED */ 5234 } 5235 *p = '\0'; 5236 #if USE_EAI 5237 if (SM_STRCASEEQ(vp, "utf-8")) 5238 { 5239 /* XXX check syntax of p+1 ! */ 5240 if (!xtextok(p + 1) && 5241 uxtext_unquote(p + 1, NULL, MAXNAME_I) <= 0) 5242 { 5243 *p = ';'; 5244 usrerr("501 5.5.4 Syntax error in UTF-8 ORCPT parameter value"); 5245 /* NOTREACHED */ 5246 } 5247 # if 0 5248 complicated... see grammar! 5249 RFC 6533 Internationalized Delivery Status and Disposition Notifications 5250 utf-8-enc-addr = utf-8-addr-xtext / utf-8-addr-unitext / utf-8-address 5251 # endif 5252 } 5253 else 5254 #endif /* USE_EAI */ 5255 /* "else" in #if code above */ 5256 if (!isatom(vp) || !xtextok(p + 1)) 5257 { 5258 *p = ';'; 5259 usrerr("501 5.5.4 Syntax error in ORCPT parameter value"); 5260 /* NOTREACHED */ 5261 } 5262 *p = ';'; 5263 a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp); 5264 } 5265 else 5266 { 5267 usrerr("555 5.5.4 %s parameter unrecognized", 5268 SHOWCMDINREPLY(kp)); 5269 /* NOTREACHED */ 5270 } 5271 } 5272 /* 5273 ** PRINTVRFYADDR -- print an entry in the verify queue 5274 ** 5275 ** Parameters: 5276 ** a -- the address to print. 5277 ** last -- set if this is the last one. 5278 ** vrfy -- set if this is a VRFY command. 5279 ** 5280 ** Returns: 5281 ** none. 5282 ** 5283 ** Side Effects: 5284 ** Prints the appropriate 250 codes. 5285 */ 5286 #define OFFF (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */ 5287 5288 static void 5289 printvrfyaddr(a, last, vrfy) 5290 register ADDRESS *a; 5291 bool last; 5292 bool vrfy; 5293 { 5294 char fmtbuf[30]; 5295 5296 if (vrfy && a->q_mailer != NULL && 5297 !bitnset(M_VRFY250, a->q_mailer->m_flags)) 5298 (void) sm_strlcpy(fmtbuf, "252", sizeof(fmtbuf)); 5299 else 5300 (void) sm_strlcpy(fmtbuf, "250", sizeof(fmtbuf)); 5301 fmtbuf[3] = last ? ' ' : '-'; 5302 (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof(fmtbuf) - 4); 5303 if (a->q_fullname == NULL) 5304 { 5305 if ((a->q_mailer == NULL || 5306 a->q_mailer->m_addrtype == NULL || 5307 SM_STRCASEEQ(a->q_mailer->m_addrtype, "rfc822")) && 5308 strchr(a->q_user, '@') == NULL) 5309 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>", 5310 sizeof(fmtbuf) - OFFF); 5311 else 5312 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s>", 5313 sizeof(fmtbuf) - OFFF); 5314 message(fmtbuf, a->q_user, MyHostName); 5315 } 5316 else 5317 { 5318 if ((a->q_mailer == NULL || 5319 a->q_mailer->m_addrtype == NULL || 5320 SM_STRCASEEQ(a->q_mailer->m_addrtype, "rfc822")) && 5321 strchr(a->q_user, '@') == NULL) 5322 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>", 5323 sizeof(fmtbuf) - OFFF); 5324 else 5325 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>", 5326 sizeof(fmtbuf) - OFFF); 5327 message(fmtbuf, a->q_fullname, a->q_user, MyHostName); 5328 } 5329 } 5330 5331 #if SASL 5332 /* 5333 ** SASLMECHS -- get list of possible AUTH mechanisms 5334 ** 5335 ** Parameters: 5336 ** conn -- SASL connection info. 5337 ** mechlist -- output parameter for list of mechanisms. 5338 ** 5339 ** Returns: 5340 ** number of mechs. 5341 */ 5342 5343 static int 5344 saslmechs(conn, mechlist) 5345 sasl_conn_t *conn; 5346 char **mechlist; 5347 { 5348 int len, num, result; 5349 5350 /* "user" is currently unused */ 5351 # if SASL >= 20000 5352 result = sasl_listmech(conn, NULL, 5353 "", " ", "", (const char **) mechlist, 5354 (unsigned int *)&len, &num); 5355 # else /* SASL >= 20000 */ 5356 result = sasl_listmech(conn, "user", /* XXX */ 5357 "", " ", "", mechlist, 5358 (unsigned int *)&len, (unsigned int *)&num); 5359 # endif /* SASL >= 20000 */ 5360 if (result != SASL_OK) 5361 { 5362 if (LogLevel > 9) 5363 sm_syslog(LOG_WARNING, NOQID, 5364 "AUTH error: listmech=%d, num=%d", 5365 result, num); 5366 num = 0; 5367 } 5368 if (num > 0) 5369 { 5370 if (LogLevel > 11) 5371 sm_syslog(LOG_INFO, NOQID, 5372 "AUTH: available mech=%s, allowed mech=%s", 5373 *mechlist, AuthMechanisms); 5374 *mechlist = intersect(AuthMechanisms, *mechlist, NULL); 5375 } 5376 else 5377 { 5378 *mechlist = NULL; /* be paranoid... */ 5379 if (result == SASL_OK && LogLevel > 9) 5380 sm_syslog(LOG_WARNING, NOQID, 5381 "AUTH warning: no mechanisms"); 5382 } 5383 return num; 5384 } 5385 5386 # if SASL >= 20000 5387 /* 5388 ** PROXY_POLICY -- define proxy policy for AUTH 5389 ** 5390 ** Parameters: 5391 ** conn -- unused. 5392 ** context -- unused. 5393 ** requested_user -- authorization identity. 5394 ** rlen -- authorization identity length. 5395 ** auth_identity -- authentication identity. 5396 ** alen -- authentication identity length. 5397 ** def_realm -- default user realm. 5398 ** urlen -- user realm length. 5399 ** propctx -- unused. 5400 ** 5401 ** Returns: 5402 ** ok? 5403 ** 5404 ** Side Effects: 5405 ** sets {auth_authen} macro. 5406 */ 5407 5408 int 5409 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen, 5410 def_realm, urlen, propctx) 5411 sasl_conn_t *conn; 5412 void *context; 5413 const char *requested_user; 5414 unsigned rlen; 5415 const char *auth_identity; 5416 unsigned alen; 5417 const char *def_realm; 5418 unsigned urlen; 5419 struct propctx *propctx; 5420 { 5421 if (auth_identity == NULL) 5422 return SASL_FAIL; 5423 5424 macdefine(&BlankEnvelope.e_macro, A_TEMP, 5425 macid("{auth_authen}"), 5426 xtextify((char *) auth_identity, "=<>\")")); 5427 5428 return SASL_OK; 5429 } 5430 # else /* SASL >= 20000 */ 5431 5432 /* 5433 ** PROXY_POLICY -- define proxy policy for AUTH 5434 ** 5435 ** Parameters: 5436 ** context -- unused. 5437 ** auth_identity -- authentication identity. 5438 ** requested_user -- authorization identity. 5439 ** user -- allowed user (output). 5440 ** errstr -- possible error string (output). 5441 ** 5442 ** Returns: 5443 ** ok? 5444 */ 5445 5446 int 5447 proxy_policy(context, auth_identity, requested_user, user, errstr) 5448 void *context; 5449 const char *auth_identity; 5450 const char *requested_user; 5451 const char **user; 5452 const char **errstr; 5453 { 5454 if (user == NULL || auth_identity == NULL) 5455 return SASL_FAIL; 5456 *user = newstr(auth_identity); 5457 return SASL_OK; 5458 } 5459 # endif /* SASL >= 20000 */ 5460 #endif /* SASL */ 5461 5462 #if STARTTLS 5463 /* 5464 ** INITSRVTLS -- initialize server side TLS 5465 ** 5466 ** Parameters: 5467 ** tls_ok -- should tls initialization be done? 5468 ** 5469 ** Returns: 5470 ** succeeded? 5471 ** 5472 ** Side Effects: 5473 ** sets tls_ok_srv which is a static variable in this module. 5474 ** Do NOT remove assignments to it! 5475 */ 5476 5477 bool 5478 initsrvtls(tls_ok) 5479 bool tls_ok; 5480 { 5481 if (!tls_ok) 5482 return false; 5483 5484 /* do NOT remove assignment */ 5485 tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, Srv_SSL_Options, true, 5486 SrvCertFile, SrvKeyFile, 5487 CACertPath, CACertFile, DHParams); 5488 return tls_ok_srv; 5489 } 5490 #endif /* STARTTLS */ 5491 /* 5492 ** SRVFEATURES -- get features for SMTP server 5493 ** 5494 ** Parameters: 5495 ** e -- envelope (should be session context). 5496 ** clientname -- name of client. 5497 ** features -- default features for this invocation. 5498 ** 5499 ** Returns: 5500 ** server features. 5501 */ 5502 5503 /* table with options: it uses just one character, how about strings? */ 5504 static struct 5505 { 5506 char srvf_opt; 5507 unsigned int srvf_flag; 5508 } srv_feat_table[] = 5509 { 5510 { 'A', SRV_OFFER_AUTH }, 5511 { 'B', SRV_OFFER_VERB }, 5512 { 'C', SRV_REQ_SEC }, 5513 { 'D', SRV_OFFER_DSN }, 5514 { 'E', SRV_OFFER_ETRN }, 5515 { 'H', SRV_NO_HTTP_CMD }, 5516 #if USE_EAI 5517 { 'I', SRV_OFFER_EAI }, 5518 #endif 5519 { 'L', SRV_REQ_AUTH }, 5520 #if PIPELINING 5521 # if _FFR_NO_PIPE 5522 { 'N', SRV_NO_PIPE }, 5523 # endif 5524 { 'P', SRV_OFFER_PIPE }, 5525 #endif /* PIPELINING */ 5526 { 'R', SRV_VRFY_CLT }, /* same as V; not documented */ 5527 { 'S', SRV_OFFER_TLS }, 5528 /* { 'T', SRV_TMP_FAIL }, */ 5529 { 'V', SRV_VRFY_CLT }, 5530 { 'X', SRV_OFFER_EXPN }, 5531 /* { 'Y', SRV_OFFER_VRFY }, */ 5532 { '\0', SRV_NONE } 5533 }; 5534 5535 static unsigned int 5536 srvfeatures(e, clientname, features) 5537 ENVELOPE *e; 5538 char *clientname; 5539 unsigned int features; 5540 { 5541 int r, i, j; 5542 char **pvp, c, opt; 5543 char pvpbuf[PSBUFSIZE]; 5544 5545 pvp = NULL; 5546 r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf, 5547 sizeof(pvpbuf)); 5548 if (r != EX_OK) 5549 return features; 5550 if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET) 5551 return features; 5552 if (pvp[1] != NULL && sm_strncasecmp(pvp[1], "temp", 4) == 0) 5553 return SRV_TMP_FAIL; 5554 5555 /* 5556 ** General rule (see sendmail.h, d_flags): 5557 ** lower case: required/offered, upper case: Not required/available 5558 ** 5559 ** Since we can change some features per daemon, we have both 5560 ** cases here: turn on/off a feature. 5561 */ 5562 5563 for (i = 1; pvp[i] != NULL; i++) 5564 { 5565 c = pvp[i][0]; 5566 j = 0; 5567 for (;;) 5568 { 5569 if ((opt = srv_feat_table[j].srvf_opt) == '\0') 5570 { 5571 if (LogLevel > 9) 5572 sm_syslog(LOG_WARNING, e->e_id, 5573 "srvfeatures: unknown feature %s", 5574 pvp[i]); 5575 break; 5576 } 5577 if (c == opt) 5578 { 5579 features &= ~(srv_feat_table[j].srvf_flag); 5580 break; 5581 } 5582 if (c == tolower(opt)) 5583 { 5584 features |= srv_feat_table[j].srvf_flag; 5585 break; 5586 } 5587 ++j; 5588 } 5589 } 5590 return features; 5591 } 5592 5593 /* 5594 ** HELP -- implement the HELP command. 5595 ** 5596 ** Parameters: 5597 ** topic -- the topic we want help for. 5598 ** e -- envelope. 5599 ** 5600 ** Returns: 5601 ** none. 5602 ** 5603 ** Side Effects: 5604 ** outputs the help file to message output. 5605 */ 5606 #define HELPVSTR "#vers " 5607 #define HELPVERSION 2 5608 5609 void 5610 help(topic, e) 5611 char *topic; 5612 ENVELOPE *e; 5613 { 5614 register SM_FILE_T *hf; 5615 register char *p; 5616 char *lstr; 5617 int len; 5618 bool noinfo; 5619 bool first = true; 5620 long sff = SFF_OPENASROOT|SFF_REGONLY; 5621 char buf[MAXLINE]; 5622 char inp[MAXLINE]; 5623 static int foundvers = -1; 5624 extern char Version[]; 5625 5626 if (DontLockReadFiles) 5627 sff |= SFF_NOLOCK; 5628 if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail)) 5629 sff |= SFF_SAFEDIRPATH; 5630 5631 if (HelpFile == NULL || 5632 (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL) 5633 { 5634 /* no help */ 5635 errno = 0; 5636 message("502 5.3.0 Sendmail %s -- HELP not implemented", 5637 Version); 5638 return; 5639 } 5640 5641 lstr = NULL; 5642 if (SM_IS_EMPTY(topic)) 5643 { 5644 topic = "smtp"; 5645 noinfo = false; 5646 } 5647 else 5648 { 5649 5650 lstr = makelower_a(&topic, NULL); 5651 if (lstr != topic) 5652 topic = lstr; 5653 else 5654 lstr = NULL; 5655 noinfo = true; 5656 } 5657 5658 len = strlen(topic); 5659 5660 while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) 5661 { 5662 if (buf[0] == '#') 5663 { 5664 if (foundvers < 0 && 5665 strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0) 5666 { 5667 int h; 5668 5669 if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d", 5670 &h) == 1) 5671 foundvers = h; 5672 } 5673 continue; 5674 } 5675 if (strncmp(buf, topic, len) == 0) 5676 { 5677 if (first) 5678 { 5679 first = false; 5680 5681 /* print version if no/old vers# in file */ 5682 if (foundvers < 2 && !noinfo) 5683 message("214-2.0.0 This is Sendmail version %s", Version); 5684 } 5685 p = strpbrk(buf, " \t"); 5686 if (p == NULL) 5687 p = buf + strlen(buf) - 1; 5688 else 5689 p++; 5690 fixcrlf(p, true); 5691 if (foundvers >= 2) 5692 { 5693 char *lbp; 5694 int lbs = sizeof(buf) - (p - buf); 5695 5696 lbp = translate_dollars(p, p, &lbs); 5697 expand(lbp, inp, sizeof(inp), e); 5698 if (p != lbp) 5699 sm_free(lbp); 5700 p = inp; 5701 } 5702 message("214-2.0.0 %s", p); 5703 noinfo = false; 5704 } 5705 } 5706 5707 if (noinfo) 5708 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic); 5709 else 5710 message("214 2.0.0 End of HELP info"); 5711 5712 if (foundvers != 0 && foundvers < HELPVERSION) 5713 { 5714 if (LogLevel > 1) 5715 sm_syslog(LOG_WARNING, e->e_id, 5716 "%s too old (require version %d)", 5717 HelpFile, HELPVERSION); 5718 5719 /* avoid log next time */ 5720 foundvers = 0; 5721 } 5722 5723 (void) sm_io_close(hf, SM_TIME_DEFAULT); 5724 SM_FREE(lstr); 5725 } 5726 5727 #if SASL 5728 /* 5729 ** RESET_SASLCONN -- reset SASL connection data 5730 ** 5731 ** Parameters: 5732 ** conn -- SASL connection context 5733 ** hostname -- host name 5734 ** various connection data 5735 ** 5736 ** Returns: 5737 ** SASL result 5738 */ 5739 5740 #ifdef __STDC__ 5741 static int 5742 reset_saslconn(sasl_conn_t **conn, char *hostname, 5743 # if SASL >= 20000 5744 char *remoteip, char *localip, 5745 char *auth_id, sasl_ssf_t * ext_ssf) 5746 # else /* SASL >= 20000 */ 5747 struct sockaddr_in *saddr_r, struct sockaddr_in *saddr_l, 5748 sasl_external_properties_t * ext_ssf) 5749 # endif /* SASL >= 20000 */ 5750 #else /* __STDC__ */ 5751 # ERROR "SASL requires __STDC__" 5752 #endif /* __STDC__ */ 5753 { 5754 int result; 5755 5756 sasl_dispose(conn); 5757 # if SASL >= 20000 5758 result = sasl_server_new("smtp", hostname, NULL, NULL, NULL, 5759 NULL, 0, conn); 5760 # elif SASL > 10505 5761 /* use empty realm: only works in SASL > 1.5.5 */ 5762 result = sasl_server_new("smtp", hostname, "", NULL, 0, conn); 5763 # else /* SASL >= 20000 */ 5764 /* use no realm -> realm is set to hostname by SASL lib */ 5765 result = sasl_server_new("smtp", hostname, NULL, NULL, 0, 5766 conn); 5767 # endif /* SASL >= 20000 */ 5768 if (result != SASL_OK) 5769 return result; 5770 5771 # if SASL >= 20000 5772 # if NETINET || NETINET6 5773 if (remoteip != NULL && *remoteip != '\0') 5774 result = sasl_setprop(*conn, SASL_IPREMOTEPORT, remoteip); 5775 if (result != SASL_OK) 5776 return result; 5777 5778 if (localip != NULL && *localip != '\0') 5779 result = sasl_setprop(*conn, SASL_IPLOCALPORT, localip); 5780 if (result != SASL_OK) 5781 return result; 5782 # endif /* NETINET || NETINET6 */ 5783 5784 result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf); 5785 if (result != SASL_OK) 5786 return result; 5787 5788 result = sasl_setprop(*conn, SASL_AUTH_EXTERNAL, auth_id); 5789 if (result != SASL_OK) 5790 return result; 5791 # else /* SASL >= 20000 */ 5792 # if NETINET 5793 if (saddr_r != NULL) 5794 result = sasl_setprop(*conn, SASL_IP_REMOTE, saddr_r); 5795 if (result != SASL_OK) 5796 return result; 5797 5798 if (saddr_l != NULL) 5799 result = sasl_setprop(*conn, SASL_IP_LOCAL, saddr_l); 5800 if (result != SASL_OK) 5801 return result; 5802 # endif /* NETINET */ 5803 5804 result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf); 5805 if (result != SASL_OK) 5806 return result; 5807 # endif /* SASL >= 20000 */ 5808 return SASL_OK; 5809 } 5810 5811 /* 5812 ** GET_SASL_USER -- extract user part from SASL reply 5813 ** 5814 ** Parameters: 5815 ** val -- sasl reply (may contain NUL) 5816 ** len -- length of val 5817 ** auth_type -- auth_type (can be NULL) 5818 ** user -- output buffer for extract user 5819 ** user_len -- length of output buffer (user) 5820 ** 5821 ** Returns: 5822 ** none. 5823 ** 5824 ** Note: val is supplied by the client and hence may contain "bad" 5825 ** (non-printable) characters, but the returned value (user) 5826 ** is only used for logging which converts those characters. 5827 */ 5828 5829 static void 5830 get_sasl_user(val, len, auth_type, user, user_len) 5831 char *val; 5832 unsigned int len; 5833 const char *auth_type; 5834 char *user; 5835 size_t user_len; 5836 { 5837 unsigned int u; 5838 5839 SM_ASSERT(val != NULL); 5840 SM_ASSERT(user != NULL); 5841 SM_ASSERT(user_len > 0); 5842 5843 *user = '\0'; 5844 if (SM_IS_EMPTY(auth_type)) 5845 return; 5846 if (0 == len) 5847 return; 5848 5849 # define DIGMD5U "username=\"" 5850 # define DIGMD5U_L (sizeof(DIGMD5U) - 1) 5851 if (SM_STRCASEEQ(auth_type, "digest-md5") && 5852 strncmp(val, DIGMD5U, DIGMD5U_L) == 0) 5853 { 5854 char *s; 5855 5856 val += DIGMD5U_L; 5857 if (len <= DIGMD5U_L) 5858 return; 5859 len -= DIGMD5U_L; 5860 5861 /* format? could there be a quoted '"'? */ 5862 for (s = val, u = 0; *s != '\0' && u < len; s++) 5863 { 5864 if ('"' == *s) 5865 { 5866 *s = '\0'; 5867 break; 5868 } 5869 if ('\\' == *s) 5870 { 5871 ++s; 5872 if ('\0' == *s) 5873 break; 5874 } 5875 } 5876 } 5877 else if (SM_STRCASEEQ(auth_type, "cram-md5")) 5878 { 5879 char *s; 5880 5881 for (s = val, u = 0; *s != '\0' && u < len; s++) 5882 { 5883 if (' ' == *s) 5884 { 5885 *s = '\0'; 5886 break; 5887 } 5888 } 5889 } 5890 5891 else if (SM_STRCASEEQ(auth_type, "plain") || 5892 SM_STRCASEEQ(auth_type, "login")) 5893 { 5894 /* 5895 ** RFC 4616: The PLAIN Simple Authentication and 5896 ** Security Layer (SASL) Mechanism 5897 ** message = [authzid] UTF8NUL authcid UTF8NUL passwd 5898 ** each part: 1*SAFE ; MUST accept up to 255 octets 5899 ** UTF8NUL = %x00 ; UTF-8 encoded NUL character 5900 ** 5901 ** draft-murchison-sasl-login: it's just username by its own 5902 */ 5903 5904 for (u = 0; u < len; u++) 5905 { 5906 if (val[u] == '\0') 5907 { 5908 val[u] = '/'; 5909 (void) sm_strlcpy(user, 5910 val + ((0 == u) ? 1 : 0), 5911 user_len); 5912 return; 5913 } 5914 } 5915 } 5916 else 5917 { 5918 /* 5919 ** Extracting the "user" from other mechanisms 5920 ** is currently not supported. 5921 */ 5922 5923 return; 5924 } 5925 5926 /* 5927 ** Does the input buffer has an NUL in it so it can be treated 5928 ** as a C string? 5929 */ 5930 5931 /* SM_ASSERT(len > 0); see above */ 5932 u = len - 1; 5933 if (val[u] != '\0') 5934 { 5935 for (u = 0; u < len; u++) 5936 { 5937 if (val[u] == '\0') 5938 break; 5939 } 5940 } 5941 if (val[u] != '\0') 5942 user_len = SM_MIN(len, user_len); 5943 5944 (void) sm_strlcpy(user, val, user_len); 5945 } 5946 #endif /* SASL */ 5947