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