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