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