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