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