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