Update zoneinfo database.
[dragonfly/netmp.git] / contrib / sendmail / src / srvrsmtp.c
blob52d47a1ff7e60c36853b69a95cdf543ab148acb7
1 /*
2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
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.
14 #include <sendmail.h>
15 #if MILTER
16 # include <libmilter/mfdef.h>
17 #endif /* MILTER */
19 SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.829.2.31 2003/07/01 17:30:01 ca Exp $")
21 #if SASL || STARTTLS
22 # include <sys/time.h>
23 # include "sfsasl.h"
24 #endif /* SASL || STARTTLS */
25 #if SASL
26 # define ENC64LEN(l) (((l) + 2) * 4 / 3 + 1)
27 static int saslmechs __P((sasl_conn_t *, char **));
28 #endif /* SASL */
29 #if STARTTLS
30 # include <sysexits.h>
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))
40 #endif /* STARTTLS */
42 /* server features */
43 #define SRV_NONE 0x0000 /* none... */
44 #define SRV_OFFER_TLS 0x0001 /* offer STARTTLS */
45 #define SRV_VRFY_CLT 0x0002 /* request a cert */
46 #define SRV_OFFER_AUTH 0x0004 /* offer AUTH */
47 #define SRV_OFFER_ETRN 0x0008 /* offer ETRN */
48 #define SRV_OFFER_VRFY 0x0010 /* offer VRFY (not yet used) */
49 #define SRV_OFFER_EXPN 0x0020 /* offer EXPN */
50 #define SRV_OFFER_VERB 0x0040 /* offer VERB */
51 #define SRV_OFFER_DSN 0x0080 /* offer DSN */
52 #if PIPELINING
53 # define SRV_OFFER_PIPE 0x0100 /* offer PIPELINING */
54 # if _FFR_NO_PIPE
55 # define SRV_NO_PIPE 0x0200 /* disable PIPELINING, sleep if used */
56 # endif /* _FFR_NO_PIPE */
57 #endif /* PIPELINING */
58 #define SRV_REQ_AUTH 0x0400 /* require AUTH */
59 #define SRV_TMP_FAIL 0x1000 /* ruleset caused a temporary failure */
61 static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int));
63 static time_t checksmtpattack __P((volatile unsigned int *, int, bool,
64 char *, ENVELOPE *));
65 static void mail_esmtp_args __P((char *, char *, ENVELOPE *));
66 static void printvrfyaddr __P((ADDRESS *, bool, bool));
67 static void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *));
68 static char *skipword __P((char *volatile, char *));
69 static void setup_smtpd_io __P((void));
71 #if SASL
72 # if SASL >= 20000
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, \
79 &ext_ssf); \
80 if (result != SASL_OK) \
81 { \
82 /* This is pretty fatal */ \
83 goto doquit; \
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) \
94 { \
95 /* This is pretty fatal */ \
96 goto doquit; \
99 # endif /* SASL >= 20000 */
100 #endif /* SASL */
102 extern ENVELOPE BlankEnvelope;
104 #define SKIP_SPACE(s) while (isascii(*s) && isspace(*s)) \
105 (s)++
108 ** SMTP -- run the SMTP protocol.
110 ** Parameters:
111 ** nullserver -- if non-NULL, rejection message for
112 ** (almost) all SMTP commands.
113 ** d_flags -- daemon flags
114 ** e -- the envelope.
116 ** Returns:
117 ** never.
119 ** Side Effects:
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.
130 struct cmd
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 */
150 #if SASL
151 # define CMDAUTH 13 /* auth -- SASL authenticate */
152 #endif /* SASL */
153 #if STARTTLS
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[] =
172 { "mail", CMDMAIL },
173 { "rcpt", CMDRCPT },
174 { "data", CMDDATA },
175 { "rset", CMDRSET },
176 { "vrfy", CMDVRFY },
177 { "expn", CMDEXPN },
178 { "help", CMDHELP },
179 { "noop", CMDNOOP },
180 { "quit", CMDQUIT },
181 { "helo", CMDHELO },
182 { "ehlo", CMDEHLO },
183 { "etrn", CMDETRN },
184 { "verb", CMDVERB },
185 { "send", CMDUNIMPL },
186 { "saml", CMDUNIMPL },
187 { "soml", CMDUNIMPL },
188 { "turn", CMDUNIMPL },
189 #if SASL
190 { "auth", CMDAUTH, },
191 #endif /* SASL */
192 #if STARTTLS
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 },
200 { NULL, CMDERROR }
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 */
220 #ifndef MAXTIMEOUT
221 # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */
222 #endif /* ! MAXTIMEOUT */
224 #if SM_HEAP_CHECK
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 */
229 typedef struct
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 */
237 bool sm_discard;
238 #if MILTER
239 bool sm_milterize;
240 bool sm_milterlist; /* any filters in the list? */
241 #endif /* MILTER */
242 #if _FFR_QUARANTINE
243 char *sm_quarmsg; /* carry quarantining across messages */
244 #endif /* _FFR_QUARANTINE */
245 } SMTP_T;
247 static void smtp_data __P((SMTP_T *, ENVELOPE *));
249 #define MSG_TEMPFAIL "451 4.7.1 Please try again later"
251 #if MILTER
252 # define MILTER_ABORT(e) milter_abort((e))
254 #if _FFR_MILTER_421
255 # define MILTER_SHUTDOWN \
256 if (strncmp(response, "421 ", 4) == 0) \
258 e->e_sendqueue = NULL; \
259 goto doquit; \
261 #else /* _FFR_MILTER_421 */
262 # define MILTER_SHUTDOWN
263 #endif /* _FFR_MILTER_421 */
265 # define MILTER_REPLY(str) \
267 int savelogusrerrs = LogUsrErrs; \
269 switch (state) \
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; \
279 usrerr(response); \
280 MILTER_SHUTDOWN \
281 break; \
283 case SMFIR_REJECT: \
284 if (MilterLogLevel > 3) \
286 sm_syslog(LOG_INFO, e->e_id, \
287 "Milter: %s=%s, reject=550 5.7.1 Command rejected", \
288 str, addr); \
289 LogUsrErrs = false; \
291 usrerr("550 5.7.1 Command rejected"); \
292 break; \
294 case SMFIR_DISCARD: \
295 if (MilterLogLevel > 3) \
296 sm_syslog(LOG_INFO, e->e_id, \
297 "Milter: %s=%s, discard", \
298 str, addr); \
299 e->e_flags |= EF_DISCARD; \
300 break; \
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); \
311 break; \
313 LogUsrErrs = savelogusrerrs; \
314 if (response != NULL) \
315 sm_free(response); /* XXX */ \
318 #else /* MILTER */
319 # define MILTER_ABORT(e)
320 #endif /* MILTER */
322 /* clear all SMTP state (for HELO/EHLO/RSET) */
323 #define CLEAR_STATE(cmd) \
325 /* abort milter filters */ \
326 MILTER_ABORT(e); \
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; \
345 SuprErrs = true; \
346 dropenvelope(e, true, false); \
347 sm_rpool_free(e->e_rpool); \
348 e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \
349 CurEnv = e; \
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) \
359 time_t dnow; \
361 sm_setproctitle(true, e, \
362 "%s: %s: delaying %s: load average: %d", \
363 qid_printname(e), CurSmtpClient, \
364 cmd, DelayLA); \
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; \
372 (void) sleep(1); \
373 sm_setproctitle(true, e, "%s %s: %.80s", \
374 qid_printname(e), CurSmtpClient, inp); \
378 void
379 smtp(nullserver, d_flags, e)
380 char *volatile nullserver;
381 BITMAP256 d_flags;
382 register ENVELOPE *volatile e;
384 register char *volatile p;
385 register struct cmd *volatile c = NULL;
386 char *cmd;
387 auto ADDRESS *vrfyqueue;
388 ADDRESS *a;
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" */
394 auto char *delimptr;
395 char *id;
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;
403 bool ok;
404 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
405 volatile bool first;
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;
411 register char *q;
412 SMTP_T smtp;
413 char *addr;
414 char *greetcode = "220";
415 char *hostname; /* my hostname ($j) */
416 QUEUE_CHAR *new;
417 int argno;
418 char *args[MAXSMTPARGS];
419 char inp[MAXLINE];
420 char cmdbuf[MAXLINE];
421 #if SASL
422 sasl_conn_t *conn;
423 volatile bool sasl_ok;
424 volatile unsigned int n_auth = 0; /* count of AUTH commands */
425 bool ismore;
426 int result;
427 volatile int authenticating;
428 char *user;
429 char *in, *out2;
430 # if SASL >= 20000
431 char *auth_id;
432 const char *out;
433 sasl_ssf_t ext_ssf;
434 char localip[60], remoteip[60];
435 # else /* SASL >= 20000 */
436 char *out;
437 const char *errstr;
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;
443 sasl_ssf_t *ssf;
444 unsigned int inlen, out2len;
445 unsigned int outlen;
446 char *volatile auth_type;
447 char *mechlist;
448 volatile unsigned int n_mechs;
449 unsigned int len;
450 #endif /* SASL */
451 #if STARTTLS
452 int r;
453 int rfd, wfd;
454 volatile bool tls_active = false;
455 # if _FFR_SMTP_SSL
456 volatile bool smtps = false;
457 # endif /* _FFR_SMTP_SSL */
458 bool saveQuickAbort;
459 bool saveSuprErrs;
460 time_t tlsstart;
461 #endif /* STARTTLS */
462 volatile unsigned int features;
463 #if PIPELINING
464 # if _FFR_NO_PIPE
465 int np_log = 0;
466 # endif /* _FFR_NO_PIPE */
467 #endif /* PIPELINING */
468 volatile time_t log_delay = (time_t) 0;
470 save_sevenbitinput = SevenBitInput;
471 smtp.sm_nrcpts = 0;
472 #if MILTER
473 smtp.sm_milterize = (nullserver == NULL);
474 smtp.sm_milterlist = false;
475 #endif /* MILTER */
477 /* setup I/O fd correctly for the SMTP server */
478 setup_smtpd_io();
480 #if SM_HEAP_CHECK
481 if (sm_debug_active(&DebugLeakSmtp, 1))
483 sm_heap_newgroup();
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;
492 settime(e);
493 sm_getla();
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);
505 #if PIPELINING
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
517 : (SRV_OFFER_EXPN
518 | (bitset(PRIV_NOVERB, PrivacyFlags)
519 ? SRV_NONE : SRV_OFFER_VERB)))
520 | (bitset(PRIV_NORECEIPTS, PrivacyFlags) ? SRV_NONE
521 : SRV_OFFER_DSN)
522 #if SASL
523 | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH)
524 #endif /* SASL */
525 #if PIPELINING
526 | SRV_OFFER_PIPE
527 #endif /* PIPELINING */
528 #if STARTTLS
529 | (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS)
530 | (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE
531 : SRV_VRFY_CLT)
532 #endif /* STARTTLS */
534 if (nullserver == NULL)
536 features = srvfeatures(e, CurSmtpClient, features);
537 if (bitset(SRV_TMP_FAIL, features))
539 if (LogLevel > 4)
540 sm_syslog(LOG_ERR, NOQID,
541 "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled",
542 CurSmtpClient);
543 nullserver = "450 4.3.0 Please try again later.";
545 #if PIPELINING
546 # if _FFR_NO_PIPE
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);
557 #if SASL
558 sasl_ok = bitset(SRV_OFFER_AUTH, features);
559 n_mechs = 0;
560 authenticating = SASL_NOT_AUTH;
562 /* SASL server new connection */
563 if (sasl_ok)
565 # if SASL >= 20000
566 result = sasl_server_new("smtp", hostname, NULL, NULL, NULL,
567 NULL, 0, &conn);
568 # elif SASL > 10505
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,
574 &conn);
575 # endif /* SASL >= 20000 */
576 sasl_ok = result == SASL_OK;
577 if (!sasl_ok)
579 if (LogLevel > 9)
580 sm_syslog(LOG_WARNING, NOQID,
581 "AUTH error: sasl_server_new failed=%d",
582 result);
585 if (sasl_ok)
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?
593 ** Kerberos_v4
596 # if SASL >= 20000
597 # if NETINET || NETINET6
598 in = macvalue(macid("{daemon_family}"), e);
599 if (in != NULL && (
600 # if NETINET6
601 strcmp(in, "inet6") == 0 ||
602 # endif /* NETINET6 */
603 strcmp(in, "inet") == 0))
605 SOCKADDR_LEN_T addrsize;
606 SOCKADDR saddr_l;
607 SOCKADDR saddr_r;
609 addrsize = sizeof(saddr_r);
610 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
611 NULL),
612 (struct sockaddr *) &saddr_r,
613 &addrsize) == 0)
615 if (iptostring(&saddr_r, addrsize,
616 remoteip, sizeof remoteip))
618 sasl_setprop(conn, SASL_IPREMOTEPORT,
619 remoteip);
621 addrsize = sizeof(saddr_l);
622 if (getsockname(sm_io_getinfo(InChannel,
623 SM_IO_WHAT_FD,
624 NULL),
625 (struct sockaddr *) &saddr_l,
626 &addrsize) == 0)
628 if (iptostring(&saddr_l, addrsize,
629 localip,
630 sizeof localip))
632 sasl_setprop(conn,
633 SASL_IPLOCALPORT,
634 localip);
639 # endif /* NETINET || NETINET6 */
640 # else /* SASL >= 20000 */
641 # if NETINET
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,
649 NULL),
650 (struct sockaddr *)&saddr_r,
651 &addrsize) == 0)
653 sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r);
654 addrsize = sizeof(struct sockaddr_in);
655 if (getsockname(sm_io_getinfo(InChannel,
656 SM_IO_WHAT_FD,
657 NULL),
658 (struct sockaddr *)&saddr_l,
659 &addrsize) == 0)
660 sasl_setprop(conn, SASL_IP_LOCAL,
661 &saddr_l);
664 # endif /* NETINET */
665 # endif /* SASL >= 20000 */
667 auth_type = NULL;
668 mechlist = NULL;
669 user = NULL;
670 # if 0
671 macdefine(&BlankEnvelope.e_macro, A_PERM,
672 macid("{auth_author}"), NULL);
673 # endif /* 0 */
675 /* set properties */
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() */
680 # if STARTTLS
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;
689 if (sasl_ok)
692 ** external security strength factor;
693 ** currently we have none so zero
696 # if SASL >= 20000
697 ext_ssf = 0;
698 auth_id = NULL;
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 */
704 ext_ssf.ssf = 0;
705 ext_ssf.auth_id = NULL;
706 sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
707 &ext_ssf) == SASL_OK;
708 # endif /* SASL >= 20000 */
710 if (sasl_ok)
711 n_mechs = saslmechs(conn, &mechlist);
713 #endif /* SASL */
715 #if STARTTLS
716 #endif /* STARTTLS */
718 #if MILTER
719 if (smtp.sm_milterize)
721 char state;
723 /* initialize mail filter connection */
724 smtp.sm_milterlist = milter_init(e, &state);
725 switch (state)
727 case SMFIR_REJECT:
728 if (MilterLogLevel > 3)
729 sm_syslog(LOG_INFO, e->e_id,
730 "Milter: initialization failed, rejecting commands");
731 greetcode = "554";
732 nullserver = "Command rejected";
733 smtp.sm_milterize = false;
734 break;
736 case SMFIR_TEMPFAIL:
737 if (MilterLogLevel > 3)
738 sm_syslog(LOG_INFO, e->e_id,
739 "Milter: initialization failed, temp failing commands");
740 tempfail = true;
741 smtp.sm_milterize = false;
742 break;
746 if (smtp.sm_milterlist && smtp.sm_milterize &&
747 !bitset(EF_DISCARD, e->e_flags))
749 char state;
750 char *response;
752 response = milter_connect(peerhostname, RealHostAddr,
753 e, &state);
754 switch (state)
756 case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
757 case SMFIR_REJECT:
758 if (MilterLogLevel > 3)
759 sm_syslog(LOG_INFO, e->e_id,
760 "Milter: connect: host=%s, addr=%s, rejecting commands",
761 peerhostname,
762 anynet_ntoa(&RealHostAddr));
763 greetcode = "554";
764 nullserver = "Command rejected";
765 smtp.sm_milterize = false;
766 break;
768 case SMFIR_TEMPFAIL:
769 if (MilterLogLevel > 3)
770 sm_syslog(LOG_INFO, e->e_id,
771 "Milter: connect: host=%s, addr=%s, temp failing commands",
772 peerhostname,
773 anynet_ntoa(&RealHostAddr));
774 tempfail = true;
775 smtp.sm_milterize = false;
776 break;
778 #if _FFR_MILTER_421
779 case SMFIR_SHUTDOWN:
780 if (MilterLogLevel > 3)
781 sm_syslog(LOG_INFO, e->e_id,
782 "Milter: connect: host=%s, addr=%s, shutdown",
783 peerhostname,
784 anynet_ntoa(&RealHostAddr));
785 tempfail = true;
786 smtp.sm_milterize = false;
787 message("421 4.7.0 %s closing connection",
788 MyHostName);
790 /* arrange to ignore send list */
791 e->e_sendqueue = NULL;
792 goto doquit;
793 #endif /* _FFR_MILTER_421 */
795 if (response != NULL)
797 sm_free(response); /* XXX */
799 #endif /* MILTER */
801 #if STARTTLS
802 # if _FFR_SMTP_SSL
803 /* If this an smtps connection, start TLS now */
804 smtps = bitnset(D_SMTPS, d_flags);
805 if (smtps)
807 Errors = 0;
808 goto starttls;
811 greeting:
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",
819 hostname);
820 else
821 expand(SmtpGreeting, inp, sizeof inp, e);
823 p = strchr(inp, '\n');
824 if (p != NULL)
825 *p++ = '\0';
826 id = strchr(inp, ' ');
827 if (id == NULL)
828 id = &inp[strlen(inp)];
829 if (p == NULL)
830 (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
831 "%s %%.*s ESMTP%%s", greetcode);
832 else
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)
840 *p++ = '\0';
841 if (isascii(*id) && isspace(*id))
842 id++;
843 (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, "-%s");
844 message(cmdbuf, id);
846 if (id != NULL)
848 if (isascii(*id) && isspace(*id))
849 id++;
850 (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, " %s");
851 message(cmdbuf, id);
854 protocol = NULL;
855 sendinghost = macvalue('s', e);
857 #if _FFR_QUARANTINE
858 /* If quarantining by a connect/ehlo action, save between messages */
859 if (e->e_quarmsg == NULL)
860 smtp.sm_quarmsg = NULL;
861 else
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
869 first = true;
870 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
871 gothello = false;
872 smtp.sm_gotmail = false;
873 for (;;)
875 SM_TRY
877 QuickAbort = false;
878 HoldErrs = false;
879 SuprErrs = false;
880 LogUsrErrs = false;
881 OnlyOneError = true;
882 e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
884 /* setup for the read */
885 e->e_to = NULL;
886 Errors = 0;
887 FileName = NULL;
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);
893 #if SASL
895 ** XXX SMTP AUTH requires accepting any length,
896 ** at least for challenge/response
898 #endif /* SASL */
900 /* handle errors */
901 if (sm_io_error(OutChannel) ||
902 (p = sfgets(inp, sizeof inp, InChannel,
903 TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
905 char *d;
907 d = macvalue(macid("{daemon_name}"), e);
908 if (d == NULL)
909 d = "stdin";
910 /* end of file, just die */
911 disconnect(1, e);
913 #if MILTER
914 /* close out milter filters */
915 milter_quit(e);
916 #endif /* MILTER */
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",
923 CurSmtpClient, d,
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;
932 goto doquit;
935 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
936 if (first)
938 #if _FFR_BLOCK_PROXIES
939 size_t inplen, cmdlen;
940 int idx;
941 char *http_cmd;
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;
947 idx++)
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",
959 CurSmtpClient, inp);
960 goto doquit;
963 #endif /* _FFR_BLOCK_PROXIES */
964 #if _FFR_ADAPTIVE_EOL
965 char *p;
967 smtp.sm_crlf = true;
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",
977 CurSmtpClient);
980 #endif /* _FFR_ADAPTIVE_EOL */
981 first = false;
983 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
985 /* clean up end of line */
986 fixcrlf(inp, true);
988 #if PIPELINING
989 # if _FFR_NO_PIPE
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)
1001 if (++np_log < 3)
1002 sm_syslog(LOG_INFO, NOQID,
1003 "unauthorized PIPELINING, sleeping");
1004 sleep(1);
1007 # endif /* _FFR_NO_PIPE */
1008 #endif /* PIPELINING */
1010 #if SASL
1011 if (authenticating == SASL_PROC_AUTH)
1013 # if 0
1014 if (*inp == '\0')
1016 authenticating = SASL_NOT_AUTH;
1017 message("501 5.5.2 missing input");
1018 RESET_SASLCONN;
1019 continue;
1021 # endif /* 0 */
1022 if (*inp == '*' && *(inp + 1) == '\0')
1024 authenticating = SASL_NOT_AUTH;
1026 /* rfc 2254 4. */
1027 message("501 5.0.0 AUTH aborted");
1028 RESET_SASLCONN;
1029 continue;
1032 /* could this be shorter? XXX */
1033 # if SASL >= 20000
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;
1045 /* rfc 2254 4. */
1046 message("501 5.5.4 cannot decode AUTH parameter %s",
1047 inp);
1048 # if SASL >= 20000
1049 sm_free(in);
1050 # endif /* SASL >= 20000 */
1051 RESET_SASLCONN;
1052 continue;
1055 # if SASL >= 20000
1056 result = sasl_server_step(conn, in, inlen,
1057 &out, &outlen);
1058 sm_free(in);
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)
1067 authenticated:
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);
1073 # if SASL >= 20000
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,
1081 (void **)&user);
1082 if (result != SASL_OK)
1084 user = "";
1085 macdefine(&BlankEnvelope.e_macro,
1086 A_PERM,
1087 macid("{auth_authen}"), NULL);
1089 else
1091 macdefine(&BlankEnvelope.e_macro,
1092 A_TEMP,
1093 macid("{auth_authen}"), user);
1096 # if 0
1097 /* get realm? */
1098 sasl_getprop(conn, SASL_REALM, (void **) &data);
1099 # endif /* 0 */
1101 /* get security strength (features) */
1102 result = sasl_getprop(conn, SASL_SSF,
1103 (void **) &ssf);
1104 # endif /* SASL >= 20000 */
1105 if (result != SASL_OK)
1107 macdefine(&BlankEnvelope.e_macro,
1108 A_PERM,
1109 macid("{auth_ssf}"), "0");
1110 ssf = NULL;
1112 else
1114 char pbuf[8];
1116 (void) sm_snprintf(pbuf, sizeof pbuf,
1117 "%u", *ssf);
1118 macdefine(&BlankEnvelope.e_macro,
1119 A_TEMP,
1120 macid("{auth_ssf}"), pbuf);
1121 if (tTd(95, 8))
1122 sm_dprintf("AUTH auth_ssf: %u\n",
1123 *ssf);
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
1136 ** is aborted.
1139 if (sfdcsasl(&InChannel, &OutChannel,
1140 conn) == 0)
1142 /* restart dialogue */
1143 n_helo = 0;
1144 # if PIPELINING
1145 (void) sm_io_autoflush(InChannel,
1146 OutChannel);
1147 # endif /* PIPELINING */
1149 else
1150 syserr("503 5.3.3 SASL TLS failed");
1153 /* NULL pointer ok since it's our function */
1154 if (LogLevel > 8)
1155 sm_syslog(LOG_INFO, NOQID,
1156 "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d",
1157 CurSmtpClient,
1158 shortenstring(user, 128),
1159 auth_type, *ssf);
1161 else if (result == SASL_CONTINUE)
1163 len = ENC64LEN(outlen);
1164 out2 = xalloc(len);
1165 result = sasl_encode64(out, outlen, out2, len,
1166 &out2len);
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");
1172 if (LogLevel > 5)
1173 sm_syslog(LOG_WARNING, e->e_id,
1174 "AUTH encode64 error [%d for \"%s\"]",
1175 result, out);
1176 /* start over? */
1177 authenticating = SASL_NOT_AUTH;
1179 else
1181 message("334 %s", out2);
1182 if (tTd(95, 2))
1183 sm_dprintf("AUTH continue: msg='%s' len=%u\n",
1184 out2, out2len);
1186 # if SASL >= 20000
1187 sm_free(out2);
1188 # endif /* SASL >= 20000 */
1190 else
1192 /* not SASL_OK or SASL_CONT */
1193 message("535 5.7.0 authentication failed");
1194 if (LogLevel > 9)
1195 sm_syslog(LOG_WARNING, e->e_id,
1196 "AUTH failure (%s): %s (%d) %s",
1197 auth_type,
1198 sasl_errstring(result, NULL,
1199 NULL),
1200 result,
1201 # if SASL >= 20000
1202 sasl_errdetail(conn));
1203 # else /* SASL >= 20000 */
1204 errstr == NULL ? "" : errstr);
1205 # endif /* SASL >= 20000 */
1206 RESET_SASLCONN;
1207 authenticating = SASL_NOT_AUTH;
1210 else
1212 /* don't want to do any of this if authenticating */
1213 #endif /* SASL */
1215 /* echo command to transcript */
1216 if (e->e_xfp != NULL)
1217 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
1218 "<<< %s\n", inp);
1220 if (LogLevel > 14)
1221 sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp);
1223 /* break off command */
1224 for (p = inp; isascii(*p) && isspace(*p); p++)
1225 continue;
1226 cmd = cmdbuf;
1227 while (*p != '\0' &&
1228 !(isascii(*p) && isspace(*p)) &&
1229 cmd < &cmdbuf[sizeof cmdbuf - 2])
1230 *cmd++ = *p++;
1231 *cmd = '\0';
1233 /* throw away leading whitespace */
1234 SKIP_SPACE(p);
1236 /* decode command */
1237 for (c = CmdTab; c->cmd_name != NULL; c++)
1239 if (sm_strcasecmp(c->cmd_name, cmdbuf) == 0)
1240 break;
1243 /* reset errors */
1244 errno = 0;
1246 /* check whether a "non-null" command has been used */
1247 switch (c->cmd_code)
1249 #if SASL
1250 case CMDAUTH:
1251 /* avoid information leak; take first two words? */
1252 q = "AUTH";
1253 break;
1254 #endif /* SASL */
1256 case CMDMAIL:
1257 case CMDEXPN:
1258 case CMDVRFY:
1259 case CMDETRN:
1260 lognullconnection = false;
1261 /* FALLTHROUGH */
1262 default:
1263 q = inp;
1264 break;
1267 if (e->e_id == NULL)
1268 sm_setproctitle(true, e, "%s: %.80s",
1269 CurSmtpClient, q);
1270 else
1271 sm_setproctitle(true, e, "%s %s: %.80s",
1272 qid_printname(e),
1273 CurSmtpClient, q);
1276 ** Process command.
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)
1286 case CMDQUIT:
1287 case CMDHELO:
1288 case CMDEHLO:
1289 case CMDNOOP:
1290 case CMDRSET:
1291 /* process normally */
1292 break;
1294 case CMDETRN:
1295 if (bitnset(D_ETRNONLY, d_flags) &&
1296 nullserver == NULL)
1297 break;
1298 DELAY_CONN("ETRN");
1299 /* FALLTHROUGH */
1301 default:
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",
1308 MyHostName);
1310 /* arrange to ignore send list */
1311 e->e_sendqueue = NULL;
1312 goto doquit;
1314 #endif /* MAXBADCOMMANDS > 0 */
1315 if (nullserver != NULL)
1317 if (ISSMTPREPLY(nullserver))
1318 usrerr(nullserver);
1319 else
1320 usrerr("550 5.0.0 %s",
1321 nullserver);
1323 else
1324 usrerr("452 4.4.5 Insufficient disk space; try again later");
1325 continue;
1329 switch (c->cmd_code)
1331 #if SASL
1332 case CMDAUTH: /* sasl */
1333 DELAY_CONN("AUTH");
1334 if (!sasl_ok || n_mechs <= 0)
1336 message("503 5.3.3 AUTH not available");
1337 break;
1339 if (authenticating == SASL_IS_AUTH)
1341 message("503 5.5.0 Already Authenticated");
1342 break;
1344 if (smtp.sm_gotmail)
1346 message("503 5.5.0 AUTH not permitted during a mail transaction");
1347 break;
1349 if (tempfail)
1351 if (LogLevel > 9)
1352 sm_syslog(LOG_INFO, e->e_id,
1353 "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)",
1354 p, CurSmtpClient);
1355 usrerr("454 4.7.1 Please try again later");
1356 break;
1359 ismore = false;
1361 /* crude way to avoid crack attempts */
1362 (void) checksmtpattack(&n_auth, n_mechs + 1, true,
1363 "AUTH", e);
1365 /* make sure mechanism (p) is a valid string */
1366 for (q = p; *q != '\0' && isascii(*q); q++)
1368 if (isspace(*q))
1370 *q = '\0';
1371 while (*++q != '\0' &&
1372 isascii(*q) && isspace(*q))
1373 continue;
1374 *(q - 1) = '\0';
1375 ismore = (*q != '\0');
1376 break;
1380 if (*p == '\0')
1382 message("501 5.5.2 AUTH mechanism must be specified");
1383 break;
1386 /* check whether mechanism is available */
1387 if (iteminlist(p, mechlist, " ") == NULL)
1389 message("504 5.3.3 AUTH mechanism %.32s not available",
1391 break;
1394 if (ismore)
1396 /* could this be shorter? XXX */
1397 # if SASL >= 20000
1398 in = xalloc(strlen(q) + 1);
1399 result = sasl_decode64(q, strlen(q), in,
1400 strlen(q), &inlen);
1401 # else /* SASL >= 20000 */
1402 in = sm_rpool_malloc(e->e_rpool, strlen(q));
1403 result = sasl_decode64(q, strlen(q), in,
1404 &inlen);
1405 # endif /* SASL >= 20000 */
1406 if (result != SASL_OK)
1408 message("501 5.5.4 cannot BASE64 decode '%s'",
1410 if (LogLevel > 5)
1411 sm_syslog(LOG_WARNING, e->e_id,
1412 "AUTH decode64 error [%d for \"%s\"]",
1413 result, q);
1414 /* start over? */
1415 authenticating = SASL_NOT_AUTH;
1416 # if SASL >= 20000
1417 sm_free(in);
1418 # endif /* SASL >= 20000 */
1419 in = NULL;
1420 inlen = 0;
1421 break;
1424 else
1426 in = NULL;
1427 inlen = 0;
1430 /* see if that auth type exists */
1431 # if SASL >= 20000
1432 result = sasl_server_start(conn, p, in, inlen,
1433 &out, &outlen);
1434 if (in != NULL)
1435 sm_free(in);
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");
1444 if (LogLevel > 9)
1445 sm_syslog(LOG_ERR, e->e_id,
1446 "AUTH failure (%s): %s (%d) %s",
1448 sasl_errstring(result, NULL,
1449 NULL),
1450 result,
1451 # if SASL >= 20000
1452 sasl_errdetail(conn));
1453 # else /* SASL >= 20000 */
1454 errstr);
1455 # endif /* SASL >= 20000 */
1456 RESET_SASLCONN;
1457 break;
1459 auth_type = newstr(p);
1461 if (result == SASL_OK)
1463 /* ugly, but same code */
1464 goto authenticated;
1465 /* authenticated by the initial response */
1468 /* len is at least 2 */
1469 len = ENC64LEN(outlen);
1470 out2 = xalloc(len);
1471 result = sasl_encode64(out, outlen, out2, len,
1472 &out2len);
1474 if (result != SASL_OK)
1476 message("454 4.5.4 Temporary authentication failure");
1477 if (LogLevel > 5)
1478 sm_syslog(LOG_WARNING, e->e_id,
1479 "AUTH encode64 error [%d for \"%s\"]",
1480 result, out);
1482 /* start over? */
1483 authenticating = SASL_NOT_AUTH;
1484 RESET_SASLCONN;
1486 else
1488 message("334 %s", out2);
1489 authenticating = SASL_PROC_AUTH;
1491 # if SASL >= 20000
1492 sm_free(out2);
1493 # endif /* SASL >= 20000 */
1494 break;
1495 #endif /* SASL */
1497 #if STARTTLS
1498 case CMDSTLS: /* starttls */
1499 DELAY_CONN("STARTTLS");
1500 if (*p != '\0')
1502 message("501 5.5.2 Syntax error (no parameters allowed)");
1503 break;
1505 if (!bitset(SRV_OFFER_TLS, features))
1507 message("503 5.5.0 TLS not available");
1508 break;
1510 if (!tls_ok_srv)
1512 message("454 4.3.3 TLS not available after start");
1513 break;
1515 if (smtp.sm_gotmail)
1517 message("503 5.5.0 TLS not permitted during a mail transaction");
1518 break;
1520 if (tempfail)
1522 if (LogLevel > 9)
1523 sm_syslog(LOG_INFO, e->e_id,
1524 "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)",
1525 p, CurSmtpClient);
1526 usrerr("454 4.7.1 Please try again later");
1527 break;
1529 # if _FFR_SMTP_SSL
1530 starttls:
1531 # endif /* _FFR_SMTP_SSL */
1532 # if TLS_NO_RSA
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
1542 ** (per SSL_CTX)
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)
1550 SSL_clear(srv_ssl);
1551 else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
1553 message("454 4.3.3 TLS not available: error generating SSL handle");
1554 if (LogLevel > 8)
1555 tlslogerr("server");
1556 # if _FFR_SMTP_SSL
1557 goto tls_done;
1558 # else /* _FFR_SMTP_SSL */
1559 break;
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");
1581 SSL_free(srv_ssl);
1582 srv_ssl = NULL;
1583 # if _FFR_SMTP_SSL
1584 goto tls_done;
1585 # else /* _FFR_SMTP_SSL */
1586 break;
1587 # endif /* _FFR_SMTP_SSL */
1589 # if _FFR_SMTP_SSL
1590 if (!smtps)
1591 # endif /* _FFR_SMTP_SSL */
1592 message("220 2.0.0 Ready to start TLS");
1593 # if PIPELINING
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();
1602 ssl_retry:
1603 if ((r = SSL_ACC(srv_ssl)) <= 0)
1605 int i;
1606 bool timedout;
1607 time_t left;
1608 time_t now = curtime();
1609 struct timeval tv;
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
1624 ** exceptions too.
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;
1634 if (!timedout)
1636 tv.tv_sec = left;
1637 tv.tv_usec = 0;
1640 if (!timedout && FD_SETSIZE > 0 &&
1641 (rfd >= FD_SETSIZE ||
1642 (i == SSL_ERROR_WANT_WRITE &&
1643 wfd >= FD_SETSIZE)))
1645 if (LogLevel > 5)
1647 sm_syslog(LOG_ERR, NOQID,
1648 "STARTTLS=server, error: fd %d/%d too large",
1649 rfd, wfd);
1650 if (LogLevel > 8)
1651 tlslogerr("server");
1653 goto tlsfail;
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)
1667 goto ssl_retry;
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)
1679 goto ssl_retry;
1681 if (LogLevel > 5)
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);
1686 if (LogLevel > 8)
1687 tlslogerr("server");
1689 tlsfail:
1690 tls_ok_srv = false;
1691 SSL_free(srv_ssl);
1692 srv_ssl = NULL;
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;
1701 goto doquit;
1704 /* ignore return code for now, it's in {verify} */
1705 (void) tls_get_info(srv_ssl, true,
1706 CurSmtpClient,
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;
1717 SuprErrs = true;
1718 QuickAbort = false;
1719 if (rscheck("tls_client",
1720 macvalue(macid("{verify}"), e),
1721 "STARTTLS", e,
1722 RSF_RMCOMM|RSF_COUNT,
1723 5, NULL, NOQID) != EX_OK ||
1724 Errors > 0)
1726 extern char MsgBuf[];
1728 if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf))
1729 nullserver = newstr(MsgBuf);
1730 else
1731 nullserver = "503 5.7.0 Authentication required.";
1733 QuickAbort = saveQuickAbort;
1734 SuprErrs = saveSuprErrs;
1736 tls_ok_srv = false; /* don't offer STARTTLS again */
1737 n_helo = 0;
1738 # if SASL
1739 if (sasl_ok)
1741 char *s;
1743 s = macvalue(macid("{cipher_bits}"), e);
1744 # if SASL >= 20000
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 */
1761 mechlist = NULL;
1762 if (sasl_ok)
1763 n_mechs = saslmechs(conn,
1764 &mechlist);
1767 # endif /* SASL */
1769 /* switch to secure connection */
1770 if (sfdctls(&InChannel, &OutChannel, srv_ssl) == 0)
1772 tls_active = true;
1773 # if PIPELINING
1774 (void) sm_io_autoflush(InChannel, OutChannel);
1775 # endif /* PIPELINING */
1777 else
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...
1785 ** just "hang up"?
1788 nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer";
1789 syserr("STARTTLS: can't switch to encrypted layer");
1791 # if _FFR_SMTP_SSL
1792 tls_done:
1793 if (smtps)
1795 if (tls_active)
1796 goto greeting;
1797 else
1798 goto doquit;
1800 # endif /* _FFR_SMTP_SSL */
1801 break;
1802 #endif /* STARTTLS */
1804 case CMDHELO: /* hello -- introduce yourself */
1805 case CMDEHLO: /* extended hello */
1806 DELAY_CONN("EHLO");
1807 if (c->cmd_code == CMDEHLO)
1809 protocol = "ESMTP";
1810 SmtpPhase = "server EHLO";
1812 else
1814 protocol = "SMTP";
1815 SmtpPhase = "server HELO";
1818 /* avoid denial-of-service */
1819 (void) checksmtpattack(&n_helo, MAXHELOCOMMANDS, true,
1820 "HELO/EHLO", e);
1822 #if 0
1823 /* RFC2821 4.1.4 allows duplicate HELO/EHLO */
1824 /* check for duplicate HELO/EHLO per RFC 1651 4.2 */
1825 if (gothello)
1827 usrerr("503 %s Duplicate HELO/EHLO",
1828 MyHostName);
1829 break;
1831 #endif /* 0 */
1833 /* check for valid domain name (re 1123 5.2.5) */
1834 if (*p == '\0' && !AllowBogusHELO)
1836 usrerr("501 %s requires domain address",
1837 cmdbuf);
1838 break;
1841 /* check for long domain name (hides Received: info) */
1842 if (strlen(p) > MAXNAME)
1844 usrerr("501 Invalid domain name");
1845 if (LogLevel > 9)
1846 sm_syslog(LOG_INFO, CurEnv->e_id,
1847 "invalid domain name (too long) from %s",
1848 CurSmtpClient);
1849 break;
1852 ok = true;
1853 for (q = p; *q != '\0'; q++)
1855 if (!isascii(*q))
1856 break;
1857 if (isalnum(*q))
1858 continue;
1859 if (isspace(*q))
1861 *q = '\0';
1863 /* only complain if strict check */
1864 ok = AllowBogusHELO;
1865 break;
1867 if (strchr("[].-_#:", *q) == NULL)
1868 break;
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");
1879 if (LogLevel > 9)
1880 sm_syslog(LOG_INFO, CurEnv->e_id,
1881 "invalid domain name (%s) from %.100s",
1882 p, CurSmtpClient);
1883 break;
1885 else
1887 q = "accepting invalid domain name";
1890 if (gothello)
1892 CLEAR_STATE(cmdbuf);
1894 #if _FFR_QUARANTINE
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}"), "");
1902 else
1904 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
1905 smtp.sm_quarmsg);
1906 macdefine(&e->e_macro, A_PERM,
1907 macid("{quarantine}"),
1908 e->e_quarmsg);
1910 #endif /* _FFR_QUARANTINE */
1913 #if MILTER
1914 if (smtp.sm_milterlist && smtp.sm_milterize &&
1915 !bitset(EF_DISCARD, e->e_flags))
1917 char state;
1918 char *response;
1920 response = milter_helo(p, e, &state);
1921 switch (state)
1923 case SMFIR_REPLYCODE:
1924 if (MilterLogLevel > 3)
1925 sm_syslog(LOG_INFO, e->e_id,
1926 "Milter: helo=%s, reject=%s",
1927 p, response);
1928 nullserver = newstr(response);
1929 smtp.sm_milterize = false;
1930 break;
1932 case SMFIR_REJECT:
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;
1939 break;
1941 case SMFIR_TEMPFAIL:
1942 if (MilterLogLevel > 3)
1943 sm_syslog(LOG_INFO, e->e_id,
1944 "Milter: helo=%s, reject=%s",
1945 p, MSG_TEMPFAIL);
1946 tempfail = true;
1947 smtp.sm_milterize = false;
1948 break;
1950 if (response != NULL)
1951 sm_free(response);
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 */
1964 #endif /* MILTER */
1965 gothello = true;
1967 /* print HELO response message */
1968 if (c->cmd_code != CMDEHLO)
1970 message("250 %s Hello %s, %s",
1971 MyHostName, CurSmtpClient, q);
1972 break;
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");
1982 break;
1986 ** print EHLO features list
1988 ** Note: If you change this list,
1989 ** remember to update 'helpfile'
1992 message("250-ENHANCEDSTATUSCODES");
1993 #if PIPELINING
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");
2003 #if MIME8TO7
2004 message("250-8BITMIME");
2005 #endif /* MIME8TO7 */
2006 if (MaxMessageSize > 0)
2007 message("250-SIZE %ld", MaxMessageSize);
2008 else
2009 message("250-SIZE");
2010 #if DSN
2011 if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features))
2012 message("250-DSN");
2013 #endif /* DSN */
2014 if (bitset(SRV_OFFER_ETRN, features))
2015 message("250-ETRN");
2016 #if SASL
2017 if (sasl_ok && mechlist != NULL && *mechlist != '\0')
2018 message("250-AUTH %s", mechlist);
2019 #endif /* SASL */
2020 #if STARTTLS
2021 if (tls_ok_srv &&
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");
2034 break;
2036 case CMDMAIL: /* mail -- designate sender */
2037 SmtpPhase = "server MAIL";
2038 DELAY_CONN("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");
2044 break;
2046 if (smtp.sm_gotmail)
2048 usrerr("503 5.5.0 Sender already specified");
2049 break;
2051 #if SASL
2052 if (bitset(SRV_REQ_AUTH, features) &&
2053 authenticating != SASL_IS_AUTH)
2055 usrerr("530 5.7.0 Authentication required");
2056 break;
2058 #endif /* SASL */
2060 p = skipword(p, "from");
2061 if (p == NULL)
2062 break;
2063 if (tempfail)
2065 if (LogLevel > 9)
2066 sm_syslog(LOG_INFO, e->e_id,
2067 "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
2068 p, CurSmtpClient);
2069 usrerr(MSG_TEMPFAIL);
2070 break;
2073 /* make sure we know who the sending host is */
2074 if (sendinghost == NULL)
2075 sendinghost = peerhostname;
2078 #if SM_HEAP_CHECK
2079 if (sm_debug_active(&DebugLeakSmtp, 1))
2081 sm_heap_newgroup();
2082 sm_dprintf("smtp() heap group #%d\n",
2083 sm_heap_group());
2085 #endif /* SM_HEAP_CHECK */
2087 if (Errors > 0)
2088 goto undo_no_pm;
2089 if (!gothello)
2091 auth_warning(e, "%s didn't use HELO protocol",
2092 CurSmtpClient);
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)
2105 protocol = "SMTP";
2106 macdefine(&e->e_macro, A_PERM, 'r', protocol);
2107 macdefine(&e->e_macro, A_PERM, 's', sendinghost);
2109 if (Errors > 0)
2110 goto undo_no_pm;
2111 smtp.sm_nrcpts = 0;
2112 n_badrcpts = 0;
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",
2117 qid_printname(e),
2118 CurSmtpClient, inp);
2120 /* do the processing */
2121 SM_TRY
2123 extern char *FullName;
2125 QuickAbort = true;
2126 SM_FREE_CLR(FullName);
2128 /* must parse sender first */
2129 delimptr = NULL;
2130 setsender(p, e, &delimptr, ' ', false);
2131 if (delimptr != NULL && *delimptr != '\0')
2132 *delimptr++ = '\0';
2133 if (Errors > 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);
2144 else
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}"),
2150 e->e_from.q_host);
2151 else
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}"),
2157 e->e_from.q_user);
2158 else
2159 macdefine(&e->e_macro, A_PERM,
2160 macid("{mail_addr}"), NULL);
2161 if (Errors > 0)
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",
2172 RealUserName);
2175 /* reset to default value */
2176 SevenBitInput = save_sevenbitinput;
2178 /* now parse ESMTP arguments */
2179 e->e_msgsize = 0;
2180 addr = p;
2181 argno = 0;
2182 args[argno++] = p;
2183 p = delimptr;
2184 while (p != NULL && *p != '\0')
2186 char *kp;
2187 char *vp = NULL;
2188 char *equal = NULL;
2190 /* locate the beginning of the keyword */
2191 SKIP_SPACE(p);
2192 if (*p == '\0')
2193 break;
2194 kp = p;
2196 /* skip to the value portion */
2197 while ((isascii(*p) && isalnum(*p)) || *p == '-')
2198 p++;
2199 if (*p == '=')
2201 equal = p;
2202 *p++ = '\0';
2203 vp = p;
2205 /* skip to the end of the value */
2206 while (*p != '\0' && *p != ' ' &&
2207 !(isascii(*p) && iscntrl(*p)) &&
2208 *p != '=')
2209 p++;
2212 if (*p != '\0')
2213 *p++ = '\0';
2215 if (tTd(19, 1))
2216 sm_dprintf("MAIL: got arg %s=\"%s\"\n", kp,
2217 vp == NULL ? "<null>" : vp);
2219 mail_esmtp_args(kp, vp, e);
2220 if (equal != NULL)
2221 *equal = '=';
2222 args[argno++] = kp;
2223 if (argno >= MAXSMTPARGS - 1)
2224 usrerr("501 5.5.4 Too many parameters");
2225 if (Errors > 0)
2226 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2228 args[argno] = NULL;
2229 if (Errors > 0)
2230 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2232 #if SASL
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 */
2250 #endif /* SASL */
2252 /* do config file checking of the sender */
2253 macdefine(&e->e_macro, A_PERM,
2254 macid("{addr_type}"), "e s");
2255 #if _FFR_MAIL_MACRO
2256 /* make the "real" sender address available */
2257 macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"),
2258 e->e_from.q_paddr);
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 ||
2263 Errors > 0)
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 ||
2270 e->e_msgsize < 0))
2272 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
2273 MaxMessageSize);
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
2282 ** enough space.
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);
2300 if (Errors > 0)
2301 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2303 LogUsrErrs = true;
2304 #if MILTER
2305 if (smtp.sm_milterlist && smtp.sm_milterize &&
2306 !bitset(EF_DISCARD, e->e_flags))
2308 char state;
2309 char *response;
2311 response = milter_envfrom(args, e, &state);
2312 MILTER_REPLY("from");
2314 #endif /* MILTER */
2315 if (Errors > 0)
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.
2328 sm_exc_free(exc);
2329 goto undo_no_pm;
2331 SM_END_TRY
2332 break;
2334 undo_no_pm:
2335 e->e_flags &= ~EF_PM_NOTIFY;
2336 undo:
2337 break;
2339 case CMDRCPT: /* rcpt -- designate recipient */
2340 DELAY_CONN("RCPT");
2341 if (!smtp.sm_gotmail)
2343 usrerr("503 5.0.0 Need MAIL before RCPT");
2344 break;
2346 SmtpPhase = "server RCPT";
2347 SM_TRY
2349 QuickAbort = true;
2350 LogUsrErrs = true;
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");
2358 goto rcpt_done;
2361 if (e->e_sendmode != SM_DELIVER)
2362 e->e_flags |= EF_VRFYONLY;
2364 #if MILTER
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;
2376 #endif /* MILTER */
2378 p = skipword(p, "to");
2379 if (p == NULL)
2380 goto rcpt_done;
2381 macdefine(&e->e_macro, A_PERM,
2382 macid("{addr_type}"), "e r");
2383 a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr,
2384 e, true);
2385 macdefine(&e->e_macro, A_PERM,
2386 macid("{addr_type}"), NULL);
2387 if (BadRcptThrottle > 0 &&
2388 n_badrcpts >= BadRcptThrottle)
2390 if (LogLevel > 5 &&
2391 n_badrcpts == BadRcptThrottle)
2393 sm_syslog(LOG_INFO, e->e_id,
2394 "%s: Possible SMTP RCPT flood, throttling.",
2395 CurSmtpClient);
2397 /* To avoid duplicated message */
2398 n_badrcpts++;
2402 ** Don't use exponential backoff for now.
2403 ** Some servers will open more connections
2404 ** and actually overload the receiver even
2405 ** more.
2408 (void) sleep(1);
2410 if (Errors > 0)
2411 goto rcpt_done;
2412 if (a == NULL)
2414 usrerr("501 5.0.0 Missing recipient");
2415 goto rcpt_done;
2418 if (delimptr != NULL && *delimptr != '\0')
2419 *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);
2426 else
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);
2432 else
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);
2438 else
2439 macdefine(&e->e_macro, A_PERM,
2440 macid("{rcpt_addr}"), NULL);
2441 if (Errors > 0)
2442 goto rcpt_done;
2444 /* now parse ESMTP arguments */
2445 addr = p;
2446 argno = 0;
2447 args[argno++] = p;
2448 p = delimptr;
2449 while (p != NULL && *p != '\0')
2451 char *kp;
2452 char *vp = NULL;
2453 char *equal = NULL;
2455 /* locate the beginning of the keyword */
2456 SKIP_SPACE(p);
2457 if (*p == '\0')
2458 break;
2459 kp = p;
2461 /* skip to the value portion */
2462 while ((isascii(*p) && isalnum(*p)) || *p == '-')
2463 p++;
2464 if (*p == '=')
2466 equal = p;
2467 *p++ = '\0';
2468 vp = p;
2470 /* skip to the end of the value */
2471 while (*p != '\0' && *p != ' ' &&
2472 !(isascii(*p) && iscntrl(*p)) &&
2473 *p != '=')
2474 p++;
2477 if (*p != '\0')
2478 *p++ = '\0';
2480 if (tTd(19, 1))
2481 sm_dprintf("RCPT: got arg %s=\"%s\"\n", kp,
2482 vp == NULL ? "<null>" : vp);
2484 rcpt_esmtp_args(a, kp, vp, e);
2485 if (equal != NULL)
2486 *equal = '=';
2487 args[argno++] = kp;
2488 if (argno >= MAXSMTPARGS - 1)
2489 usrerr("501 5.5.4 Too many parameters");
2490 if (Errors > 0)
2491 break;
2493 args[argno] = NULL;
2494 if (Errors > 0)
2495 goto rcpt_done;
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 ||
2503 Errors > 0)
2504 goto rcpt_done;
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;
2512 #if MILTER
2513 if (smtp.sm_milterlist && smtp.sm_milterize &&
2514 !bitset(EF_DISCARD, e->e_flags))
2516 char state;
2517 char *response;
2519 response = milter_envrcpt(args, e, &state);
2520 MILTER_REPLY("to");
2522 #endif /* MILTER */
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);
2532 if (Errors > 0)
2533 goto rcpt_done;
2535 /* save in recipient list after ESMTP mods */
2536 a = recipient(a, &e->e_sendqueue, 0, e);
2537 if (Errors > 0)
2538 goto rcpt_done;
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)
2545 initsys(e);
2546 message("250 2.1.5 Recipient ok%s",
2547 QS_IS_QUEUEUP(a->q_state) ?
2548 " (will queue)" : "");
2549 smtp.sm_nrcpts++;
2551 else
2553 /* punt -- should keep message in ADDRESS.... */
2554 usrerr("550 5.1.1 Addressee unknown");
2556 rcpt_done:
2557 if (Errors > 0)
2558 ++n_badrcpts;
2560 SM_EXCEPT(exc, "[!F]*")
2562 /* An exception occurred while processing RCPT */
2563 e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
2564 ++n_badrcpts;
2566 SM_END_TRY
2567 break;
2569 case CMDDATA: /* data -- text of mail */
2570 DELAY_CONN("DATA");
2571 smtp_data(&smtp, e);
2572 break;
2574 case CMDRSET: /* rset -- reset state */
2575 if (tTd(94, 100))
2576 message("451 4.0.0 Test failure");
2577 else
2578 message("250 2.0.0 Reset state");
2579 CLEAR_STATE(cmdbuf);
2580 #if _FFR_QUARANTINE
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}"), "");
2588 else
2590 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
2591 smtp.sm_quarmsg);
2592 macdefine(&e->e_macro, A_PERM,
2593 macid("{quarantine}"), e->e_quarmsg);
2595 #endif /* _FFR_QUARANTINE */
2596 break;
2598 case CMDVRFY: /* vrfy -- verify address */
2599 case CMDEXPN: /* expn -- expand address */
2600 vrfy = c->cmd_code == CMDVRFY;
2601 DELAY_CONN(vrfy ? "VRFY" : "EXPN");
2602 if (tempfail)
2604 if (LogLevel > 9)
2605 sm_syslog(LOG_INFO, e->e_id,
2606 "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)",
2607 vrfy ? "VRFY" : "EXPN",
2608 p, CurSmtpClient);
2610 /* RFC 821 doesn't allow 4xy reply code */
2611 usrerr("550 5.7.1 Please try again later");
2612 break;
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)))
2620 if (vrfy)
2621 message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
2622 else
2623 message("502 5.7.0 Sorry, we do not allow this operation");
2624 if (LogLevel > 5)
2625 sm_syslog(LOG_INFO, e->e_id,
2626 "%s: %s [rejected]",
2627 CurSmtpClient,
2628 shortenstring(inp, MAXSHORTSTR));
2629 break;
2631 else if (!gothello &&
2632 bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
2633 PrivacyFlags))
2635 usrerr("503 5.0.0 I demand that you introduce yourself first");
2636 break;
2638 if (Errors > 0)
2639 break;
2640 if (LogLevel > 5)
2641 sm_syslog(LOG_INFO, e->e_id, "%s: %s",
2642 CurSmtpClient,
2643 shortenstring(inp, MAXSHORTSTR));
2644 SM_TRY
2646 QuickAbort = true;
2647 vrfyqueue = NULL;
2648 if (vrfy)
2649 e->e_flags |= EF_VRFYONLY;
2650 while (*p != '\0' && isascii(*p) && isspace(*p))
2651 p++;
2652 if (*p == '\0')
2654 usrerr("501 5.5.2 Argument required");
2656 else
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 ||
2662 Errors > 0)
2663 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2664 (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
2666 if (wt > 0)
2668 time_t t;
2670 t = wt - (curtime() - previous);
2671 if (t > 0)
2672 (void) sleep(t);
2674 if (Errors > 0)
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;
2685 continue;
2688 /* see if there is more in the vrfy list */
2689 a = vrfyqueue;
2690 while ((a = a->q_next) != NULL &&
2691 (!QS_IS_UNDELIVERED(a->q_state)))
2692 continue;
2693 printvrfyaddr(vrfyqueue, a == NULL, vrfy);
2694 vrfyqueue = a;
2697 SM_EXCEPT(exc, "[!F]*")
2700 ** An exception occurred while processing VRFY/EXPN
2703 sm_exc_free(exc);
2704 goto undo;
2706 SM_END_TRY
2707 break;
2709 case CMDETRN: /* etrn -- force queue flush */
2710 DELAY_CONN("ETRN");
2712 /* Don't leak queue information via debug flags */
2713 if (!bitset(SRV_OFFER_ETRN, features) || UseMSP ||
2714 (RealUid != 0 && RealUid != TrustedUid &&
2715 OpMode == MD_SMTP))
2717 /* different message for MSA ? */
2718 message("502 5.7.0 Sorry, we do not allow this operation");
2719 if (LogLevel > 5)
2720 sm_syslog(LOG_INFO, e->e_id,
2721 "%s: %s [rejected]",
2722 CurSmtpClient,
2723 shortenstring(inp, MAXSHORTSTR));
2724 break;
2726 if (tempfail)
2728 if (LogLevel > 9)
2729 sm_syslog(LOG_INFO, e->e_id,
2730 "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
2731 p, CurSmtpClient);
2732 usrerr(MSG_TEMPFAIL);
2733 break;
2736 if (strlen(p) <= 0)
2738 usrerr("500 5.5.2 Parameter required");
2739 break;
2742 /* crude way to avoid denial-of-service attacks */
2743 (void) checksmtpattack(&n_etrn, MAXETRNCOMMANDS, true,
2744 "ETRN", e);
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 ||
2758 Errors > 0)
2759 break;
2761 if (LogLevel > 5)
2762 sm_syslog(LOG_INFO, e->e_id,
2763 "%s: ETRN %s", CurSmtpClient,
2764 shortenstring(p, MAXSHORTSTR));
2766 id = p;
2767 if (*id == '#')
2769 int i, qgrp;
2771 id++;
2772 qgrp = name2qid(id);
2773 if (!ISVALIDQGRP(qgrp))
2775 usrerr("459 4.5.4 Queue %s unknown",
2776 id);
2777 break;
2779 for (i = 0; i < NumQueue && Queue[i] != NULL;
2780 i++)
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);
2787 break;
2790 if (*id == '@')
2791 id++;
2792 else
2793 *--id = '@';
2795 new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR));
2796 if (new == NULL)
2798 syserr("500 5.5.0 ETRN out of memory");
2799 break;
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);
2810 break;
2812 case CMDHELP: /* help -- give user info */
2813 DELAY_CONN("HELP");
2814 help(p, e);
2815 break;
2817 case CMDNOOP: /* noop -- do nothing */
2818 DELAY_CONN("NOOP");
2819 (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2820 "NOOP", e);
2821 message("250 2.0.0 OK");
2822 break;
2824 case CMDQUIT: /* quit -- leave mail */
2825 message("221 2.0.0 %s closing connection", MyHostName);
2826 #if PIPELINING
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;
2836 #if STARTTLS
2837 /* shutdown TLS connection */
2838 if (tls_active)
2840 (void) endtls(srv_ssl, "server");
2841 tls_active = false;
2843 #endif /* STARTTLS */
2844 #if SASL
2845 if (authenticating == SASL_IS_AUTH)
2847 sasl_dispose(&conn);
2848 authenticating = SASL_NOT_AUTH;
2849 /* XXX sasl_done(); this is a child */
2851 #endif /* SASL */
2853 doquit:
2854 /* avoid future 050 messages */
2855 disconnect(1, e);
2857 #if MILTER
2858 /* close out milter filters */
2859 milter_quit(e);
2860 #endif /* MILTER */
2862 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2863 logsender(e, NULL);
2864 e->e_flags &= ~EF_LOGSENDER;
2866 if (lognullconnection && LogLevel > 5 &&
2867 nullserver == NULL)
2869 char *d;
2871 d = macvalue(macid("{daemon_name}"), e);
2872 if (d == NULL)
2873 d = "stdin";
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",
2883 CurSmtpClient, d);
2885 if (tTd(93, 100))
2887 /* return to handle next connection */
2888 return;
2890 finis(true, true, ExitStat);
2891 /* NOTREACHED */
2893 case CMDVERB: /* set verbose mode */
2894 DELAY_CONN("VERB");
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");
2900 break;
2902 (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2903 "VERB", e);
2904 Verbose = 1;
2905 set_delivery_mode(SM_DELIVER, e);
2906 message("250 2.0.0 Verbose mode");
2907 break;
2909 #if SMTPDEBUG
2910 case CMDDBGQSHOW: /* show queues */
2911 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
2912 "Send Queue=");
2913 printaddr(e->e_sendqueue, true);
2914 break;
2916 case CMDDBGDEBUG: /* set debug mode */
2917 tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
2918 tTflag(p);
2919 message("200 2.0.0 Debug set");
2920 break;
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");
2928 if (LogLevel > 0)
2929 sm_syslog(LOG_CRIT, e->e_id,
2930 "\"%s\" command from %s (%.100s)",
2931 c->cmd_name, CurSmtpClient,
2932 anynet_ntoa(&RealHostAddr));
2933 /* FALLTHROUGH */
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",
2940 MyHostName);
2942 /* arrange to ignore any current send list */
2943 e->e_sendqueue = NULL;
2944 goto doquit;
2946 #endif /* MAXBADCOMMANDS > 0 */
2948 usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2949 shortenstring(inp, MAXSHORTSTR));
2950 break;
2952 case CMDUNIMPL:
2953 DELAY_CONN("Unimpl");
2954 usrerr("502 5.5.1 Command not implemented: \"%s\"",
2955 shortenstring(inp, MAXSHORTSTR));
2956 break;
2958 default:
2959 DELAY_CONN("default");
2960 errno = 0;
2961 syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
2962 break;
2964 #if SASL
2966 #endif /* SASL */
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.
2975 SM_END_TRY
2979 ** SMTP_DATA -- implement the SMTP DATA command.
2981 ** Parameters:
2982 ** smtp -- status of SMTP connection.
2983 ** e -- envelope.
2985 ** Returns:
2986 ** none.
2988 ** Side Effects:
2989 ** possibly sends message.
2992 static void
2993 smtp_data(smtp, e)
2994 SMTP_T *smtp;
2995 ENVELOPE *e;
2997 #if MILTER
2998 bool milteraccept;
2999 #endif /* MILTER */
3000 bool aborting;
3001 bool doublequeue;
3002 ADDRESS *a;
3003 ENVELOPE *ee;
3004 char *id;
3005 char *oldid;
3006 char buf[32];
3008 SmtpPhase = "server DATA";
3009 if (!smtp->sm_gotmail)
3011 usrerr("503 5.0.0 Need MAIL command");
3012 return;
3014 else if (smtp->sm_nrcpts <= 0)
3016 usrerr("503 5.0.0 Need RCPT (recipient)");
3017 return;
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,
3022 e->e_id) != EX_OK)
3023 return;
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 */
3038 doublequeue = true;
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";
3049 buffer_errors();
3051 #if _FFR_ADAPTIVE_EOL
3052 /* triggers error in collect, disabled for now */
3053 if (smtp->sm_crlf)
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);
3063 #if _FFR_CHECK_EOM
3064 /* rscheck() will set Errors or EF_DISCARD if it trips */
3065 (void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
3066 3, NULL, e->e_id);
3067 #endif /* _FFR_CHECK_EOM */
3069 #if MILTER
3070 milteraccept = true;
3071 if (smtp->sm_milterlist && smtp->sm_milterize &&
3072 Errors <= 0 &&
3073 !bitset(EF_DISCARD, e->e_flags))
3075 char state;
3076 char *response;
3078 response = milter_data(e, &state);
3079 switch (state)
3081 case SMFIR_REPLYCODE:
3082 if (MilterLogLevel > 3)
3083 sm_syslog(LOG_INFO, e->e_id,
3084 "Milter: data, reject=%s",
3085 response);
3086 milteraccept = false;
3087 usrerr(response);
3088 break;
3090 case SMFIR_REJECT:
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");
3096 break;
3098 case SMFIR_DISCARD:
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;
3104 break;
3106 case SMFIR_TEMPFAIL:
3107 if (MilterLogLevel > 3)
3108 sm_syslog(LOG_INFO, e->e_id,
3109 "Milter: data, reject=%s",
3110 MSG_TEMPFAIL);
3111 milteraccept = false;
3112 usrerr(MSG_TEMPFAIL);
3113 break;
3115 if (response != NULL)
3116 sm_free(response);
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)
3126 milter_abort(e);
3127 if (milteraccept && MilterLogLevel > 9)
3128 sm_syslog(LOG_INFO, e->e_id, "Milter accept: message");
3130 #endif /* MILTER */
3132 #if _FFR_QUARANTINE
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
3142 ** the message.
3145 if (bitset(EF_DISCARD, e->e_flags))
3146 doublequeue = false;
3148 aborting = Errors > 0;
3149 if (!aborting &&
3150 #if _FFR_QUARANTINE
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);
3156 if (aborting)
3158 /* Log who the mail would have gone to */
3159 logundelrcpts(e, e->e_message, 8, false);
3160 flush_errors(true);
3161 buffer_errors();
3162 goto abortmessage;
3165 /* from now on, we have to operate silently */
3166 buffer_errors();
3168 #if 0
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;
3177 #endif /* 0 */
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
3189 ** on the reader.
3190 ** Then send to everyone.
3191 ** Finally give a reply code. If an error has
3192 ** already been given, don't mail a
3193 ** message back.
3194 ** We goose error returns by clearing error bit.
3197 SmtpPhase = "delivery";
3198 (void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL);
3199 id = e->e_id;
3201 #if NAMED_BIND
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;
3214 if (doublequeue)
3216 /* make sure it is in the queue */
3217 queueup(ee, false, true);
3219 else
3221 /* send to all recipients */
3222 sendall(ee, SM_DEFAULT);
3224 ee->e_to = NULL;
3227 /* put back id for SMTP logging in putoutmsg() */
3228 oldid = CurEnv->e_id;
3229 CurEnv->e_id = 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 */
3236 if (doublequeue)
3238 bool anything_to_send = false;
3240 sm_getla();
3241 for (ee = e; ee != NULL; ee = ee->e_sibling)
3243 if (WILL_BE_QUEUED(ee->e_sendmode))
3244 continue;
3245 if (shouldqueue(ee->e_msgpriority, ee->e_ctime))
3247 ee->e_sendmode = SM_QUEUE;
3248 continue;
3250 #if _FFR_QUARANTINE
3251 else if (QueueMode != QM_QUARANTINE &&
3252 ee->e_quarmsg != NULL)
3254 ee->e_sendmode = SM_QUEUE;
3255 continue;
3257 #endif /* _FFR_QUARANTINE */
3258 anything_to_send = true;
3260 /* close all the queue files */
3261 closexscript(ee);
3262 if (ee->e_dfp != NULL)
3264 (void) sm_io_close(ee->e_dfp, SM_TIME_DEFAULT);
3265 ee->e_dfp = NULL;
3267 unlockqueue(ee);
3269 if (anything_to_send)
3271 #if PIPELINING
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);
3283 abortmessage:
3284 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
3285 logsender(e, NULL);
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);
3298 else
3300 for (ee = e; ee != NULL; ee = ee->e_sibling)
3302 #if _FFR_QUARANTINE
3303 if (!doublequeue &&
3304 QueueMode != QM_QUARANTINE &&
3305 ee->e_quarmsg != NULL)
3307 dropenvelope(ee, true, false);
3308 continue;
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
3321 ** newenvelope.
3324 CurEnv = e;
3325 newenvelope(e, e, sm_rpool_new_x(NULL));
3326 e->e_flags = BlankEnvelope.e_flags;
3328 #if _FFR_QUARANTINE
3329 /* restore connection quarantining */
3330 if (smtp->sm_quarmsg == NULL)
3332 e->e_quarmsg = NULL;
3333 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), "");
3335 else
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.
3346 ** Parameters:
3347 ** e -- envelope.
3348 ** msg -- message for Stat=
3349 ** level -- log level.
3350 ** all -- log all recipients.
3352 ** Returns:
3353 ** none.
3355 ** Side Effects:
3356 ** logs undelivered (or all) recipients
3359 void
3360 logundelrcpts(e, msg, level, all)
3361 ENVELOPE *e;
3362 char *msg;
3363 int level;
3364 bool all;
3366 ADDRESS *a;
3368 if (LogLevel <= level || msg == NULL || *msg == '\0')
3369 return;
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)
3378 continue;
3379 e->e_to = a->q_paddr;
3380 logdelivery(NULL, NULL, a->q_status, msg, NULL,
3381 (time_t) 0, e);
3383 e->e_to = NULL;
3386 ** CHECKSMTPATTACK -- check for denial-of-service attack by repetition
3388 ** Parameters:
3389 ** pcounter -- pointer to a counter for this command.
3390 ** maxcount -- maximum value for this counter before we
3391 ** slow down.
3392 ** waitnow -- sleep now (in this routine)?
3393 ** cname -- command name for logging.
3394 ** e -- the current envelope.
3396 ** Returns:
3397 ** time to wait.
3399 ** Side Effects:
3400 ** Slows down if we seem to be under attack.
3403 static time_t
3404 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
3405 volatile unsigned int *pcounter;
3406 int maxcount;
3407 bool waitnow;
3408 char *cname;
3409 ENVELOPE *e;
3411 if (maxcount <= 0) /* no limit */
3412 return (time_t) 0;
3414 if (++(*pcounter) >= maxcount)
3416 time_t s;
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)
3426 s = MAXTIMEOUT;
3428 /* sleep at least 1 second before returning */
3429 (void) sleep(*pcounter / maxcount);
3430 s -= *pcounter / maxcount;
3431 if (waitnow)
3433 (void) sleep(s);
3434 return 0;
3436 return s;
3438 return (time_t) 0;
3441 ** SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
3443 ** Parameters:
3444 ** none.
3446 ** Returns:
3447 ** nothing.
3449 ** Side Effects:
3450 ** may change I/O fd.
3453 static void
3454 setup_smtpd_io()
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);
3480 if (inmode == -1)
3482 if (LogLevel > 11)
3483 sm_syslog(LOG_INFO, NOQID,
3484 "fcntl(inchfd, F_GETFL) failed: %s",
3485 sm_errstring(errno));
3486 return;
3488 outmode = fcntl(outchfd, F_GETFL, 0);
3489 if (outmode == -1)
3491 if (LogLevel > 11)
3492 sm_syslog(LOG_INFO, NOQID,
3493 "fcntl(outchfd, F_GETFL) failed: %s",
3494 sm_errstring(errno));
3495 return;
3497 if (bitset(O_NONBLOCK, inmode) ||
3498 bitset(O_NONBLOCK, outmode) ||
3499 fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1)
3500 return;
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",
3509 inchfd, outchfd);
3512 /* undo change of inchfd */
3513 (void) fcntl(inchfd, F_SETFL, inmode);
3517 ** SKIPWORD -- skip a fixed word.
3519 ** Parameters:
3520 ** p -- place to start looking.
3521 ** w -- word to skip.
3523 ** Returns:
3524 ** p following w.
3525 ** NULL on error.
3527 ** Side Effects:
3528 ** clobbers the p data area.
3531 static char *
3532 skipword(p, w)
3533 register char *volatile p;
3534 char *w;
3536 register char *q;
3537 char *firstp = p;
3539 /* find beginning of word */
3540 SKIP_SPACE(p);
3541 q = p;
3543 /* find end of word */
3544 while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
3545 p++;
3546 while (isascii(*p) && isspace(*p))
3547 *p++ = '\0';
3548 if (*p != ':')
3550 syntax:
3551 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
3552 shortenstring(firstp, MAXSHORTSTR));
3553 return NULL;
3555 *p++ = '\0';
3556 SKIP_SPACE(p);
3558 if (*p == '\0')
3559 goto syntax;
3561 /* see if the input word matches desired word */
3562 if (sm_strcasecmp(q, w))
3563 goto syntax;
3565 return p;
3568 ** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
3570 ** Parameters:
3571 ** kp -- the parameter key.
3572 ** vp -- the value of that parameter.
3573 ** e -- the envelope.
3575 ** Returns:
3576 ** none.
3579 static void
3580 mail_esmtp_args(kp, vp, e)
3581 char *kp;
3582 char *vp;
3583 ENVELOPE *e;
3585 if (sm_strcasecmp(kp, "size") == 0)
3587 if (vp == NULL)
3589 usrerr("501 5.5.2 SIZE requires a value");
3590 /* NOTREACHED */
3592 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp);
3593 errno = 0;
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");
3598 /* NOTREACHED */
3600 if (e->e_msgsize < 0)
3602 usrerr("552 5.2.3 Message size invalid");
3603 /* NOTREACHED */
3606 else if (sm_strcasecmp(kp, "body") == 0)
3608 if (vp == NULL)
3610 usrerr("501 5.5.2 BODY requires a value");
3611 /* NOTREACHED */
3613 else if (sm_strcasecmp(vp, "8bitmime") == 0)
3615 SevenBitInput = false;
3617 else if (sm_strcasecmp(vp, "7bit") == 0)
3619 SevenBitInput = true;
3621 else
3623 usrerr("501 5.5.4 Unknown BODY type %s", vp);
3624 /* NOTREACHED */
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");
3633 /* NOTREACHED */
3635 if (vp == NULL)
3637 usrerr("501 5.5.2 ENVID requires a value");
3638 /* NOTREACHED */
3640 if (!xtextok(vp))
3642 usrerr("501 5.5.4 Syntax error in ENVID parameter value");
3643 /* NOTREACHED */
3645 if (e->e_envid != NULL)
3647 usrerr("501 5.5.0 Duplicate ENVID parameter");
3648 /* NOTREACHED */
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");
3659 /* NOTREACHED */
3661 if (vp == NULL)
3663 usrerr("501 5.5.2 RET requires a value");
3664 /* NOTREACHED */
3666 if (bitset(EF_RET_PARAM, e->e_flags))
3668 usrerr("501 5.5.0 Duplicate RET parameter");
3669 /* NOTREACHED */
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);
3677 /* NOTREACHED */
3679 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp);
3681 #if SASL
3682 else if (sm_strcasecmp(kp, "auth") == 0)
3684 int len;
3685 char *q;
3686 char *auth_param; /* the value of the AUTH=x */
3687 bool saveQuickAbort = QuickAbort;
3688 bool saveSuprErrs = SuprErrs;
3689 bool saveExitStat = ExitStat;
3690 char pbuf[256];
3692 if (vp == NULL)
3694 usrerr("501 5.5.2 AUTH= requires a value");
3695 /* NOTREACHED */
3697 if (e->e_auth_param != NULL)
3699 usrerr("501 5.5.0 Duplicate AUTH parameter");
3700 /* NOTREACHED */
3702 if ((q = strchr(vp, ' ')) != NULL)
3703 len = q - vp + 1;
3704 else
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? */
3712 /* NOTREACHED */
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?)
3729 SuprErrs = true;
3730 QuickAbort = false;
3731 if (strcmp(auth_param, "<>") != 0 &&
3732 (rscheck("trust_auth", pbuf, NULL, e, RSF_RMCOMM,
3733 9, NULL, NOQID) != EX_OK || Errors > 0))
3735 if (tTd(95, 8))
3737 q = e->e_auth_param;
3738 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
3739 pbuf, (q == NULL) ? "" : q);
3742 /* not trusted */
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 */
3749 else
3751 if (tTd(95, 8))
3752 sm_dprintf("auth=\"%.100s\" trusted\n", pbuf);
3753 e->e_auth_param = sm_rpool_strdup_x(e->e_rpool,
3754 auth_param);
3756 sm_free(auth_param); /* XXX */
3758 /* reset values */
3759 Errors = 0;
3760 QuickAbort = saveQuickAbort;
3761 SuprErrs = saveSuprErrs;
3762 ExitStat = saveExitStat;
3764 #endif /* SASL */
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)
3774 char *s;
3776 if (vp == NULL)
3778 usrerr("501 5.5.2 BY= requires a value");
3779 /* NOTREACHED */
3781 errno = 0;
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);
3789 /* NOTREACHED */
3791 if (s == NULL || *s != ';')
3793 usrerr("501 5.5.2 BY= missing ';'");
3794 /* NOTREACHED */
3796 e->e_dlvr_flag = 0;
3797 ++s; /* XXX: spaces allowed? */
3798 SKIP_SPACE(s);
3799 switch (tolower(*s))
3801 case 'n':
3802 e->e_dlvr_flag = DLVR_NOTIFY;
3803 break;
3804 case 'r':
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");
3809 /* NOTREACHED */
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);
3816 /* NOTREACHED */
3818 break;
3819 default:
3820 usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s));
3821 /* NOTREACHED */
3823 ++s; /* XXX: spaces allowed? */
3824 SKIP_SPACE(s);
3825 switch (tolower(*s))
3827 case 't':
3828 e->e_dlvr_flag |= DLVR_TRACE;
3829 break;
3830 case '\0':
3831 break;
3832 default:
3833 usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s));
3834 /* NOTREACHED */
3837 /* XXX: check whether more characters follow? */
3839 else
3841 usrerr("555 5.5.4 %s parameter unrecognized", kp);
3842 /* NOTREACHED */
3846 ** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
3848 ** Parameters:
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.
3854 ** Returns:
3855 ** none.
3858 static void
3859 rcpt_esmtp_args(a, kp, vp, e)
3860 ADDRESS *a;
3861 char *kp;
3862 char *vp;
3863 ENVELOPE *e;
3865 if (sm_strcasecmp(kp, "notify") == 0)
3867 char *p;
3869 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3871 usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
3872 /* NOTREACHED */
3874 if (vp == NULL)
3876 usrerr("501 5.5.2 NOTIFY requires a value");
3877 /* NOTREACHED */
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)
3884 return;
3885 for (p = vp; p != NULL; vp = p)
3887 p = strchr(p, ',');
3888 if (p != NULL)
3889 *p++ = '\0';
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;
3896 else
3898 usrerr("501 5.5.4 Bad argument \"%s\" to NOTIFY",
3899 vp);
3900 /* NOTREACHED */
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");
3909 /* NOTREACHED */
3911 if (vp == NULL)
3913 usrerr("501 5.5.2 ORCPT requires a value");
3914 /* NOTREACHED */
3916 if (strchr(vp, ';') == NULL || !xtextok(vp))
3918 usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
3919 /* NOTREACHED */
3921 if (a->q_orcpt != NULL)
3923 usrerr("501 5.5.0 Duplicate ORCPT parameter");
3924 /* NOTREACHED */
3926 a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp);
3928 else
3930 usrerr("555 5.5.4 %s parameter unrecognized", kp);
3931 /* NOTREACHED */
3935 ** PRINTVRFYADDR -- print an entry in the verify queue
3937 ** Parameters:
3938 ** a -- the address to print.
3939 ** last -- set if this is the last one.
3940 ** vrfy -- set if this is a VRFY command.
3942 ** Returns:
3943 ** none.
3945 ** Side Effects:
3946 ** Prints the appropriate 250 codes.
3948 #define OFFF (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */
3950 static void
3951 printvrfyaddr(a, last, vrfy)
3952 register ADDRESS *a;
3953 bool last;
3954 bool vrfy;
3956 char fmtbuf[30];
3958 if (vrfy && a->q_mailer != NULL &&
3959 !bitnset(M_VRFY250, a->q_mailer->m_flags))
3960 (void) sm_strlcpy(fmtbuf, "252", sizeof fmtbuf);
3961 else
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);
3973 else
3974 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
3975 sizeof fmtbuf - OFFF);
3976 message(fmtbuf, a->q_user, MyHostName);
3978 else
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);
3986 else
3987 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
3988 sizeof fmtbuf - OFFF);
3989 message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
3993 #if SASL
3995 ** SASLMECHS -- get list of possible AUTH mechanisms
3997 ** Parameters:
3998 ** conn -- SASL connection info.
3999 ** mechlist -- output parameter for list of mechanisms.
4001 ** Returns:
4002 ** number of mechs.
4005 static int
4006 saslmechs(conn, mechlist)
4007 sasl_conn_t *conn;
4008 char **mechlist;
4010 int len, num, result;
4012 /* "user" is currently unused */
4013 # if SASL >= 20000
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)
4024 if (LogLevel > 9)
4025 sm_syslog(LOG_WARNING, NOQID,
4026 "AUTH error: listmech=%d, num=%d",
4027 result, num);
4028 num = 0;
4030 if (num > 0)
4032 if (LogLevel > 11)
4033 sm_syslog(LOG_INFO, NOQID,
4034 "AUTH: available mech=%s, allowed mech=%s",
4035 *mechlist, AuthMechanisms);
4036 *mechlist = intersect(AuthMechanisms, *mechlist, NULL);
4038 else
4040 *mechlist = NULL; /* be paranoid... */
4041 if (result == SASL_OK && LogLevel > 9)
4042 sm_syslog(LOG_WARNING, NOQID,
4043 "AUTH warning: no mechanisms");
4045 return num;
4048 # if SASL >= 20000
4050 ** PROXY_POLICY -- define proxy policy for AUTH
4052 ** Parameters:
4053 ** conn -- unused.
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.
4063 ** Returns:
4064 ** ok?
4066 ** Side Effects:
4067 ** sets {auth_authen} macro.
4071 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen,
4072 def_realm, urlen, propctx)
4073 sasl_conn_t *conn;
4074 void *context;
4075 const char *requested_user;
4076 unsigned rlen;
4077 const char *auth_identity;
4078 unsigned alen;
4079 const char *def_realm;
4080 unsigned urlen;
4081 struct propctx *propctx;
4083 if (auth_identity == NULL)
4084 return SASL_FAIL;
4086 macdefine(&BlankEnvelope.e_macro, A_TEMP,
4087 macid("{auth_authen}"), (char *) auth_identity);
4089 return SASL_OK;
4091 # else /* SASL >= 20000 */
4094 ** PROXY_POLICY -- define proxy policy for AUTH
4096 ** Parameters:
4097 ** context -- unused.
4098 ** auth_identity -- authentication identity.
4099 ** requested_user -- authorization identity.
4100 ** user -- allowed user (output).
4101 ** errstr -- possible error string (output).
4103 ** Returns:
4104 ** ok?
4108 proxy_policy(context, auth_identity, requested_user, user, errstr)
4109 void *context;
4110 const char *auth_identity;
4111 const char *requested_user;
4112 const char **user;
4113 const char **errstr;
4115 if (user == NULL || auth_identity == NULL)
4116 return SASL_FAIL;
4117 *user = newstr(auth_identity);
4118 return SASL_OK;
4120 # endif /* SASL >= 20000 */
4121 #endif /* SASL */
4123 #if STARTTLS
4125 ** INITSRVTLS -- initialize server side TLS
4127 ** Parameters:
4128 ** tls_ok -- should tls initialization be done?
4130 ** Returns:
4131 ** succeeded?
4133 ** Side Effects:
4134 ** sets tls_ok_srv which is a static variable in this module.
4135 ** Do NOT remove assignments to it!
4138 bool
4139 initsrvtls(tls_ok)
4140 bool tls_ok;
4142 if (!tls_ok)
4143 return false;
4145 /* do NOT remove assignment */
4146 tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, true, SrvCertFile,
4147 SrvKeyFile, CACertPath, CACertFile, DHParams);
4148 return tls_ok_srv;
4150 #endif /* STARTTLS */
4152 ** SRVFEATURES -- get features for SMTP server
4154 ** Parameters:
4155 ** e -- envelope (should be session context).
4156 ** clientname -- name of client.
4157 ** features -- default features for this invocation.
4159 ** Returns:
4160 ** server features.
4163 /* table with options: it uses just one character, how about strings? */
4164 static struct
4166 char srvf_opt;
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 */
4175 #if PIPELINING
4176 # if _FFR_NO_PIPE
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 }, */
4187 { '\0', SRV_NONE }
4190 static unsigned int
4191 srvfeatures(e, clientname, features)
4192 ENVELOPE *e;
4193 char *clientname;
4194 unsigned int features;
4196 int r, i, j;
4197 char **pvp, c, opt;
4198 char pvpbuf[PSBUFSIZE];
4200 pvp = NULL;
4201 r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf,
4202 sizeof(pvpbuf));
4203 if (r != EX_OK)
4204 return features;
4205 if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
4206 return features;
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++)
4220 c = pvp[i][0];
4221 j = 0;
4222 for (;;)
4224 if ((opt = srv_feat_table[j].srvf_opt) == '\0')
4226 if (LogLevel > 9)
4227 sm_syslog(LOG_WARNING, e->e_id,
4228 "srvfeatures: unknown feature %s",
4229 pvp[i]);
4230 break;
4232 if (c == opt)
4234 features &= ~(srv_feat_table[j].srvf_flag);
4235 break;
4237 if (c == tolower(opt))
4239 features |= srv_feat_table[j].srvf_flag;
4240 break;
4242 ++j;
4245 return features;
4249 ** HELP -- implement the HELP command.
4251 ** Parameters:
4252 ** topic -- the topic we want help for.
4253 ** e -- envelope.
4255 ** Returns:
4256 ** none.
4258 ** Side Effects:
4259 ** outputs the help file to message output.
4261 #define HELPVSTR "#vers "
4262 #define HELPVERSION 2
4264 void
4265 help(topic, e)
4266 char *topic;
4267 ENVELOPE *e;
4269 register SM_FILE_T *hf;
4270 register char *p;
4271 int len;
4272 bool noinfo;
4273 bool first = true;
4274 long sff = SFF_OPENASROOT|SFF_REGONLY;
4275 char buf[MAXLINE];
4276 char inp[MAXLINE];
4277 static int foundvers = -1;
4278 extern char Version[];
4280 if (DontLockReadFiles)
4281 sff |= SFF_NOLOCK;
4282 if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
4283 sff |= SFF_SAFEDIRPATH;
4285 if (HelpFile == NULL ||
4286 (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
4288 /* no help */
4289 errno = 0;
4290 message("502 5.3.0 Sendmail %s -- HELP not implemented",
4291 Version);
4292 return;
4295 if (topic == NULL || *topic == '\0')
4297 topic = "smtp";
4298 noinfo = false;
4300 else
4302 makelower(topic);
4303 noinfo = true;
4306 len = strlen(topic);
4308 while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
4310 if (buf[0] == '#')
4312 if (foundvers < 0 &&
4313 strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
4315 int h;
4317 if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d",
4318 &h) == 1)
4319 foundvers = h;
4321 continue;
4323 if (strncmp(buf, topic, len) == 0)
4325 if (first)
4327 first = false;
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");
4334 if (p == NULL)
4335 p = buf + strlen(buf) - 1;
4336 else
4337 p++;
4338 fixcrlf(p, true);
4339 if (foundvers >= 2)
4341 translate_dollars(p);
4342 expand(p, inp, sizeof inp, e);
4343 p = inp;
4345 message("214-2.0.0 %s", p);
4346 noinfo = false;
4350 if (noinfo)
4351 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
4352 else
4353 message("214 2.0.0 End of HELP info");
4355 if (foundvers != 0 && foundvers < HELPVERSION)
4357 if (LogLevel > 1)
4358 sm_syslog(LOG_WARNING, e->e_id,
4359 "%s too old (require version %d)",
4360 HelpFile, HELPVERSION);
4362 /* avoid log next time */
4363 foundvers = 0;
4366 (void) sm_io_close(hf, SM_TIME_DEFAULT);
4369 #if SASL
4371 ** RESET_SASLCONN -- reset SASL connection data
4373 ** Parameters:
4374 ** conn -- SASL connection context
4375 ** hostname -- host name
4376 ** various connection data
4378 ** Returns:
4379 ** SASL result
4382 static int
4383 reset_saslconn(sasl_conn_t ** conn, char *hostname,
4384 # if SASL >= 20000
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 */
4392 int result;
4394 sasl_dispose(conn);
4395 # if SASL >= 20000
4396 result = sasl_server_new("smtp", hostname, NULL, NULL, NULL,
4397 NULL, 0, conn);
4398 # elif SASL > 10505
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,
4404 conn);
4405 # endif /* SASL >= 20000 */
4406 if (result != SASL_OK)
4407 return result;
4409 # if SASL >= 20000
4410 # if NETINET || NETINET6
4411 if (remoteip != NULL)
4412 result = sasl_setprop(*conn, SASL_IPREMOTEPORT, remoteip);
4413 if (result != SASL_OK)
4414 return result;
4416 if (localip != NULL)
4417 result = sasl_setprop(*conn, SASL_IPLOCALPORT, localip);
4418 if (result != SASL_OK)
4419 return result;
4420 # endif /* NETINET || NETINET6 */
4422 result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf);
4423 if (result != SASL_OK)
4424 return result;
4426 result = sasl_setprop(*conn, SASL_AUTH_EXTERNAL, auth_id);
4427 if (result != SASL_OK)
4428 return result;
4429 # else /* SASL >= 20000 */
4430 # if NETINET
4431 if (saddr_r != NULL)
4432 result = sasl_setprop(*conn, SASL_IP_REMOTE, saddr_r);
4433 if (result != SASL_OK)
4434 return result;
4436 if (saddr_l != NULL)
4437 result = sasl_setprop(*conn, SASL_IP_LOCAL, saddr_l);
4438 if (result != SASL_OK)
4439 return result;
4440 # endif /* NETINET */
4442 result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf);
4443 if (result != SASL_OK)
4444 return result;
4445 # endif /* SASL >= 20000 */
4446 return SASL_OK;
4448 #endif /* SASL */