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