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.31 2003/07/01 17:30:01 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));
73 static int reset_saslconn
__P((sasl_conn_t
**_conn
, char *_hostname
,
74 char *_remoteip
, char *_localip
,
75 char *_auth_id
, sasl_ssf_t
*_ext_ssf
));
77 # define RESET_SASLCONN \
78 result = reset_saslconn(&conn, hostname, remoteip, localip, auth_id, \
80 if (result != SASL_OK) \
82 /* This is pretty fatal */ \
86 # else /* SASL >= 20000 */
87 static int reset_saslconn
__P((sasl_conn_t
**_conn
, char *_hostname
,
88 struct sockaddr_in
*_saddr_r
,
89 struct sockaddr_in
*_saddr_l
,
90 sasl_external_properties_t
*_ext_ssf
));
91 # define RESET_SASLCONN \
92 result = reset_saslconn(&conn, hostname, &saddr_r, &saddr_l, &ext_ssf); \
93 if (result != SASL_OK) \
95 /* This is pretty fatal */ \
99 # endif /* SASL >= 20000 */
102 extern ENVELOPE BlankEnvelope
;
104 #define SKIP_SPACE(s) while (isascii(*s) && isspace(*s)) \
108 ** SMTP -- run the SMTP protocol.
111 ** nullserver -- if non-NULL, rejection message for
112 ** (almost) all SMTP commands.
113 ** d_flags -- daemon flags
114 ** e -- the envelope.
120 ** Reads commands from the input channel and processes them.
124 ** Notice: The smtp server doesn't have a session context like the client
125 ** side has (mci). Therefore some data (session oriented) is allocated
126 ** or assigned to the "wrong" structure (esp. STARTTLS, AUTH).
127 ** This should be fixed in a successor version.
132 char *cmd_name
; /* command name */
133 int cmd_code
; /* internal code, see below */
136 /* values for cmd_code */
137 #define CMDERROR 0 /* bad command */
138 #define CMDMAIL 1 /* mail -- designate sender */
139 #define CMDRCPT 2 /* rcpt -- designate recipient */
140 #define CMDDATA 3 /* data -- send message text */
141 #define CMDRSET 4 /* rset -- reset state */
142 #define CMDVRFY 5 /* vrfy -- verify address */
143 #define CMDEXPN 6 /* expn -- expand address */
144 #define CMDNOOP 7 /* noop -- do nothing */
145 #define CMDQUIT 8 /* quit -- close connection and die */
146 #define CMDHELO 9 /* helo -- be polite */
147 #define CMDHELP 10 /* help -- give usage info */
148 #define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */
149 #define CMDETRN 12 /* etrn -- flush queue */
151 # define CMDAUTH 13 /* auth -- SASL authenticate */
154 # define CMDSTLS 14 /* STARTTLS -- start TLS session */
155 #endif /* STARTTLS */
156 /* non-standard commands */
157 #define CMDVERB 17 /* verb -- go into verbose mode */
158 /* unimplemented commands from RFC 821 */
159 #define CMDUNIMPL 19 /* unimplemented rfc821 commands */
160 /* use this to catch and log "door handle" attempts on your system */
161 #define CMDLOGBOGUS 23 /* bogus command that should be logged */
162 /* debugging-only commands, only enabled if SMTPDEBUG is defined */
163 #define CMDDBGQSHOW 24 /* showq -- show send queue */
164 #define CMDDBGDEBUG 25 /* debug -- set debug mode */
167 ** Note: If you change this list, remember to update 'helpfile'
170 static struct cmd CmdTab
[] =
185 { "send", CMDUNIMPL
},
186 { "saml", CMDUNIMPL
},
187 { "soml", CMDUNIMPL
},
188 { "turn", CMDUNIMPL
},
190 { "auth", CMDAUTH
, },
193 { "starttls", CMDSTLS
, },
194 #endif /* STARTTLS */
195 /* remaining commands are here only to trap and log attempts to use them */
196 { "showq", CMDDBGQSHOW
},
197 { "debug", CMDDBGDEBUG
},
198 { "wiz", CMDLOGBOGUS
},
203 static char *CurSmtpClient
; /* who's at the other end of channel */
205 #ifndef MAXBADCOMMANDS
206 # define MAXBADCOMMANDS 25 /* maximum number of bad commands */
207 #endif /* ! MAXBADCOMMANDS */
208 #ifndef MAXNOOPCOMMANDS
209 # define MAXNOOPCOMMANDS 20 /* max "noise" commands before slowdown */
210 #endif /* ! MAXNOOPCOMMANDS */
211 #ifndef MAXHELOCOMMANDS
212 # define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */
213 #endif /* ! MAXHELOCOMMANDS */
214 #ifndef MAXVRFYCOMMANDS
215 # define MAXVRFYCOMMANDS 6 /* max VRFY/EXPN commands before slowdown */
216 #endif /* ! MAXVRFYCOMMANDS */
217 #ifndef MAXETRNCOMMANDS
218 # define MAXETRNCOMMANDS 8 /* max ETRN commands before slowdown */
219 #endif /* ! MAXETRNCOMMANDS */
221 # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */
222 #endif /* ! MAXTIMEOUT */
225 static SM_DEBUG_T DebugLeakSmtp
= SM_DEBUG_INITIALIZER("leak_smtp",
226 "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $");
227 #endif /* SM_HEAP_CHECK */
231 bool sm_gotmail
; /* mail command received */
232 unsigned int sm_nrcpts
; /* number of successful RCPT commands */
233 #if _FFR_ADAPTIVE_EOL
234 WARNING
: do NOT use
this FFR
, it is most likely broken
235 bool sm_crlf
; /* input in CRLF form? */
236 #endif /* _FFR_ADAPTIVE_EOL */
240 bool sm_milterlist
; /* any filters in the list? */
243 char *sm_quarmsg
; /* carry quarantining across messages */
244 #endif /* _FFR_QUARANTINE */
247 static void smtp_data
__P((SMTP_T
*, ENVELOPE
*));
249 #define MSG_TEMPFAIL "451 4.7.1 Please try again later"
252 # define MILTER_ABORT(e) milter_abort((e))
255 # define MILTER_SHUTDOWN \
256 if (strncmp(response, "421 ", 4) == 0) \
258 e->e_sendqueue = NULL; \
261 #else /* _FFR_MILTER_421 */
262 # define MILTER_SHUTDOWN
263 #endif /* _FFR_MILTER_421 */
265 # define MILTER_REPLY(str) \
267 int savelogusrerrs = LogUsrErrs; \
271 case SMFIR_REPLYCODE: \
272 if (MilterLogLevel > 3) \
274 sm_syslog(LOG_INFO, e->e_id, \
275 "Milter: %s=%s, reject=%s", \
276 str, addr, response); \
277 LogUsrErrs = false; \
284 if (MilterLogLevel > 3) \
286 sm_syslog(LOG_INFO, e->e_id, \
287 "Milter: %s=%s, reject=550 5.7.1 Command rejected", \
289 LogUsrErrs = false; \
291 usrerr("550 5.7.1 Command rejected"); \
294 case SMFIR_DISCARD: \
295 if (MilterLogLevel > 3) \
296 sm_syslog(LOG_INFO, e->e_id, \
297 "Milter: %s=%s, discard", \
299 e->e_flags |= EF_DISCARD; \
302 case SMFIR_TEMPFAIL: \
303 if (MilterLogLevel > 3) \
305 sm_syslog(LOG_INFO, e->e_id, \
306 "Milter: %s=%s, reject=%s", \
307 str, addr, MSG_TEMPFAIL); \
308 LogUsrErrs = false; \
310 usrerr(MSG_TEMPFAIL); \
313 LogUsrErrs = savelogusrerrs; \
314 if (response != NULL) \
315 sm_free(response); /* XXX */ \
319 # define MILTER_ABORT(e)
322 /* clear all SMTP state (for HELO/EHLO/RSET) */
323 #define CLEAR_STATE(cmd) \
325 /* abort milter filters */ \
328 if (smtp.sm_nrcpts > 0) \
330 logundelrcpts(e, cmd, 10, false); \
331 smtp.sm_nrcpts = 0; \
332 macdefine(&e->e_macro, A_PERM, \
333 macid("{nrcpts}"), "0"); \
336 e->e_sendqueue = NULL; \
337 e->e_flags |= EF_CLRQUEUE; \
339 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) \
340 logsender(e, NULL); \
341 e->e_flags &= ~EF_LOGSENDER; \
343 /* clean up a bit */ \
344 smtp.sm_gotmail = false; \
346 dropenvelope(e, true, false); \
347 sm_rpool_free(e->e_rpool); \
348 e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \
352 /* sleep to flatten out connection load */
353 #define MIN_DELAY_LOG 15 /* wait before logging this again */
355 /* is it worth setting the process title for 1s? */
356 #define DELAY_CONN(cmd) \
357 if (DelayLA > 0 && (CurrentLA = getla()) >= DelayLA) \
361 sm_setproctitle(true, e, \
362 "%s: %s: delaying %s: load average: %d", \
363 qid_printname(e), CurSmtpClient, \
365 if (LogLevel > 8 && (dnow = curtime()) > log_delay) \
367 sm_syslog(LOG_INFO, e->e_id, \
368 "delaying=%s, load average=%d >= %d", \
369 cmd, CurrentLA, DelayLA); \
370 log_delay = dnow + MIN_DELAY_LOG; \
373 sm_setproctitle(true, e, "%s %s: %.80s", \
374 qid_printname(e), CurSmtpClient, inp); \
379 smtp(nullserver
, d_flags
, e
)
380 char *volatile nullserver
;
382 register ENVELOPE
*volatile e
;
384 register char *volatile p
;
385 register struct cmd
*volatile c
= NULL
;
387 auto ADDRESS
*vrfyqueue
;
389 volatile bool gothello
; /* helo command received */
390 bool vrfy
; /* set if this is a vrfy command */
391 char *volatile protocol
; /* sending protocol */
392 char *volatile sendinghost
; /* sending hostname */
393 char *volatile peerhostname
; /* name of SMTP peer or "localhost" */
396 volatile unsigned int n_badcmds
= 0; /* count of bad commands */
397 volatile unsigned int n_badrcpts
= 0; /* number of rejected RCPT */
398 volatile unsigned int n_verifies
= 0; /* count of VRFY/EXPN */
399 volatile unsigned int n_etrn
= 0; /* count of ETRN */
400 volatile unsigned int n_noop
= 0; /* count of NOOP/VERB/etc */
401 volatile unsigned int n_helo
= 0; /* count of HELO/EHLO */
402 volatile int save_sevenbitinput
;
404 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
406 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
407 volatile bool tempfail
= false;
408 volatile time_t wt
; /* timeout after too many commands */
409 volatile time_t previous
; /* time after checksmtpattack() */
410 volatile bool lognullconnection
= true;
414 char *greetcode
= "220";
415 char *hostname
; /* my hostname ($j) */
418 char *args
[MAXSMTPARGS
];
420 char cmdbuf
[MAXLINE
];
423 volatile bool sasl_ok
;
424 volatile unsigned int n_auth
= 0; /* count of AUTH commands */
427 volatile int authenticating
;
434 char localip
[60], remoteip
[60];
435 # else /* SASL >= 20000 */
438 sasl_external_properties_t ext_ssf
;
439 struct sockaddr_in saddr_l
;
440 struct sockaddr_in saddr_r
;
441 # endif /* SASL >= 20000 */
442 sasl_security_properties_t ssp
;
444 unsigned int inlen
, out2len
;
446 char *volatile auth_type
;
448 volatile unsigned int n_mechs
;
454 volatile bool tls_active
= false;
456 volatile bool smtps
= false;
457 # endif /* _FFR_SMTP_SSL */
461 #endif /* STARTTLS */
462 volatile unsigned int features
;
466 # endif /* _FFR_NO_PIPE */
467 #endif /* PIPELINING */
468 volatile time_t log_delay
= (time_t) 0;
470 save_sevenbitinput
= SevenBitInput
;
473 smtp
.sm_milterize
= (nullserver
== NULL
);
474 smtp
.sm_milterlist
= false;
477 /* setup I/O fd correctly for the SMTP server */
481 if (sm_debug_active(&DebugLeakSmtp
, 1))
484 sm_dprintf("smtp() heap group #%d\n", sm_heap_group());
486 #endif /* SM_HEAP_CHECK */
488 /* XXX the rpool should be set when e is initialized in main() */
489 e
->e_rpool
= sm_rpool_new_x(NULL
);
490 e
->e_macro
.mac_rpool
= e
->e_rpool
;
494 peerhostname
= RealHostName
;
495 if (peerhostname
== NULL
)
496 peerhostname
= "localhost";
497 CurHostName
= peerhostname
;
498 CurSmtpClient
= macvalue('_', e
);
499 if (CurSmtpClient
== NULL
)
500 CurSmtpClient
= CurHostName
;
502 /* check_relay may have set discard bit, save for later */
503 smtp
.sm_discard
= bitset(EF_DISCARD
, e
->e_flags
);
506 /* auto-flush output when reading input */
507 (void) sm_io_autoflush(InChannel
, OutChannel
);
508 #endif /* PIPELINING */
510 sm_setproctitle(true, e
, "server %s startup", CurSmtpClient
);
512 /* Set default features for server. */
513 features
= ((bitset(PRIV_NOETRN
, PrivacyFlags
) ||
514 bitnset(D_NOETRN
, d_flags
)) ? SRV_NONE
: SRV_OFFER_ETRN
)
515 | (bitnset(D_AUTHREQ
, d_flags
) ? SRV_REQ_AUTH
: SRV_NONE
)
516 | (bitset(PRIV_NOEXPN
, PrivacyFlags
) ? SRV_NONE
518 | (bitset(PRIV_NOVERB
, PrivacyFlags
)
519 ? SRV_NONE
: SRV_OFFER_VERB
)))
520 | (bitset(PRIV_NORECEIPTS
, PrivacyFlags
) ? SRV_NONE
523 | (bitnset(D_NOAUTH
, d_flags
) ? SRV_NONE
: SRV_OFFER_AUTH
)
527 #endif /* PIPELINING */
529 | (bitnset(D_NOTLS
, d_flags
) ? SRV_NONE
: SRV_OFFER_TLS
)
530 | (bitset(TLS_I_NO_VRFY
, TLS_Srv_Opts
) ? SRV_NONE
532 #endif /* STARTTLS */
534 if (nullserver
== NULL
)
536 features
= srvfeatures(e
, CurSmtpClient
, features
);
537 if (bitset(SRV_TMP_FAIL
, features
))
540 sm_syslog(LOG_ERR
, NOQID
,
541 "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled",
543 nullserver
= "450 4.3.0 Please try again later.";
547 else if (bitset(SRV_NO_PIPE
, features
))
549 /* for consistency */
550 features
&= ~SRV_OFFER_PIPE
;
552 # endif /* _FFR_NO_PIPE */
553 #endif /* PIPELINING */
556 hostname
= macvalue('j', e
);
558 sasl_ok
= bitset(SRV_OFFER_AUTH
, features
);
560 authenticating
= SASL_NOT_AUTH
;
562 /* SASL server new connection */
566 result
= sasl_server_new("smtp", hostname
, NULL
, NULL
, NULL
,
569 /* use empty realm: only works in SASL > 1.5.5 */
570 result
= sasl_server_new("smtp", hostname
, "", NULL
, 0, &conn
);
571 # else /* SASL >= 20000 */
572 /* use no realm -> realm is set to hostname by SASL lib */
573 result
= sasl_server_new("smtp", hostname
, NULL
, NULL
, 0,
575 # endif /* SASL >= 20000 */
576 sasl_ok
= result
== SASL_OK
;
580 sm_syslog(LOG_WARNING
, NOQID
,
581 "AUTH error: sasl_server_new failed=%d",
588 ** SASL set properties for sasl
589 ** set local/remote IP
590 ** XXX Cyrus SASL v1 only supports IPv4
592 ** XXX where exactly are these used/required?
597 # if NETINET || NETINET6
598 in
= macvalue(macid("{daemon_family}"), e
);
601 strcmp(in
, "inet6") == 0 ||
602 # endif /* NETINET6 */
603 strcmp(in
, "inet") == 0))
605 SOCKADDR_LEN_T addrsize
;
609 addrsize
= sizeof(saddr_r
);
610 if (getpeername(sm_io_getinfo(InChannel
, SM_IO_WHAT_FD
,
612 (struct sockaddr
*) &saddr_r
,
615 if (iptostring(&saddr_r
, addrsize
,
616 remoteip
, sizeof remoteip
))
618 sasl_setprop(conn
, SASL_IPREMOTEPORT
,
621 addrsize
= sizeof(saddr_l
);
622 if (getsockname(sm_io_getinfo(InChannel
,
625 (struct sockaddr
*) &saddr_l
,
628 if (iptostring(&saddr_l
, addrsize
,
639 # endif /* NETINET || NETINET6 */
640 # else /* SASL >= 20000 */
642 in
= macvalue(macid("{daemon_family}"), e
);
643 if (in
!= NULL
&& strcmp(in
, "inet") == 0)
645 SOCKADDR_LEN_T addrsize
;
647 addrsize
= sizeof(struct sockaddr_in
);
648 if (getpeername(sm_io_getinfo(InChannel
, SM_IO_WHAT_FD
,
650 (struct sockaddr
*)&saddr_r
,
653 sasl_setprop(conn
, SASL_IP_REMOTE
, &saddr_r
);
654 addrsize
= sizeof(struct sockaddr_in
);
655 if (getsockname(sm_io_getinfo(InChannel
,
658 (struct sockaddr
*)&saddr_l
,
660 sasl_setprop(conn
, SASL_IP_LOCAL
,
664 # endif /* NETINET */
665 # endif /* SASL >= 20000 */
671 macdefine(&BlankEnvelope
.e_macro
, A_PERM
,
672 macid("{auth_author}"), NULL
);
676 (void) memset(&ssp
, '\0', sizeof ssp
);
678 /* XXX should these be options settable via .cf ? */
679 /* ssp.min_ssf = 0; is default due to memset() */
681 # endif /* STARTTLS */
683 ssp
.max_ssf
= MaxSLBits
;
684 ssp
.maxbufsize
= MAXOUTLEN
;
686 ssp
.security_flags
= SASLOpts
& SASL_SEC_MASK
;
687 sasl_ok
= sasl_setprop(conn
, SASL_SEC_PROPS
, &ssp
) == SASL_OK
;
692 ** external security strength factor;
693 ** currently we have none so zero
699 sasl_ok
= ((sasl_setprop(conn
, SASL_SSF_EXTERNAL
,
700 &ext_ssf
) == SASL_OK
) &&
701 (sasl_setprop(conn
, SASL_AUTH_EXTERNAL
,
702 auth_id
) == SASL_OK
));
703 # else /* SASL >= 20000 */
705 ext_ssf
.auth_id
= NULL
;
706 sasl_ok
= sasl_setprop(conn
, SASL_SSF_EXTERNAL
,
707 &ext_ssf
) == SASL_OK
;
708 # endif /* SASL >= 20000 */
711 n_mechs
= saslmechs(conn
, &mechlist
);
716 #endif /* STARTTLS */
719 if (smtp
.sm_milterize
)
723 /* initialize mail filter connection */
724 smtp
.sm_milterlist
= milter_init(e
, &state
);
728 if (MilterLogLevel
> 3)
729 sm_syslog(LOG_INFO
, e
->e_id
,
730 "Milter: initialization failed, rejecting commands");
732 nullserver
= "Command rejected";
733 smtp
.sm_milterize
= false;
737 if (MilterLogLevel
> 3)
738 sm_syslog(LOG_INFO
, e
->e_id
,
739 "Milter: initialization failed, temp failing commands");
741 smtp
.sm_milterize
= false;
746 if (smtp
.sm_milterlist
&& smtp
.sm_milterize
&&
747 !bitset(EF_DISCARD
, e
->e_flags
))
752 response
= milter_connect(peerhostname
, RealHostAddr
,
756 case SMFIR_REPLYCODE
: /* REPLYCODE shouldn't happen */
758 if (MilterLogLevel
> 3)
759 sm_syslog(LOG_INFO
, e
->e_id
,
760 "Milter: connect: host=%s, addr=%s, rejecting commands",
762 anynet_ntoa(&RealHostAddr
));
764 nullserver
= "Command rejected";
765 smtp
.sm_milterize
= false;
769 if (MilterLogLevel
> 3)
770 sm_syslog(LOG_INFO
, e
->e_id
,
771 "Milter: connect: host=%s, addr=%s, temp failing commands",
773 anynet_ntoa(&RealHostAddr
));
775 smtp
.sm_milterize
= false;
780 if (MilterLogLevel
> 3)
781 sm_syslog(LOG_INFO
, e
->e_id
,
782 "Milter: connect: host=%s, addr=%s, shutdown",
784 anynet_ntoa(&RealHostAddr
));
786 smtp
.sm_milterize
= false;
787 message("421 4.7.0 %s closing connection",
790 /* arrange to ignore send list */
791 e
->e_sendqueue
= NULL
;
793 #endif /* _FFR_MILTER_421 */
795 if (response
!= NULL
)
797 sm_free(response
); /* XXX */
803 /* If this an smtps connection, start TLS now */
804 smtps
= bitnset(D_SMTPS
, d_flags
);
813 # endif /* _FFR_SMTP_SSL */
814 #endif /* STARTTLS */
816 /* output the first line, inserting "ESMTP" as second word */
817 if (*greetcode
== '5')
818 (void) sm_snprintf(inp
, sizeof inp
, "%s not accepting messages",
821 expand(SmtpGreeting
, inp
, sizeof inp
, e
);
823 p
= strchr(inp
, '\n');
826 id
= strchr(inp
, ' ');
828 id
= &inp
[strlen(inp
)];
830 (void) sm_snprintf(cmdbuf
, sizeof cmdbuf
,
831 "%s %%.*s ESMTP%%s", greetcode
);
833 (void) sm_snprintf(cmdbuf
, sizeof cmdbuf
,
834 "%s-%%.*s ESMTP%%s", greetcode
);
835 message(cmdbuf
, (int) (id
- inp
), inp
, id
);
837 /* output remaining lines */
838 while ((id
= p
) != NULL
&& (p
= strchr(id
, '\n')) != NULL
)
841 if (isascii(*id
) && isspace(*id
))
843 (void) sm_strlcpyn(cmdbuf
, sizeof cmdbuf
, 2, greetcode
, "-%s");
848 if (isascii(*id
) && isspace(*id
))
850 (void) sm_strlcpyn(cmdbuf
, sizeof cmdbuf
, 2, greetcode
, " %s");
855 sendinghost
= macvalue('s', e
);
858 /* If quarantining by a connect/ehlo action, save between messages */
859 if (e
->e_quarmsg
== NULL
)
860 smtp
.sm_quarmsg
= NULL
;
862 smtp
.sm_quarmsg
= newstr(e
->e_quarmsg
);
863 #endif /* _FFR_QUARANTINE */
865 /* sendinghost's storage must outlive the current envelope */
866 if (sendinghost
!= NULL
)
867 sendinghost
= sm_strdup_x(sendinghost
);
868 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
870 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
872 smtp
.sm_gotmail
= false;
882 e
->e_flags
&= ~(EF_VRFYONLY
|EF_GLOBALERRS
);
884 /* setup for the read */
888 (void) sm_io_flush(smioout
, SM_TIME_DEFAULT
);
890 /* read the input line */
891 SmtpPhase
= "server cmd read";
892 sm_setproctitle(true, e
, "server %s cmd read", CurSmtpClient
);
895 ** XXX SMTP AUTH requires accepting any length,
896 ** at least for challenge/response
901 if (sm_io_error(OutChannel
) ||
902 (p
= sfgets(inp
, sizeof inp
, InChannel
,
903 TimeOuts
.to_nextcommand
, SmtpPhase
)) == NULL
)
907 d
= macvalue(macid("{daemon_name}"), e
);
910 /* end of file, just die */
914 /* close out milter filters */
918 message("421 4.4.1 %s Lost input channel from %s",
919 MyHostName
, CurSmtpClient
);
920 if (LogLevel
> (smtp
.sm_gotmail
? 1 : 19))
921 sm_syslog(LOG_NOTICE
, e
->e_id
,
922 "lost input channel from %s to %s after %s",
924 (c
== NULL
|| c
->cmd_name
== NULL
) ? "startup" : c
->cmd_name
);
926 ** If have not accepted mail (DATA), do not bounce
927 ** bad addresses back to sender.
930 if (bitset(EF_CLRQUEUE
, e
->e_flags
))
931 e
->e_sendqueue
= NULL
;
935 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
938 #if _FFR_BLOCK_PROXIES
939 size_t inplen
, cmdlen
;
942 static char *http_cmds
[] = { "GET", "POST",
943 "CONNECT", "USER", NULL
};
945 inplen
= strlen(inp
);
946 for (idx
= 0; (http_cmd
= http_cmds
[idx
]) != NULL
;
949 cmdlen
= strlen(http_cmd
);
950 if (cmdlen
< inplen
&&
951 sm_strncasecmp(inp
, http_cmd
, cmdlen
) == 0 &&
952 isascii(inp
[cmdlen
]) && isspace(inp
[cmdlen
]))
954 /* Open proxy, drop it */
955 message("421 4.7.0 %s Rejecting open proxy %s",
956 MyHostName
, CurSmtpClient
);
957 sm_syslog(LOG_INFO
, e
->e_id
,
958 "%s: probable open proxy: command=%.40s",
963 #endif /* _FFR_BLOCK_PROXIES */
964 #if _FFR_ADAPTIVE_EOL
968 p
= strchr(inp
, '\n');
969 if (p
== NULL
|| p
<= inp
|| p
[-1] != '\r')
971 smtp
.sm_crlf
= false;
972 if (tTd(66, 1) && LogLevel
> 8)
974 /* how many bad guys are there? */
975 sm_syslog(LOG_INFO
, NOQID
,
976 "%s did not use CRLF",
980 #endif /* _FFR_ADAPTIVE_EOL */
983 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
985 /* clean up end of line */
991 ** if there is more input and pipelining is disabled:
992 ** delay ... (and maybe discard the input?)
993 ** XXX this doesn't really work, at least in tests using
994 ** telnet SM_IO_IS_READABLE only returns 1 if there were
995 ** more than 2 input lines available.
998 if (bitset(SRV_NO_PIPE
, features
) &&
999 sm_io_getinfo(InChannel
, SM_IO_IS_READABLE
, NULL
) > 0)
1002 sm_syslog(LOG_INFO
, NOQID
,
1003 "unauthorized PIPELINING, sleeping");
1007 # endif /* _FFR_NO_PIPE */
1008 #endif /* PIPELINING */
1011 if (authenticating
== SASL_PROC_AUTH
)
1016 authenticating
= SASL_NOT_AUTH
;
1017 message("501 5.5.2 missing input");
1022 if (*inp
== '*' && *(inp
+ 1) == '\0')
1024 authenticating
= SASL_NOT_AUTH
;
1027 message("501 5.0.0 AUTH aborted");
1032 /* could this be shorter? XXX */
1034 in
= xalloc(strlen(inp
) + 1);
1035 result
= sasl_decode64(inp
, strlen(inp
), in
,
1036 strlen(inp
), &inlen
);
1037 # else /* SASL >= 20000 */
1038 out
= xalloc(strlen(inp
));
1039 result
= sasl_decode64(inp
, strlen(inp
), out
, &outlen
);
1040 # endif /* SASL >= 20000 */
1041 if (result
!= SASL_OK
)
1043 authenticating
= SASL_NOT_AUTH
;
1046 message("501 5.5.4 cannot decode AUTH parameter %s",
1050 # endif /* SASL >= 20000 */
1056 result
= sasl_server_step(conn
, in
, inlen
,
1059 # else /* SASL >= 20000 */
1060 result
= sasl_server_step(conn
, out
, outlen
,
1061 &out
, &outlen
, &errstr
);
1062 # endif /* SASL >= 20000 */
1064 /* get an OK if we're done */
1065 if (result
== SASL_OK
)
1068 message("235 2.0.0 OK Authenticated");
1069 authenticating
= SASL_IS_AUTH
;
1070 macdefine(&BlankEnvelope
.e_macro
, A_TEMP
,
1071 macid("{auth_type}"), auth_type
);
1074 user
= macvalue(macid("{auth_authen}"), e
);
1076 /* get security strength (features) */
1077 result
= sasl_getprop(conn
, SASL_SSF
,
1078 (const void **) &ssf
);
1079 # else /* SASL >= 20000 */
1080 result
= sasl_getprop(conn
, SASL_USERNAME
,
1082 if (result
!= SASL_OK
)
1085 macdefine(&BlankEnvelope
.e_macro
,
1087 macid("{auth_authen}"), NULL
);
1091 macdefine(&BlankEnvelope
.e_macro
,
1093 macid("{auth_authen}"), user
);
1098 sasl_getprop(conn
, SASL_REALM
, (void **) &data
);
1101 /* get security strength (features) */
1102 result
= sasl_getprop(conn
, SASL_SSF
,
1104 # endif /* SASL >= 20000 */
1105 if (result
!= SASL_OK
)
1107 macdefine(&BlankEnvelope
.e_macro
,
1109 macid("{auth_ssf}"), "0");
1116 (void) sm_snprintf(pbuf
, sizeof pbuf
,
1118 macdefine(&BlankEnvelope
.e_macro
,
1120 macid("{auth_ssf}"), pbuf
);
1122 sm_dprintf("AUTH auth_ssf: %u\n",
1127 ** Only switch to encrypted connection
1128 ** if a security layer has been negotiated
1131 if (ssf
!= NULL
&& *ssf
> 0)
1134 ** Convert I/O layer to use SASL.
1135 ** If the call fails, the connection
1139 if (sfdcsasl(&InChannel
, &OutChannel
,
1142 /* restart dialogue */
1145 (void) sm_io_autoflush(InChannel
,
1147 # endif /* PIPELINING */
1150 syserr("503 5.3.3 SASL TLS failed");
1153 /* NULL pointer ok since it's our function */
1155 sm_syslog(LOG_INFO
, NOQID
,
1156 "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d",
1158 shortenstring(user
, 128),
1161 else if (result
== SASL_CONTINUE
)
1163 len
= ENC64LEN(outlen
);
1165 result
= sasl_encode64(out
, outlen
, out2
, len
,
1167 if (result
!= SASL_OK
)
1169 /* correct code? XXX */
1170 /* 454 Temp. authentication failure */
1171 message("454 4.5.4 Internal error: unable to encode64");
1173 sm_syslog(LOG_WARNING
, e
->e_id
,
1174 "AUTH encode64 error [%d for \"%s\"]",
1177 authenticating
= SASL_NOT_AUTH
;
1181 message("334 %s", out2
);
1183 sm_dprintf("AUTH continue: msg='%s' len=%u\n",
1188 # endif /* SASL >= 20000 */
1192 /* not SASL_OK or SASL_CONT */
1193 message("535 5.7.0 authentication failed");
1195 sm_syslog(LOG_WARNING
, e
->e_id
,
1196 "AUTH failure (%s): %s (%d) %s",
1198 sasl_errstring(result
, NULL
,
1202 sasl_errdetail(conn
));
1203 # else /* SASL >= 20000 */
1204 errstr
== NULL
? "" : errstr
);
1205 # endif /* SASL >= 20000 */
1207 authenticating
= SASL_NOT_AUTH
;
1212 /* don't want to do any of this if authenticating */
1215 /* echo command to transcript */
1216 if (e
->e_xfp
!= NULL
)
1217 (void) sm_io_fprintf(e
->e_xfp
, SM_TIME_DEFAULT
,
1221 sm_syslog(LOG_INFO
, e
->e_id
, "<-- %s", inp
);
1223 /* break off command */
1224 for (p
= inp
; isascii(*p
) && isspace(*p
); p
++)
1227 while (*p
!= '\0' &&
1228 !(isascii(*p
) && isspace(*p
)) &&
1229 cmd
< &cmdbuf
[sizeof cmdbuf
- 2])
1233 /* throw away leading whitespace */
1236 /* decode command */
1237 for (c
= CmdTab
; c
->cmd_name
!= NULL
; c
++)
1239 if (sm_strcasecmp(c
->cmd_name
, cmdbuf
) == 0)
1246 /* check whether a "non-null" command has been used */
1247 switch (c
->cmd_code
)
1251 /* avoid information leak; take first two words? */
1260 lognullconnection
= false;
1267 if (e
->e_id
== NULL
)
1268 sm_setproctitle(true, e
, "%s: %.80s",
1271 sm_setproctitle(true, e
, "%s %s: %.80s",
1278 ** If we are running as a null server, return 550
1279 ** to almost everything.
1282 if (nullserver
!= NULL
|| bitnset(D_ETRNONLY
, d_flags
))
1284 switch (c
->cmd_code
)
1291 /* process normally */
1295 if (bitnset(D_ETRNONLY
, d_flags
) &&
1302 #if MAXBADCOMMANDS > 0
1303 /* theoretically this could overflow */
1304 if (nullserver
!= NULL
&&
1305 ++n_badcmds
> MAXBADCOMMANDS
)
1307 message("421 4.7.0 %s Too many bad commands; closing connection",
1310 /* arrange to ignore send list */
1311 e
->e_sendqueue
= NULL
;
1314 #endif /* MAXBADCOMMANDS > 0 */
1315 if (nullserver
!= NULL
)
1317 if (ISSMTPREPLY(nullserver
))
1320 usrerr("550 5.0.0 %s",
1324 usrerr("452 4.4.5 Insufficient disk space; try again later");
1329 switch (c
->cmd_code
)
1332 case CMDAUTH
: /* sasl */
1334 if (!sasl_ok
|| n_mechs
<= 0)
1336 message("503 5.3.3 AUTH not available");
1339 if (authenticating
== SASL_IS_AUTH
)
1341 message("503 5.5.0 Already Authenticated");
1344 if (smtp
.sm_gotmail
)
1346 message("503 5.5.0 AUTH not permitted during a mail transaction");
1352 sm_syslog(LOG_INFO
, e
->e_id
,
1353 "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)",
1355 usrerr("454 4.7.1 Please try again later");
1361 /* crude way to avoid crack attempts */
1362 (void) checksmtpattack(&n_auth
, n_mechs
+ 1, true,
1365 /* make sure mechanism (p) is a valid string */
1366 for (q
= p
; *q
!= '\0' && isascii(*q
); q
++)
1371 while (*++q
!= '\0' &&
1372 isascii(*q
) && isspace(*q
))
1375 ismore
= (*q
!= '\0');
1382 message("501 5.5.2 AUTH mechanism must be specified");
1386 /* check whether mechanism is available */
1387 if (iteminlist(p
, mechlist
, " ") == NULL
)
1389 message("504 5.3.3 AUTH mechanism %.32s not available",
1396 /* could this be shorter? XXX */
1398 in
= xalloc(strlen(q
) + 1);
1399 result
= sasl_decode64(q
, strlen(q
), in
,
1401 # else /* SASL >= 20000 */
1402 in
= sm_rpool_malloc(e
->e_rpool
, strlen(q
));
1403 result
= sasl_decode64(q
, strlen(q
), in
,
1405 # endif /* SASL >= 20000 */
1406 if (result
!= SASL_OK
)
1408 message("501 5.5.4 cannot BASE64 decode '%s'",
1411 sm_syslog(LOG_WARNING
, e
->e_id
,
1412 "AUTH decode64 error [%d for \"%s\"]",
1415 authenticating
= SASL_NOT_AUTH
;
1418 # endif /* SASL >= 20000 */
1430 /* see if that auth type exists */
1432 result
= sasl_server_start(conn
, p
, in
, inlen
,
1436 # else /* SASL >= 20000 */
1437 result
= sasl_server_start(conn
, p
, in
, inlen
,
1438 &out
, &outlen
, &errstr
);
1439 # endif /* SASL >= 20000 */
1441 if (result
!= SASL_OK
&& result
!= SASL_CONTINUE
)
1443 message("535 5.7.0 authentication failed");
1445 sm_syslog(LOG_ERR
, e
->e_id
,
1446 "AUTH failure (%s): %s (%d) %s",
1448 sasl_errstring(result
, NULL
,
1452 sasl_errdetail(conn
));
1453 # else /* SASL >= 20000 */
1455 # endif /* SASL >= 20000 */
1459 auth_type
= newstr(p
);
1461 if (result
== SASL_OK
)
1463 /* ugly, but same code */
1465 /* authenticated by the initial response */
1468 /* len is at least 2 */
1469 len
= ENC64LEN(outlen
);
1471 result
= sasl_encode64(out
, outlen
, out2
, len
,
1474 if (result
!= SASL_OK
)
1476 message("454 4.5.4 Temporary authentication failure");
1478 sm_syslog(LOG_WARNING
, e
->e_id
,
1479 "AUTH encode64 error [%d for \"%s\"]",
1483 authenticating
= SASL_NOT_AUTH
;
1488 message("334 %s", out2
);
1489 authenticating
= SASL_PROC_AUTH
;
1493 # endif /* SASL >= 20000 */
1498 case CMDSTLS
: /* starttls */
1499 DELAY_CONN("STARTTLS");
1502 message("501 5.5.2 Syntax error (no parameters allowed)");
1505 if (!bitset(SRV_OFFER_TLS
, features
))
1507 message("503 5.5.0 TLS not available");
1512 message("454 4.3.3 TLS not available after start");
1515 if (smtp
.sm_gotmail
)
1517 message("503 5.5.0 TLS not permitted during a mail transaction");
1523 sm_syslog(LOG_INFO
, e
->e_id
,
1524 "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)",
1526 usrerr("454 4.7.1 Please try again later");
1531 # endif /* _FFR_SMTP_SSL */
1534 ** XXX do we need a temp key ?
1536 # else /* TLS_NO_RSA */
1537 # endif /* TLS_NO_RSA */
1539 # if TLS_VRFY_PER_CTX
1541 ** Note: this sets the verification globally
1543 ** it's ok since it applies only to one transaction
1546 TLS_VERIFY_CLIENT();
1547 # endif /* TLS_VRFY_PER_CTX */
1549 if (srv_ssl
!= NULL
)
1551 else if ((srv_ssl
= SSL_new(srv_ctx
)) == NULL
)
1553 message("454 4.3.3 TLS not available: error generating SSL handle");
1555 tlslogerr("server");
1558 # else /* _FFR_SMTP_SSL */
1560 # endif /* _FFR_SMTP_SSL */
1563 # if !TLS_VRFY_PER_CTX
1565 ** this could be used if it were possible to set
1566 ** verification per SSL (connection)
1567 ** not just per SSL_CTX (global)
1570 TLS_VERIFY_CLIENT();
1571 # endif /* !TLS_VRFY_PER_CTX */
1573 rfd
= sm_io_getinfo(InChannel
, SM_IO_WHAT_FD
, NULL
);
1574 wfd
= sm_io_getinfo(OutChannel
, SM_IO_WHAT_FD
, NULL
);
1576 if (rfd
< 0 || wfd
< 0 ||
1577 SSL_set_rfd(srv_ssl
, rfd
) <= 0 ||
1578 SSL_set_wfd(srv_ssl
, wfd
) <= 0)
1580 message("454 4.3.3 TLS not available: error set fd");
1585 # else /* _FFR_SMTP_SSL */
1587 # endif /* _FFR_SMTP_SSL */
1591 # endif /* _FFR_SMTP_SSL */
1592 message("220 2.0.0 Ready to start TLS");
1594 (void) sm_io_flush(OutChannel
, SM_TIME_DEFAULT
);
1595 # endif /* PIPELINING */
1597 SSL_set_accept_state(srv_ssl
);
1599 # define SSL_ACC(s) SSL_accept(s)
1601 tlsstart
= curtime();
1603 if ((r
= SSL_ACC(srv_ssl
)) <= 0)
1608 time_t now
= curtime();
1611 /* what to do in this case? */
1612 i
= SSL_get_error(srv_ssl
, r
);
1615 ** For SSL_ERROR_WANT_{READ,WRITE}:
1616 ** There is no SSL record available yet
1617 ** or there is only a partial SSL record
1618 ** removed from the network (socket) buffer
1619 ** into the SSL buffer. The SSL_accept will
1620 ** only succeed when a full SSL record is
1621 ** available (assuming a "real" error
1622 ** doesn't happen). To handle when a "real"
1623 ** error does happen the select is set for
1625 ** The connection may be re-negotiated
1626 ** during this time so both read and write
1627 ** "want errors" need to be handled.
1628 ** A select() exception loops back so that
1629 ** a proper SSL error message can be gotten.
1632 left
= TimeOuts
.to_starttls
- (now
- tlsstart
);
1633 timedout
= left
<= 0;
1640 if (!timedout
&& FD_SETSIZE
> 0 &&
1641 (rfd
>= FD_SETSIZE
||
1642 (i
== SSL_ERROR_WANT_WRITE
&&
1643 wfd
>= FD_SETSIZE
)))
1647 sm_syslog(LOG_ERR
, NOQID
,
1648 "STARTTLS=server, error: fd %d/%d too large",
1651 tlslogerr("server");
1656 /* XXX what about SSL_pending() ? */
1657 if (!timedout
&& i
== SSL_ERROR_WANT_READ
)
1659 fd_set ssl_maskr
, ssl_maskx
;
1661 FD_ZERO(&ssl_maskr
);
1662 FD_SET(rfd
, &ssl_maskr
);
1663 FD_ZERO(&ssl_maskx
);
1664 FD_SET(rfd
, &ssl_maskx
);
1665 if (select(rfd
+ 1, &ssl_maskr
, NULL
,
1666 &ssl_maskx
, &tv
) > 0)
1669 if (!timedout
&& i
== SSL_ERROR_WANT_WRITE
)
1671 fd_set ssl_maskw
, ssl_maskx
;
1673 FD_ZERO(&ssl_maskw
);
1674 FD_SET(wfd
, &ssl_maskw
);
1675 FD_ZERO(&ssl_maskx
);
1676 FD_SET(rfd
, &ssl_maskx
);
1677 if (select(wfd
+ 1, NULL
, &ssl_maskw
,
1678 &ssl_maskx
, &tv
) > 0)
1683 sm_syslog(LOG_WARNING
, NOQID
,
1684 "STARTTLS=server, error: accept failed=%d, SSL_error=%d, timedout=%d, errno=%d",
1685 r
, i
, (int) timedout
, errno
);
1687 tlslogerr("server");
1695 ** according to the next draft of
1696 ** RFC 2487 the connection should be dropped
1699 /* arrange to ignore any current send list */
1700 e
->e_sendqueue
= NULL
;
1704 /* ignore return code for now, it's in {verify} */
1705 (void) tls_get_info(srv_ssl
, true,
1707 &BlankEnvelope
.e_macro
,
1708 bitset(SRV_VRFY_CLT
, features
));
1711 ** call Stls_client to find out whether
1712 ** to accept the connection from the client
1715 saveQuickAbort
= QuickAbort
;
1716 saveSuprErrs
= SuprErrs
;
1719 if (rscheck("tls_client",
1720 macvalue(macid("{verify}"), e
),
1722 RSF_RMCOMM
|RSF_COUNT
,
1723 5, NULL
, NOQID
) != EX_OK
||
1726 extern char MsgBuf
[];
1728 if (MsgBuf
[0] != '\0' && ISSMTPREPLY(MsgBuf
))
1729 nullserver
= newstr(MsgBuf
);
1731 nullserver
= "503 5.7.0 Authentication required.";
1733 QuickAbort
= saveQuickAbort
;
1734 SuprErrs
= saveSuprErrs
;
1736 tls_ok_srv
= false; /* don't offer STARTTLS again */
1743 s
= macvalue(macid("{cipher_bits}"), e
);
1745 if (s
!= NULL
&& (ext_ssf
= atoi(s
)) > 0)
1747 auth_id
= macvalue(macid("{cert_subject}"),
1749 sasl_ok
= ((sasl_setprop(conn
, SASL_SSF_EXTERNAL
,
1750 &ext_ssf
) == SASL_OK
) &&
1751 (sasl_setprop(conn
, SASL_AUTH_EXTERNAL
,
1752 auth_id
) == SASL_OK
));
1753 # else /* SASL >= 20000 */
1754 if (s
!= NULL
&& (ext_ssf
.ssf
= atoi(s
)) > 0)
1756 ext_ssf
.auth_id
= macvalue(macid("{cert_subject}"),
1758 sasl_ok
= sasl_setprop(conn
, SASL_SSF_EXTERNAL
,
1759 &ext_ssf
) == SASL_OK
;
1760 # endif /* SASL >= 20000 */
1763 n_mechs
= saslmechs(conn
,
1769 /* switch to secure connection */
1770 if (sfdctls(&InChannel
, &OutChannel
, srv_ssl
) == 0)
1774 (void) sm_io_autoflush(InChannel
, OutChannel
);
1775 # endif /* PIPELINING */
1780 ** XXX this is an internal error
1781 ** how to deal with it?
1782 ** we can't generate an error message
1783 ** since the other side switched to an
1784 ** encrypted layer, but we could not...
1788 nullserver
= "454 4.3.3 TLS not available: can't switch to encrypted layer";
1789 syserr("STARTTLS: can't switch to encrypted layer");
1800 # endif /* _FFR_SMTP_SSL */
1802 #endif /* STARTTLS */
1804 case CMDHELO
: /* hello -- introduce yourself */
1805 case CMDEHLO
: /* extended hello */
1807 if (c
->cmd_code
== CMDEHLO
)
1810 SmtpPhase
= "server EHLO";
1815 SmtpPhase
= "server HELO";
1818 /* avoid denial-of-service */
1819 (void) checksmtpattack(&n_helo
, MAXHELOCOMMANDS
, true,
1823 /* RFC2821 4.1.4 allows duplicate HELO/EHLO */
1824 /* check for duplicate HELO/EHLO per RFC 1651 4.2 */
1827 usrerr("503 %s Duplicate HELO/EHLO",
1833 /* check for valid domain name (re 1123 5.2.5) */
1834 if (*p
== '\0' && !AllowBogusHELO
)
1836 usrerr("501 %s requires domain address",
1841 /* check for long domain name (hides Received: info) */
1842 if (strlen(p
) > MAXNAME
)
1844 usrerr("501 Invalid domain name");
1846 sm_syslog(LOG_INFO
, CurEnv
->e_id
,
1847 "invalid domain name (too long) from %s",
1853 for (q
= p
; *q
!= '\0'; q
++)
1863 /* only complain if strict check */
1864 ok
= AllowBogusHELO
;
1867 if (strchr("[].-_#:", *q
) == NULL
)
1871 if (*q
== '\0' && ok
)
1873 q
= "pleased to meet you";
1874 sendinghost
= sm_strdup_x(p
);
1876 else if (!AllowBogusHELO
)
1878 usrerr("501 Invalid domain name");
1880 sm_syslog(LOG_INFO
, CurEnv
->e_id
,
1881 "invalid domain name (%s) from %.100s",
1887 q
= "accepting invalid domain name";
1892 CLEAR_STATE(cmdbuf
);
1895 /* restore connection quarantining */
1896 if (smtp
.sm_quarmsg
== NULL
)
1898 e
->e_quarmsg
= NULL
;
1899 macdefine(&e
->e_macro
, A_PERM
,
1900 macid("{quarantine}"), "");
1904 e
->e_quarmsg
= sm_rpool_strdup_x(e
->e_rpool
,
1906 macdefine(&e
->e_macro
, A_PERM
,
1907 macid("{quarantine}"),
1910 #endif /* _FFR_QUARANTINE */
1914 if (smtp
.sm_milterlist
&& smtp
.sm_milterize
&&
1915 !bitset(EF_DISCARD
, e
->e_flags
))
1920 response
= milter_helo(p
, e
, &state
);
1923 case SMFIR_REPLYCODE
:
1924 if (MilterLogLevel
> 3)
1925 sm_syslog(LOG_INFO
, e
->e_id
,
1926 "Milter: helo=%s, reject=%s",
1928 nullserver
= newstr(response
);
1929 smtp
.sm_milterize
= false;
1933 if (MilterLogLevel
> 3)
1934 sm_syslog(LOG_INFO
, e
->e_id
,
1935 "Milter: helo=%s, reject=Command rejected",
1937 nullserver
= "Command rejected";
1938 smtp
.sm_milterize
= false;
1941 case SMFIR_TEMPFAIL
:
1942 if (MilterLogLevel
> 3)
1943 sm_syslog(LOG_INFO
, e
->e_id
,
1944 "Milter: helo=%s, reject=%s",
1947 smtp
.sm_milterize
= false;
1950 if (response
!= NULL
)
1953 # if _FFR_QUARANTINE
1955 ** If quarantining by a connect/ehlo action,
1956 ** save between messages
1959 if (smtp
.sm_quarmsg
== NULL
&&
1960 e
->e_quarmsg
!= NULL
)
1961 smtp
.sm_quarmsg
= newstr(e
->e_quarmsg
);
1962 # endif /* _FFR_QUARANTINE */
1967 /* print HELO response message */
1968 if (c
->cmd_code
!= CMDEHLO
)
1970 message("250 %s Hello %s, %s",
1971 MyHostName
, CurSmtpClient
, q
);
1975 message("250-%s Hello %s, %s",
1976 MyHostName
, CurSmtpClient
, q
);
1978 /* offer ENHSC even for nullserver */
1979 if (nullserver
!= NULL
)
1981 message("250 ENHANCEDSTATUSCODES");
1986 ** print EHLO features list
1988 ** Note: If you change this list,
1989 ** remember to update 'helpfile'
1992 message("250-ENHANCEDSTATUSCODES");
1994 if (bitset(SRV_OFFER_PIPE
, features
))
1995 message("250-PIPELINING");
1996 #endif /* PIPELINING */
1997 if (bitset(SRV_OFFER_EXPN
, features
))
1999 message("250-EXPN");
2000 if (bitset(SRV_OFFER_VERB
, features
))
2001 message("250-VERB");
2004 message("250-8BITMIME");
2005 #endif /* MIME8TO7 */
2006 if (MaxMessageSize
> 0)
2007 message("250-SIZE %ld", MaxMessageSize
);
2009 message("250-SIZE");
2011 if (SendMIMEErrors
&& bitset(SRV_OFFER_DSN
, features
))
2014 if (bitset(SRV_OFFER_ETRN
, features
))
2015 message("250-ETRN");
2017 if (sasl_ok
&& mechlist
!= NULL
&& *mechlist
!= '\0')
2018 message("250-AUTH %s", mechlist
);
2022 bitset(SRV_OFFER_TLS
, features
))
2023 message("250-STARTTLS");
2024 #endif /* STARTTLS */
2025 if (DeliverByMin
> 0)
2026 message("250-DELIVERBY %ld",
2027 (long) DeliverByMin
);
2028 else if (DeliverByMin
== 0)
2029 message("250-DELIVERBY");
2031 /* < 0: no deliver-by */
2033 message("250 HELP");
2036 case CMDMAIL
: /* mail -- designate sender */
2037 SmtpPhase
= "server MAIL";
2040 /* check for validity of this command */
2041 if (!gothello
&& bitset(PRIV_NEEDMAILHELO
, PrivacyFlags
))
2043 usrerr("503 5.0.0 Polite people say HELO first");
2046 if (smtp
.sm_gotmail
)
2048 usrerr("503 5.5.0 Sender already specified");
2052 if (bitset(SRV_REQ_AUTH
, features
) &&
2053 authenticating
!= SASL_IS_AUTH
)
2055 usrerr("530 5.7.0 Authentication required");
2060 p
= skipword(p
, "from");
2066 sm_syslog(LOG_INFO
, e
->e_id
,
2067 "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
2069 usrerr(MSG_TEMPFAIL
);
2073 /* make sure we know who the sending host is */
2074 if (sendinghost
== NULL
)
2075 sendinghost
= peerhostname
;
2079 if (sm_debug_active(&DebugLeakSmtp
, 1))
2082 sm_dprintf("smtp() heap group #%d\n",
2085 #endif /* SM_HEAP_CHECK */
2091 auth_warning(e
, "%s didn't use HELO protocol",
2094 #ifdef PICKY_HELO_CHECK
2095 if (sm_strcasecmp(sendinghost
, peerhostname
) != 0 &&
2096 (sm_strcasecmp(peerhostname
, "localhost") != 0 ||
2097 sm_strcasecmp(sendinghost
, MyHostName
) != 0))
2099 auth_warning(e
, "Host %s claimed to be %s",
2100 CurSmtpClient
, sendinghost
);
2102 #endif /* PICKY_HELO_CHECK */
2104 if (protocol
== NULL
)
2106 macdefine(&e
->e_macro
, A_PERM
, 'r', protocol
);
2107 macdefine(&e
->e_macro
, A_PERM
, 's', sendinghost
);
2113 macdefine(&e
->e_macro
, A_PERM
, macid("{ntries}"), "0");
2114 macdefine(&e
->e_macro
, A_PERM
, macid("{nrcpts}"), "0");
2115 e
->e_flags
|= EF_CLRQUEUE
;
2116 sm_setproctitle(true, e
, "%s %s: %.80s",
2118 CurSmtpClient
, inp
);
2120 /* do the processing */
2123 extern char *FullName
;
2126 SM_FREE_CLR(FullName
);
2128 /* must parse sender first */
2130 setsender(p
, e
, &delimptr
, ' ', false);
2131 if (delimptr
!= NULL
&& *delimptr
!= '\0')
2134 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2136 /* Successfully set e_from, allow logging */
2137 e
->e_flags
|= EF_LOGSENDER
;
2139 /* put resulting triple from parseaddr() into macros */
2140 if (e
->e_from
.q_mailer
!= NULL
)
2141 macdefine(&e
->e_macro
, A_PERM
,
2142 macid("{mail_mailer}"),
2143 e
->e_from
.q_mailer
->m_name
);
2145 macdefine(&e
->e_macro
, A_PERM
,
2146 macid("{mail_mailer}"), NULL
);
2147 if (e
->e_from
.q_host
!= NULL
)
2148 macdefine(&e
->e_macro
, A_PERM
,
2149 macid("{mail_host}"),
2152 macdefine(&e
->e_macro
, A_PERM
,
2153 macid("{mail_host}"), "localhost");
2154 if (e
->e_from
.q_user
!= NULL
)
2155 macdefine(&e
->e_macro
, A_PERM
,
2156 macid("{mail_addr}"),
2159 macdefine(&e
->e_macro
, A_PERM
,
2160 macid("{mail_addr}"), NULL
);
2162 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2164 /* check for possible spoofing */
2165 if (RealUid
!= 0 && OpMode
== MD_SMTP
&&
2166 !wordinclass(RealUserName
, 't') &&
2167 (!bitnset(M_LOCALMAILER
,
2168 e
->e_from
.q_mailer
->m_flags
) ||
2169 strcmp(e
->e_from
.q_user
, RealUserName
) != 0))
2171 auth_warning(e
, "%s owned process doing -bs",
2175 /* reset to default value */
2176 SevenBitInput
= save_sevenbitinput
;
2178 /* now parse ESMTP arguments */
2184 while (p
!= NULL
&& *p
!= '\0')
2190 /* locate the beginning of the keyword */
2196 /* skip to the value portion */
2197 while ((isascii(*p
) && isalnum(*p
)) || *p
== '-')
2205 /* skip to the end of the value */
2206 while (*p
!= '\0' && *p
!= ' ' &&
2207 !(isascii(*p
) && iscntrl(*p
)) &&
2216 sm_dprintf("MAIL: got arg %s=\"%s\"\n", kp
,
2217 vp
== NULL
? "<null>" : vp
);
2219 mail_esmtp_args(kp
, vp
, e
);
2223 if (argno
>= MAXSMTPARGS
- 1)
2224 usrerr("501 5.5.4 Too many parameters");
2226 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2230 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2233 # if _FFR_AUTH_PASSING
2234 /* set the default AUTH= if the sender didn't */
2235 if (e
->e_auth_param
== NULL
)
2237 /* XXX only do this for an MSA? */
2238 e
->e_auth_param
= macvalue(macid("{auth_authen}"),
2240 if (e
->e_auth_param
== NULL
)
2241 e
->e_auth_param
= "<>";
2244 ** XXX should we invoke Strust_auth now?
2245 ** authorizing as the client that just
2246 ** authenticated, so we'll trust implicitly
2249 # endif /* _FFR_AUTH_PASSING */
2252 /* do config file checking of the sender */
2253 macdefine(&e
->e_macro
, A_PERM
,
2254 macid("{addr_type}"), "e s");
2256 /* make the "real" sender address available */
2257 macdefine(&e
->e_macro
, A_TEMP
, macid("{mail_from}"),
2259 #endif /* _FFR_MAIL_MACRO */
2260 if (rscheck("check_mail", addr
,
2261 NULL
, e
, RSF_RMCOMM
|RSF_COUNT
, 3,
2262 NULL
, e
->e_id
) != EX_OK
||
2264 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2265 macdefine(&e
->e_macro
, A_PERM
,
2266 macid("{addr_type}"), NULL
);
2268 if (MaxMessageSize
> 0 &&
2269 (e
->e_msgsize
> MaxMessageSize
||
2272 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
2274 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2278 ** XXX always check whether there is at least one fs
2279 ** with enough space?
2280 ** However, this may not help much: the queue group
2281 ** selection may later on select a FS that hasn't
2285 if ((NumFileSys
== 1 || NumQueue
== 1) &&
2286 !enoughdiskspace(e
->e_msgsize
, e
)
2287 #if _FFR_ANY_FREE_FS
2288 && !filesys_free(e
->e_msgsize
)
2289 #endif /* _FFR_ANY_FREE_FS */
2293 ** We perform this test again when the
2294 ** queue directory is selected, in collect.
2297 usrerr("452 4.4.5 Insufficient disk space; try again later");
2298 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2301 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2305 if (smtp
.sm_milterlist
&& smtp
.sm_milterize
&&
2306 !bitset(EF_DISCARD
, e
->e_flags
))
2311 response
= milter_envfrom(args
, e
, &state
);
2312 MILTER_REPLY("from");
2316 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2318 message("250 2.1.0 Sender ok");
2319 smtp
.sm_gotmail
= true;
2321 SM_EXCEPT(exc
, "[!F]*")
2324 ** An error occurred while processing a MAIL command.
2325 ** Jump to the common error handling code.
2335 e
->e_flags
&= ~EF_PM_NOTIFY
;
2339 case CMDRCPT
: /* rcpt -- designate recipient */
2341 if (!smtp
.sm_gotmail
)
2343 usrerr("503 5.0.0 Need MAIL before RCPT");
2346 SmtpPhase
= "server RCPT";
2352 /* limit flooding of our machine */
2353 if (MaxRcptPerMsg
> 0 &&
2354 smtp
.sm_nrcpts
>= MaxRcptPerMsg
)
2356 /* sleep(1); / * slow down? */
2357 usrerr("452 4.5.3 Too many recipients");
2361 if (e
->e_sendmode
!= SM_DELIVER
)
2362 e
->e_flags
|= EF_VRFYONLY
;
2366 ** If the filter will be deleting recipients,
2367 ** don't expand them at RCPT time (in the call
2368 ** to recipient()). If they are expanded, it
2369 ** is impossible for removefromlist() to figure
2370 ** out the expanded members of the original
2371 ** recipient and mark them as QS_DONTSEND.
2374 if (milter_can_delrcpts())
2375 e
->e_flags
|= EF_VRFYONLY
;
2378 p
= skipword(p
, "to");
2381 macdefine(&e
->e_macro
, A_PERM
,
2382 macid("{addr_type}"), "e r");
2383 a
= parseaddr(p
, NULLADDR
, RF_COPYALL
, ' ', &delimptr
,
2385 macdefine(&e
->e_macro
, A_PERM
,
2386 macid("{addr_type}"), NULL
);
2387 if (BadRcptThrottle
> 0 &&
2388 n_badrcpts
>= BadRcptThrottle
)
2391 n_badrcpts
== BadRcptThrottle
)
2393 sm_syslog(LOG_INFO
, e
->e_id
,
2394 "%s: Possible SMTP RCPT flood, throttling.",
2397 /* To avoid duplicated message */
2402 ** Don't use exponential backoff for now.
2403 ** Some servers will open more connections
2404 ** and actually overload the receiver even
2414 usrerr("501 5.0.0 Missing recipient");
2418 if (delimptr
!= NULL
&& *delimptr
!= '\0')
2421 /* put resulting triple from parseaddr() into macros */
2422 if (a
->q_mailer
!= NULL
)
2423 macdefine(&e
->e_macro
, A_PERM
,
2424 macid("{rcpt_mailer}"),
2425 a
->q_mailer
->m_name
);
2427 macdefine(&e
->e_macro
, A_PERM
,
2428 macid("{rcpt_mailer}"), NULL
);
2429 if (a
->q_host
!= NULL
)
2430 macdefine(&e
->e_macro
, A_PERM
,
2431 macid("{rcpt_host}"), a
->q_host
);
2433 macdefine(&e
->e_macro
, A_PERM
,
2434 macid("{rcpt_host}"), "localhost");
2435 if (a
->q_user
!= NULL
)
2436 macdefine(&e
->e_macro
, A_PERM
,
2437 macid("{rcpt_addr}"), a
->q_user
);
2439 macdefine(&e
->e_macro
, A_PERM
,
2440 macid("{rcpt_addr}"), NULL
);
2444 /* now parse ESMTP arguments */
2449 while (p
!= NULL
&& *p
!= '\0')
2455 /* locate the beginning of the keyword */
2461 /* skip to the value portion */
2462 while ((isascii(*p
) && isalnum(*p
)) || *p
== '-')
2470 /* skip to the end of the value */
2471 while (*p
!= '\0' && *p
!= ' ' &&
2472 !(isascii(*p
) && iscntrl(*p
)) &&
2481 sm_dprintf("RCPT: got arg %s=\"%s\"\n", kp
,
2482 vp
== NULL
? "<null>" : vp
);
2484 rcpt_esmtp_args(a
, kp
, vp
, e
);
2488 if (argno
>= MAXSMTPARGS
- 1)
2489 usrerr("501 5.5.4 Too many parameters");
2497 /* do config file checking of the recipient */
2498 macdefine(&e
->e_macro
, A_PERM
,
2499 macid("{addr_type}"), "e r");
2500 if (rscheck("check_rcpt", addr
,
2501 NULL
, e
, RSF_RMCOMM
|RSF_COUNT
, 3,
2502 NULL
, e
->e_id
) != EX_OK
||
2505 macdefine(&e
->e_macro
, A_PERM
,
2506 macid("{addr_type}"), NULL
);
2508 /* If discarding, don't bother to verify user */
2509 if (bitset(EF_DISCARD
, e
->e_flags
))
2510 a
->q_state
= QS_VERIFIED
;
2513 if (smtp
.sm_milterlist
&& smtp
.sm_milterize
&&
2514 !bitset(EF_DISCARD
, e
->e_flags
))
2519 response
= milter_envrcpt(args
, e
, &state
);
2524 macdefine(&e
->e_macro
, A_PERM
,
2525 macid("{rcpt_mailer}"), NULL
);
2526 macdefine(&e
->e_macro
, A_PERM
,
2527 macid("{rcpt_host}"), NULL
);
2528 macdefine(&e
->e_macro
, A_PERM
,
2529 macid("{rcpt_addr}"), NULL
);
2530 macdefine(&e
->e_macro
, A_PERM
,
2531 macid("{dsn_notify}"), NULL
);
2535 /* save in recipient list after ESMTP mods */
2536 a
= recipient(a
, &e
->e_sendqueue
, 0, e
);
2540 /* no errors during parsing, but might be a duplicate */
2541 e
->e_to
= a
->q_paddr
;
2542 if (!QS_IS_BADADDR(a
->q_state
))
2544 if (smtp
.sm_nrcpts
== 0)
2546 message("250 2.1.5 Recipient ok%s",
2547 QS_IS_QUEUEUP(a
->q_state
) ?
2548 " (will queue)" : "");
2553 /* punt -- should keep message in ADDRESS.... */
2554 usrerr("550 5.1.1 Addressee unknown");
2560 SM_EXCEPT(exc
, "[!F]*")
2562 /* An exception occurred while processing RCPT */
2563 e
->e_flags
&= ~(EF_FATALERRS
|EF_PM_NOTIFY
);
2569 case CMDDATA
: /* data -- text of mail */
2571 smtp_data(&smtp
, e
);
2574 case CMDRSET
: /* rset -- reset state */
2576 message("451 4.0.0 Test failure");
2578 message("250 2.0.0 Reset state");
2579 CLEAR_STATE(cmdbuf
);
2581 /* restore connection quarantining */
2582 if (smtp
.sm_quarmsg
== NULL
)
2584 e
->e_quarmsg
= NULL
;
2585 macdefine(&e
->e_macro
, A_PERM
,
2586 macid("{quarantine}"), "");
2590 e
->e_quarmsg
= sm_rpool_strdup_x(e
->e_rpool
,
2592 macdefine(&e
->e_macro
, A_PERM
,
2593 macid("{quarantine}"), e
->e_quarmsg
);
2595 #endif /* _FFR_QUARANTINE */
2598 case CMDVRFY
: /* vrfy -- verify address */
2599 case CMDEXPN
: /* expn -- expand address */
2600 vrfy
= c
->cmd_code
== CMDVRFY
;
2601 DELAY_CONN(vrfy
? "VRFY" : "EXPN");
2605 sm_syslog(LOG_INFO
, e
->e_id
,
2606 "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)",
2607 vrfy
? "VRFY" : "EXPN",
2610 /* RFC 821 doesn't allow 4xy reply code */
2611 usrerr("550 5.7.1 Please try again later");
2614 wt
= checksmtpattack(&n_verifies
, MAXVRFYCOMMANDS
,
2615 false, vrfy
? "VRFY" : "EXPN", e
);
2616 previous
= curtime();
2617 if ((vrfy
&& bitset(PRIV_NOVRFY
, PrivacyFlags
)) ||
2618 (!vrfy
&& !bitset(SRV_OFFER_EXPN
, features
)))
2621 message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
2623 message("502 5.7.0 Sorry, we do not allow this operation");
2625 sm_syslog(LOG_INFO
, e
->e_id
,
2626 "%s: %s [rejected]",
2628 shortenstring(inp
, MAXSHORTSTR
));
2631 else if (!gothello
&&
2632 bitset(vrfy
? PRIV_NEEDVRFYHELO
: PRIV_NEEDEXPNHELO
,
2635 usrerr("503 5.0.0 I demand that you introduce yourself first");
2641 sm_syslog(LOG_INFO
, e
->e_id
, "%s: %s",
2643 shortenstring(inp
, MAXSHORTSTR
));
2649 e
->e_flags
|= EF_VRFYONLY
;
2650 while (*p
!= '\0' && isascii(*p
) && isspace(*p
))
2654 usrerr("501 5.5.2 Argument required");
2658 /* do config file checking of the address */
2659 if (rscheck(vrfy
? "check_vrfy" : "check_expn",
2660 p
, NULL
, e
, RSF_RMCOMM
,
2661 3, NULL
, NOQID
) != EX_OK
||
2663 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2664 (void) sendtolist(p
, NULLADDR
, &vrfyqueue
, 0, e
);
2670 t
= wt
- (curtime() - previous
);
2675 sm_exc_raisenew_x(&EtypeQuickAbort
, 1);
2676 if (vrfyqueue
== NULL
)
2678 usrerr("554 5.5.2 Nothing to %s", vrfy
? "VRFY" : "EXPN");
2680 while (vrfyqueue
!= NULL
)
2682 if (!QS_IS_UNDELIVERED(vrfyqueue
->q_state
))
2684 vrfyqueue
= vrfyqueue
->q_next
;
2688 /* see if there is more in the vrfy list */
2690 while ((a
= a
->q_next
) != NULL
&&
2691 (!QS_IS_UNDELIVERED(a
->q_state
)))
2693 printvrfyaddr(vrfyqueue
, a
== NULL
, vrfy
);
2697 SM_EXCEPT(exc
, "[!F]*")
2700 ** An exception occurred while processing VRFY/EXPN
2709 case CMDETRN
: /* etrn -- force queue flush */
2712 /* Don't leak queue information via debug flags */
2713 if (!bitset(SRV_OFFER_ETRN
, features
) || UseMSP
||
2714 (RealUid
!= 0 && RealUid
!= TrustedUid
&&
2717 /* different message for MSA ? */
2718 message("502 5.7.0 Sorry, we do not allow this operation");
2720 sm_syslog(LOG_INFO
, e
->e_id
,
2721 "%s: %s [rejected]",
2723 shortenstring(inp
, MAXSHORTSTR
));
2729 sm_syslog(LOG_INFO
, e
->e_id
,
2730 "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
2732 usrerr(MSG_TEMPFAIL
);
2738 usrerr("500 5.5.2 Parameter required");
2742 /* crude way to avoid denial-of-service attacks */
2743 (void) checksmtpattack(&n_etrn
, MAXETRNCOMMANDS
, true,
2747 ** Do config file checking of the parameter.
2748 ** Even though we have srv_features now, we still
2749 ** need this ruleset because the former is called
2750 ** when the connection has been established, while
2751 ** this ruleset is called when the command is
2752 ** actually issued and therefore has all information
2753 ** available to make a decision.
2756 if (rscheck("check_etrn", p
, NULL
, e
,
2757 RSF_RMCOMM
, 3, NULL
, NOQID
) != EX_OK
||
2762 sm_syslog(LOG_INFO
, e
->e_id
,
2763 "%s: ETRN %s", CurSmtpClient
,
2764 shortenstring(p
, MAXSHORTSTR
));
2772 qgrp
= name2qid(id
);
2773 if (!ISVALIDQGRP(qgrp
))
2775 usrerr("459 4.5.4 Queue %s unknown",
2779 for (i
= 0; i
< NumQueue
&& Queue
[i
] != NULL
;
2781 Queue
[i
]->qg_nextrun
= (time_t) -1;
2782 Queue
[qgrp
]->qg_nextrun
= 0;
2783 ok
= run_work_group(Queue
[qgrp
]->qg_wgrp
,
2784 RWG_FORK
|RWG_FORCE
);
2785 if (ok
&& Errors
== 0)
2786 message("250 2.0.0 Queuing for queue group %s started", id
);
2795 new = (QUEUE_CHAR
*) sm_malloc(sizeof(QUEUE_CHAR
));
2798 syserr("500 5.5.0 ETRN out of memory");
2801 new->queue_match
= id
;
2802 new->queue_negate
= false;
2803 new->queue_next
= NULL
;
2804 QueueLimitRecipient
= new;
2805 ok
= runqueue(true, false, false, true);
2806 sm_free(QueueLimitRecipient
); /* XXX */
2807 QueueLimitRecipient
= NULL
;
2808 if (ok
&& Errors
== 0)
2809 message("250 2.0.0 Queuing for node %s started", p
);
2812 case CMDHELP
: /* help -- give user info */
2817 case CMDNOOP
: /* noop -- do nothing */
2819 (void) checksmtpattack(&n_noop
, MAXNOOPCOMMANDS
, true,
2821 message("250 2.0.0 OK");
2824 case CMDQUIT
: /* quit -- leave mail */
2825 message("221 2.0.0 %s closing connection", MyHostName
);
2827 (void) sm_io_flush(OutChannel
, SM_TIME_DEFAULT
);
2828 #endif /* PIPELINING */
2830 if (smtp
.sm_nrcpts
> 0)
2831 logundelrcpts(e
, "aborted by sender", 9, false);
2833 /* arrange to ignore any current send list */
2834 e
->e_sendqueue
= NULL
;
2837 /* shutdown TLS connection */
2840 (void) endtls(srv_ssl
, "server");
2843 #endif /* STARTTLS */
2845 if (authenticating
== SASL_IS_AUTH
)
2847 sasl_dispose(&conn
);
2848 authenticating
= SASL_NOT_AUTH
;
2849 /* XXX sasl_done(); this is a child */
2854 /* avoid future 050 messages */
2858 /* close out milter filters */
2862 if (LogLevel
> 4 && bitset(EF_LOGSENDER
, e
->e_flags
))
2864 e
->e_flags
&= ~EF_LOGSENDER
;
2866 if (lognullconnection
&& LogLevel
> 5 &&
2871 d
= macvalue(macid("{daemon_name}"), e
);
2876 ** even though this id is "bogus", it makes
2877 ** it simpler to "grep" related events, e.g.,
2878 ** timeouts for the same connection.
2881 sm_syslog(LOG_INFO
, e
->e_id
,
2882 "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
2887 /* return to handle next connection */
2890 finis(true, true, ExitStat
);
2893 case CMDVERB
: /* set verbose mode */
2895 if (!bitset(SRV_OFFER_EXPN
, features
) ||
2896 !bitset(SRV_OFFER_VERB
, features
))
2898 /* this would give out the same info */
2899 message("502 5.7.0 Verbose unavailable");
2902 (void) checksmtpattack(&n_noop
, MAXNOOPCOMMANDS
, true,
2905 set_delivery_mode(SM_DELIVER
, e
);
2906 message("250 2.0.0 Verbose mode");
2910 case CMDDBGQSHOW
: /* show queues */
2911 (void) sm_io_fprintf(smioout
, SM_TIME_DEFAULT
,
2913 printaddr(e
->e_sendqueue
, true);
2916 case CMDDBGDEBUG
: /* set debug mode */
2917 tTsetup(tTdvect
, sizeof tTdvect
, "0-99.1");
2919 message("200 2.0.0 Debug set");
2922 #else /* SMTPDEBUG */
2923 case CMDDBGQSHOW
: /* show queues */
2924 case CMDDBGDEBUG
: /* set debug mode */
2925 #endif /* SMTPDEBUG */
2926 case CMDLOGBOGUS
: /* bogus command */
2927 DELAY_CONN("Bogus");
2929 sm_syslog(LOG_CRIT
, e
->e_id
,
2930 "\"%s\" command from %s (%.100s)",
2931 c
->cmd_name
, CurSmtpClient
,
2932 anynet_ntoa(&RealHostAddr
));
2935 case CMDERROR
: /* unknown command */
2936 #if MAXBADCOMMANDS > 0
2937 if (++n_badcmds
> MAXBADCOMMANDS
)
2939 message("421 4.7.0 %s Too many bad commands; closing connection",
2942 /* arrange to ignore any current send list */
2943 e
->e_sendqueue
= NULL
;
2946 #endif /* MAXBADCOMMANDS > 0 */
2948 usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2949 shortenstring(inp
, MAXSHORTSTR
));
2953 DELAY_CONN("Unimpl");
2954 usrerr("502 5.5.1 Command not implemented: \"%s\"",
2955 shortenstring(inp
, MAXSHORTSTR
));
2959 DELAY_CONN("default");
2961 syserr("500 5.5.0 smtp: unknown code %d", c
->cmd_code
);
2968 SM_EXCEPT(exc
, "[!F]*")
2971 ** The only possible exception is "E:mta.quickabort".
2972 ** There is nothing to do except fall through and loop.
2979 ** SMTP_DATA -- implement the SMTP DATA command.
2982 ** smtp -- status of SMTP connection.
2989 ** possibly sends message.
3008 SmtpPhase
= "server DATA";
3009 if (!smtp
->sm_gotmail
)
3011 usrerr("503 5.0.0 Need MAIL command");
3014 else if (smtp
->sm_nrcpts
<= 0)
3016 usrerr("503 5.0.0 Need RCPT (recipient)");
3019 (void) sm_snprintf(buf
, sizeof buf
, "%u", smtp
->sm_nrcpts
);
3020 if (rscheck("check_data", buf
, NULL
, e
,
3021 RSF_RMCOMM
|RSF_UNSTRUCTURED
|RSF_COUNT
, 3, NULL
,
3025 /* put back discard bit */
3026 if (smtp
->sm_discard
)
3027 e
->e_flags
|= EF_DISCARD
;
3029 /* check to see if we need to re-expand aliases */
3030 /* also reset QS_BADADDR on already-diagnosted addrs */
3031 doublequeue
= false;
3032 for (a
= e
->e_sendqueue
; a
!= NULL
; a
= a
->q_next
)
3034 if (QS_IS_VERIFIED(a
->q_state
) &&
3035 !bitset(EF_DISCARD
, e
->e_flags
))
3037 /* need to re-expand aliases */
3040 if (QS_IS_BADADDR(a
->q_state
))
3042 /* make this "go away" */
3043 a
->q_state
= QS_DONTSEND
;
3047 /* collect the text of the message */
3048 SmtpPhase
= "collect";
3051 #if _FFR_ADAPTIVE_EOL
3052 /* triggers error in collect, disabled for now */
3054 e
->e_flags
|= EF_NL_NOT_EOL
;
3055 #endif /* _FFR_ADAPTIVE_EOL */
3057 collect(InChannel
, true, NULL
, e
, true);
3059 /* redefine message size */
3060 (void) sm_snprintf(buf
, sizeof buf
, "%ld", e
->e_msgsize
);
3061 macdefine(&e
->e_macro
, A_TEMP
, macid("{msg_size}"), buf
);
3064 /* rscheck() will set Errors or EF_DISCARD if it trips */
3065 (void) rscheck("check_eom", buf
, NULL
, e
, RSF_UNSTRUCTURED
|RSF_COUNT
,
3067 #endif /* _FFR_CHECK_EOM */
3070 milteraccept
= true;
3071 if (smtp
->sm_milterlist
&& smtp
->sm_milterize
&&
3073 !bitset(EF_DISCARD
, e
->e_flags
))
3078 response
= milter_data(e
, &state
);
3081 case SMFIR_REPLYCODE
:
3082 if (MilterLogLevel
> 3)
3083 sm_syslog(LOG_INFO
, e
->e_id
,
3084 "Milter: data, reject=%s",
3086 milteraccept
= false;
3091 milteraccept
= false;
3092 if (MilterLogLevel
> 3)
3093 sm_syslog(LOG_INFO
, e
->e_id
,
3094 "Milter: data, reject=554 5.7.1 Command rejected");
3095 usrerr("554 5.7.1 Command rejected");
3099 if (MilterLogLevel
> 3)
3100 sm_syslog(LOG_INFO
, e
->e_id
,
3101 "Milter: data, discard");
3102 milteraccept
= false;
3103 e
->e_flags
|= EF_DISCARD
;
3106 case SMFIR_TEMPFAIL
:
3107 if (MilterLogLevel
> 3)
3108 sm_syslog(LOG_INFO
, e
->e_id
,
3109 "Milter: data, reject=%s",
3111 milteraccept
= false;
3112 usrerr(MSG_TEMPFAIL
);
3115 if (response
!= NULL
)
3119 /* Milter may have changed message size */
3120 (void) sm_snprintf(buf
, sizeof buf
, "%ld", e
->e_msgsize
);
3121 macdefine(&e
->e_macro
, A_TEMP
, macid("{msg_size}"), buf
);
3123 /* abort message filters that didn't get the body & log msg is OK */
3124 if (smtp
->sm_milterlist
&& smtp
->sm_milterize
)
3127 if (milteraccept
&& MilterLogLevel
> 9)
3128 sm_syslog(LOG_INFO
, e
->e_id
, "Milter accept: message");
3133 /* Check if quarantining stats should be updated */
3134 if (e
->e_quarmsg
!= NULL
)
3135 markstats(e
, NULL
, STATS_QUARANTINE
);
3136 #endif /* _FFR_QUARANTINE */
3139 ** If a header/body check (header checks or milter)
3140 ** set EF_DISCARD, don't queueup the message --
3141 ** that would lose the EF_DISCARD bit and deliver
3145 if (bitset(EF_DISCARD
, e
->e_flags
))
3146 doublequeue
= false;
3148 aborting
= Errors
> 0;
3151 (QueueMode
== QM_QUARANTINE
|| e
->e_quarmsg
== NULL
) &&
3152 #endif /* _FFR_QUARANTINE */
3153 !split_by_recipient(e
))
3154 aborting
= bitset(EF_FATALERRS
, e
->e_flags
);
3158 /* Log who the mail would have gone to */
3159 logundelrcpts(e
, e
->e_message
, 8, false);
3165 /* from now on, we have to operate silently */
3170 ** Clear message, it may contain an error from the SMTP dialogue.
3171 ** This error must not show up in the queue.
3172 ** Some error message should show up, e.g., alias database
3173 ** not available, but others shouldn't, e.g., from check_rcpt.
3176 e
->e_message
= NULL
;
3180 ** Arrange to send to everyone.
3181 ** If sending to multiple people, mail back
3182 ** errors rather than reporting directly.
3183 ** In any case, don't mail back errors for
3184 ** anything that has happened up to
3185 ** now (the other end will do this).
3186 ** Truncate our transcript -- the mail has gotten
3187 ** to us successfully, and if we have
3188 ** to mail this back, it will be easier
3190 ** Then send to everyone.
3191 ** Finally give a reply code. If an error has
3192 ** already been given, don't mail a
3194 ** We goose error returns by clearing error bit.
3197 SmtpPhase
= "delivery";
3198 (void) sm_io_setinfo(e
->e_xfp
, SM_BF_TRUNCATE
, NULL
);
3202 _res
.retry
= TimeOuts
.res_retry
[RES_TO_FIRST
];
3203 _res
.retrans
= TimeOuts
.res_retrans
[RES_TO_FIRST
];
3204 #endif /* NAMED_BIND */
3206 for (ee
= e
; ee
!= NULL
; ee
= ee
->e_sibling
)
3208 /* make sure we actually do delivery */
3209 ee
->e_flags
&= ~EF_CLRQUEUE
;
3211 /* from now on, operate silently */
3212 ee
->e_errormode
= EM_MAIL
;
3216 /* make sure it is in the queue */
3217 queueup(ee
, false, true);
3221 /* send to all recipients */
3222 sendall(ee
, SM_DEFAULT
);
3227 /* put back id for SMTP logging in putoutmsg() */
3228 oldid
= CurEnv
->e_id
;
3231 /* issue success message */
3232 message("250 2.0.0 %s Message accepted for delivery", id
);
3233 CurEnv
->e_id
= oldid
;
3235 /* if we just queued, poke it */
3238 bool anything_to_send
= false;
3241 for (ee
= e
; ee
!= NULL
; ee
= ee
->e_sibling
)
3243 if (WILL_BE_QUEUED(ee
->e_sendmode
))
3245 if (shouldqueue(ee
->e_msgpriority
, ee
->e_ctime
))
3247 ee
->e_sendmode
= SM_QUEUE
;
3251 else if (QueueMode
!= QM_QUARANTINE
&&
3252 ee
->e_quarmsg
!= NULL
)
3254 ee
->e_sendmode
= SM_QUEUE
;
3257 #endif /* _FFR_QUARANTINE */
3258 anything_to_send
= true;
3260 /* close all the queue files */
3262 if (ee
->e_dfp
!= NULL
)
3264 (void) sm_io_close(ee
->e_dfp
, SM_TIME_DEFAULT
);
3269 if (anything_to_send
)
3273 ** XXX if we don't do this, we get 250 twice
3274 ** because it is also flushed in the child.
3277 (void) sm_io_flush(OutChannel
, SM_TIME_DEFAULT
);
3278 #endif /* PIPELINING */
3279 (void) doworklist(e
, true, true);
3284 if (LogLevel
> 4 && bitset(EF_LOGSENDER
, e
->e_flags
))
3286 e
->e_flags
&= ~EF_LOGSENDER
;
3288 /* clean up a bit */
3289 smtp
->sm_gotmail
= false;
3292 ** Call dropenvelope if and only if the envelope is *not*
3293 ** being processed by the child process forked by doworklist().
3296 if (aborting
|| bitset(EF_DISCARD
, e
->e_flags
))
3297 dropenvelope(e
, true, false);
3300 for (ee
= e
; ee
!= NULL
; ee
= ee
->e_sibling
)
3304 QueueMode
!= QM_QUARANTINE
&&
3305 ee
->e_quarmsg
!= NULL
)
3307 dropenvelope(ee
, true, false);
3310 #endif /* _FFR_QUARANTINE */
3311 if (WILL_BE_QUEUED(ee
->e_sendmode
))
3312 dropenvelope(ee
, true, false);
3315 sm_rpool_free(e
->e_rpool
);
3318 ** At this point, e == &MainEnvelope, but if we did splitting,
3319 ** then CurEnv may point to an envelope structure that was just
3320 ** freed with the rpool. So reset CurEnv *before* calling
3325 newenvelope(e
, e
, sm_rpool_new_x(NULL
));
3326 e
->e_flags
= BlankEnvelope
.e_flags
;
3329 /* restore connection quarantining */
3330 if (smtp
->sm_quarmsg
== NULL
)
3332 e
->e_quarmsg
= NULL
;
3333 macdefine(&e
->e_macro
, A_PERM
, macid("{quarantine}"), "");
3337 e
->e_quarmsg
= sm_rpool_strdup_x(e
->e_rpool
, smtp
->sm_quarmsg
);
3338 macdefine(&e
->e_macro
, A_PERM
,
3339 macid("{quarantine}"), e
->e_quarmsg
);
3341 #endif /* _FFR_QUARANTINE */
3344 ** LOGUNDELRCPTS -- log undelivered (or all) recipients.
3348 ** msg -- message for Stat=
3349 ** level -- log level.
3350 ** all -- log all recipients.
3356 ** logs undelivered (or all) recipients
3360 logundelrcpts(e
, msg
, level
, all
)
3368 if (LogLevel
<= level
|| msg
== NULL
|| *msg
== '\0')
3371 /* Clear $h so relay= doesn't get mislogged by logdelivery() */
3372 macdefine(&e
->e_macro
, A_PERM
, 'h', NULL
);
3374 /* Log who the mail would have gone to */
3375 for (a
= e
->e_sendqueue
; a
!= NULL
; a
= a
->q_next
)
3377 if (!QS_IS_UNDELIVERED(a
->q_state
) && !all
)
3379 e
->e_to
= a
->q_paddr
;
3380 logdelivery(NULL
, NULL
, a
->q_status
, msg
, NULL
,
3386 ** CHECKSMTPATTACK -- check for denial-of-service attack by repetition
3389 ** pcounter -- pointer to a counter for this command.
3390 ** maxcount -- maximum value for this counter before we
3392 ** waitnow -- sleep now (in this routine)?
3393 ** cname -- command name for logging.
3394 ** e -- the current envelope.
3400 ** Slows down if we seem to be under attack.
3404 checksmtpattack(pcounter
, maxcount
, waitnow
, cname
, e
)
3405 volatile unsigned int *pcounter
;
3411 if (maxcount
<= 0) /* no limit */
3414 if (++(*pcounter
) >= maxcount
)
3418 if (*pcounter
== maxcount
&& LogLevel
> 5)
3420 sm_syslog(LOG_INFO
, e
->e_id
,
3421 "%s: possible SMTP attack: command=%.40s, count=%u",
3422 CurSmtpClient
, cname
, *pcounter
);
3424 s
= 1 << (*pcounter
- maxcount
);
3425 if (s
>= MAXTIMEOUT
|| s
<= 0)
3428 /* sleep at least 1 second before returning */
3429 (void) sleep(*pcounter
/ maxcount
);
3430 s
-= *pcounter
/ maxcount
;
3441 ** SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
3450 ** may change I/O fd.
3456 int inchfd
, outchfd
, outfd
;
3458 inchfd
= sm_io_getinfo(InChannel
, SM_IO_WHAT_FD
, NULL
);
3459 outchfd
= sm_io_getinfo(OutChannel
, SM_IO_WHAT_FD
, NULL
);
3460 outfd
= sm_io_getinfo(smioout
, SM_IO_WHAT_FD
, NULL
);
3461 if (outchfd
!= outfd
)
3463 /* arrange for debugging output to go to remote host */
3464 (void) dup2(outchfd
, outfd
);
3468 ** if InChannel and OutChannel are stdin/stdout
3469 ** and connected to ttys
3470 ** and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT,
3471 ** then "chain" them together.
3474 if (inchfd
== STDIN_FILENO
&& outchfd
== STDOUT_FILENO
&&
3475 isatty(inchfd
) && isatty(outchfd
))
3477 int inmode
, outmode
;
3479 inmode
= fcntl(inchfd
, F_GETFL
, 0);
3483 sm_syslog(LOG_INFO
, NOQID
,
3484 "fcntl(inchfd, F_GETFL) failed: %s",
3485 sm_errstring(errno
));
3488 outmode
= fcntl(outchfd
, F_GETFL
, 0);
3492 sm_syslog(LOG_INFO
, NOQID
,
3493 "fcntl(outchfd, F_GETFL) failed: %s",
3494 sm_errstring(errno
));
3497 if (bitset(O_NONBLOCK
, inmode
) ||
3498 bitset(O_NONBLOCK
, outmode
) ||
3499 fcntl(inchfd
, F_SETFL
, inmode
| O_NONBLOCK
) == -1)
3501 outmode
= fcntl(outchfd
, F_GETFL
, 0);
3502 if (outmode
!= -1 && bitset(O_NONBLOCK
, outmode
))
3504 /* changing InChannel also changes OutChannel */
3505 sm_io_automode(OutChannel
, InChannel
);
3506 if (tTd(97, 4) && LogLevel
> 9)
3507 sm_syslog(LOG_INFO
, NOQID
,
3508 "set automode for I (%d)/O (%d) in SMTP server",
3512 /* undo change of inchfd */
3513 (void) fcntl(inchfd
, F_SETFL
, inmode
);
3517 ** SKIPWORD -- skip a fixed word.
3520 ** p -- place to start looking.
3521 ** w -- word to skip.
3528 ** clobbers the p data area.
3533 register char *volatile p
;
3539 /* find beginning of word */
3543 /* find end of word */
3544 while (*p
!= '\0' && *p
!= ':' && !(isascii(*p
) && isspace(*p
)))
3546 while (isascii(*p
) && isspace(*p
))
3551 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
3552 shortenstring(firstp
, MAXSHORTSTR
));
3561 /* see if the input word matches desired word */
3562 if (sm_strcasecmp(q
, w
))
3568 ** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
3571 ** kp -- the parameter key.
3572 ** vp -- the value of that parameter.
3573 ** e -- the envelope.
3580 mail_esmtp_args(kp
, vp
, e
)
3585 if (sm_strcasecmp(kp
, "size") == 0)
3589 usrerr("501 5.5.2 SIZE requires a value");
3592 macdefine(&e
->e_macro
, A_TEMP
, macid("{msg_size}"), vp
);
3594 e
->e_msgsize
= strtol(vp
, (char **) NULL
, 10);
3595 if (e
->e_msgsize
== LONG_MAX
&& errno
== ERANGE
)
3597 usrerr("552 5.2.3 Message size exceeds maximum value");
3600 if (e
->e_msgsize
< 0)
3602 usrerr("552 5.2.3 Message size invalid");
3606 else if (sm_strcasecmp(kp
, "body") == 0)
3610 usrerr("501 5.5.2 BODY requires a value");
3613 else if (sm_strcasecmp(vp
, "8bitmime") == 0)
3615 SevenBitInput
= false;
3617 else if (sm_strcasecmp(vp
, "7bit") == 0)
3619 SevenBitInput
= true;
3623 usrerr("501 5.5.4 Unknown BODY type %s", vp
);
3626 e
->e_bodytype
= sm_rpool_strdup_x(e
->e_rpool
, vp
);
3628 else if (sm_strcasecmp(kp
, "envid") == 0)
3630 if (bitset(PRIV_NORECEIPTS
, PrivacyFlags
))
3632 usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
3637 usrerr("501 5.5.2 ENVID requires a value");
3642 usrerr("501 5.5.4 Syntax error in ENVID parameter value");
3645 if (e
->e_envid
!= NULL
)
3647 usrerr("501 5.5.0 Duplicate ENVID parameter");
3650 e
->e_envid
= sm_rpool_strdup_x(e
->e_rpool
, vp
);
3651 macdefine(&e
->e_macro
, A_PERM
,
3652 macid("{dsn_envid}"), e
->e_envid
);
3654 else if (sm_strcasecmp(kp
, "ret") == 0)
3656 if (bitset(PRIV_NORECEIPTS
, PrivacyFlags
))
3658 usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
3663 usrerr("501 5.5.2 RET requires a value");
3666 if (bitset(EF_RET_PARAM
, e
->e_flags
))
3668 usrerr("501 5.5.0 Duplicate RET parameter");
3671 e
->e_flags
|= EF_RET_PARAM
;
3672 if (sm_strcasecmp(vp
, "hdrs") == 0)
3673 e
->e_flags
|= EF_NO_BODY_RETN
;
3674 else if (sm_strcasecmp(vp
, "full") != 0)
3676 usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp
);
3679 macdefine(&e
->e_macro
, A_TEMP
, macid("{dsn_ret}"), vp
);
3682 else if (sm_strcasecmp(kp
, "auth") == 0)
3686 char *auth_param
; /* the value of the AUTH=x */
3687 bool saveQuickAbort
= QuickAbort
;
3688 bool saveSuprErrs
= SuprErrs
;
3689 bool saveExitStat
= ExitStat
;
3694 usrerr("501 5.5.2 AUTH= requires a value");
3697 if (e
->e_auth_param
!= NULL
)
3699 usrerr("501 5.5.0 Duplicate AUTH parameter");
3702 if ((q
= strchr(vp
, ' ')) != NULL
)
3705 len
= strlen(vp
) + 1;
3706 auth_param
= xalloc(len
);
3707 (void) sm_strlcpy(auth_param
, vp
, len
);
3708 if (!xtextok(auth_param
))
3710 usrerr("501 5.5.4 Syntax error in AUTH parameter value");
3711 /* just a warning? */
3715 /* XXX this might be cut off */
3716 (void) sm_strlcpy(pbuf
, xuntextify(auth_param
), sizeof pbuf
);
3717 /* xalloc() the buffer instead? */
3719 /* XXX define this always or only if trusted? */
3720 macdefine(&e
->e_macro
, A_TEMP
, macid("{auth_author}"), pbuf
);
3723 ** call Strust_auth to find out whether
3724 ** auth_param is acceptable (trusted)
3725 ** we shouldn't trust it if not authenticated
3726 ** (required by RFC, leave it to ruleset?)
3731 if (strcmp(auth_param
, "<>") != 0 &&
3732 (rscheck("trust_auth", pbuf
, NULL
, e
, RSF_RMCOMM
,
3733 9, NULL
, NOQID
) != EX_OK
|| Errors
> 0))
3737 q
= e
->e_auth_param
;
3738 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
3739 pbuf
, (q
== NULL
) ? "" : q
);
3743 e
->e_auth_param
= "<>";
3744 # if _FFR_AUTH_PASSING
3745 macdefine(&BlankEnvelope
.e_macro
, A_PERM
,
3746 macid("{auth_author}"), NULL
);
3747 # endif /* _FFR_AUTH_PASSING */
3752 sm_dprintf("auth=\"%.100s\" trusted\n", pbuf
);
3753 e
->e_auth_param
= sm_rpool_strdup_x(e
->e_rpool
,
3756 sm_free(auth_param
); /* XXX */
3760 QuickAbort
= saveQuickAbort
;
3761 SuprErrs
= saveSuprErrs
;
3762 ExitStat
= saveExitStat
;
3765 #define PRTCHAR(c) ((isascii(c) && isprint(c)) ? (c) : '?')
3768 ** "by" is only accepted if DeliverByMin >= 0.
3769 ** We maybe could add this to the list of server_features.
3772 else if (sm_strcasecmp(kp
, "by") == 0 && DeliverByMin
>= 0)
3778 usrerr("501 5.5.2 BY= requires a value");
3782 e
->e_deliver_by
= strtol(vp
, &s
, 10);
3783 if (e
->e_deliver_by
== LONG_MIN
||
3784 e
->e_deliver_by
== LONG_MAX
||
3785 e
->e_deliver_by
> 999999999l ||
3786 e
->e_deliver_by
< -999999999l)
3788 usrerr("501 5.5.2 BY=%s out of range", vp
);
3791 if (s
== NULL
|| *s
!= ';')
3793 usrerr("501 5.5.2 BY= missing ';'");
3797 ++s
; /* XXX: spaces allowed? */
3799 switch (tolower(*s
))
3802 e
->e_dlvr_flag
= DLVR_NOTIFY
;
3805 e
->e_dlvr_flag
= DLVR_RETURN
;
3806 if (e
->e_deliver_by
<= 0)
3808 usrerr("501 5.5.4 mode R requires BY time > 0");
3811 if (DeliverByMin
> 0 && e
->e_deliver_by
> 0 &&
3812 e
->e_deliver_by
< DeliverByMin
)
3814 usrerr("555 5.5.2 time %ld less than %ld",
3815 e
->e_deliver_by
, (long) DeliverByMin
);
3820 usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s
));
3823 ++s
; /* XXX: spaces allowed? */
3825 switch (tolower(*s
))
3828 e
->e_dlvr_flag
|= DLVR_TRACE
;
3833 usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s
));
3837 /* XXX: check whether more characters follow? */
3841 usrerr("555 5.5.4 %s parameter unrecognized", kp
);
3846 ** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
3849 ** a -- the address corresponding to the To: parameter.
3850 ** kp -- the parameter key.
3851 ** vp -- the value of that parameter.
3852 ** e -- the envelope.
3859 rcpt_esmtp_args(a
, kp
, vp
, e
)
3865 if (sm_strcasecmp(kp
, "notify") == 0)
3869 if (bitset(PRIV_NORECEIPTS
, PrivacyFlags
))
3871 usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
3876 usrerr("501 5.5.2 NOTIFY requires a value");
3879 a
->q_flags
&= ~(QPINGONSUCCESS
|QPINGONFAILURE
|QPINGONDELAY
);
3880 a
->q_flags
|= QHASNOTIFY
;
3881 macdefine(&e
->e_macro
, A_TEMP
, macid("{dsn_notify}"), vp
);
3883 if (sm_strcasecmp(vp
, "never") == 0)
3885 for (p
= vp
; p
!= NULL
; vp
= p
)
3890 if (sm_strcasecmp(vp
, "success") == 0)
3891 a
->q_flags
|= QPINGONSUCCESS
;
3892 else if (sm_strcasecmp(vp
, "failure") == 0)
3893 a
->q_flags
|= QPINGONFAILURE
;
3894 else if (sm_strcasecmp(vp
, "delay") == 0)
3895 a
->q_flags
|= QPINGONDELAY
;
3898 usrerr("501 5.5.4 Bad argument \"%s\" to NOTIFY",
3904 else if (sm_strcasecmp(kp
, "orcpt") == 0)
3906 if (bitset(PRIV_NORECEIPTS
, PrivacyFlags
))
3908 usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
3913 usrerr("501 5.5.2 ORCPT requires a value");
3916 if (strchr(vp
, ';') == NULL
|| !xtextok(vp
))
3918 usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
3921 if (a
->q_orcpt
!= NULL
)
3923 usrerr("501 5.5.0 Duplicate ORCPT parameter");
3926 a
->q_orcpt
= sm_rpool_strdup_x(e
->e_rpool
, vp
);
3930 usrerr("555 5.5.4 %s parameter unrecognized", kp
);
3935 ** PRINTVRFYADDR -- print an entry in the verify queue
3938 ** a -- the address to print.
3939 ** last -- set if this is the last one.
3940 ** vrfy -- set if this is a VRFY command.
3946 ** Prints the appropriate 250 codes.
3948 #define OFFF (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */
3951 printvrfyaddr(a
, last
, vrfy
)
3952 register ADDRESS
*a
;
3958 if (vrfy
&& a
->q_mailer
!= NULL
&&
3959 !bitnset(M_VRFY250
, a
->q_mailer
->m_flags
))
3960 (void) sm_strlcpy(fmtbuf
, "252", sizeof fmtbuf
);
3962 (void) sm_strlcpy(fmtbuf
, "250", sizeof fmtbuf
);
3963 fmtbuf
[3] = last
? ' ' : '-';
3964 (void) sm_strlcpy(&fmtbuf
[4], "2.1.5 ", sizeof fmtbuf
- 4);
3965 if (a
->q_fullname
== NULL
)
3967 if ((a
->q_mailer
== NULL
||
3968 a
->q_mailer
->m_addrtype
== NULL
||
3969 sm_strcasecmp(a
->q_mailer
->m_addrtype
, "rfc822") == 0) &&
3970 strchr(a
->q_user
, '@') == NULL
)
3971 (void) sm_strlcpy(&fmtbuf
[OFFF
], "<%s@%s>",
3972 sizeof fmtbuf
- OFFF
);
3974 (void) sm_strlcpy(&fmtbuf
[OFFF
], "<%s>",
3975 sizeof fmtbuf
- OFFF
);
3976 message(fmtbuf
, a
->q_user
, MyHostName
);
3980 if ((a
->q_mailer
== NULL
||
3981 a
->q_mailer
->m_addrtype
== NULL
||
3982 sm_strcasecmp(a
->q_mailer
->m_addrtype
, "rfc822") == 0) &&
3983 strchr(a
->q_user
, '@') == NULL
)
3984 (void) sm_strlcpy(&fmtbuf
[OFFF
], "%s <%s@%s>",
3985 sizeof fmtbuf
- OFFF
);
3987 (void) sm_strlcpy(&fmtbuf
[OFFF
], "%s <%s>",
3988 sizeof fmtbuf
- OFFF
);
3989 message(fmtbuf
, a
->q_fullname
, a
->q_user
, MyHostName
);
3995 ** SASLMECHS -- get list of possible AUTH mechanisms
3998 ** conn -- SASL connection info.
3999 ** mechlist -- output parameter for list of mechanisms.
4006 saslmechs(conn
, mechlist
)
4010 int len
, num
, result
;
4012 /* "user" is currently unused */
4014 result
= sasl_listmech(conn
, NULL
,
4015 "", " ", "", (const char **) mechlist
,
4016 (unsigned int *)&len
, &num
);
4017 # else /* SASL >= 20000 */
4018 result
= sasl_listmech(conn
, "user", /* XXX */
4019 "", " ", "", mechlist
,
4020 (unsigned int *)&len
, (unsigned int *)&num
);
4021 # endif /* SASL >= 20000 */
4022 if (result
!= SASL_OK
)
4025 sm_syslog(LOG_WARNING
, NOQID
,
4026 "AUTH error: listmech=%d, num=%d",
4033 sm_syslog(LOG_INFO
, NOQID
,
4034 "AUTH: available mech=%s, allowed mech=%s",
4035 *mechlist
, AuthMechanisms
);
4036 *mechlist
= intersect(AuthMechanisms
, *mechlist
, NULL
);
4040 *mechlist
= NULL
; /* be paranoid... */
4041 if (result
== SASL_OK
&& LogLevel
> 9)
4042 sm_syslog(LOG_WARNING
, NOQID
,
4043 "AUTH warning: no mechanisms");
4050 ** PROXY_POLICY -- define proxy policy for AUTH
4054 ** context -- unused.
4055 ** requested_user -- authorization identity.
4056 ** rlen -- authorization identity length.
4057 ** auth_identity -- authentication identity.
4058 ** alen -- authentication identity length.
4059 ** def_realm -- default user realm.
4060 ** urlen -- user realm length.
4061 ** propctx -- unused.
4067 ** sets {auth_authen} macro.
4071 proxy_policy(conn
, context
, requested_user
, rlen
, auth_identity
, alen
,
4072 def_realm
, urlen
, propctx
)
4075 const char *requested_user
;
4077 const char *auth_identity
;
4079 const char *def_realm
;
4081 struct propctx
*propctx
;
4083 if (auth_identity
== NULL
)
4086 macdefine(&BlankEnvelope
.e_macro
, A_TEMP
,
4087 macid("{auth_authen}"), (char *) auth_identity
);
4091 # else /* SASL >= 20000 */
4094 ** PROXY_POLICY -- define proxy policy for AUTH
4097 ** context -- unused.
4098 ** auth_identity -- authentication identity.
4099 ** requested_user -- authorization identity.
4100 ** user -- allowed user (output).
4101 ** errstr -- possible error string (output).
4108 proxy_policy(context
, auth_identity
, requested_user
, user
, errstr
)
4110 const char *auth_identity
;
4111 const char *requested_user
;
4113 const char **errstr
;
4115 if (user
== NULL
|| auth_identity
== NULL
)
4117 *user
= newstr(auth_identity
);
4120 # endif /* SASL >= 20000 */
4125 ** INITSRVTLS -- initialize server side TLS
4128 ** tls_ok -- should tls initialization be done?
4134 ** sets tls_ok_srv which is a static variable in this module.
4135 ** Do NOT remove assignments to it!
4145 /* do NOT remove assignment */
4146 tls_ok_srv
= inittls(&srv_ctx
, TLS_Srv_Opts
, true, SrvCertFile
,
4147 SrvKeyFile
, CACertPath
, CACertFile
, DHParams
);
4150 #endif /* STARTTLS */
4152 ** SRVFEATURES -- get features for SMTP server
4155 ** e -- envelope (should be session context).
4156 ** clientname -- name of client.
4157 ** features -- default features for this invocation.
4163 /* table with options: it uses just one character, how about strings? */
4167 unsigned int srvf_flag
;
4168 } srv_feat_table
[] =
4170 { 'A', SRV_OFFER_AUTH
},
4171 { 'B', SRV_OFFER_VERB
}, /* FFR; not documented in 8.12 */
4172 { 'D', SRV_OFFER_DSN
}, /* FFR; not documented in 8.12 */
4173 { 'E', SRV_OFFER_ETRN
}, /* FFR; not documented in 8.12 */
4174 { 'L', SRV_REQ_AUTH
}, /* FFR; not documented in 8.12 */
4177 { 'N', SRV_NO_PIPE
},
4178 # endif /* _FFR_NO_PIPE */
4179 { 'P', SRV_OFFER_PIPE
},
4180 #endif /* PIPELINING */
4181 { 'R', SRV_VRFY_CLT
}, /* FFR; not documented in 8.12 */
4182 { 'S', SRV_OFFER_TLS
},
4183 /* { 'T', SRV_TMP_FAIL }, */
4184 { 'V', SRV_VRFY_CLT
},
4185 { 'X', SRV_OFFER_EXPN
}, /* FFR; not documented in 8.12 */
4186 /* { 'Y', SRV_OFFER_VRFY }, */
4191 srvfeatures(e
, clientname
, features
)
4194 unsigned int features
;
4198 char pvpbuf
[PSBUFSIZE
];
4201 r
= rscap("srv_features", clientname
, "", e
, &pvp
, pvpbuf
,
4205 if (pvp
== NULL
|| pvp
[0] == NULL
|| (pvp
[0][0] & 0377) != CANONNET
)
4207 if (pvp
[1] != NULL
&& sm_strncasecmp(pvp
[1], "temp", 4) == 0)
4208 return SRV_TMP_FAIL
;
4211 ** General rule (see sendmail.h, d_flags):
4212 ** lower case: required/offered, upper case: Not required/available
4214 ** Since we can change some features per daemon, we have both
4215 ** cases here: turn on/off a feature.
4218 for (i
= 1; pvp
[i
] != NULL
; i
++)
4224 if ((opt
= srv_feat_table
[j
].srvf_opt
) == '\0')
4227 sm_syslog(LOG_WARNING
, e
->e_id
,
4228 "srvfeatures: unknown feature %s",
4234 features
&= ~(srv_feat_table
[j
].srvf_flag
);
4237 if (c
== tolower(opt
))
4239 features
|= srv_feat_table
[j
].srvf_flag
;
4249 ** HELP -- implement the HELP command.
4252 ** topic -- the topic we want help for.
4259 ** outputs the help file to message output.
4261 #define HELPVSTR "#vers "
4262 #define HELPVERSION 2
4269 register SM_FILE_T
*hf
;
4274 long sff
= SFF_OPENASROOT
|SFF_REGONLY
;
4277 static int foundvers
= -1;
4278 extern char Version
[];
4280 if (DontLockReadFiles
)
4282 if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH
, DontBlameSendmail
))
4283 sff
|= SFF_SAFEDIRPATH
;
4285 if (HelpFile
== NULL
||
4286 (hf
= safefopen(HelpFile
, O_RDONLY
, 0444, sff
)) == NULL
)
4290 message("502 5.3.0 Sendmail %s -- HELP not implemented",
4295 if (topic
== NULL
|| *topic
== '\0')
4306 len
= strlen(topic
);
4308 while (sm_io_fgets(hf
, SM_TIME_DEFAULT
, buf
, sizeof buf
) != NULL
)
4312 if (foundvers
< 0 &&
4313 strncmp(buf
, HELPVSTR
, strlen(HELPVSTR
)) == 0)
4317 if (sm_io_sscanf(buf
+ strlen(HELPVSTR
), "%d",
4323 if (strncmp(buf
, topic
, len
) == 0)
4329 /* print version if no/old vers# in file */
4330 if (foundvers
< 2 && !noinfo
)
4331 message("214-2.0.0 This is Sendmail version %s", Version
);
4333 p
= strpbrk(buf
, " \t");
4335 p
= buf
+ strlen(buf
) - 1;
4341 translate_dollars(p
);
4342 expand(p
, inp
, sizeof inp
, e
);
4345 message("214-2.0.0 %s", p
);
4351 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic
);
4353 message("214 2.0.0 End of HELP info");
4355 if (foundvers
!= 0 && foundvers
< HELPVERSION
)
4358 sm_syslog(LOG_WARNING
, e
->e_id
,
4359 "%s too old (require version %d)",
4360 HelpFile
, HELPVERSION
);
4362 /* avoid log next time */
4366 (void) sm_io_close(hf
, SM_TIME_DEFAULT
);
4371 ** RESET_SASLCONN -- reset SASL connection data
4374 ** conn -- SASL connection context
4375 ** hostname -- host name
4376 ** various connection data
4383 reset_saslconn(sasl_conn_t
** conn
, char *hostname
,
4385 char *remoteip
, char *localip
,
4386 char *auth_id
, sasl_ssf_t
* ext_ssf
)
4387 # else /* SASL >= 20000 */
4388 struct sockaddr_in
* saddr_r
, struct sockaddr_in
* saddr_l
,
4389 sasl_external_properties_t
* ext_ssf
)
4390 # endif /* SASL >= 20000 */
4396 result
= sasl_server_new("smtp", hostname
, NULL
, NULL
, NULL
,
4399 /* use empty realm: only works in SASL > 1.5.5 */
4400 result
= sasl_server_new("smtp", hostname
, "", NULL
, 0, conn
);
4401 # else /* SASL >= 20000 */
4402 /* use no realm -> realm is set to hostname by SASL lib */
4403 result
= sasl_server_new("smtp", hostname
, NULL
, NULL
, 0,
4405 # endif /* SASL >= 20000 */
4406 if (result
!= SASL_OK
)
4410 # if NETINET || NETINET6
4411 if (remoteip
!= NULL
)
4412 result
= sasl_setprop(*conn
, SASL_IPREMOTEPORT
, remoteip
);
4413 if (result
!= SASL_OK
)
4416 if (localip
!= NULL
)
4417 result
= sasl_setprop(*conn
, SASL_IPLOCALPORT
, localip
);
4418 if (result
!= SASL_OK
)
4420 # endif /* NETINET || NETINET6 */
4422 result
= sasl_setprop(*conn
, SASL_SSF_EXTERNAL
, ext_ssf
);
4423 if (result
!= SASL_OK
)
4426 result
= sasl_setprop(*conn
, SASL_AUTH_EXTERNAL
, auth_id
);
4427 if (result
!= SASL_OK
)
4429 # else /* SASL >= 20000 */
4431 if (saddr_r
!= NULL
)
4432 result
= sasl_setprop(*conn
, SASL_IP_REMOTE
, saddr_r
);
4433 if (result
!= SASL_OK
)
4436 if (saddr_l
!= NULL
)
4437 result
= sasl_setprop(*conn
, SASL_IP_LOCAL
, saddr_l
);
4438 if (result
!= SASL_OK
)
4440 # endif /* NETINET */
4442 result
= sasl_setprop(*conn
, SASL_SSF_EXTERNAL
, ext_ssf
);
4443 if (result
!= SASL_OK
)
4445 # endif /* SASL >= 20000 */