2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
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.
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.
16 # include <libmilter/mfdef.h>
19 SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.829.2.22 2003/02/19 02:45:40 ca Exp $")
22 # include <sys/time.h>
24 #endif /* SASL || STARTTLS */
26 # define ENC64LEN(l) (((l) + 2) * 4 / 3 + 1)
27 static int saslmechs __P((sasl_conn_t *, char **));
30 # include <sysexits.h>
32 static SSL_CTX *srv_ctx = NULL; /* TLS server context */
33 static SSL *srv_ssl = NULL; /* per connection context */
35 static bool tls_ok_srv = false;
37 extern void tls_set_verify __P((SSL_CTX *, SSL *, bool));
38 # define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \
39 bitset(SRV_VRFY_CLT, features))
43 #define SRV_NONE 0x0000 /* none... */
44 #define SRV_OFFER_TLS 0x0001 /* offer STARTTLS */
45 #define SRV_VRFY_CLT 0x0002 /* request a cert */
46 #define SRV_OFFER_AUTH 0x0004 /* offer AUTH */
47 #define SRV_OFFER_ETRN 0x0008 /* offer ETRN */
48 #define SRV_OFFER_VRFY 0x0010 /* offer VRFY (not yet used) */
49 #define SRV_OFFER_EXPN 0x0020 /* offer EXPN */
50 #define SRV_OFFER_VERB 0x0040 /* offer VERB */
51 #define SRV_OFFER_DSN 0x0080 /* offer DSN */
53 # define SRV_OFFER_PIPE 0x0100 /* offer PIPELINING */
55 # define SRV_NO_PIPE 0x0200 /* disable PIPELINING, sleep if used */
56 # endif /* _FFR_NO_PIPE */
57 #endif /* PIPELINING */
58 #define SRV_REQ_AUTH 0x0400 /* require AUTH */
59 #define SRV_TMP_FAIL 0x1000 /* ruleset caused a temporary failure */
61 static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int));
63 static time_t checksmtpattack __P((volatile unsigned int *, int, bool,
65 static void mail_esmtp_args __P((char *, char *, ENVELOPE *));
66 static void printvrfyaddr __P((ADDRESS *, bool, bool));
67 static void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *));
68 static char *skipword __P((char *volatile, char *));
69 static void setup_smtpd_io __P((void));
70 extern ENVELOPE BlankEnvelope;
72 #define SKIP_SPACE(s) while (isascii(*s) && isspace(*s)) \
76 ** SMTP -- run the SMTP protocol.
79 ** nullserver -- if non-NULL, rejection message for
80 ** (almost) all SMTP commands.
81 ** d_flags -- daemon flags
88 ** Reads commands from the input channel and processes them.
92 ** Notice: The smtp server doesn't have a session context like the client
93 ** side has (mci). Therefore some data (session oriented) is allocated
94 ** or assigned to the "wrong" structure (esp. STARTTLS, AUTH).
95 ** This should be fixed in a successor version.
100 char *cmd_name; /* command name */
101 int cmd_code; /* internal code, see below */
104 /* values for cmd_code */
105 #define CMDERROR 0 /* bad command */
106 #define CMDMAIL 1 /* mail -- designate sender */
107 #define CMDRCPT 2 /* rcpt -- designate recipient */
108 #define CMDDATA 3 /* data -- send message text */
109 #define CMDRSET 4 /* rset -- reset state */
110 #define CMDVRFY 5 /* vrfy -- verify address */
111 #define CMDEXPN 6 /* expn -- expand address */
112 #define CMDNOOP 7 /* noop -- do nothing */
113 #define CMDQUIT 8 /* quit -- close connection and die */
114 #define CMDHELO 9 /* helo -- be polite */
115 #define CMDHELP 10 /* help -- give usage info */
116 #define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */
117 #define CMDETRN 12 /* etrn -- flush queue */
119 # define CMDAUTH 13 /* auth -- SASL authenticate */
122 # define CMDSTLS 14 /* STARTTLS -- start TLS session */
123 #endif /* STARTTLS */
124 /* non-standard commands */
125 #define CMDVERB 17 /* verb -- go into verbose mode */
126 /* unimplemented commands from RFC 821 */
127 #define CMDUNIMPL 19 /* unimplemented rfc821 commands */
128 /* use this to catch and log "door handle" attempts on your system */
129 #define CMDLOGBOGUS 23 /* bogus command that should be logged */
130 /* debugging-only commands, only enabled if SMTPDEBUG is defined */
131 #define CMDDBGQSHOW 24 /* showq -- show send queue */
132 #define CMDDBGDEBUG 25 /* debug -- set debug mode */
135 ** Note: If you change this list, remember to update 'helpfile'
138 static struct cmd CmdTab[] =
153 { "send", CMDUNIMPL },
154 { "saml", CMDUNIMPL },
155 { "soml", CMDUNIMPL },
156 { "turn", CMDUNIMPL },
158 { "auth", CMDAUTH, },
161 { "starttls", CMDSTLS, },
162 #endif /* STARTTLS */
163 /* remaining commands are here only to trap and log attempts to use them */
164 { "showq", CMDDBGQSHOW },
165 { "debug", CMDDBGDEBUG },
166 { "wiz", CMDLOGBOGUS },
171 static char *CurSmtpClient; /* who's at the other end of channel */
173 #ifndef MAXBADCOMMANDS
174 # define MAXBADCOMMANDS 25 /* maximum number of bad commands */
175 #endif /* ! MAXBADCOMMANDS */
176 #ifndef MAXNOOPCOMMANDS
177 # define MAXNOOPCOMMANDS 20 /* max "noise" commands before slowdown */
178 #endif /* ! MAXNOOPCOMMANDS */
179 #ifndef MAXHELOCOMMANDS
180 # define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */
181 #endif /* ! MAXHELOCOMMANDS */
182 #ifndef MAXVRFYCOMMANDS
183 # define MAXVRFYCOMMANDS 6 /* max VRFY/EXPN commands before slowdown */
184 #endif /* ! MAXVRFYCOMMANDS */
185 #ifndef MAXETRNCOMMANDS
186 # define MAXETRNCOMMANDS 8 /* max ETRN commands before slowdown */
187 #endif /* ! MAXETRNCOMMANDS */
189 # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */
190 #endif /* ! MAXTIMEOUT */
193 static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp",
194 "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $");
195 #endif /* SM_HEAP_CHECK */
199 bool sm_gotmail; /* mail command received */
200 unsigned int sm_nrcpts; /* number of successful RCPT commands */
201 #if _FFR_ADAPTIVE_EOL
202 WARNING: do NOT use this FFR, it is most likely broken
203 bool sm_crlf; /* input in CRLF form? */
204 #endif /* _FFR_ADAPTIVE_EOL */
208 bool sm_milterlist; /* any filters in the list? */
211 char *sm_quarmsg; /* carry quarantining across messages */
212 #endif /* _FFR_QUARANTINE */
215 static void smtp_data __P((SMTP_T *, ENVELOPE *));
217 #define MSG_TEMPFAIL "451 4.7.1 Please try again later"
220 # define MILTER_ABORT(e) milter_abort((e))
223 # define MILTER_SHUTDOWN \
224 if (strncmp(response, "421 ", 4) == 0) \
226 e->e_sendqueue = NULL; \
229 #else /* _FFR_MILTER_421 */
230 # define MILTER_SHUTDOWN
231 #endif /* _FFR_MILTER_421 */
233 # define MILTER_REPLY(str) \
235 int savelogusrerrs = LogUsrErrs; \
239 case SMFIR_REPLYCODE: \
240 if (MilterLogLevel > 3) \
242 sm_syslog(LOG_INFO, e->e_id, \
243 "Milter: %s=%s, reject=%s", \
244 str, addr, response); \
245 LogUsrErrs = false; \
252 if (MilterLogLevel > 3) \
254 sm_syslog(LOG_INFO, e->e_id, \
255 "Milter: %s=%s, reject=550 5.7.1 Command rejected", \
257 LogUsrErrs = false; \
259 usrerr("550 5.7.1 Command rejected"); \
262 case SMFIR_DISCARD: \
263 if (MilterLogLevel > 3) \
264 sm_syslog(LOG_INFO, e->e_id, \
265 "Milter: %s=%s, discard", \
267 e->e_flags |= EF_DISCARD; \
270 case SMFIR_TEMPFAIL: \
271 if (MilterLogLevel > 3) \
273 sm_syslog(LOG_INFO, e->e_id, \
274 "Milter: %s=%s, reject=%s", \
275 str, addr, MSG_TEMPFAIL); \
276 LogUsrErrs = false; \
278 usrerr(MSG_TEMPFAIL); \
281 LogUsrErrs = savelogusrerrs; \
282 if (response != NULL) \
283 sm_free(response); /* XXX */ \
287 # define MILTER_ABORT(e)
290 /* clear all SMTP state (for HELO/EHLO/RSET) */
291 #define CLEAR_STATE(cmd) \
293 /* abort milter filters */ \
296 if (smtp.sm_nrcpts > 0) \
298 logundelrcpts(e, cmd, 10, false); \
299 smtp.sm_nrcpts = 0; \
300 macdefine(&e->e_macro, A_PERM, \
301 macid("{nrcpts}"), "0"); \
304 e->e_sendqueue = NULL; \
305 e->e_flags |= EF_CLRQUEUE; \
307 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) \
308 logsender(e, NULL); \
309 e->e_flags &= ~EF_LOGSENDER; \
311 /* clean up a bit */ \
312 smtp.sm_gotmail = false; \
314 dropenvelope(e, true, false); \
315 sm_rpool_free(e->e_rpool); \
316 e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \
320 /* sleep to flatten out connection load */
321 #define MIN_DELAY_LOG 15 /* wait before logging this again */
323 /* is it worth setting the process title for 1s? */
324 #define DELAY_CONN(cmd) \
325 if (DelayLA > 0 && (CurrentLA = getla()) >= DelayLA) \
329 sm_setproctitle(true, e, \
330 "%s: %s: delaying %s: load average: %d", \
331 qid_printname(e), CurSmtpClient, \
333 if (LogLevel > 8 && (dnow = curtime()) > log_delay) \
335 sm_syslog(LOG_INFO, e->e_id, \
336 "delaying=%s, load average=%d >= %d", \
337 cmd, CurrentLA, DelayLA); \
338 log_delay = dnow + MIN_DELAY_LOG; \
341 sm_setproctitle(true, e, "%s %s: %.80s", \
342 qid_printname(e), CurSmtpClient, inp); \
347 smtp(nullserver, d_flags, e)
348 char *volatile nullserver;
350 register ENVELOPE *volatile e;
352 register char *volatile p;
353 register struct cmd *volatile c = NULL;
355 auto ADDRESS *vrfyqueue;
357 volatile bool gothello; /* helo command received */
358 bool vrfy; /* set if this is a vrfy command */
359 char *volatile protocol; /* sending protocol */
360 char *volatile sendinghost; /* sending hostname */
361 char *volatile peerhostname; /* name of SMTP peer or "localhost" */
364 volatile unsigned int n_badcmds = 0; /* count of bad commands */
365 volatile unsigned int n_badrcpts = 0; /* number of rejected RCPT */
366 volatile unsigned int n_verifies = 0; /* count of VRFY/EXPN */
367 volatile unsigned int n_etrn = 0; /* count of ETRN */
368 volatile unsigned int n_noop = 0; /* count of NOOP/VERB/etc */
369 volatile unsigned int n_helo = 0; /* count of HELO/EHLO */
371 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
373 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
374 volatile bool tempfail = false;
375 volatile time_t wt; /* timeout after too many commands */
376 volatile time_t previous; /* time after checksmtpattack() */
377 volatile bool lognullconnection = true;
381 char *greetcode = "220";
382 char *hostname; /* my hostname ($j) */
385 char *args[MAXSMTPARGS];
387 char cmdbuf[MAXLINE];
390 volatile bool sasl_ok;
391 volatile unsigned int n_auth = 0; /* count of AUTH commands */
394 volatile int authenticating;
401 # else /* SASL >= 20000 */
404 sasl_external_properties_t ext_ssf;
405 # endif /* SASL >= 20000 */
406 sasl_security_properties_t ssp;
408 unsigned int inlen, out2len;
410 char *volatile auth_type;
412 volatile unsigned int n_mechs;
418 volatile bool tls_active = false;
420 volatile bool smtps = false;
421 # endif /* _FFR_SMTP_SSL */
425 #endif /* STARTTLS */
426 volatile unsigned int features;
430 # endif /* _FFR_NO_PIPE */
431 #endif /* PIPELINING */
432 volatile time_t log_delay = (time_t) 0;
436 smtp.sm_milterize = (nullserver == NULL);
437 smtp.sm_milterlist = false;
440 /* setup I/O fd correctly for the SMTP server */
444 if (sm_debug_active(&DebugLeakSmtp, 1))
447 sm_dprintf("smtp() heap group #%d\n", sm_heap_group());
449 #endif /* SM_HEAP_CHECK */
451 /* XXX the rpool should be set when e is initialized in main() */
452 e->e_rpool = sm_rpool_new_x(NULL);
453 e->e_macro.mac_rpool = e->e_rpool;
457 peerhostname = RealHostName;
458 if (peerhostname == NULL)
459 peerhostname = "localhost";
460 CurHostName = peerhostname;
461 CurSmtpClient = macvalue('_', e);
462 if (CurSmtpClient == NULL)
463 CurSmtpClient = CurHostName;
465 /* check_relay may have set discard bit, save for later */
466 smtp.sm_discard = bitset(EF_DISCARD, e->e_flags);
469 /* auto-flush output when reading input */
470 (void) sm_io_autoflush(InChannel, OutChannel);
471 #endif /* PIPELINING */
473 sm_setproctitle(true, e, "server %s startup", CurSmtpClient);
475 /* Set default features for server. */
476 features = ((bitset(PRIV_NOETRN, PrivacyFlags) ||
477 bitnset(D_NOETRN, d_flags)) ? SRV_NONE : SRV_OFFER_ETRN)
478 | (bitnset(D_AUTHREQ, d_flags) ? SRV_REQ_AUTH : SRV_NONE)
479 | (bitset(PRIV_NOEXPN, PrivacyFlags) ? SRV_NONE
481 | (bitset(PRIV_NOVERB, PrivacyFlags)
482 ? SRV_NONE : SRV_OFFER_VERB)))
483 | (bitset(PRIV_NORECEIPTS, PrivacyFlags) ? SRV_NONE
486 | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH)
490 #endif /* PIPELINING */
492 | (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS)
493 | (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE
495 #endif /* STARTTLS */
497 if (nullserver == NULL)
499 features = srvfeatures(e, CurSmtpClient, features);
500 if (bitset(SRV_TMP_FAIL, features))
503 sm_syslog(LOG_ERR, NOQID,
504 "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled",
506 nullserver = "450 4.3.0 Please try again later.";
510 else if (bitset(SRV_NO_PIPE, features))
512 /* for consistency */
513 features &= ~SRV_OFFER_PIPE;
515 # endif /* _FFR_NO_PIPE */
516 #endif /* PIPELINING */
519 hostname = macvalue('j', e);
521 sasl_ok = bitset(SRV_OFFER_AUTH, features);
523 authenticating = SASL_NOT_AUTH;
525 /* SASL server new connection */
529 result = sasl_server_new("smtp", hostname, NULL, NULL, NULL,
532 /* use empty realm: only works in SASL > 1.5.5 */
533 result = sasl_server_new("smtp", hostname, "", NULL, 0, &conn);
534 # else /* SASL >= 20000 */
535 /* use no realm -> realm is set to hostname by SASL lib */
536 result = sasl_server_new("smtp", hostname, NULL, NULL, 0,
538 # endif /* SASL >= 20000 */
539 sasl_ok = result == SASL_OK;
543 sm_syslog(LOG_WARNING, NOQID,
544 "AUTH error: sasl_server_new failed=%d",
551 ** SASL set properties for sasl
552 ** set local/remote IP
553 ** XXX Cyrus SASL v1 only supports IPv4
555 ** XXX where exactly are these used/required?
560 # if NETINET || NETINET6
561 in = macvalue(macid("{daemon_family}"), e);
564 strcmp(in, "inet6") == 0 ||
565 # endif /* NETINET6 */
566 strcmp(in, "inet") == 0))
568 SOCKADDR_LEN_T addrsize;
571 char localip[60], remoteip[60];
573 addrsize = sizeof(saddr_r);
574 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
576 (struct sockaddr *) &saddr_r,
579 if (iptostring(&saddr_r, addrsize,
580 remoteip, sizeof remoteip))
582 sasl_setprop(conn, SASL_IPREMOTEPORT,
585 addrsize = sizeof(saddr_l);
586 if (getsockname(sm_io_getinfo(InChannel,
589 (struct sockaddr *) &saddr_l,
592 if (iptostring(&saddr_l, addrsize,
603 # endif /* NETINET || NETINET6 */
604 # else /* SASL >= 20000 */
606 in = macvalue(macid("{daemon_family}"), e);
607 if (in != NULL && strcmp(in, "inet") == 0)
609 SOCKADDR_LEN_T addrsize;
610 struct sockaddr_in saddr_l;
611 struct sockaddr_in saddr_r;
613 addrsize = sizeof(struct sockaddr_in);
614 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
616 (struct sockaddr *)&saddr_r,
619 sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r);
620 addrsize = sizeof(struct sockaddr_in);
621 if (getsockname(sm_io_getinfo(InChannel,
624 (struct sockaddr *)&saddr_l,
626 sasl_setprop(conn, SASL_IP_LOCAL,
630 # endif /* NETINET */
631 # endif /* SASL >= 20000 */
637 macdefine(&BlankEnvelope.e_macro, A_PERM,
638 macid("{auth_author}"), NULL);
642 (void) memset(&ssp, '\0', sizeof ssp);
644 /* XXX should these be options settable via .cf ? */
645 /* ssp.min_ssf = 0; is default due to memset() */
647 # endif /* STARTTLS */
649 ssp.max_ssf = MaxSLBits;
650 ssp.maxbufsize = MAXOUTLEN;
652 ssp.security_flags = SASLOpts & SASL_SEC_MASK;
653 sasl_ok = sasl_setprop(conn, SASL_SEC_PROPS, &ssp) == SASL_OK;
658 ** external security strength factor;
659 ** currently we have none so zero
665 sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL,
666 &ext_ssf) == SASL_OK) &&
667 (sasl_setprop(conn, SASL_AUTH_EXTERNAL,
668 auth_id) == SASL_OK));
669 # else /* SASL >= 20000 */
671 ext_ssf.auth_id = NULL;
672 sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
673 &ext_ssf) == SASL_OK;
674 # endif /* SASL >= 20000 */
677 n_mechs = saslmechs(conn, &mechlist);
682 if (smtp.sm_milterize)
686 /* initialize mail filter connection */
687 smtp.sm_milterlist = milter_init(e, &state);
691 if (MilterLogLevel > 3)
692 sm_syslog(LOG_INFO, e->e_id,
693 "Milter: initialization failed, rejecting commands");
695 nullserver = "Command rejected";
696 smtp.sm_milterize = false;
700 if (MilterLogLevel > 3)
701 sm_syslog(LOG_INFO, e->e_id,
702 "Milter: initialization failed, temp failing commands");
704 smtp.sm_milterize = false;
709 if (smtp.sm_milterlist && smtp.sm_milterize &&
710 !bitset(EF_DISCARD, e->e_flags))
715 response = milter_connect(peerhostname, RealHostAddr,
719 case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
721 if (MilterLogLevel > 3)
722 sm_syslog(LOG_INFO, e->e_id,
723 "Milter: connect: host=%s, addr=%s, rejecting commands",
725 anynet_ntoa(&RealHostAddr));
727 nullserver = "Command rejected";
728 smtp.sm_milterize = false;
732 if (MilterLogLevel > 3)
733 sm_syslog(LOG_INFO, e->e_id,
734 "Milter: connect: host=%s, addr=%s, temp failing commands",
736 anynet_ntoa(&RealHostAddr));
738 smtp.sm_milterize = false;
743 if (MilterLogLevel > 3)
744 sm_syslog(LOG_INFO, e->e_id,
745 "Milter: connect: host=%s, addr=%s, shutdown",
747 anynet_ntoa(&RealHostAddr));
749 smtp.sm_milterize = false;
750 message("421 4.7.0 %s closing connection",
753 /* arrange to ignore send list */
754 e->e_sendqueue = NULL;
756 #endif /* _FFR_MILTER_421 */
758 if (response != NULL)
760 sm_free(response); /* XXX */
766 /* If this an smtps connection, start TLS now */
767 smtps = bitnset(D_SMTPS, d_flags);
773 # endif /* _FFR_SMTP_SSL */
774 #endif /* STARTTLS */
776 /* output the first line, inserting "ESMTP" as second word */
777 if (*greetcode == '5')
778 (void) sm_snprintf(inp, sizeof inp, "%s not accepting messages",
781 expand(SmtpGreeting, inp, sizeof inp, e);
783 p = strchr(inp, '\n');
786 id = strchr(inp, ' ');
788 id = &inp[strlen(inp)];
790 (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
791 "%s %%.*s ESMTP%%s", greetcode);
793 (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
794 "%s-%%.*s ESMTP%%s", greetcode);
795 message(cmdbuf, (int) (id - inp), inp, id);
797 /* output remaining lines */
798 while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
801 if (isascii(*id) && isspace(*id))
803 (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, "-%s");
808 if (isascii(*id) && isspace(*id))
810 (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, " %s");
815 sendinghost = macvalue('s', e);
818 /* If quarantining by a connect/ehlo action, save between messages */
819 if (e->e_quarmsg == NULL)
820 smtp.sm_quarmsg = NULL;
822 smtp.sm_quarmsg = newstr(e->e_quarmsg);
823 #endif /* _FFR_QUARANTINE */
825 /* sendinghost's storage must outlive the current envelope */
826 if (sendinghost != NULL)
827 sendinghost = sm_strdup_x(sendinghost);
828 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
830 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
832 smtp.sm_gotmail = false;
842 e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
844 /* setup for the read */
848 (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
850 /* read the input line */
851 SmtpPhase = "server cmd read";
852 sm_setproctitle(true, e, "server %s cmd read", CurSmtpClient);
855 ** XXX SMTP AUTH requires accepting any length,
856 ** at least for challenge/response
861 if (sm_io_error(OutChannel) ||
862 (p = sfgets(inp, sizeof inp, InChannel,
863 TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
867 d = macvalue(macid("{daemon_name}"), e);
870 /* end of file, just die */
874 /* close out milter filters */
878 message("421 4.4.1 %s Lost input channel from %s",
879 MyHostName, CurSmtpClient);
880 if (LogLevel > (smtp.sm_gotmail ? 1 : 19))
881 sm_syslog(LOG_NOTICE, e->e_id,
882 "lost input channel from %s to %s after %s",
884 (c == NULL || c->cmd_name == NULL) ? "startup" : c->cmd_name);
886 ** If have not accepted mail (DATA), do not bounce
887 ** bad addresses back to sender.
890 if (bitset(EF_CLRQUEUE, e->e_flags))
891 e->e_sendqueue = NULL;
895 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
898 #if _FFR_BLOCK_PROXIES
899 size_t inplen, cmdlen;
902 static char *http_cmds[] = { "GET", "POST",
903 "CONNECT", "USER", NULL };
905 inplen = strlen(inp);
906 for (idx = 0; (http_cmd = http_cmds[idx]) != NULL;
909 cmdlen = strlen(http_cmd);
910 if (cmdlen < inplen &&
911 sm_strncasecmp(inp, http_cmd, cmdlen) == 0 &&
912 isascii(inp[cmdlen]) && isspace(inp[cmdlen]))
914 /* Open proxy, drop it */
915 message("421 4.7.0 %s Rejecting open proxy %s",
916 MyHostName, CurSmtpClient);
917 sm_syslog(LOG_INFO, e->e_id,
918 "%s: probable open proxy: command=%.40s",
923 #endif /* _FFR_BLOCK_PROXIES */
924 #if _FFR_ADAPTIVE_EOL
928 p = strchr(inp, '\n');
929 if (p == NULL || p <= inp || p[-1] != '\r')
931 smtp.sm_crlf = false;
932 if (tTd(66, 1) && LogLevel > 8)
934 /* how many bad guys are there? */
935 sm_syslog(LOG_INFO, NOQID,
936 "%s did not use CRLF",
940 #endif /* _FFR_ADAPTIVE_EOL */
943 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
945 /* clean up end of line */
951 ** if there is more input and pipelining is disabled:
952 ** delay ... (and maybe discard the input?)
953 ** XXX this doesn't really work, at least in tests using
954 ** telnet SM_IO_IS_READABLE only returns 1 if there were
955 ** more than 2 input lines available.
958 if (bitset(SRV_NO_PIPE, features) &&
959 sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0)
962 sm_syslog(LOG_INFO, NOQID,
963 "unauthorized PIPELINING, sleeping");
967 # endif /* _FFR_NO_PIPE */
968 #endif /* PIPELINING */
971 if (authenticating == SASL_PROC_AUTH)
976 authenticating = SASL_NOT_AUTH;
977 message("501 5.5.2 missing input");
981 if (*inp == '*' && *(inp + 1) == '\0')
983 authenticating = SASL_NOT_AUTH;
986 message("501 5.0.0 AUTH aborted");
990 /* could this be shorter? XXX */
992 in = xalloc(strlen(inp) + 1);
993 result = sasl_decode64(inp, strlen(inp), in,
994 strlen(inp), &inlen);
995 # else /* SASL >= 20000 */
996 out = xalloc(strlen(inp));
997 result = sasl_decode64(inp, strlen(inp), out, &outlen);
998 # endif /* SASL >= 20000 */
999 if (result != SASL_OK)
1001 authenticating = SASL_NOT_AUTH;
1004 message("501 5.5.4 cannot decode AUTH parameter %s",
1008 # endif /* SASL >= 20000 */
1013 result = sasl_server_step(conn, in, inlen,
1016 # else /* SASL >= 20000 */
1017 result = sasl_server_step(conn, out, outlen,
1018 &out, &outlen, &errstr);
1019 # endif /* SASL >= 20000 */
1021 /* get an OK if we're done */
1022 if (result == SASL_OK)
1025 message("235 2.0.0 OK Authenticated");
1026 authenticating = SASL_IS_AUTH;
1027 macdefine(&BlankEnvelope.e_macro, A_TEMP,
1028 macid("{auth_type}"), auth_type);
1031 user = macvalue(macid("{auth_authen}"), e);
1033 /* get security strength (features) */
1034 result = sasl_getprop(conn, SASL_SSF,
1035 (const void **) &ssf);
1036 # else /* SASL >= 20000 */
1037 result = sasl_getprop(conn, SASL_USERNAME,
1039 if (result != SASL_OK)
1042 macdefine(&BlankEnvelope.e_macro,
1044 macid("{auth_authen}"), NULL);
1048 macdefine(&BlankEnvelope.e_macro,
1050 macid("{auth_authen}"), user);
1055 sasl_getprop(conn, SASL_REALM, (void **) &data);
1058 /* get security strength (features) */
1059 result = sasl_getprop(conn, SASL_SSF,
1061 # endif /* SASL >= 20000 */
1062 if (result != SASL_OK)
1064 macdefine(&BlankEnvelope.e_macro,
1066 macid("{auth_ssf}"), "0");
1073 (void) sm_snprintf(pbuf, sizeof pbuf,
1075 macdefine(&BlankEnvelope.e_macro,
1077 macid("{auth_ssf}"), pbuf);
1079 sm_dprintf("AUTH auth_ssf: %u\n",
1084 ** Only switch to encrypted connection
1085 ** if a security layer has been negotiated
1088 if (ssf != NULL && *ssf > 0)
1091 ** Convert I/O layer to use SASL.
1092 ** If the call fails, the connection
1096 if (sfdcsasl(&InChannel, &OutChannel,
1099 /* restart dialogue */
1102 (void) sm_io_autoflush(InChannel,
1104 # endif /* PIPELINING */
1107 syserr("503 5.3.3 SASL TLS failed");
1110 /* NULL pointer ok since it's our function */
1112 sm_syslog(LOG_INFO, NOQID,
1113 "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d",
1115 shortenstring(user, 128),
1118 else if (result == SASL_CONTINUE)
1120 len = ENC64LEN(outlen);
1122 result = sasl_encode64(out, outlen, out2, len,
1124 if (result != SASL_OK)
1126 /* correct code? XXX */
1127 /* 454 Temp. authentication failure */
1128 message("454 4.5.4 Internal error: unable to encode64");
1130 sm_syslog(LOG_WARNING, e->e_id,
1131 "AUTH encode64 error [%d for \"%s\"]",
1134 authenticating = SASL_NOT_AUTH;
1138 message("334 %s", out2);
1140 sm_dprintf("AUTH continue: msg='%s' len=%u\n",
1145 # endif /* SASL >= 20000 */
1149 /* not SASL_OK or SASL_CONT */
1150 message("535 5.7.0 authentication failed");
1152 sm_syslog(LOG_WARNING, e->e_id,
1153 "AUTH failure (%s): %s (%d) %s",
1155 sasl_errstring(result, NULL,
1159 sasl_errdetail(conn));
1160 # else /* SASL >= 20000 */
1161 errstr == NULL ? "" : errstr);
1162 # endif /* SASL >= 20000 */
1163 authenticating = SASL_NOT_AUTH;
1168 /* don't want to do any of this if authenticating */
1171 /* echo command to transcript */
1172 if (e->e_xfp != NULL)
1173 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
1177 sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp);
1179 /* break off command */
1180 for (p = inp; isascii(*p) && isspace(*p); p++)
1183 while (*p != '\0' &&
1184 !(isascii(*p) && isspace(*p)) &&
1185 cmd < &cmdbuf[sizeof cmdbuf - 2])
1189 /* throw away leading whitespace */
1192 /* decode command */
1193 for (c = CmdTab; c->cmd_name != NULL; c++)
1195 if (sm_strcasecmp(c->cmd_name, cmdbuf) == 0)
1202 /* check whether a "non-null" command has been used */
1203 switch (c->cmd_code)
1207 /* avoid information leak; take first two words? */
1216 lognullconnection = false;
1223 if (e->e_id == NULL)
1224 sm_setproctitle(true, e, "%s: %.80s",
1227 sm_setproctitle(true, e, "%s %s: %.80s",
1234 ** If we are running as a null server, return 550
1235 ** to almost everything.
1238 if (nullserver != NULL || bitnset(D_ETRNONLY, d_flags))
1240 switch (c->cmd_code)
1247 /* process normally */
1251 if (bitnset(D_ETRNONLY, d_flags) &&
1258 #if MAXBADCOMMANDS > 0
1259 /* theoretically this could overflow */
1260 if (nullserver != NULL &&
1261 ++n_badcmds > MAXBADCOMMANDS)
1263 message("421 4.7.0 %s Too many bad commands; closing connection",
1266 /* arrange to ignore send list */
1267 e->e_sendqueue = NULL;
1270 #endif /* MAXBADCOMMANDS > 0 */
1271 if (nullserver != NULL)
1273 if (ISSMTPREPLY(nullserver))
1276 usrerr("550 5.0.0 %s",
1280 usrerr("452 4.4.5 Insufficient disk space; try again later");
1285 switch (c->cmd_code)
1288 case CMDAUTH: /* sasl */
1290 if (!sasl_ok || n_mechs <= 0)
1292 message("503 5.3.3 AUTH not available");
1295 if (authenticating == SASL_IS_AUTH)
1297 message("503 5.5.0 Already Authenticated");
1300 if (smtp.sm_gotmail)
1302 message("503 5.5.0 AUTH not permitted during a mail transaction");
1308 sm_syslog(LOG_INFO, e->e_id,
1309 "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)",
1311 usrerr("454 4.7.1 Please try again later");
1317 /* crude way to avoid crack attempts */
1318 (void) checksmtpattack(&n_auth, n_mechs + 1, true,
1321 /* make sure mechanism (p) is a valid string */
1322 for (q = p; *q != '\0' && isascii(*q); q++)
1327 while (*++q != '\0' &&
1328 isascii(*q) && isspace(*q))
1331 ismore = (*q != '\0');
1338 message("501 5.5.2 AUTH mechanism must be specified");
1342 /* check whether mechanism is available */
1343 if (iteminlist(p, mechlist, " ") == NULL)
1345 message("504 5.3.3 AUTH mechanism %.32s not available",
1352 /* could this be shorter? XXX */
1354 in = xalloc(strlen(q) + 1);
1355 result = sasl_decode64(q, strlen(q), in,
1357 # else /* SASL >= 20000 */
1358 in = sm_rpool_malloc(e->e_rpool, strlen(q));
1359 result = sasl_decode64(q, strlen(q), in,
1361 # endif /* SASL >= 20000 */
1362 if (result != SASL_OK)
1364 message("501 5.5.4 cannot BASE64 decode '%s'",
1367 sm_syslog(LOG_WARNING, e->e_id,
1368 "AUTH decode64 error [%d for \"%s\"]",
1371 authenticating = SASL_NOT_AUTH;
1374 # endif /* SASL >= 20000 */
1386 /* see if that auth type exists */
1388 result = sasl_server_start(conn, p, in, inlen,
1392 # else /* SASL >= 20000 */
1393 result = sasl_server_start(conn, p, in, inlen,
1394 &out, &outlen, &errstr);
1395 # endif /* SASL >= 20000 */
1397 if (result != SASL_OK && result != SASL_CONTINUE)
1399 message("535 5.7.0 authentication failed");
1401 sm_syslog(LOG_ERR, e->e_id,
1402 "AUTH failure (%s): %s (%d) %s",
1404 sasl_errstring(result, NULL,
1408 sasl_errdetail(conn));
1409 # else /* SASL >= 20000 */
1411 # endif /* SASL >= 20000 */
1414 auth_type = newstr(p);
1416 if (result == SASL_OK)
1418 /* ugly, but same code */
1420 /* authenticated by the initial response */
1423 /* len is at least 2 */
1424 len = ENC64LEN(outlen);
1426 result = sasl_encode64(out, outlen, out2, len,
1429 if (result != SASL_OK)
1431 message("454 4.5.4 Temporary authentication failure");
1433 sm_syslog(LOG_WARNING, e->e_id,
1434 "AUTH encode64 error [%d for \"%s\"]",
1438 authenticating = SASL_NOT_AUTH;
1442 message("334 %s", out2);
1443 authenticating = SASL_PROC_AUTH;
1447 # endif /* SASL >= 20000 */
1452 case CMDSTLS: /* starttls */
1453 DELAY_CONN("STARTTLS");
1456 message("501 5.5.2 Syntax error (no parameters allowed)");
1459 if (!bitset(SRV_OFFER_TLS, features))
1461 message("503 5.5.0 TLS not available");
1466 message("454 4.3.3 TLS not available after start");
1469 if (smtp.sm_gotmail)
1471 message("503 5.5.0 TLS not permitted during a mail transaction");
1477 sm_syslog(LOG_INFO, e->e_id,
1478 "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)",
1480 usrerr("454 4.7.1 Please try again later");
1485 # endif /* _FFR_SMTP_SSL */
1488 ** XXX do we need a temp key ?
1490 # else /* TLS_NO_RSA */
1491 # endif /* TLS_NO_RSA */
1493 # if TLS_VRFY_PER_CTX
1495 ** Note: this sets the verification globally
1497 ** it's ok since it applies only to one transaction
1500 TLS_VERIFY_CLIENT();
1501 # endif /* TLS_VRFY_PER_CTX */
1503 if (srv_ssl != NULL)
1505 else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
1507 message("454 4.3.3 TLS not available: error generating SSL handle");
1510 # else /* _FFR_SMTP_SSL */
1512 # endif /* _FFR_SMTP_SSL */
1515 # if !TLS_VRFY_PER_CTX
1517 ** this could be used if it were possible to set
1518 ** verification per SSL (connection)
1519 ** not just per SSL_CTX (global)
1522 TLS_VERIFY_CLIENT();
1523 # endif /* !TLS_VRFY_PER_CTX */
1525 rfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
1526 wfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
1528 if (rfd < 0 || wfd < 0 ||
1529 SSL_set_rfd(srv_ssl, rfd) <= 0 ||
1530 SSL_set_wfd(srv_ssl, wfd) <= 0)
1532 message("454 4.3.3 TLS not available: error set fd");
1537 # else /* _FFR_SMTP_SSL */
1539 # endif /* _FFR_SMTP_SSL */
1543 # endif /* _FFR_SMTP_SSL */
1544 message("220 2.0.0 Ready to start TLS");
1546 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
1547 # endif /* PIPELINING */
1549 SSL_set_accept_state(srv_ssl);
1551 # define SSL_ACC(s) SSL_accept(s)
1553 tlsstart = curtime();
1555 if ((r = SSL_ACC(srv_ssl)) <= 0)
1560 time_t now = curtime();
1563 /* what to do in this case? */
1564 i = SSL_get_error(srv_ssl, r);
1567 ** For SSL_ERROR_WANT_{READ,WRITE}:
1568 ** There is no SSL record available yet
1569 ** or there is only a partial SSL record
1570 ** removed from the network (socket) buffer
1571 ** into the SSL buffer. The SSL_accept will
1572 ** only succeed when a full SSL record is
1573 ** available (assuming a "real" error
1574 ** doesn't happen). To handle when a "real"
1575 ** error does happen the select is set for
1577 ** The connection may be re-negotiated
1578 ** during this time so both read and write
1579 ** "want errors" need to be handled.
1580 ** A select() exception loops back so that
1581 ** a proper SSL error message can be gotten.
1584 left = TimeOuts.to_starttls - (now - tlsstart);
1585 timedout = left <= 0;
1592 if (!timedout && FD_SETSIZE > 0 &&
1593 (rfd >= FD_SETSIZE ||
1594 (i == SSL_ERROR_WANT_WRITE &&
1595 wfd >= FD_SETSIZE)))
1599 sm_syslog(LOG_ERR, NOQID,
1600 "STARTTLS=server, error: fd %d/%d too large",
1603 tlslogerr("server");
1608 /* XXX what about SSL_pending() ? */
1609 if (!timedout && i == SSL_ERROR_WANT_READ)
1611 fd_set ssl_maskr, ssl_maskx;
1613 FD_ZERO(&ssl_maskr);
1614 FD_SET(rfd, &ssl_maskr);
1615 FD_ZERO(&ssl_maskx);
1616 FD_SET(rfd, &ssl_maskx);
1617 if (select(rfd + 1, &ssl_maskr, NULL,
1618 &ssl_maskx, &tv) > 0)
1621 if (!timedout && i == SSL_ERROR_WANT_WRITE)
1623 fd_set ssl_maskw, ssl_maskx;
1625 FD_ZERO(&ssl_maskw);
1626 FD_SET(wfd, &ssl_maskw);
1627 FD_ZERO(&ssl_maskx);
1628 FD_SET(rfd, &ssl_maskx);
1629 if (select(wfd + 1, NULL, &ssl_maskw,
1630 &ssl_maskx, &tv) > 0)
1635 sm_syslog(LOG_WARNING, NOQID,
1636 "STARTTLS=server, error: accept failed=%d, SSL_error=%d, timedout=%d, errno=%d",
1637 r, i, (int) timedout, errno);
1639 tlslogerr("server");
1647 ** according to the next draft of
1648 ** RFC 2487 the connection should be dropped
1651 /* arrange to ignore any current send list */
1652 e->e_sendqueue = NULL;
1656 /* ignore return code for now, it's in {verify} */
1657 (void) tls_get_info(srv_ssl, true,
1659 &BlankEnvelope.e_macro,
1660 bitset(SRV_VRFY_CLT, features));
1663 ** call Stls_client to find out whether
1664 ** to accept the connection from the client
1667 saveQuickAbort = QuickAbort;
1668 saveSuprErrs = SuprErrs;
1671 if (rscheck("tls_client",
1672 macvalue(macid("{verify}"), e),
1674 RSF_RMCOMM|RSF_COUNT,
1675 5, NULL, NOQID) != EX_OK ||
1678 extern char MsgBuf[];
1680 if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf))
1681 nullserver = newstr(MsgBuf);
1683 nullserver = "503 5.7.0 Authentication required.";
1685 QuickAbort = saveQuickAbort;
1686 SuprErrs = saveSuprErrs;
1688 tls_ok_srv = false; /* don't offer STARTTLS again */
1695 s = macvalue(macid("{cipher_bits}"), e);
1697 if (s != NULL && (ext_ssf = atoi(s)) > 0)
1699 auth_id = macvalue(macid("{cert_subject}"),
1701 sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL,
1702 &ext_ssf) == SASL_OK) &&
1703 (sasl_setprop(conn, SASL_AUTH_EXTERNAL,
1704 auth_id) == SASL_OK));
1705 # else /* SASL >= 20000 */
1706 if (s != NULL && (ext_ssf.ssf = atoi(s)) > 0)
1708 ext_ssf.auth_id = macvalue(macid("{cert_subject}"),
1710 sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
1711 &ext_ssf) == SASL_OK;
1712 # endif /* SASL >= 20000 */
1715 n_mechs = saslmechs(conn,
1721 /* switch to secure connection */
1722 if (sfdctls(&InChannel, &OutChannel, srv_ssl) == 0)
1726 (void) sm_io_autoflush(InChannel, OutChannel);
1727 # endif /* PIPELINING */
1732 ** XXX this is an internal error
1733 ** how to deal with it?
1734 ** we can't generate an error message
1735 ** since the other side switched to an
1736 ** encrypted layer, but we could not...
1740 nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer";
1741 syserr("STARTTLS: can't switch to encrypted layer");
1752 # endif /* _FFR_SMTP_SSL */
1754 #endif /* STARTTLS */
1756 case CMDHELO: /* hello -- introduce yourself */
1757 case CMDEHLO: /* extended hello */
1759 if (c->cmd_code == CMDEHLO)
1762 SmtpPhase = "server EHLO";
1767 SmtpPhase = "server HELO";
1770 /* avoid denial-of-service */
1771 (void) checksmtpattack(&n_helo, MAXHELOCOMMANDS, true,
1775 /* RFC2821 4.1.4 allows duplicate HELO/EHLO */
1776 /* check for duplicate HELO/EHLO per RFC 1651 4.2 */
1779 usrerr("503 %s Duplicate HELO/EHLO",
1785 /* check for valid domain name (re 1123 5.2.5) */
1786 if (*p == '\0' && !AllowBogusHELO)
1788 usrerr("501 %s requires domain address",
1793 /* check for long domain name (hides Received: info) */
1794 if (strlen(p) > MAXNAME)
1796 usrerr("501 Invalid domain name");
1798 sm_syslog(LOG_INFO, CurEnv->e_id,
1799 "invalid domain name (too long) from %s",
1805 for (q = p; *q != '\0'; q++)
1815 /* only complain if strict check */
1816 ok = AllowBogusHELO;
1819 if (strchr("[].-_#", *q) == NULL)
1823 if (*q == '\0' && ok)
1825 q = "pleased to meet you";
1826 sendinghost = sm_strdup_x(p);
1828 else if (!AllowBogusHELO)
1830 usrerr("501 Invalid domain name");
1832 sm_syslog(LOG_INFO, CurEnv->e_id,
1833 "invalid domain name (%s) from %.100s",
1839 q = "accepting invalid domain name";
1844 CLEAR_STATE(cmdbuf);
1847 /* restore connection quarantining */
1848 if (smtp.sm_quarmsg == NULL)
1850 e->e_quarmsg = NULL;
1851 macdefine(&e->e_macro, A_PERM,
1852 macid("{quarantine}"), "");
1856 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
1858 macdefine(&e->e_macro, A_PERM,
1859 macid("{quarantine}"),
1862 #endif /* _FFR_QUARANTINE */
1866 if (smtp.sm_milterlist && smtp.sm_milterize &&
1867 !bitset(EF_DISCARD, e->e_flags))
1872 response = milter_helo(p, e, &state);
1875 case SMFIR_REPLYCODE:
1876 if (MilterLogLevel > 3)
1877 sm_syslog(LOG_INFO, e->e_id,
1878 "Milter: helo=%s, reject=%s",
1880 nullserver = newstr(response);
1881 smtp.sm_milterize = false;
1885 if (MilterLogLevel > 3)
1886 sm_syslog(LOG_INFO, e->e_id,
1887 "Milter: helo=%s, reject=Command rejected",
1889 nullserver = "Command rejected";
1890 smtp.sm_milterize = false;
1893 case SMFIR_TEMPFAIL:
1894 if (MilterLogLevel > 3)
1895 sm_syslog(LOG_INFO, e->e_id,
1896 "Milter: helo=%s, reject=%s",
1899 smtp.sm_milterize = false;
1902 if (response != NULL)
1905 # if _FFR_QUARANTINE
1907 ** If quarantining by a connect/ehlo action,
1908 ** save between messages
1911 if (smtp.sm_quarmsg == NULL &&
1912 e->e_quarmsg != NULL)
1913 smtp.sm_quarmsg = newstr(e->e_quarmsg);
1914 # endif /* _FFR_QUARANTINE */
1919 /* print HELO response message */
1920 if (c->cmd_code != CMDEHLO)
1922 message("250 %s Hello %s, %s",
1923 MyHostName, CurSmtpClient, q);
1927 message("250-%s Hello %s, %s",
1928 MyHostName, CurSmtpClient, q);
1930 /* offer ENHSC even for nullserver */
1931 if (nullserver != NULL)
1933 message("250 ENHANCEDSTATUSCODES");
1938 ** print EHLO features list
1940 ** Note: If you change this list,
1941 ** remember to update 'helpfile'
1944 message("250-ENHANCEDSTATUSCODES");
1946 if (bitset(SRV_OFFER_PIPE, features))
1947 message("250-PIPELINING");
1948 #endif /* PIPELINING */
1949 if (bitset(SRV_OFFER_EXPN, features))
1951 message("250-EXPN");
1952 if (bitset(SRV_OFFER_VERB, features))
1953 message("250-VERB");
1956 message("250-8BITMIME");
1957 #endif /* MIME8TO7 */
1958 if (MaxMessageSize > 0)
1959 message("250-SIZE %ld", MaxMessageSize);
1961 message("250-SIZE");
1963 if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features))
1966 if (bitset(SRV_OFFER_ETRN, features))
1967 message("250-ETRN");
1969 if (sasl_ok && mechlist != NULL && *mechlist != '\0')
1970 message("250-AUTH %s", mechlist);
1974 bitset(SRV_OFFER_TLS, features))
1975 message("250-STARTTLS");
1976 #endif /* STARTTLS */
1977 if (DeliverByMin > 0)
1978 message("250-DELIVERBY %ld",
1979 (long) DeliverByMin);
1980 else if (DeliverByMin == 0)
1981 message("250-DELIVERBY");
1983 /* < 0: no deliver-by */
1985 message("250 HELP");
1988 case CMDMAIL: /* mail -- designate sender */
1989 SmtpPhase = "server MAIL";
1992 /* check for validity of this command */
1993 if (!gothello && bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
1995 usrerr("503 5.0.0 Polite people say HELO first");
1998 if (smtp.sm_gotmail)
2000 usrerr("503 5.5.0 Sender already specified");
2004 if (bitset(SRV_REQ_AUTH, features) &&
2005 authenticating != SASL_IS_AUTH)
2007 usrerr("530 5.7.0 Authentication required");
2012 p = skipword(p, "from");
2018 sm_syslog(LOG_INFO, e->e_id,
2019 "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
2021 usrerr(MSG_TEMPFAIL);
2025 /* make sure we know who the sending host is */
2026 if (sendinghost == NULL)
2027 sendinghost = peerhostname;
2031 if (sm_debug_active(&DebugLeakSmtp, 1))
2034 sm_dprintf("smtp() heap group #%d\n",
2037 #endif /* SM_HEAP_CHECK */
2043 auth_warning(e, "%s didn't use HELO protocol",
2046 #ifdef PICKY_HELO_CHECK
2047 if (sm_strcasecmp(sendinghost, peerhostname) != 0 &&
2048 (sm_strcasecmp(peerhostname, "localhost") != 0 ||
2049 sm_strcasecmp(sendinghost, MyHostName) != 0))
2051 auth_warning(e, "Host %s claimed to be %s",
2052 CurSmtpClient, sendinghost);
2054 #endif /* PICKY_HELO_CHECK */
2056 if (protocol == NULL)
2058 macdefine(&e->e_macro, A_PERM, 'r', protocol);
2059 macdefine(&e->e_macro, A_PERM, 's', sendinghost);
2065 macdefine(&e->e_macro, A_PERM, macid("{ntries}"), "0");
2066 macdefine(&e->e_macro, A_PERM, macid("{nrcpts}"), "0");
2067 e->e_flags |= EF_CLRQUEUE;
2068 sm_setproctitle(true, e, "%s %s: %.80s",
2070 CurSmtpClient, inp);
2072 /* do the processing */
2075 extern char *FullName;
2078 SM_FREE_CLR(FullName);
2080 /* must parse sender first */
2082 setsender(p, e, &delimptr, ' ', false);
2083 if (delimptr != NULL && *delimptr != '\0')
2086 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2088 /* Successfully set e_from, allow logging */
2089 e->e_flags |= EF_LOGSENDER;
2091 /* put resulting triple from parseaddr() into macros */
2092 if (e->e_from.q_mailer != NULL)
2093 macdefine(&e->e_macro, A_PERM,
2094 macid("{mail_mailer}"),
2095 e->e_from.q_mailer->m_name);
2097 macdefine(&e->e_macro, A_PERM,
2098 macid("{mail_mailer}"), NULL);
2099 if (e->e_from.q_host != NULL)
2100 macdefine(&e->e_macro, A_PERM,
2101 macid("{mail_host}"),
2104 macdefine(&e->e_macro, A_PERM,
2105 macid("{mail_host}"), "localhost");
2106 if (e->e_from.q_user != NULL)
2107 macdefine(&e->e_macro, A_PERM,
2108 macid("{mail_addr}"),
2111 macdefine(&e->e_macro, A_PERM,
2112 macid("{mail_addr}"), NULL);
2114 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2116 /* check for possible spoofing */
2117 if (RealUid != 0 && OpMode == MD_SMTP &&
2118 !wordinclass(RealUserName, 't') &&
2119 (!bitnset(M_LOCALMAILER,
2120 e->e_from.q_mailer->m_flags) ||
2121 strcmp(e->e_from.q_user, RealUserName) != 0))
2123 auth_warning(e, "%s owned process doing -bs",
2127 /* now parse ESMTP arguments */
2133 while (p != NULL && *p != '\0')
2139 /* locate the beginning of the keyword */
2145 /* skip to the value portion */
2146 while ((isascii(*p) && isalnum(*p)) || *p == '-')
2154 /* skip to the end of the value */
2155 while (*p != '\0' && *p != ' ' &&
2156 !(isascii(*p) && iscntrl(*p)) &&
2165 sm_dprintf("MAIL: got arg %s=\"%s\"\n", kp,
2166 vp == NULL ? "<null>" : vp);
2168 mail_esmtp_args(kp, vp, e);
2172 if (argno >= MAXSMTPARGS - 1)
2173 usrerr("501 5.5.4 Too many parameters");
2175 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2179 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2182 # if _FFR_AUTH_PASSING
2183 /* set the default AUTH= if the sender didn't */
2184 if (e->e_auth_param == NULL)
2186 /* XXX only do this for an MSA? */
2187 e->e_auth_param = macvalue(macid("{auth_authen}"),
2189 if (e->e_auth_param == NULL)
2190 e->e_auth_param = "<>";
2193 ** XXX should we invoke Strust_auth now?
2194 ** authorizing as the client that just
2195 ** authenticated, so we'll trust implicitly
2198 # endif /* _FFR_AUTH_PASSING */
2201 /* do config file checking of the sender */
2202 macdefine(&e->e_macro, A_PERM,
2203 macid("{addr_type}"), "e s");
2205 /* make the "real" sender address available */
2206 macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"),
2208 #endif /* _FFR_MAIL_MACRO */
2209 if (rscheck("check_mail", addr,
2210 NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
2211 NULL, e->e_id) != EX_OK ||
2213 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2214 macdefine(&e->e_macro, A_PERM,
2215 macid("{addr_type}"), NULL);
2217 if (MaxMessageSize > 0 &&
2218 (e->e_msgsize > MaxMessageSize ||
2221 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
2223 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2227 ** XXX always check whether there is at least one fs
2228 ** with enough space?
2229 ** However, this may not help much: the queue group
2230 ** selection may later on select a FS that hasn't
2234 if ((NumFileSys == 1 || NumQueue == 1) &&
2235 !enoughdiskspace(e->e_msgsize, e)
2236 #if _FFR_ANY_FREE_FS
2237 && !filesys_free(e->e_msgsize)
2238 #endif /* _FFR_ANY_FREE_FS */
2242 ** We perform this test again when the
2243 ** queue directory is selected, in collect.
2246 usrerr("452 4.4.5 Insufficient disk space; try again later");
2247 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2250 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2254 if (smtp.sm_milterlist && smtp.sm_milterize &&
2255 !bitset(EF_DISCARD, e->e_flags))
2260 response = milter_envfrom(args, e, &state);
2261 MILTER_REPLY("from");
2265 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2267 message("250 2.1.0 Sender ok");
2268 smtp.sm_gotmail = true;
2270 SM_EXCEPT(exc, "[!F]*")
2273 ** An error occurred while processing a MAIL command.
2274 ** Jump to the common error handling code.
2284 e->e_flags &= ~EF_PM_NOTIFY;
2288 case CMDRCPT: /* rcpt -- designate recipient */
2290 if (!smtp.sm_gotmail)
2292 usrerr("503 5.0.0 Need MAIL before RCPT");
2295 SmtpPhase = "server RCPT";
2301 /* limit flooding of our machine */
2302 if (MaxRcptPerMsg > 0 &&
2303 smtp.sm_nrcpts >= MaxRcptPerMsg)
2305 /* sleep(1); / * slow down? */
2306 usrerr("452 4.5.3 Too many recipients");
2310 if (e->e_sendmode != SM_DELIVER)
2311 e->e_flags |= EF_VRFYONLY;
2315 ** If the filter will be deleting recipients,
2316 ** don't expand them at RCPT time (in the call
2317 ** to recipient()). If they are expanded, it
2318 ** is impossible for removefromlist() to figure
2319 ** out the expanded members of the original
2320 ** recipient and mark them as QS_DONTSEND.
2323 if (milter_can_delrcpts())
2324 e->e_flags |= EF_VRFYONLY;
2327 p = skipword(p, "to");
2330 macdefine(&e->e_macro, A_PERM,
2331 macid("{addr_type}"), "e r");
2332 a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr,
2334 macdefine(&e->e_macro, A_PERM,
2335 macid("{addr_type}"), NULL);
2336 if (BadRcptThrottle > 0 &&
2337 n_badrcpts >= BadRcptThrottle)
2340 n_badrcpts == BadRcptThrottle)
2342 sm_syslog(LOG_INFO, e->e_id,
2343 "%s: Possible SMTP RCPT flood, throttling.",
2346 /* To avoid duplicated message */
2351 ** Don't use exponential backoff for now.
2352 ** Some servers will open more connections
2353 ** and actually overload the receiver even
2363 usrerr("501 5.0.0 Missing recipient");
2367 if (delimptr != NULL && *delimptr != '\0')
2370 /* put resulting triple from parseaddr() into macros */
2371 if (a->q_mailer != NULL)
2372 macdefine(&e->e_macro, A_PERM,
2373 macid("{rcpt_mailer}"),
2374 a->q_mailer->m_name);
2376 macdefine(&e->e_macro, A_PERM,
2377 macid("{rcpt_mailer}"), NULL);
2378 if (a->q_host != NULL)
2379 macdefine(&e->e_macro, A_PERM,
2380 macid("{rcpt_host}"), a->q_host);
2382 macdefine(&e->e_macro, A_PERM,
2383 macid("{rcpt_host}"), "localhost");
2384 if (a->q_user != NULL)
2385 macdefine(&e->e_macro, A_PERM,
2386 macid("{rcpt_addr}"), a->q_user);
2388 macdefine(&e->e_macro, A_PERM,
2389 macid("{rcpt_addr}"), NULL);
2393 /* now parse ESMTP arguments */
2398 while (p != NULL && *p != '\0')
2404 /* locate the beginning of the keyword */
2410 /* skip to the value portion */
2411 while ((isascii(*p) && isalnum(*p)) || *p == '-')
2419 /* skip to the end of the value */
2420 while (*p != '\0' && *p != ' ' &&
2421 !(isascii(*p) && iscntrl(*p)) &&
2430 sm_dprintf("RCPT: got arg %s=\"%s\"\n", kp,
2431 vp == NULL ? "<null>" : vp);
2433 rcpt_esmtp_args(a, kp, vp, e);
2437 if (argno >= MAXSMTPARGS - 1)
2438 usrerr("501 5.5.4 Too many parameters");
2446 /* do config file checking of the recipient */
2447 macdefine(&e->e_macro, A_PERM,
2448 macid("{addr_type}"), "e r");
2449 if (rscheck("check_rcpt", addr,
2450 NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
2451 NULL, e->e_id) != EX_OK ||
2454 macdefine(&e->e_macro, A_PERM,
2455 macid("{addr_type}"), NULL);
2457 /* If discarding, don't bother to verify user */
2458 if (bitset(EF_DISCARD, e->e_flags))
2459 a->q_state = QS_VERIFIED;
2462 if (smtp.sm_milterlist && smtp.sm_milterize &&
2463 !bitset(EF_DISCARD, e->e_flags))
2468 response = milter_envrcpt(args, e, &state);
2473 macdefine(&e->e_macro, A_PERM,
2474 macid("{rcpt_mailer}"), NULL);
2475 macdefine(&e->e_macro, A_PERM,
2476 macid("{rcpt_host}"), NULL);
2477 macdefine(&e->e_macro, A_PERM,
2478 macid("{rcpt_addr}"), NULL);
2479 macdefine(&e->e_macro, A_PERM,
2480 macid("{dsn_notify}"), NULL);
2484 /* save in recipient list after ESMTP mods */
2485 a = recipient(a, &e->e_sendqueue, 0, e);
2489 /* no errors during parsing, but might be a duplicate */
2490 e->e_to = a->q_paddr;
2491 if (!QS_IS_BADADDR(a->q_state))
2493 if (smtp.sm_nrcpts == 0)
2495 message("250 2.1.5 Recipient ok%s",
2496 QS_IS_QUEUEUP(a->q_state) ?
2497 " (will queue)" : "");
2502 /* punt -- should keep message in ADDRESS.... */
2503 usrerr("550 5.1.1 Addressee unknown");
2509 SM_EXCEPT(exc, "[!F]*")
2511 /* An exception occurred while processing RCPT */
2512 e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
2518 case CMDDATA: /* data -- text of mail */
2520 smtp_data(&smtp, e);
2523 case CMDRSET: /* rset -- reset state */
2525 message("451 4.0.0 Test failure");
2527 message("250 2.0.0 Reset state");
2528 CLEAR_STATE(cmdbuf);
2530 /* restore connection quarantining */
2531 if (smtp.sm_quarmsg == NULL)
2533 e->e_quarmsg = NULL;
2534 macdefine(&e->e_macro, A_PERM,
2535 macid("{quarantine}"), "");
2539 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
2541 macdefine(&e->e_macro, A_PERM,
2542 macid("{quarantine}"), e->e_quarmsg);
2544 #endif /* _FFR_QUARANTINE */
2547 case CMDVRFY: /* vrfy -- verify address */
2548 case CMDEXPN: /* expn -- expand address */
2549 vrfy = c->cmd_code == CMDVRFY;
2550 DELAY_CONN(vrfy ? "VRFY" : "EXPN");
2554 sm_syslog(LOG_INFO, e->e_id,
2555 "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)",
2556 vrfy ? "VRFY" : "EXPN",
2559 /* RFC 821 doesn't allow 4xy reply code */
2560 usrerr("550 5.7.1 Please try again later");
2563 wt = checksmtpattack(&n_verifies, MAXVRFYCOMMANDS,
2564 false, vrfy ? "VRFY" : "EXPN", e);
2565 previous = curtime();
2566 if ((vrfy && bitset(PRIV_NOVRFY, PrivacyFlags)) ||
2567 (!vrfy && !bitset(SRV_OFFER_EXPN, features)))
2570 message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
2572 message("502 5.7.0 Sorry, we do not allow this operation");
2574 sm_syslog(LOG_INFO, e->e_id,
2575 "%s: %s [rejected]",
2577 shortenstring(inp, MAXSHORTSTR));
2580 else if (!gothello &&
2581 bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
2584 usrerr("503 5.0.0 I demand that you introduce yourself first");
2590 sm_syslog(LOG_INFO, e->e_id, "%s: %s",
2592 shortenstring(inp, MAXSHORTSTR));
2598 e->e_flags |= EF_VRFYONLY;
2599 while (*p != '\0' && isascii(*p) && isspace(*p))
2603 usrerr("501 5.5.2 Argument required");
2607 /* do config file checking of the address */
2608 if (rscheck(vrfy ? "check_vrfy" : "check_expn",
2609 p, NULL, e, RSF_RMCOMM,
2610 3, NULL, NOQID) != EX_OK ||
2612 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2613 (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
2619 t = wt - (curtime() - previous);
2624 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2625 if (vrfyqueue == NULL)
2627 usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN");
2629 while (vrfyqueue != NULL)
2631 if (!QS_IS_UNDELIVERED(vrfyqueue->q_state))
2633 vrfyqueue = vrfyqueue->q_next;
2637 /* see if there is more in the vrfy list */
2639 while ((a = a->q_next) != NULL &&
2640 (!QS_IS_UNDELIVERED(a->q_state)))
2642 printvrfyaddr(vrfyqueue, a == NULL, vrfy);
2646 SM_EXCEPT(exc, "[!F]*")
2649 ** An exception occurred while processing VRFY/EXPN
2658 case CMDETRN: /* etrn -- force queue flush */
2661 /* Don't leak queue information via debug flags */
2662 if (!bitset(SRV_OFFER_ETRN, features) || UseMSP ||
2663 (RealUid != 0 && RealUid != TrustedUid &&
2666 /* different message for MSA ? */
2667 message("502 5.7.0 Sorry, we do not allow this operation");
2669 sm_syslog(LOG_INFO, e->e_id,
2670 "%s: %s [rejected]",
2672 shortenstring(inp, MAXSHORTSTR));
2678 sm_syslog(LOG_INFO, e->e_id,
2679 "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
2681 usrerr(MSG_TEMPFAIL);
2687 usrerr("500 5.5.2 Parameter required");
2691 /* crude way to avoid denial-of-service attacks */
2692 (void) checksmtpattack(&n_etrn, MAXETRNCOMMANDS, true,
2696 ** Do config file checking of the parameter.
2697 ** Even though we have srv_features now, we still
2698 ** need this ruleset because the former is called
2699 ** when the connection has been established, while
2700 ** this ruleset is called when the command is
2701 ** actually issued and therefore has all information
2702 ** available to make a decision.
2705 if (rscheck("check_etrn", p, NULL, e,
2706 RSF_RMCOMM, 3, NULL, NOQID) != EX_OK ||
2711 sm_syslog(LOG_INFO, e->e_id,
2712 "%s: ETRN %s", CurSmtpClient,
2713 shortenstring(p, MAXSHORTSTR));
2721 qgrp = name2qid(id);
2722 if (!ISVALIDQGRP(qgrp))
2724 usrerr("459 4.5.4 Queue %s unknown",
2728 for (i = 0; i < NumQueue && Queue[i] != NULL;
2730 Queue[i]->qg_nextrun = (time_t) -1;
2731 Queue[qgrp]->qg_nextrun = 0;
2732 ok = run_work_group(Queue[qgrp]->qg_wgrp,
2733 RWG_FORK|RWG_FORCE);
2734 if (ok && Errors == 0)
2735 message("250 2.0.0 Queuing for queue group %s started", id);
2744 new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR));
2747 syserr("500 5.5.0 ETRN out of memory");
2750 new->queue_match = id;
2751 new->queue_negate = false;
2752 new->queue_next = NULL;
2753 QueueLimitRecipient = new;
2754 ok = runqueue(true, false, false, true);
2755 sm_free(QueueLimitRecipient); /* XXX */
2756 QueueLimitRecipient = NULL;
2757 if (ok && Errors == 0)
2758 message("250 2.0.0 Queuing for node %s started", p);
2761 case CMDHELP: /* help -- give user info */
2766 case CMDNOOP: /* noop -- do nothing */
2768 (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2770 message("250 2.0.0 OK");
2773 case CMDQUIT: /* quit -- leave mail */
2774 message("221 2.0.0 %s closing connection", MyHostName);
2776 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
2777 #endif /* PIPELINING */
2779 if (smtp.sm_nrcpts > 0)
2780 logundelrcpts(e, "aborted by sender", 9, false);
2782 /* arrange to ignore any current send list */
2783 e->e_sendqueue = NULL;
2786 /* shutdown TLS connection */
2789 (void) endtls(srv_ssl, "server");
2792 #endif /* STARTTLS */
2794 if (authenticating == SASL_IS_AUTH)
2796 sasl_dispose(&conn);
2797 authenticating = SASL_NOT_AUTH;
2798 /* XXX sasl_done(); this is a child */
2803 /* avoid future 050 messages */
2807 /* close out milter filters */
2811 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2813 e->e_flags &= ~EF_LOGSENDER;
2815 if (lognullconnection && LogLevel > 5 &&
2820 d = macvalue(macid("{daemon_name}"), e);
2825 ** even though this id is "bogus", it makes
2826 ** it simpler to "grep" related events, e.g.,
2827 ** timeouts for the same connection.
2830 sm_syslog(LOG_INFO, e->e_id,
2831 "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
2836 /* return to handle next connection */
2839 finis(true, true, ExitStat);
2842 case CMDVERB: /* set verbose mode */
2844 if (!bitset(SRV_OFFER_EXPN, features) ||
2845 !bitset(SRV_OFFER_VERB, features))
2847 /* this would give out the same info */
2848 message("502 5.7.0 Verbose unavailable");
2851 (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2854 set_delivery_mode(SM_DELIVER, e);
2855 message("250 2.0.0 Verbose mode");
2859 case CMDDBGQSHOW: /* show queues */
2860 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
2862 printaddr(e->e_sendqueue, true);
2865 case CMDDBGDEBUG: /* set debug mode */
2866 tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
2868 message("200 2.0.0 Debug set");
2871 #else /* SMTPDEBUG */
2872 case CMDDBGQSHOW: /* show queues */
2873 case CMDDBGDEBUG: /* set debug mode */
2874 #endif /* SMTPDEBUG */
2875 case CMDLOGBOGUS: /* bogus command */
2876 DELAY_CONN("Bogus");
2878 sm_syslog(LOG_CRIT, e->e_id,
2879 "\"%s\" command from %s (%.100s)",
2880 c->cmd_name, CurSmtpClient,
2881 anynet_ntoa(&RealHostAddr));
2884 case CMDERROR: /* unknown command */
2885 #if MAXBADCOMMANDS > 0
2886 if (++n_badcmds > MAXBADCOMMANDS)
2888 message("421 4.7.0 %s Too many bad commands; closing connection",
2891 /* arrange to ignore any current send list */
2892 e->e_sendqueue = NULL;
2895 #endif /* MAXBADCOMMANDS > 0 */
2897 usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2898 shortenstring(inp, MAXSHORTSTR));
2902 DELAY_CONN("Unimpl");
2903 usrerr("502 5.5.1 Command not implemented: \"%s\"",
2904 shortenstring(inp, MAXSHORTSTR));
2908 DELAY_CONN("default");
2910 syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
2917 SM_EXCEPT(exc, "[!F]*")
2920 ** The only possible exception is "E:mta.quickabort".
2921 ** There is nothing to do except fall through and loop.
2928 ** SMTP_DATA -- implement the SMTP DATA command.
2931 ** smtp -- status of SMTP connection.
2938 ** possibly sends message.
2957 SmtpPhase = "server DATA";
2958 if (!smtp->sm_gotmail)
2960 usrerr("503 5.0.0 Need MAIL command");
2963 else if (smtp->sm_nrcpts <= 0)
2965 usrerr("503 5.0.0 Need RCPT (recipient)");
2968 (void) sm_snprintf(buf, sizeof buf, "%u", smtp->sm_nrcpts);
2969 if (rscheck("check_data", buf, NULL, e,
2970 RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
2974 /* put back discard bit */
2975 if (smtp->sm_discard)
2976 e->e_flags |= EF_DISCARD;
2978 /* check to see if we need to re-expand aliases */
2979 /* also reset QS_BADADDR on already-diagnosted addrs */
2980 doublequeue = false;
2981 for (a = e->e_sendqueue; a != NULL; a = a->q_next)
2983 if (QS_IS_VERIFIED(a->q_state) &&
2984 !bitset(EF_DISCARD, e->e_flags))
2986 /* need to re-expand aliases */
2989 if (QS_IS_BADADDR(a->q_state))
2991 /* make this "go away" */
2992 a->q_state = QS_DONTSEND;
2996 /* collect the text of the message */
2997 SmtpPhase = "collect";
3000 #if _FFR_ADAPTIVE_EOL
3001 /* triggers error in collect, disabled for now */
3003 e->e_flags |= EF_NL_NOT_EOL;
3004 #endif /* _FFR_ADAPTIVE_EOL */
3006 collect(InChannel, true, NULL, e);
3008 /* redefine message size */
3009 (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
3010 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3013 /* rscheck() will set Errors or EF_DISCARD if it trips */
3014 (void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
3016 #endif /* _FFR_CHECK_EOM */
3019 milteraccept = true;
3020 if (smtp->sm_milterlist && smtp->sm_milterize &&
3022 !bitset(EF_DISCARD, e->e_flags))
3027 response = milter_data(e, &state);
3030 case SMFIR_REPLYCODE:
3031 if (MilterLogLevel > 3)
3032 sm_syslog(LOG_INFO, e->e_id,
3033 "Milter: data, reject=%s",
3035 milteraccept = false;
3040 milteraccept = false;
3041 if (MilterLogLevel > 3)
3042 sm_syslog(LOG_INFO, e->e_id,
3043 "Milter: data, reject=554 5.7.1 Command rejected");
3044 usrerr("554 5.7.1 Command rejected");
3048 if (MilterLogLevel > 3)
3049 sm_syslog(LOG_INFO, e->e_id,
3050 "Milter: data, discard");
3051 milteraccept = false;
3052 e->e_flags |= EF_DISCARD;
3055 case SMFIR_TEMPFAIL:
3056 if (MilterLogLevel > 3)
3057 sm_syslog(LOG_INFO, e->e_id,
3058 "Milter: data, reject=%s",
3060 milteraccept = false;
3061 usrerr(MSG_TEMPFAIL);
3064 if (response != NULL)
3068 /* Milter may have changed message size */
3069 (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
3070 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3072 /* abort message filters that didn't get the body & log msg is OK */
3073 if (smtp->sm_milterlist && smtp->sm_milterize)
3076 if (milteraccept && MilterLogLevel > 9)
3077 sm_syslog(LOG_INFO, e->e_id, "Milter accept: message");
3082 /* Check if quarantining stats should be updated */
3083 if (e->e_quarmsg != NULL)
3084 markstats(e, NULL, STATS_QUARANTINE);
3085 #endif /* _FFR_QUARANTINE */
3088 ** If a header/body check (header checks or milter)
3089 ** set EF_DISCARD, don't queueup the message --
3090 ** that would lose the EF_DISCARD bit and deliver
3094 if (bitset(EF_DISCARD, e->e_flags))
3095 doublequeue = false;
3097 aborting = Errors > 0;
3100 (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) &&
3101 #endif /* _FFR_QUARANTINE */
3102 !split_by_recipient(e))
3103 aborting = bitset(EF_FATALERRS, e->e_flags);
3107 /* Log who the mail would have gone to */
3108 logundelrcpts(e, e->e_message, 8, false);
3114 /* from now on, we have to operate silently */
3119 ** Clear message, it may contain an error from the SMTP dialogue.
3120 ** This error must not show up in the queue.
3121 ** Some error message should show up, e.g., alias database
3122 ** not available, but others shouldn't, e.g., from check_rcpt.
3125 e->e_message = NULL;
3129 ** Arrange to send to everyone.
3130 ** If sending to multiple people, mail back
3131 ** errors rather than reporting directly.
3132 ** In any case, don't mail back errors for
3133 ** anything that has happened up to
3134 ** now (the other end will do this).
3135 ** Truncate our transcript -- the mail has gotten
3136 ** to us successfully, and if we have
3137 ** to mail this back, it will be easier
3139 ** Then send to everyone.
3140 ** Finally give a reply code. If an error has
3141 ** already been given, don't mail a
3143 ** We goose error returns by clearing error bit.
3146 SmtpPhase = "delivery";
3147 (void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL);
3151 _res.retry = TimeOuts.res_retry[RES_TO_FIRST];
3152 _res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
3153 #endif /* NAMED_BIND */
3155 for (ee = e; ee != NULL; ee = ee->e_sibling)
3157 /* make sure we actually do delivery */
3158 ee->e_flags &= ~EF_CLRQUEUE;
3160 /* from now on, operate silently */
3161 ee->e_errormode = EM_MAIL;
3165 /* make sure it is in the queue */
3166 queueup(ee, false, true);
3170 /* send to all recipients */
3171 sendall(ee, SM_DEFAULT);
3176 /* put back id for SMTP logging in putoutmsg() */
3177 oldid = CurEnv->e_id;
3180 /* issue success message */
3181 message("250 2.0.0 %s Message accepted for delivery", id);
3182 CurEnv->e_id = oldid;
3184 /* if we just queued, poke it */
3187 bool anything_to_send = false;
3190 for (ee = e; ee != NULL; ee = ee->e_sibling)
3192 if (WILL_BE_QUEUED(ee->e_sendmode))
3194 if (shouldqueue(ee->e_msgpriority, ee->e_ctime))
3196 ee->e_sendmode = SM_QUEUE;
3200 else if (QueueMode != QM_QUARANTINE &&
3201 ee->e_quarmsg != NULL)
3203 ee->e_sendmode = SM_QUEUE;
3206 #endif /* _FFR_QUARANTINE */
3207 anything_to_send = true;
3209 /* close all the queue files */
3211 if (ee->e_dfp != NULL)
3213 (void) sm_io_close(ee->e_dfp, SM_TIME_DEFAULT);
3218 if (anything_to_send)
3222 ** XXX if we don't do this, we get 250 twice
3223 ** because it is also flushed in the child.
3226 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
3227 #endif /* PIPELINING */
3228 (void) doworklist(e, true, true);
3233 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
3235 e->e_flags &= ~EF_LOGSENDER;
3237 /* clean up a bit */
3238 smtp->sm_gotmail = false;
3241 ** Call dropenvelope if and only if the envelope is *not*
3242 ** being processed by the child process forked by doworklist().
3245 if (aborting || bitset(EF_DISCARD, e->e_flags))
3246 dropenvelope(e, true, false);
3249 for (ee = e; ee != NULL; ee = ee->e_sibling)
3253 QueueMode != QM_QUARANTINE &&
3254 ee->e_quarmsg != NULL)
3256 dropenvelope(ee, true, false);
3259 #endif /* _FFR_QUARANTINE */
3260 if (WILL_BE_QUEUED(ee->e_sendmode))
3261 dropenvelope(ee, true, false);
3264 sm_rpool_free(e->e_rpool);
3267 ** At this point, e == &MainEnvelope, but if we did splitting,
3268 ** then CurEnv may point to an envelope structure that was just
3269 ** freed with the rpool. So reset CurEnv *before* calling
3274 newenvelope(e, e, sm_rpool_new_x(NULL));
3275 e->e_flags = BlankEnvelope.e_flags;
3278 /* restore connection quarantining */
3279 if (smtp->sm_quarmsg == NULL)
3281 e->e_quarmsg = NULL;
3282 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), "");
3286 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg);
3287 macdefine(&e->e_macro, A_PERM,
3288 macid("{quarantine}"), e->e_quarmsg);
3290 #endif /* _FFR_QUARANTINE */
3293 ** LOGUNDELRCPTS -- log undelivered (or all) recipients.
3297 ** msg -- message for Stat=
3298 ** level -- log level.
3299 ** all -- log all recipients.
3305 ** logs undelivered (or all) recipients
3309 logundelrcpts(e, msg, level, all)
3317 if (LogLevel <= level || msg == NULL || *msg == '\0')
3320 /* Clear $h so relay= doesn't get mislogged by logdelivery() */
3321 macdefine(&e->e_macro, A_PERM, 'h', NULL);
3323 /* Log who the mail would have gone to */
3324 for (a = e->e_sendqueue; a != NULL; a = a->q_next)
3326 if (!QS_IS_UNDELIVERED(a->q_state) && !all)
3328 e->e_to = a->q_paddr;
3329 logdelivery(NULL, NULL, a->q_status, msg, NULL,
3335 ** CHECKSMTPATTACK -- check for denial-of-service attack by repetition
3338 ** pcounter -- pointer to a counter for this command.
3339 ** maxcount -- maximum value for this counter before we
3341 ** waitnow -- sleep now (in this routine)?
3342 ** cname -- command name for logging.
3343 ** e -- the current envelope.
3349 ** Slows down if we seem to be under attack.
3353 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
3354 volatile unsigned int *pcounter;
3360 if (maxcount <= 0) /* no limit */
3363 if (++(*pcounter) >= maxcount)
3367 if (*pcounter == maxcount && LogLevel > 5)
3369 sm_syslog(LOG_INFO, e->e_id,
3370 "%s: possible SMTP attack: command=%.40s, count=%u",
3371 CurSmtpClient, cname, *pcounter);
3373 s = 1 << (*pcounter - maxcount);
3374 if (s >= MAXTIMEOUT || s <= 0)
3377 /* sleep at least 1 second before returning */
3378 (void) sleep(*pcounter / maxcount);
3379 s -= *pcounter / maxcount;
3390 ** SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
3399 ** may change I/O fd.
3405 int inchfd, outchfd, outfd;
3407 inchfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
3408 outchfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
3409 outfd = sm_io_getinfo(smioout, SM_IO_WHAT_FD, NULL);
3410 if (outchfd != outfd)
3412 /* arrange for debugging output to go to remote host */
3413 (void) dup2(outchfd, outfd);
3417 ** if InChannel and OutChannel are stdin/stdout
3418 ** and connected to ttys
3419 ** and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT,
3420 ** then "chain" them together.
3423 if (inchfd == STDIN_FILENO && outchfd == STDOUT_FILENO &&
3424 isatty(inchfd) && isatty(outchfd))
3426 int inmode, outmode;
3428 inmode = fcntl(inchfd, F_GETFL, 0);
3432 sm_syslog(LOG_INFO, NOQID,
3433 "fcntl(inchfd, F_GETFL) failed: %s",
3434 sm_errstring(errno));
3437 outmode = fcntl(outchfd, F_GETFL, 0);
3441 sm_syslog(LOG_INFO, NOQID,
3442 "fcntl(outchfd, F_GETFL) failed: %s",
3443 sm_errstring(errno));
3446 if (bitset(O_NONBLOCK, inmode) ||
3447 bitset(O_NONBLOCK, outmode) ||
3448 fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1)
3450 outmode = fcntl(outchfd, F_GETFL, 0);
3451 if (outmode != -1 && bitset(O_NONBLOCK, outmode))
3453 /* changing InChannel also changes OutChannel */
3454 sm_io_automode(OutChannel, InChannel);
3455 if (tTd(97, 4) && LogLevel > 9)
3456 sm_syslog(LOG_INFO, NOQID,
3457 "set automode for I (%d)/O (%d) in SMTP server",
3461 /* undo change of inchfd */
3462 (void) fcntl(inchfd, F_SETFL, inmode);
3466 ** SKIPWORD -- skip a fixed word.
3469 ** p -- place to start looking.
3470 ** w -- word to skip.
3477 ** clobbers the p data area.
3482 register char *volatile p;
3488 /* find beginning of word */
3492 /* find end of word */
3493 while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
3495 while (isascii(*p) && isspace(*p))
3500 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
3501 shortenstring(firstp, MAXSHORTSTR));
3510 /* see if the input word matches desired word */
3511 if (sm_strcasecmp(q, w))
3517 ** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
3520 ** kp -- the parameter key.
3521 ** vp -- the value of that parameter.
3522 ** e -- the envelope.
3529 mail_esmtp_args(kp, vp, e)
3534 if (sm_strcasecmp(kp, "size") == 0)
3538 usrerr("501 5.5.2 SIZE requires a value");
3541 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp);
3543 e->e_msgsize = strtol(vp, (char **) NULL, 10);
3544 if (e->e_msgsize == LONG_MAX && errno == ERANGE)
3546 usrerr("552 5.2.3 Message size exceeds maximum value");
3549 if (e->e_msgsize < 0)
3551 usrerr("552 5.2.3 Message size invalid");
3555 else if (sm_strcasecmp(kp, "body") == 0)
3559 usrerr("501 5.5.2 BODY requires a value");
3562 else if (sm_strcasecmp(vp, "8bitmime") == 0)
3564 SevenBitInput = false;
3566 else if (sm_strcasecmp(vp, "7bit") == 0)
3568 SevenBitInput = true;
3572 usrerr("501 5.5.4 Unknown BODY type %s", vp);
3575 e->e_bodytype = sm_rpool_strdup_x(e->e_rpool, vp);
3577 else if (sm_strcasecmp(kp, "envid") == 0)
3579 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3581 usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
3586 usrerr("501 5.5.2 ENVID requires a value");
3591 usrerr("501 5.5.4 Syntax error in ENVID parameter value");
3594 if (e->e_envid != NULL)
3596 usrerr("501 5.5.0 Duplicate ENVID parameter");
3599 e->e_envid = sm_rpool_strdup_x(e->e_rpool, vp);
3600 macdefine(&e->e_macro, A_PERM,
3601 macid("{dsn_envid}"), e->e_envid);
3603 else if (sm_strcasecmp(kp, "ret") == 0)
3605 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3607 usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
3612 usrerr("501 5.5.2 RET requires a value");
3615 if (bitset(EF_RET_PARAM, e->e_flags))
3617 usrerr("501 5.5.0 Duplicate RET parameter");
3620 e->e_flags |= EF_RET_PARAM;
3621 if (sm_strcasecmp(vp, "hdrs") == 0)
3622 e->e_flags |= EF_NO_BODY_RETN;
3623 else if (sm_strcasecmp(vp, "full") != 0)
3625 usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp);
3628 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp);
3631 else if (sm_strcasecmp(kp, "auth") == 0)
3635 char *auth_param; /* the value of the AUTH=x */
3636 bool saveQuickAbort = QuickAbort;
3637 bool saveSuprErrs = SuprErrs;
3638 bool saveExitStat = ExitStat;
3643 usrerr("501 5.5.2 AUTH= requires a value");
3646 if (e->e_auth_param != NULL)
3648 usrerr("501 5.5.0 Duplicate AUTH parameter");
3651 if ((q = strchr(vp, ' ')) != NULL)
3654 len = strlen(vp) + 1;
3655 auth_param = xalloc(len);
3656 (void) sm_strlcpy(auth_param, vp, len);
3657 if (!xtextok(auth_param))
3659 usrerr("501 5.5.4 Syntax error in AUTH parameter value");
3660 /* just a warning? */
3664 /* XXX this might be cut off */
3665 (void) sm_strlcpy(pbuf, xuntextify(auth_param), sizeof pbuf);
3666 /* xalloc() the buffer instead? */
3668 /* XXX define this always or only if trusted? */
3669 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), pbuf);
3672 ** call Strust_auth to find out whether
3673 ** auth_param is acceptable (trusted)
3674 ** we shouldn't trust it if not authenticated
3675 ** (required by RFC, leave it to ruleset?)
3680 if (strcmp(auth_param, "<>") != 0 &&
3681 (rscheck("trust_auth", pbuf, NULL, e, RSF_RMCOMM,
3682 9, NULL, NOQID) != EX_OK || Errors > 0))
3686 q = e->e_auth_param;
3687 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
3688 pbuf, (q == NULL) ? "" : q);
3692 e->e_auth_param = "<>";
3693 # if _FFR_AUTH_PASSING
3694 macdefine(&BlankEnvelope.e_macro, A_PERM,
3695 macid("{auth_author}"), NULL);
3696 # endif /* _FFR_AUTH_PASSING */
3701 sm_dprintf("auth=\"%.100s\" trusted\n", pbuf);
3702 e->e_auth_param = sm_rpool_strdup_x(e->e_rpool,
3705 sm_free(auth_param); /* XXX */
3709 QuickAbort = saveQuickAbort;
3710 SuprErrs = saveSuprErrs;
3711 ExitStat = saveExitStat;
3714 #define PRTCHAR(c) ((isascii(c) && isprint(c)) ? (c) : '?')
3717 ** "by" is only accepted if DeliverByMin >= 0.
3718 ** We maybe could add this to the list of server_features.
3721 else if (sm_strcasecmp(kp, "by") == 0 && DeliverByMin >= 0)
3727 usrerr("501 5.5.2 BY= requires a value");
3731 e->e_deliver_by = strtol(vp, &s, 10);
3732 if (e->e_deliver_by == LONG_MIN ||
3733 e->e_deliver_by == LONG_MAX ||
3734 e->e_deliver_by > 999999999l ||
3735 e->e_deliver_by < -999999999l)
3737 usrerr("501 5.5.2 BY=%s out of range", vp);
3740 if (s == NULL || *s != ';')
3742 usrerr("501 5.5.2 BY= missing ';'");
3746 ++s; /* XXX: spaces allowed? */
3748 switch (tolower(*s))
3751 e->e_dlvr_flag = DLVR_NOTIFY;
3754 e->e_dlvr_flag = DLVR_RETURN;
3755 if (e->e_deliver_by <= 0)
3757 usrerr("501 5.5.4 mode R requires BY time > 0");
3760 if (DeliverByMin > 0 && e->e_deliver_by > 0 &&
3761 e->e_deliver_by < DeliverByMin)
3763 usrerr("555 5.5.2 time %ld less than %ld",
3764 e->e_deliver_by, (long) DeliverByMin);
3769 usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s));
3772 ++s; /* XXX: spaces allowed? */
3774 switch (tolower(*s))
3777 e->e_dlvr_flag |= DLVR_TRACE;
3782 usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s));
3786 /* XXX: check whether more characters follow? */
3790 usrerr("555 5.5.4 %s parameter unrecognized", kp);
3795 ** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
3798 ** a -- the address corresponding to the To: parameter.
3799 ** kp -- the parameter key.
3800 ** vp -- the value of that parameter.
3801 ** e -- the envelope.
3808 rcpt_esmtp_args(a, kp, vp, e)
3814 if (sm_strcasecmp(kp, "notify") == 0)
3818 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3820 usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
3825 usrerr("501 5.5.2 NOTIFY requires a value");
3828 a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
3829 a->q_flags |= QHASNOTIFY;
3830 macdefine(&e->e_macro, A_TEMP, macid("{dsn_notify}"), vp);
3832 if (sm_strcasecmp(vp, "never") == 0)
3834 for (p = vp; p != NULL; vp = p)
3839 if (sm_strcasecmp(vp, "success") == 0)
3840 a->q_flags |= QPINGONSUCCESS;
3841 else if (sm_strcasecmp(vp, "failure") == 0)
3842 a->q_flags |= QPINGONFAILURE;
3843 else if (sm_strcasecmp(vp, "delay") == 0)
3844 a->q_flags |= QPINGONDELAY;
3847 usrerr("501 5.5.4 Bad argument \"%s\" to NOTIFY",
3853 else if (sm_strcasecmp(kp, "orcpt") == 0)
3855 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3857 usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
3862 usrerr("501 5.5.2 ORCPT requires a value");
3865 if (strchr(vp, ';') == NULL || !xtextok(vp))
3867 usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
3870 if (a->q_orcpt != NULL)
3872 usrerr("501 5.5.0 Duplicate ORCPT parameter");
3875 a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp);
3879 usrerr("555 5.5.4 %s parameter unrecognized", kp);
3884 ** PRINTVRFYADDR -- print an entry in the verify queue
3887 ** a -- the address to print.
3888 ** last -- set if this is the last one.
3889 ** vrfy -- set if this is a VRFY command.
3895 ** Prints the appropriate 250 codes.
3897 #define OFFF (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */
3900 printvrfyaddr(a, last, vrfy)
3901 register ADDRESS *a;
3907 if (vrfy && a->q_mailer != NULL &&
3908 !bitnset(M_VRFY250, a->q_mailer->m_flags))
3909 (void) sm_strlcpy(fmtbuf, "252", sizeof fmtbuf);
3911 (void) sm_strlcpy(fmtbuf, "250", sizeof fmtbuf);
3912 fmtbuf[3] = last ? ' ' : '-';
3913 (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof fmtbuf - 4);
3914 if (a->q_fullname == NULL)
3916 if ((a->q_mailer == NULL ||
3917 a->q_mailer->m_addrtype == NULL ||
3918 sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
3919 strchr(a->q_user, '@') == NULL)
3920 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>",
3921 sizeof fmtbuf - OFFF);
3923 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
3924 sizeof fmtbuf - OFFF);
3925 message(fmtbuf, a->q_user, MyHostName);
3929 if ((a->q_mailer == NULL ||
3930 a->q_mailer->m_addrtype == NULL ||
3931 sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
3932 strchr(a->q_user, '@') == NULL)
3933 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
3934 sizeof fmtbuf - OFFF);
3936 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
3937 sizeof fmtbuf - OFFF);
3938 message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
3944 ** SASLMECHS -- get list of possible AUTH mechanisms
3947 ** conn -- SASL connection info.
3948 ** mechlist -- output parameter for list of mechanisms.
3955 saslmechs(conn, mechlist)
3959 int len, num, result;
3961 /* "user" is currently unused */
3963 result = sasl_listmech(conn, NULL,
3964 "", " ", "", (const char **) mechlist,
3965 (unsigned int *)&len, (unsigned int *)&num);
3966 # else /* SASL >= 20000 */
3967 result = sasl_listmech(conn, "user", /* XXX */
3968 "", " ", "", mechlist,
3969 (unsigned int *)&len, (unsigned int *)&num);
3970 # endif /* SASL >= 20000 */
3971 if (result != SASL_OK)
3974 sm_syslog(LOG_WARNING, NOQID,
3975 "AUTH error: listmech=%d, num=%d",
3982 sm_syslog(LOG_INFO, NOQID,
3983 "AUTH: available mech=%s, allowed mech=%s",
3984 *mechlist, AuthMechanisms);
3985 *mechlist = intersect(AuthMechanisms, *mechlist, NULL);
3989 *mechlist = NULL; /* be paranoid... */
3990 if (result == SASL_OK && LogLevel > 9)
3991 sm_syslog(LOG_WARNING, NOQID,
3992 "AUTH warning: no mechanisms");
3999 ** PROXY_POLICY -- define proxy policy for AUTH
4003 ** context -- unused.
4004 ** requested_user -- authorization identity.
4005 ** rlen -- authorization identity length.
4006 ** auth_identity -- authentication identity.
4007 ** alen -- authentication identity length.
4008 ** def_realm -- default user realm.
4009 ** urlen -- user realm length.
4010 ** propctx -- unused.
4016 ** sets {auth_authen} macro.
4020 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen,
4021 def_realm, urlen, propctx)
4024 const char *requested_user;
4026 const char *auth_identity;
4028 const char *def_realm;
4030 struct propctx *propctx;
4032 if (auth_identity == NULL)
4035 macdefine(&BlankEnvelope.e_macro, A_TEMP,
4036 macid("{auth_authen}"), (char *) auth_identity);
4040 # else /* SASL >= 20000 */
4043 ** PROXY_POLICY -- define proxy policy for AUTH
4046 ** context -- unused.
4047 ** auth_identity -- authentication identity.
4048 ** requested_user -- authorization identity.
4049 ** user -- allowed user (output).
4050 ** errstr -- possible error string (output).
4057 proxy_policy(context, auth_identity, requested_user, user, errstr)
4059 const char *auth_identity;
4060 const char *requested_user;
4062 const char **errstr;
4064 if (user == NULL || auth_identity == NULL)
4066 *user = newstr(auth_identity);
4069 # endif /* SASL >= 20000 */
4074 ** INITSRVTLS -- initialize server side TLS
4077 ** tls_ok -- should tls initialization be done?
4083 ** sets tls_ok_srv which is a static variable in this module.
4084 ** Do NOT remove assignments to it!
4094 /* do NOT remove assignment */
4095 tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, true, SrvCertFile,
4096 SrvKeyFile, CACertPath, CACertFile, DHParams);
4099 #endif /* STARTTLS */
4101 ** SRVFEATURES -- get features for SMTP server
4104 ** e -- envelope (should be session context).
4105 ** clientname -- name of client.
4106 ** features -- default features for this invocation.
4112 /* table with options: it uses just one character, how about strings? */
4116 unsigned int srvf_flag;
4117 } srv_feat_table[] =
4119 { 'A', SRV_OFFER_AUTH },
4120 { 'B', SRV_OFFER_VERB }, /* FFR; not documented in 8.12 */
4121 { 'D', SRV_OFFER_DSN }, /* FFR; not documented in 8.12 */
4122 { 'E', SRV_OFFER_ETRN }, /* FFR; not documented in 8.12 */
4123 { 'L', SRV_REQ_AUTH }, /* FFR; not documented in 8.12 */
4126 { 'N', SRV_NO_PIPE },
4127 # endif /* _FFR_NO_PIPE */
4128 { 'P', SRV_OFFER_PIPE },
4129 #endif /* PIPELINING */
4130 { 'R', SRV_VRFY_CLT }, /* FFR; not documented in 8.12 */
4131 { 'S', SRV_OFFER_TLS },
4132 /* { 'T', SRV_TMP_FAIL }, */
4133 { 'V', SRV_VRFY_CLT },
4134 { 'X', SRV_OFFER_EXPN }, /* FFR; not documented in 8.12 */
4135 /* { 'Y', SRV_OFFER_VRFY }, */
4140 srvfeatures(e, clientname, features)
4143 unsigned int features;
4147 char pvpbuf[PSBUFSIZE];
4150 r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf,
4154 if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
4156 if (pvp[1] != NULL && sm_strncasecmp(pvp[1], "temp", 4) == 0)
4157 return SRV_TMP_FAIL;
4160 ** General rule (see sendmail.h, d_flags):
4161 ** lower case: required/offered, upper case: Not required/available
4163 ** Since we can change some features per daemon, we have both
4164 ** cases here: turn on/off a feature.
4167 for (i = 1; pvp[i] != NULL; i++)
4173 if ((opt = srv_feat_table[j].srvf_opt) == '\0')
4176 sm_syslog(LOG_WARNING, e->e_id,
4177 "srvfeatures: unknown feature %s",
4183 features &= ~(srv_feat_table[j].srvf_flag);
4186 if (c == tolower(opt))
4188 features |= srv_feat_table[j].srvf_flag;
4198 ** HELP -- implement the HELP command.
4201 ** topic -- the topic we want help for.
4208 ** outputs the help file to message output.
4210 #define HELPVSTR "#vers "
4211 #define HELPVERSION 2
4218 register SM_FILE_T *hf;
4223 long sff = SFF_OPENASROOT|SFF_REGONLY;
4226 static int foundvers = -1;
4227 extern char Version[];
4229 if (DontLockReadFiles)
4231 if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
4232 sff |= SFF_SAFEDIRPATH;
4234 if (HelpFile == NULL ||
4235 (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
4239 message("502 5.3.0 Sendmail %s -- HELP not implemented",
4244 if (topic == NULL || *topic == '\0')
4255 len = strlen(topic);
4257 while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
4261 if (foundvers < 0 &&
4262 strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
4266 if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d",
4272 if (strncmp(buf, topic, len) == 0)
4278 /* print version if no/old vers# in file */
4279 if (foundvers < 2 && !noinfo)
4280 message("214-2.0.0 This is Sendmail version %s", Version);
4282 p = strpbrk(buf, " \t");
4284 p = buf + strlen(buf) - 1;
4290 translate_dollars(p);
4291 expand(p, inp, sizeof inp, e);
4294 message("214-2.0.0 %s", p);
4300 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
4302 message("214 2.0.0 End of HELP info");
4304 if (foundvers != 0 && foundvers < HELPVERSION)
4307 sm_syslog(LOG_WARNING, e->e_id,
4308 "%s too old (require version %d)",
4309 HelpFile, HELPVERSION);
4311 /* avoid log next time */
4315 (void) sm_io_close(hf, SM_TIME_DEFAULT);