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