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