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