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