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