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