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