1 /*
2 * Copyright (c) 1998-2010, 2012-2014,2021-2024 Proofpoint, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14 #include <sendmail.h>
15 #if MILTER
16 # include <libmilter/mfapi.h>
17 # include <libmilter/mfdef.h>
18 #endif
19
20 SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.1016 2013-11-22 20:51:56 ca Exp $")
21
22 #include <sm/sendmail.h>
23 #if _FFR_8BITENVADDR
24 # include <sm/ixlen.h>
25 #endif
26 #include <sm/time.h>
27 #include <sm/fdset.h>
28
29 #if SASL || STARTTLS
30 # include <tls.h>
31 # include "sfsasl.h"
32 #endif
33 #if SASL
34 # define ENC64LEN(l) (((l) + 2) * 4 / 3 + 1)
35 static int saslmechs __P((sasl_conn_t *, char **));
36 #endif
37 #if STARTTLS
38 # include <openssl/err.h>
39
40 static SSL_CTX *srv_ctx = NULL; /* TLS server context */
41 static SSL *srv_ssl = NULL; /* per connection context */
42 static tlsi_ctx_T tlsi_ctx; /* TLS information context */
43
44 static bool tls_ok_srv = false;
45
46 # define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \
47 bitset(SRV_VRFY_CLT, features))
48 #endif /* STARTTLS */
49
50 #if _FFR_DM_ONE
51 static bool NotFirstDelivery = false;
52 #endif
53
54 /* server features */
55 #define SRV_NONE 0x00000000 /* none... */
56 #define SRV_OFFER_TLS 0x00000001 /* offer STARTTLS */
57 #define SRV_VRFY_CLT 0x00000002 /* request a cert */
58 #define SRV_OFFER_AUTH 0x00000004 /* offer AUTH */
59 #define SRV_OFFER_ETRN 0x00000008 /* offer ETRN */
60 #define SRV_OFFER_VRFY 0x00000010 /* offer VRFY (not yet used) */
61 #define SRV_OFFER_EXPN 0x00000020 /* offer EXPN */
62 #define SRV_OFFER_VERB 0x00000040 /* offer VERB */
63 #define SRV_OFFER_DSN 0x00000080 /* offer DSN */
64 #if PIPELINING
65 # define SRV_OFFER_PIPE 0x00000100 /* offer PIPELINING */
66 # if _FFR_NO_PIPE
67 # define SRV_NO_PIPE 0x00000200 /* disable PIPELINING, sleep if used */
68 # endif
69 #endif /* PIPELINING */
70 #define SRV_REQ_AUTH 0x00000400 /* require AUTH */
71 #define SRV_REQ_SEC 0x00000800 /* require security - equiv to AuthOptions=p */
72 #define SRV_TMP_FAIL 0x00001000 /* ruleset caused a temporary failure */
73 #if USE_EAI
74 # define SRV_OFFER_EAI 0x00002000 /* offer SMTPUTF8 */
75 #endif
76 #define SRV_NO_HTTP_CMD 0x00004000 /* always reject HTTP commands */
77 #define SRV_BAD_PIPELINE 0x00008000 /* reject bad pipelining (see comment below) */
78 #define SRV_REQ_CRLF 0x00010000 /* require CRLF as EOL */
79 #define SRV_BARE_LF_421 0x00020000 /* bare LF - drop connection */
80 #define SRV_BARE_CR_421 0x00040000 /* bare CR - drop connection */
81 #define SRV_BARE_LF_SP 0x00080000
82 #define SRV_BARE_CR_SP 0x00100000
83
84 static unsigned long srvfeatures __P((ENVELOPE *, char *, unsigned long));
85
86 #define STOP_ATTACK ((time_t) -1)
87 static time_t checksmtpattack __P((volatile unsigned int *, unsigned int,
88 bool, char *, ENVELOPE *));
89 static void printvrfyaddr __P((ADDRESS *, bool, bool));
90 static char *skipword __P((char *volatile, char *));
91 static void setup_smtpd_io __P((void));
92 static struct timeval *channel_readable __P((SM_FILE_T *, int));
93
94 #if SASL
95 # ifndef MAX_AUTH_USER_LEN
96 # define MAX_AUTH_USER_LEN 256
97 # endif
98 # ifndef MAX_AUTH_LOG_LEN
99 # define MAX_AUTH_LOG_LEN 64
100 # endif
101 static void get_sasl_user __P((char *, unsigned int, const char *, char *out, size_t));
102 # define RESET_AUTH_FAIL_LOG_USER \
103 do \
104 { \
105 (void) memset(auth_user, 0, sizeof(auth_user)); \
106 (void) memset(auth_user_tmp, 0, sizeof(auth_user_tmp)); \
107 auth_user_len = 0; \
108 } while (0)
109 # define SET_AUTH_USER_TMP(s, len) \
110 do \
111 { \
112 auth_user_len = SM_MIN(len, MAX_AUTH_USER_LEN-1); \
113 (void) memcpy(auth_user_tmp, s, auth_user_len); \
114 } while (0)
115 # define SET_AUTH_USER \
116 get_sasl_user(auth_user_tmp, auth_user_len, auth_type, auth_user, sizeof(auth_user))
117 # define SET_AUTH_USER_CONDITIONALLY \
118 if ('\0' == auth_user[0]) \
119 SET_AUTH_USER;
120 # define LOG_AUTH_FAIL_USER ", user=", (int)MAX_AUTH_LOG_LEN, auth_user
121 # if SASL >= 20000
122 static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
123 char *_remoteip, char *_localip,
124 char *_auth_id, sasl_ssf_t *_ext_ssf));
125
126 # define RESET_SASLCONN \
127 do \
128 { \
129 RESET_AUTH_FAIL_LOG_USER; \
130 result = reset_saslconn(&conn, AuthRealm, remoteip, \
131 localip, auth_id, &ext_ssf); \
132 if (result != SASL_OK) \
133 sasl_ok = false; \
134 } while (0)
135
136 # else /* SASL >= 20000 */
137 static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
138 struct sockaddr_in *_saddr_r,
139 struct sockaddr_in *_saddr_l,
140 sasl_external_properties_t *_ext_ssf));
141 # define RESET_SASLCONN \
142 do \
143 { \
144 RESET_AUTH_FAIL_LOG_USER; \
145 result = reset_saslconn(&conn, AuthRealm, &saddr_r, \
146 &saddr_l, &ext_ssf); \
147 if (result != SASL_OK) \
148 sasl_ok = false; \
149 } while (0)
150
151 # endif /* SASL >= 20000 */
152 #endif /* SASL */
153
154 #if !defined(RESET_AUTH_FAIL_LOG_USER)
155 # define RESET_AUTH_FAIL_LOG_USER
156 #endif
157
158 extern ENVELOPE BlankEnvelope;
159
160 #define NBADRCPTS \
161 do \
162 { \
163 char buf[16]; \
164 (void) sm_snprintf(buf, sizeof(buf), "%d", \
165 BadRcptThrottle > 0 && n_badrcpts > BadRcptThrottle \
166 ? n_badrcpts - 1 : n_badrcpts); \
167 macdefine(&e->e_macro, A_TEMP, macid("{nbadrcpts}"), buf); \
168 } while (0)
169
170 #define SKIP_SPACE(s) while (SM_ISSPACE(*s)) \
171 (s)++
172
173 #if USE_EAI
174 /*
175 ** ADDR_IS_ASCII -- check whether a string (address) is ASCII
176 **
177 ** Parameters:
178 ** str -- a string
179 **
180 ** Returns:
181 ** TRUE iff str is non-NULL and points to only ASCII
182 */
183
184 bool
addr_is_ascii(str)185 addr_is_ascii(str)
186 const char *str;
187 {
188 while (str != NULL && *str != '\0' && isascii((unsigned char)*str))
189 str++;
190 return (str != NULL && *str == '\0');
191 }
192
193 /*
194 ** STR_IS_PRINT -- check whether a string is printable ASCII
195 **
196 ** Parameters:
197 ** str -- a string
198 **
199 ** Returns:
200 ** TRUE iff str is non-NULL and points to only printable ASCII
201 */
202
203 bool
str_is_print(str)204 str_is_print(str)
205 const char *str;
206 {
207 while (str != NULL && *str != '\0' && *str >= ' ' && (unsigned char)*str < 127)
208 str++;
209 return (str != NULL && *str == '\0');
210 }
211
212
213 # define CHECK_UTF8_ADDR(a, q) \
214 do \
215 { \
216 q = NULL; \
217 if (addr_is_ascii(a)) \
218 break; \
219 if (!SMTP_UTF8) \
220 break; \
221 if (!e->e_smtputf8) \
222 q = "553 5.6.7 Address requires SMTPUTF8"; \
223 else \
224 { \
225 char str[MAXNAME]; \
226 dequote_internal_chars(a, str, sizeof(str)); \
227 if (!utf8_valid(str, strlen(str)) && SMTP_UTF8 <= 1) \
228 q = "553 5.6.7 Address not valid UTF8"; \
229 } \
230 } while (0)
231 #endif /* USE_EAI */
232
233 /*
234 ** PARSE_ESMTP_ARGS -- parse ESMTP arguments (for MAIL, RCPT)
235 **
236 ** Parameters:
237 ** e -- the envelope
238 ** addr_st -- address (RCPT only)
239 ** p -- read buffer
240 ** delimptr -- current position in read buffer
241 ** which -- MAIL/RCPT
242 ** args -- arguments (output)
243 ** esmtp_args -- function to process a single ESMTP argument
244 **
245 ** Returns:
246 ** none
247 */
248
249 void
parse_esmtp_args(e,addr_st,p,delimptr,which,args,esmtp_args)250 parse_esmtp_args(e, addr_st, p, delimptr, which, args, esmtp_args)
251 ENVELOPE *e;
252 ADDRESS *addr_st;
253 char *p;
254 char *delimptr;
255 char *which;
256 char *args[];
257 esmtp_args_F esmtp_args;
258 {
259 int argno;
260
261 argno = 0;
262 if (args != NULL)
263 args[argno++] = p;
264 p = delimptr;
265 while (p != NULL && *p != '\0')
266 {
267 char *kp;
268 char *vp = NULL;
269 char *equal = NULL;
270
271 /* locate the beginning of the keyword */
272 SKIP_SPACE(p);
273 if (*p == '\0')
274 break;
275 kp = p;
276
277 /* skip to the value portion */
278 while ((isascii(*p) && isalnum(*p)) || *p == '-')
279 p++;
280 if (*p == '=')
281 {
282 equal = p;
283 *p++ = '\0';
284 vp = p;
285
286 /* skip to the end of the value */
287 while (*p != '\0' && *p != ' ' &&
288 !(isascii(*p) && iscntrl(*p)) &&
289 *p != '=')
290 p++;
291 }
292
293 if (*p != '\0')
294 *p++ = '\0';
295
296 if (tTd(19, 1))
297 sm_dprintf("%s: got arg %s=\"%s\"\n", which, kp,
298 vp == NULL ? "<null>" : vp);
299
300 esmtp_args(addr_st, kp, vp, e);
301 if (equal != NULL)
302 *equal = '=';
303 if (args != NULL)
304 args[argno] = kp;
305 argno++;
306 if (argno >= MAXSMTPARGS - 1)
307 usrerr("501 5.5.4 Too many parameters");
308 if (Errors > 0)
309 break;
310 }
311 if (args != NULL)
312 args[argno] = NULL;
313 }
314
315 #if _FFR_ADD_BCC
316
317 /*
318 ** ADDRCPT -- Add a rcpt to sendq list
319 **
320 ** Parameters:
321 ** rcpt -- rcpt [i]
322 ** sendq -- a pointer to the head of a queue to put
323 ** these people into.
324 ** e -- the envelope in which to add these recipients.
325 **
326 ** Returns:
327 ** The number of addresses added to the list.
328 */
329
330 static int
addrcpt(rcpt,sendq,e)331 addrcpt(rcpt, sendq, e)
332 char *rcpt;
333 ADDRESS **sendq;
334 ENVELOPE *e;
335 {
336 int r;
337 char *oldto;
338 ADDRESS *a;
339
340 SM_REQUIRE(rcpt != NULL);
341 SM_REQUIRE(sendq != NULL);
342 SM_REQUIRE(e != NULL);
343 oldto = e->e_to;
344 if (tTd(25, 1))
345 sm_dprintf("addrcpt: rcpt=%s\n", rcpt);
346 r = Errors;
347 a = NULL;
348 SM_TRY
349 {
350 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e b");
351 /* XXX rcpt must be [i] */
352 a = parseaddr(rcpt, NULLADDR, RF_COPYALL, ' ', NULL, e, true);
353 if (a == NULL)
354 return 0;
355
356 a->q_flags &= ~Q_PINGFLAGS;
357 a->q_flags |= QINTBCC;
358 a->q_owner = "<>";
359
360 /* disable alias expansion? */
361 a = recipient(a, sendq, 0, e);
362 }
363 SM_FINALLY
364 {
365 e->e_to = oldto;
366 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL);
367 }
368 SM_END_TRY
369 if (tTd(25, 1))
370 sm_dprintf("addrcpt: rcpt=%s, flags=%#lx\n", rcpt,
371 a != NULL ? a->q_flags : 0);
372 Errors = r;
373 return 1;
374 }
375
376 /*
377 ** ADDBCC -- Maybe create a copy of an e-mail
378 **
379 ** Parameters:
380 ** a -- current RCPT
381 ** e -- the envelope.
382 **
383 ** Returns:
384 ** nothing
385 **
386 ** Side Effects:
387 ** rscheck() can trigger an "exception"
388 */
389
390 static void
addbcc(a,e)391 addbcc(a, e)
392 ADDRESS *a;
393 ENVELOPE *e;
394 {
395 int nobcc;
396 char *newrcpt, empty[1];
397
398 if (!AddBcc)
399 return;
400
401 nobcc = false;
402 empty[0] = '\0';
403 newrcpt = empty;
404
405 nobcc = rscheck("bcc", a->q_paddr, NULL, e, RSF_ADDR, 12, NULL, NOQID,
406 NULL, &newrcpt);
407 if (tTd(25, 1))
408 sm_dprintf("addbcc: nobcc=%d, Errors=%d, newrcpt=<%s>\n", nobcc, Errors, newrcpt);
409 if (nobcc != EX_OK || Errors > 0 || *newrcpt == '\0')
410 return;
411
412 (void) addrcpt(newrcpt, &e->e_sendqueue, e);
413 return;
414 }
415 #else /* _FFR_ADD_BCC */
416 # define addbcc(a, e)
417 #endif /* _FFR_ADD_BCC */
418
419 #if _FFR_RCPTFLAGS
420 /*
421 ** RCPTMODS -- Perform rcpt modifications if requested
422 **
423 ** Parameters:
424 ** rcpt -- current RCPT
425 ** e -- the envelope.
426 **
427 ** Returns:
428 ** nothing.
429 */
430
431 void
rcptmods(rcpt,e)432 rcptmods(rcpt, e)
433 ADDRESS *rcpt;
434 ENVELOPE *e;
435 {
436 char *fl;
437
438 SM_REQUIRE(rcpt != NULL);
439 SM_REQUIRE(e != NULL);
440
441 fl = macvalue(macid("{rcpt_flags}"), e);
442 if (SM_IS_EMPTY(fl))
443 return;
444 if (tTd(25, 1))
445 sm_dprintf("rcptmods: rcpt=%s, flags=%s\n", rcpt->q_paddr, fl);
446
447 /* parse flags */
448 for ( ; *fl != '\0'; ++fl)
449 {
450 switch (*fl)
451 {
452 case 'n':
453 rcpt->q_flags &= ~Q_PINGFLAGS;
454 rcpt->q_flags |= QINTBCC;
455 rcpt->q_owner = "<>";
456 break;
457
458 case 'N':
459 rcpt->q_flags &= ~Q_PINGFLAGS;
460 rcpt->q_owner = "<>";
461 break;
462
463 case QDYNMAILFLG:
464 rcpt->q_flags |= QDYNMAILER;
465 newmodmailer(rcpt, *fl);
466 break;
467
468 default:
469 sm_syslog(LOG_INFO, e->e_id,
470 "rcpt=%s, rcpt_flags=%s, status=unknown",
471 rcpt->q_paddr, fl);
472 break;
473 }
474 }
475
476 /* reset macro to avoid confusion later on */
477 macdefine(&e->e_macro, A_PERM, macid("{rcpt_flags}"), NULL);
478
479 }
480 #else /* _FFR_RCPTFLAGS */
481 # define rcptmods(a, e)
482 #endif /* _FFR_RCPTFLAGS */
483
484 #if _FFR_8BITENVADDR
485
486 /*
487 ** SEP_ARGS -- separate address and argument string for MAIL/RCPT command
488 **
489 ** Parameters:
490 ** args -- arguments (converted to and from internal format)
491 ** orig -- string after command (original data)
492 ** id -- envelope id (for logging only)
493 ** addr -- for logging only: address (original data)
494 **
495 ** Returns:
496 ** nothing
497 */
498
499 static void sep_args __P((char *, char *, const char *, const char *));
500
501 static void
sep_args(args,orig,id,addr)502 sep_args(args, orig, id, addr)
503 char *args;
504 char *orig;
505 const char *id;
506 const char *addr;
507 {
508 int lr, lo;
509 char *q;
510
511 lr = strlen(args);
512 lo = strlen(orig);
513 if (lr >= lo)
514 {
515 sm_syslog(LOG_ERR, id,
516 "ERROR=ARGS_NOT_FOUND, address='%s', rest='%s', orig='%s', strlen(rest)=%d, strlen(orig)=%d",
517 addr, args, orig, lr, lo);
518 return;
519 }
520
521 q = orig + (lo - lr);
522 if (!(q > orig && *--q == ' '))
523 {
524 sm_syslog(LOG_INFO, id,
525 "ERROR=ARGS_DO_NOT_MATCH, address='%s', rest='%s', orig='%s', q='%s', strlen(rest)=%d, strlen(orig)=%d, cmp=%d",
526 addr, args, orig, q, lr, lo, strcmp(args, q));
527 return;
528 }
529
530 for (; q > orig && *q == ' '; q--)
531 *q = '\0';
532 }
533 #endif /* _FFR_8BITENVADDR */
534
535 /*
536 ** CHANNEL_READBLE -- determine if data is readable from the SMTP channel
537 **
538 ** Parameters:
539 ** channel -- connect channel for reading
540 ** timeout -- how long to pause for data in milliseconds
541 **
542 ** Returns:
543 ** timeval contained how long we waited if data detected,
544 ** NULL otherwise
545 */
546
547 static struct timeval *
channel_readable(channel,timeout)548 channel_readable(channel, timeout)
549 SM_FILE_T *channel;
550 int timeout;
551 {
552 struct timeval bp, ep; /* {begin,end} pause */
553 static struct timeval tp; /* total pause */
554 int eoftest;
555
556 /* check if data is on the channel during the pause */
557 gettimeofday(&bp, NULL);
558 if ((eoftest = sm_io_getc(channel, timeout)) != SM_IO_EOF)
559 {
560 gettimeofday(&ep, NULL);
561 sm_io_ungetc(channel, SM_TIME_DEFAULT, eoftest);
562 timersub(&ep, &bp, &tp);
563 return &tp;
564 }
565 return NULL;
566 }
567
568 /*
569 ** SMTP -- run the SMTP protocol.
570 **
571 ** Parameters:
572 ** nullserver -- if non-NULL, rejection message for
573 ** (almost) all SMTP commands.
574 ** d_flags -- daemon flags
575 ** e -- the envelope.
576 **
577 ** Returns:
578 ** never.
579 **
580 ** Side Effects:
581 ** Reads commands from the input channel and processes them.
582 */
583
584 /*
585 ** Notice: The smtp server doesn't have a session context like the client
586 ** side has (mci). Therefore some data (session oriented) is allocated
587 ** or assigned to the "wrong" structure (esp. STARTTLS, AUTH).
588 ** This should be fixed in a successor version.
589 */
590
591 struct cmd
592 {
593 char *cmd_name; /* command name */
594 int cmd_code; /* internal code, see below */
595 };
596
597 /* values for cmd_code */
598 #define CMDERROR 0 /* bad command */
599 #define CMDMAIL 1 /* mail -- designate sender */
600 #define CMDRCPT 2 /* rcpt -- designate recipient */
601 #define CMDDATA 3 /* data -- send message text */
602 #define CMDRSET 4 /* rset -- reset state */
603 #define CMDVRFY 5 /* vrfy -- verify address */
604 #define CMDEXPN 6 /* expn -- expand address */
605 #define CMDNOOP 7 /* noop -- do nothing */
606 #define CMDQUIT 8 /* quit -- close connection and die */
607 #define CMDHELO 9 /* helo -- be polite */
608 #define CMDHELP 10 /* help -- give usage info */
609 #define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */
610 #define CMDETRN 12 /* etrn -- flush queue */
611 #if SASL
612 # define CMDAUTH 13 /* auth -- SASL authenticate */
613 #endif
614 #if STARTTLS
615 # define CMDSTLS 14 /* STARTTLS -- start TLS session */
616 #endif
617 /* non-standard commands */
618 #define CMDVERB 17 /* verb -- go into verbose mode */
619 /* unimplemented commands from RFC 821 */
620 #define CMDUNIMPL 19 /* unimplemented rfc821 commands */
621 /* use this to catch and log "door handle" attempts on your system */
622 #define CMDLOGBOGUS 23 /* bogus command that should be logged */
623 /* debugging-only commands, only enabled if SMTPDEBUG is defined */
624 #define CMDDBGQSHOW 24 /* showq -- show send queue */
625 #define CMDDBGDEBUG 25 /* debug -- set debug mode */
626
627 /*
628 ** Note: If you change this list, remember to update 'helpfile'
629 */
630
631 static struct cmd CmdTab[] =
632 {
633 { "mail", CMDMAIL },
634 { "rcpt", CMDRCPT },
635 { "data", CMDDATA },
636 { "rset", CMDRSET },
637 { "vrfy", CMDVRFY },
638 { "expn", CMDEXPN },
639 { "help", CMDHELP },
640 { "noop", CMDNOOP },
641 { "quit", CMDQUIT },
642 { "helo", CMDHELO },
643 { "ehlo", CMDEHLO },
644 { "etrn", CMDETRN },
645 { "verb", CMDVERB },
646 { "send", CMDUNIMPL },
647 { "saml", CMDUNIMPL },
648 { "soml", CMDUNIMPL },
649 { "turn", CMDUNIMPL },
650 #if SASL
651 { "auth", CMDAUTH, },
652 #endif
653 #if STARTTLS
654 { "starttls", CMDSTLS, },
655 #endif
656 /* remaining commands are here only to trap and log attempts to use them */
657 { "showq", CMDDBGQSHOW },
658 { "debug", CMDDBGDEBUG },
659 { "wiz", CMDLOGBOGUS },
660
661 { NULL, CMDERROR }
662 };
663
664 static char *CurSmtpClient; /* who's at the other end of channel */
665
666 #ifndef MAXBADCOMMANDS
667 # define MAXBADCOMMANDS 25 /* maximum number of bad commands */
668 #endif
669 #ifndef MAXHELOCOMMANDS
670 # define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */
671 #endif
672 #ifndef MAXVRFYCOMMANDS
673 # define MAXVRFYCOMMANDS 6 /* max VRFY/EXPN commands before slowdown */
674 #endif
675 #ifndef MAXETRNCOMMANDS
676 # define MAXETRNCOMMANDS 8 /* max ETRN commands before slowdown */
677 #endif
678 #ifndef MAXTIMEOUT
679 # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */
680 #endif
681
682 /*
683 ** Maximum shift value to compute timeout for bad commands.
684 ** This introduces an upper limit of 2^MAXSHIFT for the timeout.
685 */
686
687 #ifndef MAXSHIFT
688 # define MAXSHIFT 8
689 #endif
690 #if MAXSHIFT > 31
691 # error "MAXSHIFT > 31 is invalid"
692 #endif
693
694
695 #if MAXBADCOMMANDS > 0
696 # define STOP_IF_ATTACK(r) do \
697 { \
698 if ((r) == STOP_ATTACK) \
699 goto stopattack; \
700 } while (0)
701
702 #else /* MAXBADCOMMANDS > 0 */
703 # define STOP_IF_ATTACK(r) r
704 #endif /* MAXBADCOMMANDS > 0 */
705
706
707 #if SM_HEAP_CHECK
708 static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp",
709 "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $");
710 #endif
711
712 typedef struct
713 {
714 bool sm_gotmail; /* mail command received */
715 unsigned int sm_nrcpts; /* number of successful RCPT commands */
716 bool sm_discard;
717 #if MILTER
718 bool sm_milterize;
719 bool sm_milterlist; /* any filters in the list? */
720 milters_T sm_milters;
721
722 /* e_nrcpts from envelope before recipient() call */
723 unsigned int sm_e_nrcpts_orig;
724 #endif /* MILTER */
725 char *sm_quarmsg; /* carry quarantining across messages */
726 } SMTP_T;
727
728 static bool smtp_data __P((SMTP_T *, ENVELOPE *, bool));
729
730 #define MSG_TEMPFAIL "451 4.3.2 Please try again later"
731
732 #if MILTER
733 # define MILTER_ABORT(e) milter_abort((e))
734
735 # define MILTER_REPLY(str) \
736 { \
737 int savelogusrerrs = LogUsrErrs; \
738 \
739 milter_cmd_fail = true; \
740 switch (state) \
741 { \
742 case SMFIR_SHUTDOWN: \
743 if (MilterLogLevel > 3) \
744 { \
745 sm_syslog(LOG_INFO, e->e_id, \
746 "Milter: %s=%s, reject=421, errormode=4", \
747 str, addr); \
748 LogUsrErrs = false; \
749 } \
750 { \
751 bool tsave = QuickAbort; \
752 \
753 QuickAbort = false; \
754 usrerr("421 4.3.0 closing connection"); \
755 QuickAbort = tsave; \
756 e->e_sendqueue = NULL; \
757 goto doquit; \
758 } \
759 break; \
760 case SMFIR_REPLYCODE: \
761 if (MilterLogLevel > 3) \
762 { \
763 sm_syslog(LOG_INFO, e->e_id, \
764 "Milter: %s=%s, reject=%s", \
765 str, addr, response); \
766 LogUsrErrs = false; \
767 } \
768 if (strncmp(response, "421 ", 4) == 0 \
769 || strncmp(response, "421-", 4) == 0) \
770 { \
771 bool tsave = QuickAbort; \
772 \
773 QuickAbort = false; \
774 usrerr(response); \
775 QuickAbort = tsave; \
776 e->e_sendqueue = NULL; \
777 goto doquit; \
778 } \
779 else \
780 usrerr(response); \
781 break; \
782 \
783 case SMFIR_REJECT: \
784 if (MilterLogLevel > 3) \
785 { \
786 sm_syslog(LOG_INFO, e->e_id, \
787 "Milter: %s=%s, reject=550 5.7.1 Command rejected", \
788 str, addr); \
789 LogUsrErrs = false; \
790 } \
791 usrerr("550 5.7.1 Command rejected"); \
792 break; \
793 \
794 case SMFIR_DISCARD: \
795 if (MilterLogLevel > 3) \
796 sm_syslog(LOG_INFO, e->e_id, \
797 "Milter: %s=%s, discard", \
798 str, addr); \
799 e->e_flags |= EF_DISCARD; \
800 milter_cmd_fail = false; \
801 break; \
802 \
803 case SMFIR_TEMPFAIL: \
804 if (MilterLogLevel > 3) \
805 { \
806 sm_syslog(LOG_INFO, e->e_id, \
807 "Milter: %s=%s, reject=%s", \
808 str, addr, MSG_TEMPFAIL); \
809 LogUsrErrs = false; \
810 } \
811 usrerr(MSG_TEMPFAIL); \
812 break; \
813 default: \
814 milter_cmd_fail = false; \
815 break; \
816 } \
817 LogUsrErrs = savelogusrerrs; \
818 if (response != NULL) \
819 sm_free(response); /* XXX */ \
820 }
821
822 #else /* MILTER */
823 # define MILTER_ABORT(e)
824 #endif /* MILTER */
825
826 /* clear all SMTP state (for HELO/EHLO/RSET) */
827 #define CLEAR_STATE(cmd) \
828 do \
829 { \
830 /* abort milter filters */ \
831 MILTER_ABORT(e); \
832 \
833 if (smtp.sm_nrcpts > 0) \
834 { \
835 logundelrcpts(e, cmd, 10, false); \
836 smtp.sm_nrcpts = 0; \
837 macdefine(&e->e_macro, A_PERM, \
838 macid("{nrcpts}"), "0"); \
839 } \
840 \
841 e->e_sendqueue = NULL; \
842 e->e_flags |= EF_CLRQUEUE; \
843 \
844 if (tTd(92, 2)) \
845 sm_dprintf("CLEAR_STATE: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",\
846 e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);\
847 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) \
848 logsender(e, NULL); \
849 e->e_flags &= ~EF_LOGSENDER; \
850 \
851 /* clean up a bit */ \
852 smtp.sm_gotmail = false; \
853 SuprErrs = true; \
854 (void) dropenvelope(e, true, false); \
855 sm_rpool_free(e->e_rpool); \
856 e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \
857 CurEnv = e; \
858 e->e_features = features; \
859 \
860 /* put back discard bit */ \
861 if (smtp.sm_discard) \
862 e->e_flags |= EF_DISCARD; \
863 \
864 /* restore connection quarantining */ \
865 if (smtp.sm_quarmsg == NULL) \
866 { \
867 e->e_quarmsg = NULL; \
868 macdefine(&e->e_macro, A_PERM, \
869 macid("{quarantine}"), ""); \
870 } \
871 else \
872 { \
873 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
874 smtp.sm_quarmsg); \
875 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
876 e->e_quarmsg); \
877 } \
878 } while (0)
879
880 /* sleep to flatten out connection load */
881 #define MIN_DELAY_LOG 15 /* wait before logging this again */
882
883 /* is it worth setting the process title for 1s? */
884 #define DELAY_CONN(cmd) \
885 if (DelayLA > 0 && (CurrentLA = getla()) >= DelayLA) \
886 { \
887 time_t dnow; \
888 \
889 sm_setproctitle(true, e, \
890 "%s: %s: delaying %s: load average: %d", \
891 qid_printname(e), CurSmtpClient, \
892 cmd, DelayLA); \
893 if (LogLevel > 8 && (dnow = curtime()) > log_delay) \
894 { \
895 sm_syslog(LOG_INFO, e->e_id, \
896 "delaying=%s, load average=%d >= %d", \
897 cmd, CurrentLA, DelayLA); \
898 log_delay = dnow + MIN_DELAY_LOG; \
899 } \
900 (void) sleep(1); \
901 sm_setproctitle(true, e, "%s %s: %.80s", \
902 qid_printname(e), CurSmtpClient, inp); \
903 }
904
905 /*
906 ** Determine the correct protocol keyword to use in the
907 ** Received: header, following RFC 3848.
908 */
909
910 #if !STARTTLS
911 # define tls_active false
912 #endif
913 #if SASL
914 # define auth_active (authenticating == SASL_IS_AUTH)
915 #else
916 # define auth_active false
917 #endif
918 #if USE_EAI
919 #define GET_PROTOCOL() \
920 (e->e_smtputf8 \
921 ? (auth_active \
922 ? (tls_active ? "UTF8SMTPSA" : "UTF8SMTPA") \
923 : (tls_active ? "UTF8SMTPS" : "UTF8SMTP")) \
924 : (auth_active \
925 ? (tls_active ? "ESMTPSA" : "ESMTPA") \
926 : (tls_active ? "ESMTPS" : "ESMTP")))
927 #else /* USE_EAI */
928 #define GET_PROTOCOL() \
929 (auth_active \
930 ? (tls_active ? "ESMTPSA" : "ESMTPA") \
931 : (tls_active ? "ESMTPS" : "ESMTP"))
932 #endif /* USE_EAI */
933
934 #if _FFR_NOREFLECT
935 # define SHOWCMDINREPLY(inp) (bitset(PRIV_NOREFLECTION, PrivacyFlags) ? \
936 "(suppressed)" : inp)
937 # define SHOWSHRTCMDINREPLY(inp) (bitset(PRIV_NOREFLECTION, PrivacyFlags) ? \
938 "(suppressed)" : shortenstring(inp, MAXSHORTSTR))
939 #else
940 # define SHOWCMDINREPLY(inp) inp
941 # define SHOWSHRTCMDINREPLY(inp) shortenstring(inp, MAXSHORTSTR)
942 #endif
943
944 void
smtp(nullserver,d_flags,e)945 smtp(nullserver, d_flags, e)
946 char *volatile nullserver;
947 BITMAP256 d_flags;
948 register ENVELOPE *volatile e;
949 {
950 register char *volatile p;
951 register struct cmd *volatile c = NULL;
952 char *cmd;
953 auto ADDRESS *vrfyqueue;
954 ADDRESS *a;
955 volatile bool gothello; /* helo command received */
956 bool vrfy; /* set if this is a vrfy command */
957 char *volatile protocol; /* sending protocol */
958 char *volatile sendinghost; /* sending hostname */
959 char *volatile peerhostname; /* name of SMTP peer or "localhost" */
960 auto char *delimptr;
961 char *id;
962 volatile unsigned int n_badcmds = 0; /* count of bad commands */
963 volatile unsigned int n_badrcpts = 0; /* number of rejected RCPT */
964 volatile unsigned int n_verifies = 0; /* count of VRFY/EXPN */
965 volatile unsigned int n_etrn = 0; /* count of ETRN */
966 volatile unsigned int n_noop = 0; /* count of NOOP/VERB/etc */
967 volatile unsigned int n_helo = 0; /* count of HELO/EHLO */
968 bool ok;
969 volatile bool first;
970 volatile bool tempfail = false;
971 volatile time_t wt; /* timeout after too many commands */
972 volatile time_t previous; /* time after checksmtpattack() */
973 volatile bool lognullconnection = true;
974 register char *q;
975 SMTP_T smtp;
976 char *addr;
977 char *greetcode = "220";
978 const char *greetmsg = "not accepting messages";
979 char *hostname; /* my hostname ($j) */
980 QUEUE_CHAR *new;
981 char *args[MAXSMTPARGS];
982 char inp[MAXINPLINE];
983 #if MAXINPLINE < MAXLINE
984 # error "MAXINPLINE must NOT be less than MAXLINE"
985 #endif
986 char cmdbuf[MAXLINE];
987 #if SASL
988 sasl_conn_t *conn;
989 volatile bool sasl_ok;
990 volatile unsigned int n_auth = 0; /* count of AUTH commands */
991 bool ismore;
992 int result;
993 volatile int authenticating;
994 char *user;
995 char *in, *out2;
996 char auth_user[MAX_AUTH_USER_LEN], auth_user_tmp[MAX_AUTH_USER_LEN];
997 unsigned int auth_user_len;
998 # if SASL >= 20000
999 char *auth_id = NULL;
1000 const char *out;
1001 sasl_ssf_t ext_ssf;
1002 char localip[60], remoteip[60];
1003 # else /* SASL >= 20000 */
1004 char *out;
1005 const char *errstr;
1006 sasl_external_properties_t ext_ssf;
1007 struct sockaddr_in saddr_l;
1008 struct sockaddr_in saddr_r;
1009 # endif /* SASL >= 20000 */
1010 sasl_security_properties_t ssp;
1011 sasl_ssf_t *ssf;
1012 unsigned int inlen, out2len;
1013 unsigned int outlen;
1014 char *volatile auth_type;
1015 char *mechlist;
1016 volatile unsigned int n_mechs;
1017 unsigned int len;
1018 #endif /* SASL */
1019 int r;
1020 #if STARTTLS
1021 int rfd, wfd;
1022 volatile bool tls_active = false;
1023 volatile bool smtps = bitnset(D_SMTPS, d_flags);
1024 bool gotostarttls = false;
1025 bool saveQuickAbort;
1026 bool saveSuprErrs;
1027 time_t tlsstart;
1028 int ssl_err, tlsret;
1029 int save_errno;
1030 extern int TLSsslidx;
1031 #endif /* STARTTLS */
1032 volatile unsigned long features;
1033 #if PIPELINING && _FFR_NO_PIPE
1034 int np_log = 0;
1035 #endif
1036 volatile time_t log_delay = (time_t) 0;
1037 #if MILTER
1038 volatile bool milter_cmd_done, milter_cmd_safe;
1039 volatile bool milter_rcpt_added, milter_cmd_fail;
1040 ADDRESS addr_st;
1041 # define p_addr_st &addr_st
1042 #else /* MILTER */
1043 # define p_addr_st NULL
1044 #endif /* MILTER */
1045 size_t inplen;
1046 #if _FFR_BADRCPT_SHUTDOWN
1047 int n_badrcpts_adj;
1048 #endif
1049 bool gotodoquit = false;
1050
1051 RESET_AUTH_FAIL_LOG_USER;
1052 smtp.sm_nrcpts = 0;
1053 #if MILTER
1054 smtp.sm_milterize = (nullserver == NULL);
1055 smtp.sm_milterlist = false;
1056 addr = NULL;
1057 #endif
1058
1059 /* setup I/O fd correctly for the SMTP server */
1060 setup_smtpd_io();
1061
1062 #if SM_HEAP_CHECK
1063 if (sm_debug_active(&DebugLeakSmtp, 1))
1064 {
1065 sm_heap_newgroup();
1066 sm_dprintf("smtp() heap group #%d\n", sm_heap_group());
1067 }
1068 #endif /* SM_HEAP_CHECK */
1069
1070 /* XXX the rpool should be set when e is initialized in main() */
1071 e->e_rpool = sm_rpool_new_x(NULL);
1072 e->e_macro.mac_rpool = e->e_rpool;
1073
1074 settime(e);
1075 sm_getla();
1076 peerhostname = RealHostName;
1077 if (peerhostname == NULL)
1078 peerhostname = "localhost";
1079 CurHostName = peerhostname;
1080 CurSmtpClient = macvalue('_', e);
1081 if (CurSmtpClient == NULL)
1082 CurSmtpClient = CurHostName;
1083
1084 /* check_relay may have set discard bit, save for later */
1085 smtp.sm_discard = bitset(EF_DISCARD, e->e_flags);
1086
1087 #if PIPELINING
1088 /* auto-flush output when reading input */
1089 (void) sm_io_autoflush(InChannel, OutChannel);
1090 #endif
1091
1092 sm_setproctitle(true, e, "server %s startup", CurSmtpClient);
1093
1094 maps_reset_chged("server:smtp");
1095
1096 /*
1097 ** Set default features for server.
1098 **
1099 ** Changing SRV_BARE_LF_421 | SRV_BARE_CR_421 below also
1100 ** requires changing srvfeatures() variant code.
1101 */
1102
1103 features = ((bitset(PRIV_NOETRN, PrivacyFlags) ||
1104 bitnset(D_NOETRN, d_flags)) ? SRV_NONE : SRV_OFFER_ETRN)
1105 | (bitnset(D_AUTHREQ, d_flags) ? SRV_REQ_AUTH : SRV_NONE)
1106 | (bitset(PRIV_NOEXPN, PrivacyFlags) ? SRV_NONE
1107 : (SRV_OFFER_EXPN
1108 | (bitset(PRIV_NOVERB, PrivacyFlags)
1109 ? SRV_NONE : SRV_OFFER_VERB)))
1110 | ((bitset(PRIV_NORECEIPTS, PrivacyFlags) || !SendMIMEErrors)
1111 ? SRV_NONE : SRV_OFFER_DSN)
1112 #if SASL
1113 | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH)
1114 | (bitset(SASL_SEC_NOPLAINTEXT, SASLOpts) ? SRV_REQ_SEC
1115 : SRV_NONE)
1116 #endif /* SASL */
1117 #if PIPELINING
1118 | SRV_OFFER_PIPE
1119 #endif
1120 | SRV_BAD_PIPELINE
1121 #if STARTTLS
1122 | (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS)
1123 | (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE
1124 : SRV_VRFY_CLT)
1125 #endif
1126 #if USE_EAI
1127 | (SMTP_UTF8 ? SRV_OFFER_EAI : 0)
1128 #endif
1129 | SRV_REQ_CRLF | SRV_BARE_LF_421 | SRV_BARE_CR_421
1130 ;
1131 if (nullserver == NULL)
1132 {
1133 features = srvfeatures(e, CurSmtpClient, features);
1134 if (bitset(SRV_TMP_FAIL, features))
1135 {
1136 if (LogLevel > 4)
1137 sm_syslog(LOG_ERR, NOQID,
1138 "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled",
1139 CurSmtpClient);
1140 nullserver = "450 4.3.0 Please try again later.";
1141 }
1142 else
1143 {
1144 #if PIPELINING && _FFR_NO_PIPE
1145 if (bitset(SRV_NO_PIPE, features))
1146 {
1147 /* for consistency */
1148 features &= ~SRV_OFFER_PIPE;
1149 }
1150 #endif /* PIPELINING && _FFR_NO_PIPE */
1151 #if SASL
1152 if (bitset(SRV_REQ_SEC, features))
1153 SASLOpts |= SASL_SEC_NOPLAINTEXT;
1154 else
1155 SASLOpts &= ~SASL_SEC_NOPLAINTEXT;
1156 #endif /* SASL */
1157 }
1158 }
1159 else if (strncmp(nullserver, "421 ", 4) == 0)
1160 {
1161 /* Can't use ("%s", ...) due to message() requirements */
1162 message(nullserver);
1163 gotodoquit = true;
1164 goto cmdloop;
1165 }
1166
1167 e->e_features = features;
1168 hostname = macvalue('j', e);
1169 #if SASL
1170 if (AuthRealm == NULL)
1171 AuthRealm = hostname;
1172 sasl_ok = bitset(SRV_OFFER_AUTH, features);
1173 n_mechs = 0;
1174 authenticating = SASL_NOT_AUTH;
1175
1176 /* SASL server new connection */
1177 if (sasl_ok)
1178 {
1179 # if SASL >= 20000
1180 result = sasl_server_new("smtp", AuthRealm, NULL, NULL, NULL,
1181 NULL, 0, &conn);
1182 # elif SASL > 10505
1183 /* use empty realm: only works in SASL > 1.5.5 */
1184 result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn);
1185 # else /* SASL >= 20000 */
1186 /* use no realm -> realm is set to hostname by SASL lib */
1187 result = sasl_server_new("smtp", AuthRealm, NULL, NULL, 0,
1188 &conn);
1189 # endif /* SASL >= 20000 */
1190 sasl_ok = result == SASL_OK;
1191 if (!sasl_ok)
1192 {
1193 if (LogLevel > 9)
1194 sm_syslog(LOG_WARNING, NOQID,
1195 "AUTH error: sasl_server_new failed=%d",
1196 result);
1197 }
1198 }
1199 if (sasl_ok)
1200 {
1201 /*
1202 ** SASL set properties for sasl
1203 ** set local/remote IP
1204 ** XXX Cyrus SASL v1 only supports IPv4
1205 **
1206 ** XXX where exactly are these used/required?
1207 ** Kerberos_v4
1208 */
1209
1210 # if SASL >= 20000
1211 localip[0] = remoteip[0] = '\0';
1212 # if NETINET || NETINET6
1213 in = macvalue(macid("{daemon_family}"), e);
1214 if (in != NULL && (
1215 # if NETINET6
1216 strcmp(in, "inet6") == 0 ||
1217 # endif
1218 strcmp(in, "inet") == 0))
1219 {
1220 SOCKADDR_LEN_T addrsize;
1221 SOCKADDR saddr_l;
1222 SOCKADDR saddr_r;
1223
1224 addrsize = sizeof(saddr_r);
1225 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
1226 NULL),
1227 (struct sockaddr *) &saddr_r,
1228 &addrsize) == 0)
1229 {
1230 if (iptostring(&saddr_r, addrsize,
1231 remoteip, sizeof(remoteip)))
1232 {
1233 sasl_setprop(conn, SASL_IPREMOTEPORT,
1234 remoteip);
1235 }
1236 addrsize = sizeof(saddr_l);
1237 if (getsockname(sm_io_getinfo(InChannel,
1238 SM_IO_WHAT_FD,
1239 NULL),
1240 (struct sockaddr *) &saddr_l,
1241 &addrsize) == 0)
1242 {
1243 if (iptostring(&saddr_l, addrsize,
1244 localip,
1245 sizeof(localip)))
1246 {
1247 sasl_setprop(conn,
1248 SASL_IPLOCALPORT,
1249 localip);
1250 }
1251 }
1252 }
1253 }
1254 # endif /* NETINET || NETINET6 */
1255 # else /* SASL >= 20000 */
1256 # if NETINET
1257 in = macvalue(macid("{daemon_family}"), e);
1258 if (in != NULL && strcmp(in, "inet") == 0)
1259 {
1260 SOCKADDR_LEN_T addrsize;
1261
1262 addrsize = sizeof(struct sockaddr_in);
1263 if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
1264 NULL),
1265 (struct sockaddr *)&saddr_r,
1266 &addrsize) == 0)
1267 {
1268 sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r);
1269 addrsize = sizeof(struct sockaddr_in);
1270 if (getsockname(sm_io_getinfo(InChannel,
1271 SM_IO_WHAT_FD,
1272 NULL),
1273 (struct sockaddr *)&saddr_l,
1274 &addrsize) == 0)
1275 sasl_setprop(conn, SASL_IP_LOCAL,
1276 &saddr_l);
1277 }
1278 }
1279 # endif /* NETINET */
1280 # endif /* SASL >= 20000 */
1281
1282 auth_type = NULL;
1283 mechlist = NULL;
1284 user = NULL;
1285 # if 0
1286 macdefine(&BlankEnvelope.e_macro, A_PERM,
1287 macid("{auth_author}"), NULL);
1288 # endif
1289
1290 /* set properties */
1291 (void) memset(&ssp, '\0', sizeof(ssp));
1292
1293 /* XXX should these be options settable via .cf ? */
1294 /* ssp.min_ssf = 0; is default due to memset() */
1295 ssp.max_ssf = MaxSLBits;
1296 ssp.maxbufsize = MAXOUTLEN;
1297 ssp.security_flags = SASLOpts & SASL_SEC_MASK;
1298 sasl_ok = sasl_setprop(conn, SASL_SEC_PROPS, &ssp) == SASL_OK;
1299
1300 if (sasl_ok)
1301 {
1302 /*
1303 ** external security strength factor;
1304 ** currently we have none so zero
1305 */
1306
1307 # if SASL >= 20000
1308 ext_ssf = 0;
1309 auth_id = NULL;
1310 sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL,
1311 &ext_ssf) == SASL_OK) &&
1312 (sasl_setprop(conn, SASL_AUTH_EXTERNAL,
1313 auth_id) == SASL_OK));
1314 # else /* SASL >= 20000 */
1315 ext_ssf.ssf = 0;
1316 ext_ssf.auth_id = NULL;
1317 sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
1318 &ext_ssf) == SASL_OK;
1319 # endif /* SASL >= 20000 */
1320 }
1321 if (sasl_ok)
1322 n_mechs = saslmechs(conn, &mechlist);
1323 }
1324 #endif /* SASL */
1325
1326 (void) set_tls_rd_tmo(TimeOuts.to_nextcommand);
1327
1328 #if MILTER
1329 if (smtp.sm_milterize)
1330 {
1331 char state;
1332
1333 /* initialize mail filter connection */
1334 smtp.sm_milterlist = milter_init(e, &state, &smtp.sm_milters);
1335 switch (state)
1336 {
1337 case SMFIR_REJECT:
1338 if (MilterLogLevel > 3)
1339 sm_syslog(LOG_INFO, e->e_id,
1340 "Milter: initialization failed, rejecting commands");
1341 greetcode = "554";
1342 nullserver = "Command rejected";
1343 smtp.sm_milterize = false;
1344 break;
1345
1346 case SMFIR_TEMPFAIL:
1347 if (MilterLogLevel > 3)
1348 sm_syslog(LOG_INFO, e->e_id,
1349 "Milter: initialization failed, temp failing commands");
1350 tempfail = true;
1351 smtp.sm_milterize = false;
1352 break;
1353
1354 case SMFIR_SHUTDOWN:
1355 if (MilterLogLevel > 3)
1356 sm_syslog(LOG_INFO, e->e_id,
1357 "Milter: initialization failed, closing connection");
1358 tempfail = true;
1359 smtp.sm_milterize = false;
1360 message("421 4.7.0 %s closing connection",
1361 MyHostName);
1362
1363 /* arrange to ignore send list */
1364 e->e_sendqueue = NULL;
1365 lognullconnection = false;
1366 gotodoquit = true;
1367 goto cmdloop;
1368 }
1369 }
1370
1371 if (smtp.sm_milterlist && smtp.sm_milterize &&
1372 !bitset(EF_DISCARD, e->e_flags))
1373 {
1374 char state;
1375 char *response;
1376
1377 q = macvalue(macid("{client_name}"), e);
1378 SM_ASSERT(q != NULL || OpMode == MD_SMTP);
1379 if (q == NULL)
1380 q = "localhost";
1381 response = milter_connect(q, RealHostAddr, e, &state);
1382 switch (state)
1383 {
1384 # if _FFR_MILTER_CONNECT_REPLYCODE
1385 case SMFIR_REPLYCODE:
1386 if (*response == '5')
1387 {
1388 if (MilterLogLevel > 3)
1389 sm_syslog(LOG_INFO, e->e_id,
1390 "Milter: connect: host=%s, addr=%s, reject=%s",
1391 peerhostname,
1392 anynet_ntoa(&RealHostAddr),
1393 response);
1394 greetcode = "554"; /* Required by 2821 3.1 */
1395 nullserver = newstr(response);
1396 if (strlen(nullserver) > 4)
1397 {
1398 int skip;
1399
1400 greetmsg = nullserver + 4;
1401
1402 /* skip over enhanced status code */
1403 skip = isenhsc(greetmsg, ' ');
1404 if (skip > 0)
1405 greetmsg += skip + 1;
1406 }
1407 smtp.sm_milterize = false;
1408 break;
1409 }
1410 else if (strncmp(response, "421 ", 4) == 0)
1411 {
1412 int skip;
1413 const char *msg = response + 4;
1414
1415 if (MilterLogLevel > 3)
1416 sm_syslog(LOG_INFO, e->e_id,
1417 "Milter: connect: host=%s, addr=%s, shutdown=%s",
1418 peerhostname,
1419 anynet_ntoa(&RealHostAddr),
1420 response);
1421 tempfail = true;
1422 smtp.sm_milterize = false;
1423
1424 /* skip over enhanced status code */
1425 skip = isenhsc(msg, ' ');
1426 if (skip > 0)
1427 msg += skip + 1;
1428 message("421 %s %s", MyHostName, msg);
1429
1430 /* arrange to ignore send list */
1431 e->e_sendqueue = NULL;
1432 gotodoquit = true;
1433 goto cmdloop;
1434 }
1435 else
1436 {
1437 if (MilterLogLevel > 3)
1438 sm_syslog(LOG_INFO, e->e_id,
1439 "Milter: connect: host=%s, addr=%s, temp failing commands=%s",
1440 peerhostname,
1441 anynet_ntoa(&RealHostAddr),
1442 response);
1443 /*tempfail = true;*/
1444 smtp.sm_milterize = false;
1445 nullserver = newstr(response);
1446 break;
1447 }
1448
1449 # else /* _FFR_MILTER_CONNECT_REPLYCODE */
1450 case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
1451 # endif /* _FFR_MILTER_CONNECT_REPLYCODE */
1452 case SMFIR_REJECT:
1453 if (MilterLogLevel > 3)
1454 sm_syslog(LOG_INFO, e->e_id,
1455 "Milter: connect: host=%s, addr=%s, rejecting commands",
1456 peerhostname,
1457 anynet_ntoa(&RealHostAddr));
1458 greetcode = "554";
1459 nullserver = "Command rejected";
1460 smtp.sm_milterize = false;
1461 break;
1462
1463 case SMFIR_TEMPFAIL:
1464 if (MilterLogLevel > 3)
1465 sm_syslog(LOG_INFO, e->e_id,
1466 "Milter: connect: host=%s, addr=%s, temp failing commands",
1467 peerhostname,
1468 anynet_ntoa(&RealHostAddr));
1469 tempfail = true;
1470 smtp.sm_milterize = false;
1471 break;
1472
1473 case SMFIR_SHUTDOWN:
1474 if (MilterLogLevel > 3)
1475 sm_syslog(LOG_INFO, e->e_id,
1476 "Milter: connect: host=%s, addr=%s, shutdown",
1477 peerhostname,
1478 anynet_ntoa(&RealHostAddr));
1479 tempfail = true;
1480 smtp.sm_milterize = false;
1481 message("421 4.7.0 %s closing connection",
1482 MyHostName);
1483
1484 /* arrange to ignore send list */
1485 e->e_sendqueue = NULL;
1486 gotodoquit = true;
1487 goto cmdloop;
1488 }
1489 if (response != NULL)
1490 sm_free(response);
1491 }
1492 #endif /* MILTER */
1493
1494 /*
1495 ** Broken proxies and SMTP slammers
1496 ** push data without waiting, catch them
1497 */
1498
1499 if (
1500 #if STARTTLS
1501 !smtps &&
1502 #endif
1503 *greetcode == '2' && nullserver == NULL)
1504 {
1505 time_t msecs = 0;
1506 char **pvp;
1507 char pvpbuf[PSBUFSIZE];
1508
1509 /* Ask the rulesets how long to pause */
1510 pvp = NULL;
1511 r = rscap("greet_pause", peerhostname,
1512 anynet_ntoa(&RealHostAddr), e,
1513 &pvp, pvpbuf, sizeof(pvpbuf));
1514 if (r == EX_OK && pvp != NULL && pvp[0] != NULL &&
1515 (pvp[0][0] & 0377) == CANONNET && pvp[1] != NULL)
1516 {
1517 msecs = strtol(pvp[1], NULL, 10);
1518 }
1519
1520 if (msecs > 0)
1521 {
1522 struct timeval *tp; /* total pause */
1523
1524 /* Obey RFC 2821: 4.5.3.2: 220 timeout of 5 minutes (300 seconds) */
1525 if (msecs >= 300000)
1526 msecs = 300000;
1527
1528 /* check if data is on the socket during the pause */
1529 if ((tp = channel_readable(InChannel, msecs)) != NULL)
1530 {
1531 greetcode = "554";
1532 nullserver = "Command rejected";
1533 sm_syslog(LOG_INFO, e->e_id,
1534 "rejecting commands from %s [%s] due to pre-greeting traffic after %d seconds",
1535 peerhostname,
1536 anynet_ntoa(&RealHostAddr),
1537 (int) tp->tv_sec +
1538 (tp->tv_usec >= 500000 ? 1 : 0)
1539 );
1540 }
1541 }
1542 }
1543
1544 #if STARTTLS
1545 /* If this an smtps connection, start TLS now */
1546 if (smtps)
1547 {
1548 if (!tls_ok_srv || srv_ctx == NULL)
1549 {
1550 sm_syslog(LOG_ERR, e->e_id,
1551 "smtps: TLS not available, exiting");
1552 exit(EX_CONFIG);
1553 }
1554 Errors = 0;
1555 first = true;
1556 gothello = false;
1557 smtp.sm_gotmail = false;
1558 gotostarttls = true;
1559 goto cmdloop;
1560 }
1561
1562 greeting:
1563
1564 #endif /* STARTTLS */
1565
1566 /* output the first line, inserting "ESMTP" as second word */
1567 if (*greetcode == '5')
1568 (void) sm_snprintf(inp, sizeof(inp), "%s %s", hostname,
1569 greetmsg);
1570 else
1571 expand(SmtpGreeting, inp, sizeof(inp), e);
1572
1573 p = strchr(inp, '\n');
1574 if (p != NULL)
1575 *p++ = '\0';
1576 id = strchr(inp, ' ');
1577 if (id == NULL)
1578 id = &inp[strlen(inp)];
1579 if (p == NULL)
1580 (void) sm_snprintf(cmdbuf, sizeof(cmdbuf),
1581 "%s %%.*s ESMTP%%s", greetcode);
1582 else
1583 (void) sm_snprintf(cmdbuf, sizeof(cmdbuf),
1584 "%s-%%.*s ESMTP%%s", greetcode);
1585 message(cmdbuf, (int) (id - inp), inp, id);
1586
1587 /* output remaining lines */
1588 while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
1589 {
1590 *p++ = '\0';
1591 if (SM_ISSPACE(*id))
1592 id++;
1593 (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, "-%s");
1594 message(cmdbuf, id);
1595 }
1596 if (id != NULL)
1597 {
1598 if (SM_ISSPACE(*id))
1599 id++;
1600 (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, " %s");
1601 message(cmdbuf, id);
1602 }
1603
1604 protocol = NULL;
1605 sendinghost = macvalue('s', e);
1606
1607 /* If quarantining by a connect/ehlo action, save between messages */
1608 if (e->e_quarmsg == NULL)
1609 smtp.sm_quarmsg = NULL;
1610 else
1611 smtp.sm_quarmsg = newstr(e->e_quarmsg);
1612
1613 /* sendinghost's storage must outlive the current envelope */
1614 if (sendinghost != NULL)
1615 sendinghost = sm_strdup_x(sendinghost);
1616 first = true;
1617 gothello = false;
1618 smtp.sm_gotmail = false;
1619 for (;;)
1620 {
1621
1622 cmdloop:
1623 SM_TRY
1624 {
1625 QuickAbort = false;
1626 HoldErrs = false;
1627 SuprErrs = false;
1628 LogUsrErrs = false;
1629 OnlyOneError = true;
1630 e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
1631 #if MILTER
1632 milter_cmd_fail = false;
1633 #endif
1634
1635 /* setup for the read */
1636 e->e_to = NULL;
1637 Errors = 0;
1638 FileName = NULL;
1639 (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
1640
1641 if (gotodoquit)
1642 {
1643 gotodoquit = false;
1644 goto doquit;
1645 }
1646 #if STARTTLS
1647 if (gotostarttls)
1648 {
1649 gotostarttls = false;
1650 goto starttls;
1651 }
1652 #endif
1653
1654 /* read the input line */
1655 SmtpPhase = "server cmd read";
1656 sm_setproctitle(true, e, "server %s cmd read", CurSmtpClient);
1657
1658 /* handle errors */
1659 if (sm_io_error(OutChannel) ||
1660 (p = sfgets(inp, sizeof(inp), InChannel,
1661 TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
1662 {
1663 char *d;
1664
1665 d = macvalue(macid("{daemon_name}"), e);
1666 if (d == NULL)
1667 d = "stdin";
1668 /* end of file, just die */
1669 disconnect(1, e);
1670
1671 #if MILTER
1672 /* close out milter filters */
1673 milter_quit(e);
1674 #endif
1675
1676 message("421 4.4.1 %s Lost input channel from %s",
1677 MyHostName, CurSmtpClient);
1678 if (LogLevel > (smtp.sm_gotmail ? 1 : 19))
1679 sm_syslog(LOG_NOTICE, e->e_id,
1680 "lost input channel from %s to %s after %s",
1681 CurSmtpClient, d,
1682 (c == NULL || c->cmd_name == NULL) ? "startup" : c->cmd_name);
1683 /*
1684 ** If have not accepted mail (DATA), do not bounce
1685 ** bad addresses back to sender.
1686 */
1687
1688 if (bitset(EF_CLRQUEUE, e->e_flags))
1689 e->e_sendqueue = NULL;
1690 goto doquit;
1691 }
1692
1693 /* also used by "proxy" check below */
1694 inplen = strlen(inp);
1695 #if SASL
1696 /*
1697 ** SMTP AUTH requires accepting any length,
1698 ** at least for challenge/response. However, not imposing
1699 ** a limit is a bad idea (denial of service).
1700 */
1701
1702 if (authenticating != SASL_PROC_AUTH
1703 && sm_strncasecmp(inp, "AUTH ", 5) != 0
1704 && inplen > MAXLINE)
1705 {
1706 message("421 4.7.0 %s Command too long, possible attack %s",
1707 MyHostName, CurSmtpClient);
1708 sm_syslog(LOG_INFO, e->e_id,
1709 "%s: SMTP violation, input too long: %lu",
1710 CurSmtpClient, (unsigned long) inplen);
1711 goto doquit;
1712 }
1713 #endif /* SASL */
1714
1715 if (first || bitset(SRV_NO_HTTP_CMD, features))
1716 {
1717 size_t cmdlen;
1718 int idx;
1719 char *http_cmd;
1720 static char *http_cmds[] = { "GET", "POST",
1721 "CONNECT", "USER", NULL };
1722
1723 for (idx = 0; (http_cmd = http_cmds[idx]) != NULL;
1724 idx++)
1725 {
1726 cmdlen = strlen(http_cmd);
1727 if (cmdlen < inplen &&
1728 sm_strncasecmp(inp, http_cmd, cmdlen) == 0 &&
1729 SM_ISSPACE(inp[cmdlen]))
1730 {
1731 /* Open proxy, drop it */
1732 message("421 4.7.0 %s %s %s",
1733 MyHostName,
1734 first ? "Rejecting open proxy"
1735 : "HTTP command",
1736 CurSmtpClient);
1737 sm_syslog(LOG_INFO, e->e_id,
1738 "%s: probable open proxy: command=%.40s",
1739 CurSmtpClient, inp);
1740 goto doquit;
1741 }
1742 }
1743 first = false;
1744 }
1745
1746 /* clean up end of line */
1747 fixcrlf(inp, true);
1748
1749 #if PIPELINING && _FFR_NO_PIPE
1750 /*
1751 ** if there is more input and pipelining is disabled:
1752 ** delay ... (and maybe discard the input?)
1753 */
1754
1755 if (bitset(SRV_NO_PIPE, features) &&
1756 sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0)
1757 {
1758 if (++np_log < 3)
1759 sm_syslog(LOG_INFO, NOQID,
1760 "unauthorized PIPELINING, sleeping, relay=%.100s",
1761 CurSmtpClient);
1762 sleep(1);
1763 }
1764 #endif /* PIPELINING && _FFR_NO_PIPE */
1765
1766 #if SASL
1767 if (authenticating == SASL_PROC_AUTH)
1768 {
1769 # if 0
1770 if (*inp == '\0')
1771 {
1772 authenticating = SASL_NOT_AUTH;
1773 message("501 5.5.2 missing input");
1774 RESET_SASLCONN;
1775 continue;
1776 }
1777 # endif /* 0 */
1778 if (*inp == '*' && *(inp + 1) == '\0')
1779 {
1780 authenticating = SASL_NOT_AUTH;
1781
1782 /* RFC 2554 4. */
1783 message("501 5.0.0 AUTH aborted");
1784 RESET_SASLCONN;
1785 continue;
1786 }
1787
1788 /* could this be shorter? XXX */
1789 # if SASL >= 20000
1790 in = xalloc(strlen(inp) + 1);
1791 result = sasl_decode64(inp, strlen(inp), in,
1792 strlen(inp), &inlen);
1793 # else /* SASL >= 20000 */
1794 out = xalloc(strlen(inp));
1795 result = sasl_decode64(inp, strlen(inp), out, &outlen);
1796 # endif /* SASL >= 20000 */
1797 if (result != SASL_OK)
1798 {
1799 authenticating = SASL_NOT_AUTH;
1800
1801 /* RFC 2554 4. */
1802 message("501 5.5.4 cannot decode AUTH parameter %s",
1803 inp);
1804 # if SASL >= 20000
1805 sm_free(in);
1806 # endif
1807 RESET_SASLCONN;
1808 continue;
1809 }
1810
1811 # if SASL >= 20000
1812 SET_AUTH_USER_TMP(in, inlen);
1813 result = sasl_server_step(conn, in, inlen,
1814 &out, &outlen);
1815 sm_free(in);
1816 # else /* SASL >= 20000 */
1817 SET_AUTH_USER_TMP(out, outlen);
1818 result = sasl_server_step(conn, out, outlen,
1819 &out, &outlen, &errstr);
1820 # endif /* SASL >= 20000 */
1821
1822 /* get an OK if we're done */
1823 if (result == SASL_OK)
1824 {
1825 authenticated:
1826 message("235 2.0.0 OK Authenticated");
1827 authenticating = SASL_IS_AUTH;
1828 macdefine(&BlankEnvelope.e_macro, A_TEMP,
1829 macid("{auth_type}"), auth_type);
1830
1831 # if SASL >= 20000
1832 user = macvalue(macid("{auth_authen}"), e);
1833
1834 /* get security strength (features) */
1835 result = sasl_getprop(conn, SASL_SSF,
1836 (const void **) &ssf);
1837 # else /* SASL >= 20000 */
1838 result = sasl_getprop(conn, SASL_USERNAME,
1839 (void **)&user);
1840 if (result != SASL_OK)
1841 {
1842 user = "";
1843 macdefine(&BlankEnvelope.e_macro,
1844 A_PERM,
1845 macid("{auth_authen}"), NULL);
1846 }
1847 else
1848 {
1849 macdefine(&BlankEnvelope.e_macro,
1850 A_TEMP,
1851 macid("{auth_authen}"),
1852 xtextify(user, "<>\")"));
1853 }
1854
1855 # if 0
1856 /* get realm? */
1857 sasl_getprop(conn, SASL_REALM, (void **) &data);
1858 # endif
1859
1860 /* get security strength (features) */
1861 result = sasl_getprop(conn, SASL_SSF,
1862 (void **) &ssf);
1863 # endif /* SASL >= 20000 */
1864 if (result != SASL_OK)
1865 {
1866 macdefine(&BlankEnvelope.e_macro,
1867 A_PERM,
1868 macid("{auth_ssf}"), "0");
1869 ssf = NULL;
1870 }
1871 else
1872 {
1873 char pbuf[8];
1874
1875 (void) sm_snprintf(pbuf, sizeof(pbuf),
1876 "%u", *ssf);
1877 macdefine(&BlankEnvelope.e_macro,
1878 A_TEMP,
1879 macid("{auth_ssf}"), pbuf);
1880 if (tTd(95, 8))
1881 sm_dprintf("AUTH auth_ssf: %u\n",
1882 *ssf);
1883 }
1884
1885 protocol = GET_PROTOCOL();
1886
1887 /*
1888 ** Only switch to encrypted connection
1889 ** if a security layer has been negotiated
1890 */
1891
1892 if (ssf != NULL && *ssf > 0)
1893 {
1894 int tmo;
1895
1896 /*
1897 ** Convert I/O layer to use SASL.
1898 ** If the call fails, the connection
1899 ** is aborted.
1900 */
1901
1902 tmo = TimeOuts.to_datablock * 1000;
1903 if (sfdcsasl(&InChannel, &OutChannel,
1904 conn, tmo) == 0)
1905 {
1906 /* restart dialogue */
1907 n_helo = 0;
1908 # if PIPELINING
1909 (void) sm_io_autoflush(InChannel,
1910 OutChannel);
1911 # endif /* PIPELINING */
1912 }
1913 else
1914 syserr("503 5.3.3 SASL TLS failed");
1915 }
1916
1917 /* NULL pointer ok since it's our function */
1918 if (LogLevel > 8)
1919 sm_syslog(LOG_INFO, NOQID,
1920 "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d",
1921 CurSmtpClient,
1922 shortenstring(user, 128),
1923 auth_type, *ssf);
1924 }
1925 else if (result == SASL_CONTINUE)
1926 {
1927 SET_AUTH_USER;
1928
1929 len = ENC64LEN(outlen);
1930 out2 = xalloc(len);
1931 result = sasl_encode64(out, outlen, out2, len,
1932 &out2len);
1933 if (result != SASL_OK)
1934 {
1935 /* correct code? XXX */
1936 /* 454 Temp. authentication failure */
1937 message("454 4.5.4 Internal error: unable to encode64");
1938 if (LogLevel > 5)
1939 sm_syslog(LOG_WARNING, e->e_id,
1940 "AUTH encode64 error [%d for \"%s\"], relay=%.100s",
1941 result, out,
1942 CurSmtpClient);
1943 /* start over? */
1944 authenticating = SASL_NOT_AUTH;
1945 }
1946 else
1947 {
1948 message("334 %s", out2);
1949 if (tTd(95, 2))
1950 sm_dprintf("AUTH continue: msg='%s' len=%u\n",
1951 out2, out2len);
1952 }
1953 # if SASL >= 20000
1954 sm_free(out2);
1955 # endif
1956 }
1957 else
1958 {
1959
1960 # if SASL >= 20000
1961 # define SASLERR sasl_errdetail(conn)
1962 # else
1963 # define SASLERR errstr == NULL ? "" : errstr
1964 # endif
1965 #define LOGAUTHFAIL \
1966 do \
1967 { \
1968 SET_AUTH_USER_CONDITIONALLY \
1969 message("535 5.7.0 authentication failed"); \
1970 if (LogLevel >= 9) \
1971 sm_syslog(LOG_WARNING, e->e_id, \
1972 "AUTH failure (%s): %s (%d) %s%s%.*s, relay=%.100s", \
1973 (auth_type != NULL) ? auth_type : "unknown", \
1974 sasl_errstring(result, NULL, NULL), \
1975 result, \
1976 SASLERR, \
1977 LOG_AUTH_FAIL_USER, \
1978 CurSmtpClient); \
1979 RESET_SASLCONN; \
1980 } while (0)
1981
1982
1983 LOGAUTHFAIL;
1984 authenticating = SASL_NOT_AUTH;
1985 }
1986 }
1987 else
1988 {
1989 /* don't want to do any of this if authenticating */
1990 #endif /* SASL */
1991
1992 /* echo command to transcript */
1993 if (e->e_xfp != NULL)
1994 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
1995 "<<< %s\n", inp);
1996
1997 if (LogLevel > 14)
1998 sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp);
1999
2000 /* break off command */
2001 for (p = inp; SM_ISSPACE(*p); p++)
2002 continue;
2003 cmd = cmdbuf;
2004 while (*p != '\0' &&
2005 !(SM_ISSPACE(*p)) &&
2006 cmd < &cmdbuf[sizeof(cmdbuf) - 2])
2007 *cmd++ = *p++;
2008 *cmd = '\0';
2009
2010 /* throw away leading whitespace */
2011 SKIP_SPACE(p);
2012
2013 /* decode command */
2014 for (c = CmdTab; c->cmd_name != NULL; c++)
2015 {
2016 if (SM_STRCASEEQ(c->cmd_name, cmdbuf))
2017 break;
2018 }
2019
2020 /* reset errors */
2021 errno = 0;
2022
2023 /* check whether a "non-null" command has been used */
2024 switch (c->cmd_code)
2025 {
2026 #if SASL
2027 case CMDAUTH:
2028 /* avoid information leak; take first two words? */
2029 q = "AUTH";
2030 break;
2031 #endif /* SASL */
2032
2033 case CMDMAIL:
2034 case CMDEXPN:
2035 case CMDVRFY:
2036 case CMDETRN:
2037 lognullconnection = false;
2038 /* FALLTHROUGH */
2039 default:
2040 q = inp;
2041 break;
2042 }
2043
2044 if (e->e_id == NULL)
2045 sm_setproctitle(true, e, "%s: %.80s",
2046 CurSmtpClient, q);
2047 else
2048 sm_setproctitle(true, e, "%s %s: %.80s",
2049 qid_printname(e),
2050 CurSmtpClient, q);
2051
2052 /*
2053 ** Process command.
2054 **
2055 ** If we are running as a null server, return 550
2056 ** to almost everything.
2057 */
2058
2059 if (nullserver != NULL || bitnset(D_ETRNONLY, d_flags))
2060 {
2061 switch (c->cmd_code)
2062 {
2063 case CMDQUIT:
2064 case CMDHELO:
2065 case CMDEHLO:
2066 case CMDNOOP:
2067 case CMDRSET:
2068 case CMDERROR:
2069 /* process normally */
2070 break;
2071
2072 case CMDETRN:
2073 if (bitnset(D_ETRNONLY, d_flags) &&
2074 nullserver == NULL)
2075 break;
2076 DELAY_CONN("ETRN");
2077 /* FALLTHROUGH */
2078
2079 default:
2080 #if MAXBADCOMMANDS > 0
2081 /* theoretically this could overflow */
2082 if (nullserver != NULL &&
2083 ++n_badcmds > MAXBADCOMMANDS)
2084 {
2085 message("421 4.7.0 %s Too many bad commands; closing connection",
2086 MyHostName);
2087
2088 /* arrange to ignore send list */
2089 e->e_sendqueue = NULL;
2090 goto doquit;
2091 }
2092 #endif /* MAXBADCOMMANDS > 0 */
2093 if (nullserver != NULL)
2094 {
2095 if (ISSMTPREPLY(nullserver))
2096 {
2097 /* Can't use ("%s", ...) due to usrerr() requirements */
2098 usrerr(nullserver);
2099 }
2100 else
2101 {
2102 usrerr("550 5.0.0 %s",
2103 nullserver);
2104 }
2105 }
2106 else
2107 usrerr("452 4.4.5 Insufficient disk space; try again later");
2108 continue;
2109 }
2110 }
2111
2112 switch (c->cmd_code)
2113 {
2114 #if SASL
2115 case CMDAUTH: /* sasl */
2116 DELAY_CONN("AUTH");
2117 if (!sasl_ok || n_mechs <= 0)
2118 {
2119 message("503 5.3.3 AUTH not available");
2120 break;
2121 }
2122 if (auth_active)
2123 {
2124 message("503 5.5.0 Already Authenticated");
2125 break;
2126 }
2127 if (smtp.sm_gotmail)
2128 {
2129 message("503 5.5.0 AUTH not permitted during a mail transaction");
2130 break;
2131 }
2132 if (tempfail)
2133 {
2134 if (LogLevel > 9)
2135 sm_syslog(LOG_INFO, e->e_id,
2136 "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)",
2137 p, CurSmtpClient);
2138 usrerr("454 4.3.0 Please try again later");
2139 break;
2140 }
2141
2142 ismore = false;
2143
2144 /* crude way to avoid crack attempts */
2145 STOP_IF_ATTACK(checksmtpattack(&n_auth, n_mechs + 1,
2146 true, "AUTH", e));
2147
2148 /* make sure mechanism (p) is a valid string */
2149 for (q = p; *q != '\0' && isascii(*q); q++)
2150 {
2151 if (isspace(*q))
2152 {
2153 *q = '\0';
2154 while (*++q != '\0' && SM_ISSPACE(*q))
2155 continue;
2156 *(q - 1) = '\0';
2157 ismore = (*q != '\0');
2158 break;
2159 }
2160 }
2161
2162 if (*p == '\0')
2163 {
2164 message("501 5.5.2 AUTH mechanism must be specified");
2165 break;
2166 }
2167
2168 /* check whether mechanism is available */
2169 if (iteminlist(p, mechlist, " ") == NULL)
2170 {
2171 message("504 5.3.3 AUTH mechanism %.32s not available",
2172 p);
2173 break;
2174 }
2175
2176 /*
2177 ** RFC 2554 4.
2178 ** Unlike a zero-length client answer to a
2179 ** 334 reply, a zero- length initial response
2180 ** is sent as a single equals sign ("=").
2181 */
2182
2183 if (ismore && *q == '=' && *(q + 1) == '\0')
2184 {
2185 /* will be free()d, don't use in=""; */
2186 in = xalloc(1);
2187 *in = '\0';
2188 inlen = 0;
2189 }
2190 else if (ismore)
2191 {
2192 /* could this be shorter? XXX */
2193 # if SASL >= 20000
2194 in = xalloc(strlen(q) + 1);
2195 result = sasl_decode64(q, strlen(q), in,
2196 strlen(q), &inlen);
2197 # else /* SASL >= 20000 */
2198 in = sm_rpool_malloc(e->e_rpool, strlen(q));
2199 result = sasl_decode64(q, strlen(q), in,
2200 &inlen);
2201 # endif /* SASL >= 20000 */
2202
2203 if (result != SASL_OK)
2204 {
2205 message("501 5.5.4 cannot BASE64 decode '%s'",
2206 q);
2207 if (LogLevel > 5)
2208 sm_syslog(LOG_WARNING, e->e_id,
2209 "AUTH decode64 error [%d for \"%s\"], relay=%.100s",
2210 result, q,
2211 CurSmtpClient);
2212 /* start over? */
2213 authenticating = SASL_NOT_AUTH;
2214 # if SASL >= 20000
2215 sm_free(in);
2216 # endif
2217 in = NULL;
2218 inlen = 0;
2219 break;
2220 }
2221 SET_AUTH_USER_TMP(in, inlen);
2222 }
2223 else
2224 {
2225 in = NULL;
2226 inlen = 0;
2227 }
2228
2229 /* see if that auth type exists */
2230 # if SASL >= 20000
2231 result = sasl_server_start(conn, p, in, inlen,
2232 &out, &outlen);
2233 SM_FREE(in);
2234 # else /* SASL >= 20000 */
2235 result = sasl_server_start(conn, p, in, inlen,
2236 &out, &outlen, &errstr);
2237 # endif /* SASL >= 20000 */
2238
2239 if (p != NULL)
2240 auth_type = newstr(p);
2241 if (result != SASL_OK && result != SASL_CONTINUE)
2242 {
2243 LOGAUTHFAIL;
2244 break;
2245 }
2246
2247 if (result == SASL_OK)
2248 {
2249 /* ugly, but same code */
2250 goto authenticated;
2251 /* authenticated by the initial response */
2252 }
2253
2254 SET_AUTH_USER;
2255
2256 /* len is at least 2 */
2257 len = ENC64LEN(outlen);
2258 out2 = xalloc(len);
2259 result = sasl_encode64(out, outlen, out2, len,
2260 &out2len);
2261
2262 if (result != SASL_OK)
2263 {
2264 message("454 4.5.4 Temporary authentication failure");
2265 if (LogLevel > 5)
2266 sm_syslog(LOG_WARNING, e->e_id,
2267 "AUTH encode64 error [%d for \"%s\"]",
2268 result, out);
2269
2270 /* start over? */
2271 authenticating = SASL_NOT_AUTH;
2272 RESET_SASLCONN;
2273 }
2274 else
2275 {
2276 message("334 %s", out2);
2277 authenticating = SASL_PROC_AUTH;
2278 }
2279 # if SASL >= 20000
2280 sm_free(out2);
2281 # endif
2282 break;
2283 #endif /* SASL */
2284
2285 #if STARTTLS
2286 case CMDSTLS: /* starttls */
2287 DELAY_CONN("STARTTLS");
2288 if (*p != '\0')
2289 {
2290 message("501 5.5.2 Syntax error (no parameters allowed)");
2291 break;
2292 }
2293 if (!bitset(SRV_OFFER_TLS, features))
2294 {
2295 message("503 5.5.0 TLS not available");
2296 break;
2297 }
2298 starttls:
2299 if (!tls_ok_srv)
2300 {
2301 message("454 4.3.3 TLS not available after start");
2302 break;
2303 }
2304 if (smtp.sm_gotmail)
2305 {
2306 message("503 5.5.0 TLS not permitted during a mail transaction");
2307 break;
2308 }
2309 if (tempfail)
2310 {
2311 if (LogLevel > 9)
2312 sm_syslog(LOG_INFO, e->e_id,
2313 "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)",
2314 p, CurSmtpClient);
2315 usrerr("454 4.7.0 Please try again later");
2316 break;
2317 }
2318 if (!TLS_set_engine(SSLEngine, false))
2319 {
2320 sm_syslog(LOG_ERR, NOQID,
2321 "STARTTLS=server, engine=%s, TLS_set_engine=failed",
2322 SSLEngine);
2323 tls_ok_srv = false;
2324 message("454 4.3.3 TLS not available right now");
2325 break;
2326 }
2327 # if TLS_NO_RSA
2328 /*
2329 ** XXX do we need a temp key ?
2330 */
2331 # endif
2332
2333 # if TLS_VRFY_PER_CTX
2334 /*
2335 ** Note: this sets the verification globally
2336 ** (per SSL_CTX)
2337 ** it's ok since it applies only to one transaction
2338 */
2339
2340 TLS_VERIFY_CLIENT();
2341 # endif /* TLS_VRFY_PER_CTX */
2342
2343 #define SMTLSFAILED \
2344 do { \
2345 SM_SSL_FREE(srv_ssl); \
2346 goto tls_done; \
2347 } while (0)
2348
2349 if (srv_ssl != NULL)
2350 SSL_clear(srv_ssl);
2351 else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
2352 {
2353 message("454 4.3.3 TLS not available: error generating SSL handle");
2354 tlslogerr(LOG_WARNING, 8, "server");
2355 goto tls_done;
2356 }
2357 # if DANE
2358 tlsi_ctx.tlsi_dvc.dane_vrfy_dane_enabled = false;
2359 tlsi_ctx.tlsi_dvc.dane_vrfy_chk = DANE_NEVER;
2360 # endif
2361 if (get_tls_se_features(e, srv_ssl, &tlsi_ctx, true)
2362 != EX_OK)
2363 {
2364 /* do not offer too much info to client */
2365 message("454 4.3.3 TLS currently not available");
2366 SMTLSFAILED;
2367 }
2368 r = SSL_set_ex_data(srv_ssl, TLSsslidx, &tlsi_ctx);
2369 if (0 == r)
2370 {
2371 if (LogLevel > 5)
2372 {
2373 sm_syslog(LOG_ERR, NOQID,
2374 "STARTTLS=server, error: SSL_set_ex_data failed=%d, TLSsslidx=%d",
2375 r, TLSsslidx);
2376 tlslogerr(LOG_WARNING, 9, "server");
2377 }
2378 SMTLSFAILED;
2379 }
2380
2381 # if !TLS_VRFY_PER_CTX
2382 /*
2383 ** this could be used if it were possible to set
2384 ** verification per SSL (connection)
2385 ** not just per SSL_CTX (global)
2386 */
2387
2388 TLS_VERIFY_CLIENT();
2389 # endif /* !TLS_VRFY_PER_CTX */
2390
2391 rfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
2392 wfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
2393
2394 if (rfd < 0 || wfd < 0 ||
2395 SSL_set_rfd(srv_ssl, rfd) <= 0 ||
2396 SSL_set_wfd(srv_ssl, wfd) <= 0)
2397 {
2398 message("454 4.3.3 TLS not available: error set fd");
2399 SMTLSFAILED;
2400 }
2401 if (!smtps)
2402 message("220 2.0.0 Ready to start TLS");
2403 # if PIPELINING
2404 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
2405 # endif
2406
2407 SSL_set_accept_state(srv_ssl);
2408
2409 tlsstart = curtime();
2410
2411 ssl_err = SSL_ERROR_WANT_READ;
2412 save_errno = 0;
2413 do
2414 {
2415 tlsret = tls_retry(srv_ssl, rfd, wfd, tlsstart,
2416 TimeOuts.to_starttls, ssl_err,
2417 "server");
2418 if (tlsret <= 0)
2419 {
2420 if (LogLevel > 5)
2421 {
2422 unsigned long l;
2423 const char *sr;
2424
2425 l = ERR_peek_error();
2426 sr = ERR_reason_error_string(l);
2427
2428 sm_syslog(LOG_WARNING, NOQID,
2429 "STARTTLS=server, error: accept failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d, relay=%.100s",
2430 r, sr == NULL ? "unknown"
2431 : sr,
2432 ssl_err, save_errno,
2433 tlsret, CurSmtpClient);
2434 tlslogerr(LOG_WARNING, 9, "server");
2435 }
2436 tls_ok_srv = false;
2437 SM_SSL_FREE(srv_ssl);
2438
2439 /*
2440 ** according to the next draft of
2441 ** RFC 2487 the connection should
2442 ** be dropped
2443 **
2444 ** arrange to ignore any current
2445 ** send list
2446 */
2447
2448 e->e_sendqueue = NULL;
2449 goto doquit;
2450 }
2451
2452 r = SSL_accept(srv_ssl);
2453 save_errno = 0;
2454 if (r <= 0)
2455 ssl_err = SSL_get_error(srv_ssl, r);
2456 } while (r <= 0);
2457
2458 /* ignore return code for now, it's in {verify} */
2459 (void) tls_get_info(srv_ssl, true,
2460 CurSmtpClient,
2461 &BlankEnvelope.e_macro,
2462 bitset(SRV_VRFY_CLT, features));
2463
2464 /*
2465 ** call Stls_client to find out whether
2466 ** to accept the connection from the client
2467 */
2468
2469 saveQuickAbort = QuickAbort;
2470 saveSuprErrs = SuprErrs;
2471 SuprErrs = true;
2472 QuickAbort = false;
2473 if (rscheck("tls_client",
2474 macvalue(macid("{verify}"), e),
2475 "STARTTLS", e,
2476 RSF_RMCOMM|RSF_COUNT,
2477 5, NULL, NOQID, NULL, NULL) != EX_OK ||
2478 Errors > 0)
2479 {
2480 extern char MsgBuf[];
2481
2482 if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf))
2483 nullserver = newstr(MsgBuf);
2484 else
2485 nullserver = "503 5.7.0 Authentication required.";
2486 }
2487 QuickAbort = saveQuickAbort;
2488 SuprErrs = saveSuprErrs;
2489
2490 tls_ok_srv = false; /* don't offer STARTTLS again */
2491 first = true;
2492 n_helo = 0;
2493 # if SASL
2494 if (sasl_ok)
2495 {
2496 int cipher_bits;
2497 bool verified;
2498 char *s, *v, *c;
2499
2500 s = macvalue(macid("{cipher_bits}"), e);
2501 v = macvalue(macid("{verify}"), e);
2502 c = macvalue(macid("{cert_subject}"), e);
2503 verified = (v != NULL && strcmp(v, "OK") == 0);
2504 if (s != NULL && (cipher_bits = atoi(s)) > 0)
2505 {
2506 # if SASL >= 20000
2507 ext_ssf = cipher_bits;
2508 auth_id = verified ? c : NULL;
2509 sasl_ok = ((sasl_setprop(conn,
2510 SASL_SSF_EXTERNAL,
2511 &ext_ssf) == SASL_OK) &&
2512 (sasl_setprop(conn,
2513 SASL_AUTH_EXTERNAL,
2514 auth_id) == SASL_OK));
2515 # else /* SASL >= 20000 */
2516 ext_ssf.ssf = cipher_bits;
2517 ext_ssf.auth_id = verified ? c : NULL;
2518 sasl_ok = sasl_setprop(conn,
2519 SASL_SSF_EXTERNAL,
2520 &ext_ssf) == SASL_OK;
2521 # endif /* SASL >= 20000 */
2522 mechlist = NULL;
2523 if (sasl_ok)
2524 n_mechs = saslmechs(conn,
2525 &mechlist);
2526 }
2527 }
2528 # endif /* SASL */
2529
2530 /* switch to secure connection */
2531 if (sfdctls(&InChannel, &OutChannel, srv_ssl) == 0)
2532 {
2533 tls_active = true;
2534 # if PIPELINING
2535 (void) sm_io_autoflush(InChannel, OutChannel);
2536 # endif
2537 }
2538 else
2539 {
2540 /*
2541 ** XXX this is an internal error
2542 ** how to deal with it?
2543 ** we can't generate an error message
2544 ** since the other side switched to an
2545 ** encrypted layer, but we could not...
2546 ** just "hang up"?
2547 */
2548
2549 nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer";
2550 syserr("STARTTLS: can't switch to encrypted layer");
2551 }
2552 tls_done:
2553 if (smtps)
2554 {
2555 if (tls_active)
2556 goto greeting;
2557 else
2558 goto doquit;
2559 }
2560 break;
2561 #endif /* STARTTLS */
2562
2563 case CMDHELO: /* hello -- introduce yourself */
2564 case CMDEHLO: /* extended hello */
2565 DELAY_CONN("EHLO");
2566 if (c->cmd_code == CMDEHLO)
2567 {
2568 protocol = GET_PROTOCOL();
2569 SmtpPhase = "server EHLO";
2570 }
2571 else
2572 {
2573 protocol = "SMTP";
2574 SmtpPhase = "server HELO";
2575 }
2576
2577 /* avoid denial-of-service */
2578 STOP_IF_ATTACK(checksmtpattack(&n_helo, MAXHELOCOMMANDS,
2579 true, "HELO/EHLO", e));
2580
2581 /*
2582 ** Despite the fact that the name indicates this
2583 ** a PIPELINE related feature, do not enclose
2584 ** it in #if PIPELINING so we can protect SMTP
2585 ** servers not compiled with PIPELINE support
2586 ** from transaction stuffing.
2587 */
2588
2589 /* check if data is on the socket before the EHLO reply */
2590 if (bitset(SRV_BAD_PIPELINE, features) &&
2591 sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0)
2592 {
2593 sm_syslog(LOG_INFO, e->e_id,
2594 "rejecting %s from %s [%s] due to traffic before response",
2595 SmtpPhase, CurHostName,
2596 anynet_ntoa(&RealHostAddr));
2597 usrerr("554 5.5.0 SMTP protocol error");
2598 nullserver = "Command rejected";
2599 #if MILTER
2600 smtp.sm_milterize = false;
2601 #endif
2602 break;
2603 }
2604
2605 #if 0
2606 /* RFC2821 4.1.4 allows duplicate HELO/EHLO */
2607 /* check for duplicate HELO/EHLO per RFC 1651 4.2 */
2608 if (gothello)
2609 {
2610 usrerr("503 %s Duplicate HELO/EHLO",
2611 MyHostName);
2612 break;
2613 }
2614 #endif /* 0 */
2615
2616 /* check for valid domain name (re 1123 5.2.5) */
2617 if (*p == '\0' && !AllowBogusHELO)
2618 {
2619 usrerr("501 %s requires domain address",
2620 cmdbuf);
2621 break;
2622 }
2623
2624 /* check for long domain name (hides Received: info) */
2625 if (strlen(p) > MAXNAME) /* EAI:ok:EHLO name must be ASCII */
2626 {
2627 usrerr("501 Invalid domain name");
2628 if (LogLevel > 9)
2629 sm_syslog(LOG_INFO, CurEnv->e_id,
2630 "invalid domain name (too long) from %s",
2631 CurSmtpClient);
2632 break;
2633 }
2634
2635 ok = true;
2636 for (q = p; *q != '\0'; q++)
2637 {
2638 if (!isascii(*q))
2639 break;
2640 if (isalnum(*q))
2641 continue;
2642 if (isspace(*q))
2643 {
2644 *q = '\0';
2645
2646 /* only complain if strict check */
2647 ok = AllowBogusHELO;
2648
2649 /* allow trailing whitespace */
2650 while (!ok && *++q != '\0' &&
2651 isspace(*q))
2652 ;
2653 if (*q == '\0')
2654 ok = true;
2655 break;
2656 }
2657 if (strchr("[].-_#:", *q) == NULL)
2658 break;
2659 }
2660
2661 if (*q == '\0' && ok)
2662 {
2663 q = "pleased to meet you";
2664 sendinghost = sm_strdup_x(p);
2665 }
2666 else if (!AllowBogusHELO)
2667 {
2668 usrerr("501 Invalid domain name");
2669 if (LogLevel > 9)
2670 sm_syslog(LOG_INFO, CurEnv->e_id,
2671 "invalid domain name (%s) from %.100s",
2672 p, CurSmtpClient);
2673 break;
2674 }
2675 else
2676 {
2677 q = "accepting invalid domain name";
2678 }
2679
2680 if (gothello || smtp.sm_gotmail)
2681 CLEAR_STATE(cmdbuf);
2682
2683 #if MILTER
2684 if (smtp.sm_milterlist && smtp.sm_milterize &&
2685 !bitset(EF_DISCARD, e->e_flags))
2686 {
2687 char state;
2688 char *response;
2689
2690 response = milter_helo(p, e, &state);
2691 switch (state)
2692 {
2693 case SMFIR_REJECT:
2694 if (MilterLogLevel > 3)
2695 sm_syslog(LOG_INFO, e->e_id,
2696 "Milter: helo=%s, reject=Command rejected",
2697 p);
2698 nullserver = "Command rejected";
2699 smtp.sm_milterize = false;
2700 break;
2701
2702 case SMFIR_TEMPFAIL:
2703 if (MilterLogLevel > 3)
2704 sm_syslog(LOG_INFO, e->e_id,
2705 "Milter: helo=%s, reject=%s",
2706 p, MSG_TEMPFAIL);
2707 tempfail = true;
2708 smtp.sm_milterize = false;
2709 break;
2710
2711 case SMFIR_REPLYCODE:
2712 if (MilterLogLevel > 3)
2713 sm_syslog(LOG_INFO, e->e_id,
2714 "Milter: helo=%s, reject=%s",
2715 p, response);
2716 if (strncmp(response, "421 ", 4) != 0
2717 && strncmp(response, "421-", 4) != 0)
2718 {
2719 nullserver = newstr(response);
2720 smtp.sm_milterize = false;
2721 break;
2722 }
2723 /* FALLTHROUGH */
2724
2725 case SMFIR_SHUTDOWN:
2726 if (MilterLogLevel > 3 &&
2727 response == NULL)
2728 sm_syslog(LOG_INFO, e->e_id,
2729 "Milter: helo=%s, reject=421 4.7.0 %s closing connection",
2730 p, MyHostName);
2731 tempfail = true;
2732 smtp.sm_milterize = false;
2733 if (response != NULL)
2734 {
2735 /* Can't use ("%s", ...) due to usrerr() requirements */
2736 usrerr(response);
2737 }
2738 else
2739 {
2740 message("421 4.7.0 %s closing connection",
2741 MyHostName);
2742 }
2743 /* arrange to ignore send list */
2744 e->e_sendqueue = NULL;
2745 lognullconnection = false;
2746 goto doquit;
2747 }
2748 if (response != NULL)
2749 sm_free(response);
2750
2751 /*
2752 ** If quarantining by a connect/ehlo action,
2753 ** save between messages
2754 */
2755
2756 if (smtp.sm_quarmsg == NULL &&
2757 e->e_quarmsg != NULL)
2758 smtp.sm_quarmsg = newstr(e->e_quarmsg);
2759 }
2760 #endif /* MILTER */
2761 gothello = true;
2762
2763 /* print HELO response message */
2764 if (c->cmd_code != CMDEHLO)
2765 {
2766 message("250 %s Hello %s, %s",
2767 MyHostName, CurSmtpClient, q);
2768 break;
2769 }
2770
2771 message("250-%s Hello %s, %s",
2772 MyHostName, CurSmtpClient, q);
2773
2774 /* offer ENHSC even for nullserver */
2775 if (nullserver != NULL)
2776 {
2777 message("250 ENHANCEDSTATUSCODES");
2778 break;
2779 }
2780
2781 /*
2782 ** print EHLO features list
2783 **
2784 ** Note: If you change this list,
2785 ** remember to update 'helpfile'
2786 */
2787
2788 message("250-ENHANCEDSTATUSCODES");
2789 #if PIPELINING
2790 if (bitset(SRV_OFFER_PIPE, features))
2791 message("250-PIPELINING");
2792 #endif
2793 if (bitset(SRV_OFFER_EXPN, features))
2794 {
2795 message("250-EXPN");
2796 if (bitset(SRV_OFFER_VERB, features))
2797 message("250-VERB");
2798 }
2799 #if MIME8TO7
2800 message("250-8BITMIME");
2801 #endif
2802 if (MaxMessageSize > 0)
2803 message("250-SIZE %ld", MaxMessageSize);
2804 else
2805 message("250-SIZE");
2806 #if DSN
2807 if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features))
2808 message("250-DSN");
2809 #endif
2810 #if USE_EAI
2811 if (bitset(SRV_OFFER_EAI, features))
2812 message("250-SMTPUTF8");
2813 #endif
2814 if (bitset(SRV_OFFER_ETRN, features))
2815 message("250-ETRN");
2816 #if SASL
2817 if (sasl_ok && mechlist != NULL && *mechlist != '\0')
2818 message("250-AUTH %s", mechlist);
2819 #endif
2820 #if STARTTLS
2821 if (tls_ok_srv && bitset(SRV_OFFER_TLS, features))
2822 message("250-STARTTLS");
2823 #endif
2824 if (DeliverByMin > 0)
2825 message("250-DELIVERBY %ld",
2826 (long) DeliverByMin);
2827 else if (DeliverByMin == 0)
2828 message("250-DELIVERBY");
2829
2830 /* < 0: no deliver-by */
2831
2832 message("250 HELP");
2833 break;
2834
2835 case CMDMAIL: /* mail -- designate sender */
2836 SmtpPhase = "server MAIL";
2837 DELAY_CONN("MAIL");
2838
2839 /* check for validity of this command */
2840 if (!gothello && bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
2841 {
2842 usrerr("503 5.0.0 Polite people say HELO first");
2843 break;
2844 }
2845 if (smtp.sm_gotmail)
2846 {
2847 usrerr("503 5.5.0 Sender already specified");
2848 break;
2849 }
2850 #if SASL
2851 if (bitset(SRV_REQ_AUTH, features) &&
2852 authenticating != SASL_IS_AUTH)
2853 {
2854 usrerr("530 5.7.0 Authentication required");
2855 break;
2856 }
2857 #endif /* SASL */
2858
2859 p = skipword(p, "from");
2860 if (p == NULL)
2861 break;
2862 maps_reset_chged("server:MAIL");
2863 if (tempfail)
2864 {
2865 if (LogLevel > 9)
2866 sm_syslog(LOG_INFO, e->e_id,
2867 "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
2868 p, CurSmtpClient);
2869 /* Can't use ("%s", ...) due to usrerr() requirements */
2870 usrerr(MSG_TEMPFAIL);
2871 break;
2872 }
2873
2874 /* make sure we know who the sending host is */
2875 if (sendinghost == NULL)
2876 sendinghost = peerhostname;
2877
2878
2879 #if SM_HEAP_CHECK
2880 if (sm_debug_active(&DebugLeakSmtp, 1))
2881 {
2882 sm_heap_newgroup();
2883 sm_dprintf("smtp() heap group #%d\n",
2884 sm_heap_group());
2885 }
2886 #endif /* SM_HEAP_CHECK */
2887
2888 if (Errors > 0)
2889 goto undo_no_pm;
2890 if (!gothello)
2891 {
2892 auth_warning(e, "%s didn't use HELO protocol",
2893 CurSmtpClient);
2894 }
2895 #ifdef PICKY_HELO_CHECK
2896 if (sm_strcasecmp(sendinghost, peerhostname) != 0 &&
2897 (sm_strcasecmp(peerhostname, "localhost") != 0 ||
2898 sm_strcasecmp(sendinghost, MyHostName) != 0))
2899 {
2900 auth_warning(e, "Host %s claimed to be %s",
2901 CurSmtpClient, sendinghost);
2902 }
2903 #endif /* PICKY_HELO_CHECK */
2904
2905 if (protocol == NULL)
2906 protocol = "SMTP";
2907 macdefine(&e->e_macro, A_PERM, 'r', protocol);
2908 macdefine(&e->e_macro, A_PERM, 's', sendinghost);
2909
2910 if (Errors > 0)
2911 goto undo_no_pm;
2912 smtp.sm_nrcpts = 0;
2913 n_badrcpts = 0;
2914 macdefine(&e->e_macro, A_PERM, macid("{ntries}"), "0");
2915 macdefine(&e->e_macro, A_PERM, macid("{nrcpts}"), "0");
2916 macdefine(&e->e_macro, A_PERM, macid("{nbadrcpts}"),
2917 "0");
2918 e->e_flags |= EF_CLRQUEUE;
2919 sm_setproctitle(true, e, "%s %s: %.80s",
2920 qid_printname(e),
2921 CurSmtpClient, inp);
2922
2923 /* do the processing */
2924 SM_TRY
2925 {
2926 extern char *FullName;
2927 #if _FFR_8BITENVADDR
2928 char *origp;
2929 char iaddr[MAXLINE * 2];
2930 int len;
2931 #else
2932 # define origp p
2933 #endif
2934
2935 QuickAbort = true;
2936 SM_FREE(FullName);
2937 #if _FFR_8BITENVADDR
2938 len = sizeof(iaddr);
2939 origp = p;
2940
2941 /* HACK!!!! p is more than the address! */
2942 p = quote_internal_chars(p, iaddr, &len, NULL);
2943 #endif
2944
2945 /* must parse sender first */
2946 delimptr = NULL;
2947 setsender(p, e, &delimptr, ' ', false);
2948 if (delimptr != NULL && *delimptr != '\0')
2949 {
2950 *delimptr++ = '\0';
2951 #if _FFR_8BITENVADDR
2952 len = sizeof(iaddr) - (delimptr - iaddr);
2953 (void) dequote_internal_chars(delimptr, delimptr, len);
2954 sep_args(delimptr, origp, e->e_id, p);
2955 #endif
2956 }
2957 if (Errors > 0)
2958 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2959
2960 /* Successfully set e_from, allow logging */
2961 e->e_flags |= EF_LOGSENDER;
2962
2963 /* put resulting triple from parseaddr() into macros */
2964 if (e->e_from.q_mailer != NULL)
2965 macdefine(&e->e_macro, A_PERM,
2966 macid("{mail_mailer}"),
2967 e->e_from.q_mailer->m_name);
2968 else
2969 macdefine(&e->e_macro, A_PERM,
2970 macid("{mail_mailer}"), NULL);
2971 if (e->e_from.q_host != NULL)
2972 macdefine(&e->e_macro, A_PERM,
2973 macid("{mail_host}"),
2974 e->e_from.q_host);
2975 else
2976 macdefine(&e->e_macro, A_PERM,
2977 macid("{mail_host}"), "localhost");
2978 if (e->e_from.q_user != NULL)
2979 macdefine(&e->e_macro, A_PERM,
2980 macid("{mail_addr}"),
2981 e->e_from.q_user);
2982 else
2983 macdefine(&e->e_macro, A_PERM,
2984 macid("{mail_addr}"), NULL);
2985 if (Errors > 0)
2986 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2987
2988 /* check for possible spoofing */
2989 if (RealUid != 0 && OpMode == MD_SMTP &&
2990 !wordinclass(RealUserName, 't') &&
2991 (!bitnset(M_LOCALMAILER,
2992 e->e_from.q_mailer->m_flags) ||
2993 strcmp(e->e_from.q_user, RealUserName) != 0))
2994 {
2995 auth_warning(e, "%s owned process doing -bs",
2996 RealUserName);
2997 }
2998
2999 /* reset to default value */
3000 e->e_flags &= ~EF_7BITBODY;
3001
3002 /* now parse ESMTP arguments */
3003 e->e_msgsize = 0;
3004 addr = p;
3005 parse_esmtp_args(e, NULL, origp, delimptr, "MAIL", args,
3006 mail_esmtp_args);
3007 if (Errors > 0)
3008 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3009
3010 #if USE_EAI
3011 if (e->e_smtputf8)
3012 {
3013 protocol = GET_PROTOCOL();
3014 macdefine(&e->e_macro, A_PERM, 'r', protocol);
3015 }
3016
3017 /* UTF8 addresses are only legal with SMTPUTF8 */
3018 /* XXX different error if SMTPUTF8 is not enabled? */
3019 CHECK_UTF8_ADDR(e->e_from.q_paddr, q);
3020 if (q != NULL)
3021 {
3022 usrerr(q);
3023 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3024 }
3025 #endif
3026
3027 #if SASL
3028 # if _FFR_AUTH_PASSING
3029 /* set the default AUTH= if the sender didn't */
3030 if (e->e_auth_param == NULL)
3031 {
3032 /* XXX only do this for an MSA? */
3033 e->e_auth_param = macvalue(macid("{auth_authen}"),
3034 e);
3035 if (e->e_auth_param == NULL)
3036 e->e_auth_param = "<>";
3037
3038 /*
3039 ** XXX should we invoke Strust_auth now?
3040 ** authorizing as the client that just
3041 ** authenticated, so we'll trust implicitly
3042 */
3043 }
3044 # endif /* _FFR_AUTH_PASSING */
3045 #endif /* SASL */
3046
3047 /* do config file checking of the sender */
3048 macdefine(&e->e_macro, A_PERM,
3049 macid("{addr_type}"), "e s");
3050 #if _FFR_MAIL_MACRO
3051 /* make the "real" sender address available */
3052 macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"),
3053 e->e_from.q_paddr);
3054 #endif
3055 if (rscheck("check_mail", addr,
3056 NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
3057 NULL, e->e_id, NULL, NULL) != EX_OK ||
3058 Errors > 0)
3059 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3060 macdefine(&e->e_macro, A_PERM,
3061 macid("{addr_type}"), NULL);
3062
3063 if (MaxMessageSize > 0 &&
3064 (e->e_msgsize > MaxMessageSize ||
3065 e->e_msgsize < 0))
3066 {
3067 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
3068 MaxMessageSize);
3069 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3070 }
3071
3072 /*
3073 ** XXX always check whether there is at least one fs
3074 ** with enough space?
3075 ** However, this may not help much: the queue group
3076 ** selection may later on select a FS that hasn't
3077 ** enough space.
3078 */
3079
3080 if ((NumFileSys == 1 || NumQueue == 1) &&
3081 !enoughdiskspace(e->e_msgsize, e)
3082 #if _FFR_ANY_FREE_FS
3083 && !filesys_free(e->e_msgsize)
3084 #endif
3085 )
3086 {
3087 /*
3088 ** We perform this test again when the
3089 ** queue directory is selected, in collect.
3090 */
3091
3092 usrerr("452 4.4.5 Insufficient disk space; try again later");
3093 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3094 }
3095 if (Errors > 0)
3096 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3097
3098 LogUsrErrs = true;
3099 #if MILTER
3100 if (smtp.sm_milterlist && smtp.sm_milterize &&
3101 !bitset(EF_DISCARD, e->e_flags))
3102 {
3103 char state;
3104 char *response;
3105
3106 response = milter_envfrom(args, e, &state);
3107 MILTER_REPLY("from");
3108 }
3109 #endif /* MILTER */
3110 if (Errors > 0)
3111 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3112
3113 message("250 2.1.0 Sender ok");
3114 smtp.sm_gotmail = true;
3115 }
3116 SM_EXCEPT(exc, "[!F]*")
3117 {
3118 /*
3119 ** An error occurred while processing a MAIL command.
3120 ** Jump to the common error handling code.
3121 */
3122
3123 sm_exc_free(exc);
3124 goto undo_no_pm;
3125 }
3126 SM_END_TRY
3127 break;
3128
3129 undo_no_pm:
3130 e->e_flags &= ~EF_PM_NOTIFY;
3131 undo:
3132 break;
3133
3134 case CMDRCPT: /* rcpt -- designate recipient */
3135 DELAY_CONN("RCPT");
3136 macdefine(&e->e_macro, A_PERM,
3137 macid("{rcpt_mailer}"), NULL);
3138 macdefine(&e->e_macro, A_PERM,
3139 macid("{rcpt_host}"), NULL);
3140 macdefine(&e->e_macro, A_PERM,
3141 macid("{rcpt_addr}"), NULL);
3142 #if MILTER
3143 (void) memset(&addr_st, '\0', sizeof(addr_st));
3144 a = NULL;
3145 milter_rcpt_added = false;
3146 smtp.sm_e_nrcpts_orig = e->e_nrcpts;
3147 #endif
3148 #if _FFR_BADRCPT_SHUTDOWN
3149 /*
3150 ** hack to deal with hack, see below:
3151 ** n_badrcpts is increased if limit is reached.
3152 */
3153
3154 n_badrcpts_adj = (BadRcptThrottle > 0 &&
3155 n_badrcpts > BadRcptThrottle &&
3156 LogLevel > 5)
3157 ? n_badrcpts - 1 : n_badrcpts;
3158 if (BadRcptShutdown > 0 &&
3159 n_badrcpts_adj >= BadRcptShutdown &&
3160 (BadRcptShutdownGood == 0 ||
3161 smtp.sm_nrcpts == 0 ||
3162 (n_badrcpts_adj * 100 /
3163 (smtp.sm_nrcpts + n_badrcpts) >=
3164 BadRcptShutdownGood)))
3165 {
3166 if (LogLevel > 5)
3167 sm_syslog(LOG_INFO, e->e_id,
3168 "%s: Possible SMTP RCPT flood, shutting down connection.",
3169 CurSmtpClient);
3170 message("421 4.7.0 %s Too many bad recipients; closing connection",
3171 MyHostName);
3172
3173 /* arrange to ignore any current send list */
3174 e->e_sendqueue = NULL;
3175 goto doquit;
3176 }
3177 #endif /* _FFR_BADRCPT_SHUTDOWN */
3178 if (BadRcptThrottle > 0 &&
3179 n_badrcpts >= BadRcptThrottle)
3180 {
3181 if (LogLevel > 5 &&
3182 n_badrcpts == BadRcptThrottle)
3183 {
3184 sm_syslog(LOG_INFO, e->e_id,
3185 "%s: Possible SMTP RCPT flood, throttling.",
3186 CurSmtpClient);
3187
3188 /* To avoid duplicated message */
3189 n_badrcpts++;
3190 }
3191 NBADRCPTS;
3192
3193 /*
3194 ** Don't use exponential backoff for now.
3195 ** Some systems will open more connections
3196 ** and actually overload the receiver even
3197 ** more.
3198 */
3199
3200 (void) sleep(BadRcptThrottleDelay);
3201 }
3202 if (!smtp.sm_gotmail)
3203 {
3204 usrerr("503 5.0.0 Need MAIL before RCPT");
3205 break;
3206 }
3207 SmtpPhase = "server RCPT";
3208 SM_TRY
3209 {
3210 #if _FFR_8BITENVADDR
3211 char iaddr[MAXLINE * 2];
3212 int len;
3213 char *origp;
3214 #endif
3215
3216 QuickAbort = true;
3217 LogUsrErrs = true;
3218
3219 /* limit flooding of our machine */
3220 if (MaxRcptPerMsg > 0 &&
3221 smtp.sm_nrcpts >= MaxRcptPerMsg)
3222 {
3223 /* sleep(1); / * slow down? */
3224 usrerr("452 4.5.3 Too many recipients");
3225 goto rcpt_done;
3226 }
3227
3228 if (!SM_IS_INTERACTIVE(e->e_sendmode)
3229 #if _FFR_DM_ONE
3230 && (NotFirstDelivery || SM_DM_ONE != e->e_sendmode)
3231 #endif
3232 )
3233 e->e_flags |= EF_VRFYONLY;
3234
3235 #if MILTER
3236 /*
3237 ** Do not expand recipients at RCPT time (in the call
3238 ** to recipient()) if a milter can delete or reject
3239 ** a RCPT. If they are expanded, it is impossible
3240 ** for removefromlist() to figure out the expanded
3241 ** members of the original recipient and mark them
3242 ** as QS_DONTSEND.
3243 */
3244
3245 if (smtp.sm_milterlist && smtp.sm_milterize &&
3246 !bitset(EF_DISCARD, e->e_flags) &&
3247 (smtp.sm_milters.mis_flags &
3248 (MIS_FL_DEL_RCPT|MIS_FL_REJ_RCPT)) != 0)
3249 e->e_flags |= EF_VRFYONLY;
3250 milter_cmd_done = false;
3251 milter_cmd_safe = false;
3252 #endif /* MILTER */
3253
3254 p = skipword(p, "to");
3255 if (p == NULL)
3256 goto rcpt_done;
3257 macdefine(&e->e_macro, A_PERM,
3258 macid("{addr_type}"), "e r");
3259 #if _FFR_8BITENVADDR
3260 len = sizeof(iaddr);
3261 origp = p;
3262
3263 /* HACK!!!! p is more than the address! */
3264 p = quote_internal_chars(p, iaddr, &len, NULL);
3265 #endif
3266 a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr,
3267 e, true);
3268 macdefine(&e->e_macro, A_PERM,
3269 macid("{addr_type}"), NULL);
3270 if (Errors > 0)
3271 goto rcpt_done;
3272 if (a == NULL)
3273 {
3274 usrerr("501 5.0.0 Missing recipient");
3275 goto rcpt_done;
3276 }
3277 #if USE_EAI
3278 CHECK_UTF8_ADDR(a->q_paddr, q);
3279 if (q != NULL)
3280 {
3281 usrerr(q);
3282 goto rcpt_done;
3283 }
3284 #endif
3285
3286 if (delimptr != NULL && *delimptr != '\0')
3287 {
3288 *delimptr++ = '\0';
3289 #if _FFR_8BITENVADDR
3290 len = sizeof(iaddr) - (delimptr - iaddr);
3291 (void) dequote_internal_chars(delimptr, delimptr, len);
3292 sep_args(delimptr, origp, e->e_id, p);
3293 #endif
3294 }
3295
3296 /* put resulting triple from parseaddr() into macros */
3297 if (a->q_mailer != NULL)
3298 macdefine(&e->e_macro, A_PERM,
3299 macid("{rcpt_mailer}"),
3300 a->q_mailer->m_name);
3301 else
3302 macdefine(&e->e_macro, A_PERM,
3303 macid("{rcpt_mailer}"), NULL);
3304 if (a->q_host != NULL)
3305 macdefine(&e->e_macro, A_PERM,
3306 macid("{rcpt_host}"), a->q_host);
3307 else
3308 macdefine(&e->e_macro, A_PERM,
3309 macid("{rcpt_host}"), "localhost");
3310 if (a->q_user != NULL)
3311 macdefine(&e->e_macro, A_PERM,
3312 macid("{rcpt_addr}"), a->q_user);
3313 else
3314 macdefine(&e->e_macro, A_PERM,
3315 macid("{rcpt_addr}"), NULL);
3316 if (Errors > 0)
3317 goto rcpt_done;
3318
3319 /* now parse ESMTP arguments */
3320 addr = sm_rpool_strdup_x(e->e_rpool, p);
3321 parse_esmtp_args(e, a, origp, delimptr, "RCPT", args,
3322 rcpt_esmtp_args);
3323 if (Errors > 0)
3324 goto rcpt_done;
3325
3326 #if MILTER
3327 /*
3328 ** rscheck() can trigger an "exception"
3329 ** in which case the execution continues at
3330 ** SM_EXCEPT(exc, "[!F]*")
3331 ** This means milter_cmd_safe is not set
3332 ** and hence milter is not invoked.
3333 ** Would it be "safe" to change that, i.e., use
3334 ** milter_cmd_safe = true;
3335 ** here so a milter is informed (if requested)
3336 ** about RCPTs that are rejected by check_rcpt?
3337 */
3338 # if _FFR_MILTER_CHECK_REJECTIONS_TOO
3339 milter_cmd_safe = true;
3340 # endif
3341 #endif
3342
3343 /* do config file checking of the recipient */
3344 macdefine(&e->e_macro, A_PERM,
3345 macid("{addr_type}"), "e r");
3346 if (rscheck("check_rcpt", addr,
3347 NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
3348 NULL, e->e_id, p_addr_st, NULL) != EX_OK ||
3349 Errors > 0)
3350 goto rcpt_done;
3351 macdefine(&e->e_macro, A_PERM,
3352 macid("{addr_type}"), NULL);
3353
3354 /* If discarding, don't bother to verify user */
3355 if (bitset(EF_DISCARD, e->e_flags))
3356 a->q_state = QS_VERIFIED;
3357 #if MILTER
3358 milter_cmd_safe = true;
3359 #endif
3360
3361 addbcc(a, e);
3362 rcptmods(a, e);
3363
3364 /* save in recipient list after ESMTP mods */
3365 a = recipient(a, &e->e_sendqueue, 0, e);
3366 /* may trigger exception... */
3367
3368 #if MILTER
3369 milter_rcpt_added = true;
3370 #endif
3371
3372 if(!(Errors > 0) && QS_IS_BADADDR(a->q_state))
3373 {
3374 /* punt -- should keep message in ADDRESS.... */
3375 usrerr("550 5.1.1 Addressee unknown");
3376 }
3377
3378 #if MILTER
3379 rcpt_done:
3380 if (smtp.sm_milterlist && smtp.sm_milterize &&
3381 !bitset(EF_DISCARD, e->e_flags))
3382 {
3383 char state;
3384 char *response;
3385
3386 /* how to get the error codes? */
3387 if (Errors > 0)
3388 {
3389 macdefine(&e->e_macro, A_PERM,
3390 macid("{rcpt_mailer}"),
3391 "error");
3392 if (a != NULL &&
3393 a->q_status != NULL &&
3394 a->q_rstatus != NULL)
3395 {
3396 macdefine(&e->e_macro, A_PERM,
3397 macid("{rcpt_host}"),
3398 a->q_status);
3399 macdefine(&e->e_macro, A_PERM,
3400 macid("{rcpt_addr}"),
3401 a->q_rstatus);
3402 }
3403 else
3404 {
3405 if (addr_st.q_host != NULL)
3406 macdefine(&e->e_macro,
3407 A_PERM,
3408 macid("{rcpt_host}"),
3409 addr_st.q_host);
3410 if (addr_st.q_user != NULL)
3411 macdefine(&e->e_macro,
3412 A_PERM,
3413 macid("{rcpt_addr}"),
3414 addr_st.q_user);
3415 }
3416 }
3417
3418 response = milter_envrcpt(args, e, &state,
3419 Errors > 0);
3420 milter_cmd_done = true;
3421 MILTER_REPLY("to");
3422 }
3423 #endif /* MILTER */
3424
3425 /* no errors during parsing, but might be a duplicate */
3426 e->e_to = a->q_paddr;
3427 if (!(Errors > 0) && !QS_IS_BADADDR(a->q_state))
3428 {
3429 if (smtp.sm_nrcpts == 0)
3430 initsys(e);
3431 message("250 2.1.5 Recipient ok%s",
3432 QS_IS_QUEUEUP(a->q_state) ?
3433 " (will queue)" : "");
3434 smtp.sm_nrcpts++;
3435 }
3436
3437 /* Is this needed? */
3438 #if !MILTER
3439 rcpt_done:
3440 #endif
3441
3442 macdefine(&e->e_macro, A_PERM,
3443 macid("{rcpt_mailer}"), NULL);
3444 macdefine(&e->e_macro, A_PERM,
3445 macid("{rcpt_host}"), NULL);
3446 macdefine(&e->e_macro, A_PERM,
3447 macid("{rcpt_addr}"), NULL);
3448 macdefine(&e->e_macro, A_PERM,
3449 macid("{dsn_notify}"), NULL);
3450
3451 if (Errors > 0)
3452 {
3453 ++n_badrcpts;
3454 NBADRCPTS;
3455 }
3456 }
3457 SM_EXCEPT(exc, "[!F]*")
3458 {
3459 /* An exception occurred while processing RCPT */
3460 e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
3461 ++n_badrcpts;
3462 NBADRCPTS;
3463 #if MILTER
3464 if (smtp.sm_milterlist && smtp.sm_milterize &&
3465 !bitset(EF_DISCARD, e->e_flags) &&
3466 !milter_cmd_done && milter_cmd_safe)
3467 {
3468 char state;
3469 char *response;
3470
3471 macdefine(&e->e_macro, A_PERM,
3472 macid("{rcpt_mailer}"), "error");
3473
3474 /* how to get the error codes? */
3475 if (addr_st.q_host != NULL)
3476 macdefine(&e->e_macro, A_PERM,
3477 macid("{rcpt_host}"),
3478 addr_st.q_host);
3479 else if (a != NULL && a->q_status != NULL)
3480 macdefine(&e->e_macro, A_PERM,
3481 macid("{rcpt_host}"),
3482 a->q_status);
3483
3484 if (addr_st.q_user != NULL)
3485 macdefine(&e->e_macro, A_PERM,
3486 macid("{rcpt_addr}"),
3487 addr_st.q_user);
3488 else if (a != NULL && a->q_rstatus != NULL)
3489 macdefine(&e->e_macro, A_PERM,
3490 macid("{rcpt_addr}"),
3491 a->q_rstatus);
3492
3493 response = milter_envrcpt(args, e, &state,
3494 true);
3495 milter_cmd_done = true;
3496 MILTER_REPLY("to");
3497 macdefine(&e->e_macro, A_PERM,
3498 macid("{rcpt_mailer}"), NULL);
3499 macdefine(&e->e_macro, A_PERM,
3500 macid("{rcpt_host}"), NULL);
3501 macdefine(&e->e_macro, A_PERM,
3502 macid("{rcpt_addr}"), NULL);
3503 }
3504 if (smtp.sm_milterlist && smtp.sm_milterize &&
3505 milter_rcpt_added && milter_cmd_done &&
3506 milter_cmd_fail)
3507 {
3508 (void) removefromlist(addr, &e->e_sendqueue, e);
3509 milter_cmd_fail = false;
3510 if (smtp.sm_e_nrcpts_orig < e->e_nrcpts)
3511 e->e_nrcpts = smtp.sm_e_nrcpts_orig;
3512 }
3513 #endif /* MILTER */
3514 }
3515 SM_END_TRY
3516 break;
3517
3518 case CMDDATA: /* data -- text of mail */
3519 DELAY_CONN("DATA");
3520 if (!smtp_data(&smtp, e,
3521 bitset(SRV_BAD_PIPELINE, features)))
3522 goto doquit;
3523 break;
3524
3525 case CMDRSET: /* rset -- reset state */
3526 if (tTd(94, 100))
3527 message("451 4.0.0 Test failure");
3528 else
3529 message("250 2.0.0 Reset state");
3530 CLEAR_STATE(cmdbuf);
3531 break;
3532
3533 case CMDVRFY: /* vrfy -- verify address */
3534 case CMDEXPN: /* expn -- expand address */
3535 vrfy = c->cmd_code == CMDVRFY;
3536 DELAY_CONN(vrfy ? "VRFY" : "EXPN");
3537 if (tempfail)
3538 {
3539 if (LogLevel > 9)
3540 sm_syslog(LOG_INFO, e->e_id,
3541 "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)",
3542 vrfy ? "VRFY" : "EXPN",
3543 p, CurSmtpClient);
3544
3545 /* RFC 821 doesn't allow 4xy reply code */
3546 usrerr("550 5.7.1 Please try again later");
3547 break;
3548 }
3549 wt = checksmtpattack(&n_verifies, MAXVRFYCOMMANDS,
3550 false, vrfy ? "VRFY" : "EXPN", e);
3551 STOP_IF_ATTACK(wt);
3552 previous = curtime();
3553 if ((vrfy && bitset(PRIV_NOVRFY, PrivacyFlags)) ||
3554 (!vrfy && !bitset(SRV_OFFER_EXPN, features)))
3555 {
3556 if (vrfy)
3557 message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
3558 else
3559 message("502 5.7.0 Sorry, we do not allow this operation");
3560 if (LogLevel > 5)
3561 sm_syslog(LOG_INFO, e->e_id,
3562 "%s: %s [rejected]",
3563 CurSmtpClient,
3564 shortenstring(inp, MAXSHORTSTR));
3565 break;
3566 }
3567 else if (!gothello &&
3568 bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
3569 PrivacyFlags))
3570 {
3571 usrerr("503 5.0.0 I demand that you introduce yourself first");
3572 break;
3573 }
3574 if (Errors > 0)
3575 break;
3576 if (LogLevel > 5)
3577 sm_syslog(LOG_INFO, e->e_id, "%s: %s",
3578 CurSmtpClient,
3579 shortenstring(inp, MAXSHORTSTR));
3580 SM_TRY
3581 {
3582 QuickAbort = true;
3583 vrfyqueue = NULL;
3584 if (vrfy)
3585 e->e_flags |= EF_VRFYONLY;
3586 while (*p != '\0' && SM_ISSPACE(*p))
3587 p++;
3588 if (*p == '\0')
3589 {
3590 usrerr("501 5.5.2 Argument required");
3591 }
3592 else
3593 {
3594 /* do config file checking of the address */
3595 if (rscheck(vrfy ? "check_vrfy" : "check_expn",
3596 p, NULL, e, RSF_RMCOMM, 3, NULL,
3597 NOQID, NULL, NULL) != EX_OK ||
3598 Errors > 0)
3599 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3600 (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
3601 }
3602 if (wt > 0)
3603 {
3604 time_t t;
3605
3606 t = wt - (curtime() - previous);
3607 if (t > 0)
3608 (void) sleep(t);
3609 }
3610 if (Errors > 0)
3611 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3612 if (vrfyqueue == NULL)
3613 {
3614 usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN");
3615 }
3616 while (vrfyqueue != NULL)
3617 {
3618 if (!QS_IS_UNDELIVERED(vrfyqueue->q_state))
3619 {
3620 vrfyqueue = vrfyqueue->q_next;
3621 continue;
3622 }
3623
3624 /* see if there is more in the vrfy list */
3625 a = vrfyqueue;
3626 while ((a = a->q_next) != NULL &&
3627 (!QS_IS_UNDELIVERED(a->q_state)))
3628 continue;
3629 printvrfyaddr(vrfyqueue, a == NULL, vrfy);
3630 vrfyqueue = a;
3631 }
3632 }
3633 SM_EXCEPT(exc, "[!F]*")
3634 {
3635 /*
3636 ** An exception occurred while processing VRFY/EXPN
3637 */
3638
3639 sm_exc_free(exc);
3640 goto undo;
3641 }
3642 SM_END_TRY
3643 break;
3644
3645 case CMDETRN: /* etrn -- force queue flush */
3646 DELAY_CONN("ETRN");
3647
3648 /* Don't leak queue information via debug flags */
3649 if (!bitset(SRV_OFFER_ETRN, features) || UseMSP ||
3650 (RealUid != 0 && RealUid != TrustedUid &&
3651 OpMode == MD_SMTP))
3652 {
3653 /* different message for MSA ? */
3654 message("502 5.7.0 Sorry, we do not allow this operation");
3655 if (LogLevel > 5)
3656 sm_syslog(LOG_INFO, e->e_id,
3657 "%s: %s [rejected]",
3658 CurSmtpClient,
3659 shortenstring(inp, MAXSHORTSTR));
3660 break;
3661 }
3662 if (tempfail)
3663 {
3664 if (LogLevel > 9)
3665 sm_syslog(LOG_INFO, e->e_id,
3666 "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
3667 p, CurSmtpClient);
3668 /* Can't use ("%s", ...) due to usrerr() requirements */
3669 usrerr(MSG_TEMPFAIL);
3670 break;
3671 }
3672
3673 if (strlen(p) <= 0)
3674 {
3675 usrerr("500 5.5.2 Parameter required");
3676 break;
3677 }
3678
3679 /* crude way to avoid denial-of-service attacks */
3680 STOP_IF_ATTACK(checksmtpattack(&n_etrn, MAXETRNCOMMANDS,
3681 true, "ETRN", e));
3682
3683 /*
3684 ** Do config file checking of the parameter.
3685 ** Even though we have srv_features now, we still
3686 ** need this ruleset because the former is called
3687 ** when the connection has been established, while
3688 ** this ruleset is called when the command is
3689 ** actually issued and therefore has all information
3690 ** available to make a decision.
3691 */
3692
3693 if (rscheck("check_etrn", p, NULL, e, RSF_RMCOMM, 3,
3694 NULL, NOQID, NULL, NULL) != EX_OK ||
3695 Errors > 0)
3696 break;
3697
3698 if (LogLevel > 5)
3699 sm_syslog(LOG_INFO, e->e_id,
3700 "%s: ETRN %s", CurSmtpClient,
3701 shortenstring(p, MAXSHORTSTR));
3702
3703 id = p;
3704 if (*id == '#')
3705 {
3706 int i, qgrp;
3707
3708 id++;
3709 qgrp = name2qid(id);
3710 if (!ISVALIDQGRP(qgrp))
3711 {
3712 usrerr("459 4.5.4 Queue %s unknown",
3713 id);
3714 break;
3715 }
3716 for (i = 0; i < NumQueue && Queue[i] != NULL;
3717 i++)
3718 Queue[i]->qg_nextrun = (time_t) -1;
3719 Queue[qgrp]->qg_nextrun = 0;
3720 ok = run_work_group(Queue[qgrp]->qg_wgrp,
3721 RWG_FORK|RWG_FORCE);
3722 if (ok && Errors == 0)
3723 message("250 2.0.0 Queuing for queue group %s started", id);
3724 break;
3725 }
3726
3727 if (*id == '@')
3728 id++;
3729 else
3730 *--id = '@';
3731
3732 new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR));
3733 if (new == NULL)
3734 {
3735 syserr("500 5.5.0 ETRN out of memory");
3736 break;
3737 }
3738 new->queue_match = id;
3739 new->queue_negate = false;
3740 new->queue_next = NULL;
3741 QueueLimitRecipient = new;
3742 ok = runqueue(true, false, false, true);
3743 sm_free(QueueLimitRecipient); /* XXX */
3744 QueueLimitRecipient = NULL;
3745 if (ok && Errors == 0)
3746 message("250 2.0.0 Queuing for node %s started", p);
3747 break;
3748
3749 case CMDHELP: /* help -- give user info */
3750 DELAY_CONN("HELP");
3751 help(p, e);
3752 break;
3753
3754 #define CHECK_OTHER(type) do \
3755 { \
3756 bool saveQuickAbort = QuickAbort; \
3757 extern char MsgBuf[]; \
3758 int rsc; \
3759 QuickAbort = false; \
3760 if ((rsc = rscheck("check_other", inp, type, e, \
3761 RSF_UNSTRUCTURED, 3, NULL, NOQID, NULL, NULL)) \
3762 != EX_OK || \
3763 Errors > 0) \
3764 { \
3765 if (strncmp(MsgBuf, "421 ", 4) == 0) \
3766 { \
3767 e->e_sendqueue = NULL; \
3768 goto doquit; \
3769 } \
3770 } \
3771 QuickAbort = saveQuickAbort; \
3772 } while (0)
3773
3774 case CMDNOOP: /* noop -- do nothing */
3775 DELAY_CONN("NOOP");
3776 STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands,
3777 true, "NOOP", e));
3778 CHECK_OTHER("2");
3779 message("250 2.0.0 OK");
3780 break;
3781
3782 case CMDQUIT: /* quit -- leave mail */
3783 message("221 2.0.0 %s closing connection", MyHostName);
3784 #if PIPELINING
3785 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
3786 #endif
3787
3788 if (smtp.sm_nrcpts > 0)
3789 logundelrcpts(e, "aborted by sender", 9, false);
3790
3791 /* arrange to ignore any current send list */
3792 e->e_sendqueue = NULL;
3793
3794 #if STARTTLS
3795 /* shutdown TLS connection */
3796 if (tls_active)
3797 {
3798 (void) endtls(&srv_ssl, "server");
3799 tls_active = false;
3800 }
3801 #endif /* STARTTLS */
3802 #if SASL
3803 if (auth_active)
3804 {
3805 sasl_dispose(&conn);
3806 authenticating = SASL_NOT_AUTH;
3807 /* XXX sasl_done(); this is a child */
3808 }
3809 #endif /* SASL */
3810
3811 doquit:
3812 /* avoid future 050 messages */
3813 disconnect(1, e);
3814
3815 #if MILTER
3816 /* close out milter filters */
3817 milter_quit(e);
3818 #endif
3819
3820 if (tTd(92, 2))
3821 sm_dprintf("QUIT: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",
3822 e->e_id,
3823 bitset(EF_LOGSENDER, e->e_flags),
3824 LogLevel);
3825 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
3826 logsender(e, NULL);
3827 e->e_flags &= ~EF_LOGSENDER;
3828
3829 if (lognullconnection && LogLevel > 5 &&
3830 nullserver == NULL)
3831 {
3832 char *d;
3833
3834 d = macvalue(macid("{daemon_name}"), e);
3835 if (d == NULL)
3836 d = "stdin";
3837
3838 /*
3839 ** even though this id is "bogus", it makes
3840 ** it simpler to "grep" related events, e.g.,
3841 ** timeouts for the same connection.
3842 */
3843
3844 sm_syslog(LOG_INFO, e->e_id,
3845 "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
3846 CurSmtpClient, d);
3847 }
3848 if (tTd(93, 100))
3849 {
3850 /* return to handle next connection */
3851 #if SM_HEAP_CHECK
3852 # define SM_HC_TRIGGER "heapdump"
3853 if (sm_debug_active(&SmHeapCheck, 2)
3854 && access(SM_HC_TRIGGER, F_OK) == 0
3855 )
3856 {
3857 SM_FILE_T *out;
3858
3859 remove(SM_HC_TRIGGER);
3860 out = sm_io_open(SmFtStdio,
3861 SM_TIME_DEFAULT, SM_HC_TRIGGER ".heap",
3862 SM_IO_APPEND, NULL);
3863 if (out != NULL)
3864 {
3865 (void) sm_io_fprintf(out, SM_TIME_DEFAULT, "----------------------\n");
3866 sm_heap_report(out,
3867 sm_debug_level(&SmHeapCheck) - 1);
3868 (void) sm_io_close(out, SM_TIME_DEFAULT);
3869 }
3870 }
3871 #endif /* SM_HEAP_CHECK */
3872 return;
3873 }
3874 finis(true, true, ExitStat);
3875 /* NOTREACHED */
3876
3877 /* just to avoid bogus warning from some compilers */
3878 exit(EX_OSERR);
3879
3880 case CMDVERB: /* set verbose mode */
3881 DELAY_CONN("VERB");
3882 if (!bitset(SRV_OFFER_EXPN, features) ||
3883 !bitset(SRV_OFFER_VERB, features))
3884 {
3885 /* this would give out the same info */
3886 message("502 5.7.0 Verbose unavailable");
3887 break;
3888 }
3889 STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands,
3890 true, "VERB", e));
3891 CHECK_OTHER("2");
3892 Verbose = 1;
3893 set_delivery_mode(SM_DELIVER, e);
3894 message("250 2.0.0 Verbose mode");
3895 break;
3896
3897 #if SMTPDEBUG
3898 case CMDDBGQSHOW: /* show queues */
3899 CHECK_OTHER("2");
3900 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
3901 "Send Queue=");
3902 printaddr(smioout, e->e_sendqueue, true);
3903 break;
3904
3905 case CMDDBGDEBUG: /* set debug mode */
3906 CHECK_OTHER("2");
3907 tTsetup(tTdvect, sizeof(tTdvect), "0-99.1");
3908 tTflag(p);
3909 message("200 2.0.0 Debug set");
3910 break;
3911
3912 #else /* SMTPDEBUG */
3913 case CMDDBGQSHOW: /* show queues */
3914 case CMDDBGDEBUG: /* set debug mode */
3915 #endif /* SMTPDEBUG */
3916 case CMDLOGBOGUS: /* bogus command */
3917 DELAY_CONN("Bogus");
3918 if (LogLevel > 0)
3919 sm_syslog(LOG_CRIT, e->e_id,
3920 "\"%s\" command from %s (%.100s)",
3921 c->cmd_name, CurSmtpClient,
3922 anynet_ntoa(&RealHostAddr));
3923 /* FALLTHROUGH */
3924
3925 case CMDERROR: /* unknown command */
3926 #if MAXBADCOMMANDS > 0
3927 if (++n_badcmds > MAXBADCOMMANDS)
3928 {
3929 stopattack:
3930 message("421 4.7.0 %s Too many bad commands; closing connection",
3931 MyHostName);
3932
3933 /* arrange to ignore any current send list */
3934 e->e_sendqueue = NULL;
3935 goto doquit;
3936 }
3937 #endif /* MAXBADCOMMANDS > 0 */
3938
3939 #if MILTER && SMFI_VERSION > 2
3940 if (smtp.sm_milterlist && smtp.sm_milterize &&
3941 !bitset(EF_DISCARD, e->e_flags))
3942 {
3943 char state;
3944 char *response;
3945
3946 if (MilterLogLevel > 9)
3947 sm_syslog(LOG_INFO, e->e_id,
3948 "Sending \"%s\" to Milter", inp);
3949 response = milter_unknown(inp, e, &state);
3950 MILTER_REPLY("unknown");
3951 if (state == SMFIR_REPLYCODE ||
3952 state == SMFIR_REJECT ||
3953 state == SMFIR_TEMPFAIL ||
3954 state == SMFIR_SHUTDOWN)
3955 {
3956 /* MILTER_REPLY already gave an error */
3957 break;
3958 }
3959 }
3960 #endif /* MILTER && SMFI_VERSION > 2 */
3961
3962 CHECK_OTHER("5");
3963 usrerr("500 5.5.1 Command unrecognized: \"%s\"",
3964 SHOWSHRTCMDINREPLY(inp));
3965 break;
3966
3967 case CMDUNIMPL:
3968 DELAY_CONN("Unimpl");
3969 CHECK_OTHER("5");
3970 usrerr("502 5.5.1 Command not implemented: \"%s\"",
3971 SHOWSHRTCMDINREPLY(inp));
3972 break;
3973
3974 default:
3975 DELAY_CONN("default");
3976 CHECK_OTHER("5");
3977 errno = 0;
3978 syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
3979 break;
3980 }
3981 #if SASL
3982 }
3983 #endif
3984 }
3985 SM_EXCEPT(exc, "[!F]*")
3986 {
3987 /*
3988 ** The only possible exception is "E:mta.quickabort".
3989 ** There is nothing to do except fall through and loop.
3990 */
3991 }
3992 SM_END_TRY
3993 }
3994 }
3995 /*
3996 ** SMTP_DATA -- implement the SMTP DATA command.
3997 **
3998 ** Parameters:
3999 ** smtp -- status of SMTP connection.
4000 ** e -- envelope.
4001 ** check_stuffing -- check for transaction stuffing.
4002 **
4003 ** Returns:
4004 ** true iff SMTP session can continue.
4005 **
4006 ** Side Effects:
4007 ** possibly sends message.
4008 */
4009
4010 static bool
smtp_data(smtp,e,check_stuffing)4011 smtp_data(smtp, e, check_stuffing)
4012 SMTP_T *smtp;
4013 ENVELOPE *e;
4014 bool check_stuffing;
4015 {
4016 #if MILTER
4017 bool milteraccept;
4018 #endif
4019 bool aborting;
4020 bool doublequeue;
4021 bool rv = true;
4022 ADDRESS *a;
4023 ENVELOPE *ee;
4024 char *id;
4025 char *oldid;
4026 unsigned long features;
4027 char buf[32];
4028
4029 SmtpPhase = "server DATA";
4030 if (!smtp->sm_gotmail)
4031 {
4032 usrerr("503 5.0.0 Need MAIL command");
4033 return true;
4034 }
4035 else if (smtp->sm_nrcpts <= 0)
4036 {
4037 usrerr("503 5.0.0 Need RCPT (recipient)");
4038 return true;
4039 }
4040
4041 /* check if data is on the socket before the DATA reply */
4042 if (check_stuffing &&
4043 sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0)
4044 {
4045 sm_syslog(LOG_INFO, e->e_id,
4046 "rejecting %s from %s [%s] due to traffic before response",
4047 SmtpPhase, CurHostName, anynet_ntoa(&RealHostAddr));
4048 usrerr("554 5.5.0 SMTP protocol error");
4049 return false;
4050 }
4051
4052 (void) sm_snprintf(buf, sizeof(buf), "%u", smtp->sm_nrcpts);
4053 if (rscheck("check_data", buf, NULL, e,
4054 RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
4055 e->e_id, NULL, NULL) != EX_OK)
4056 return true;
4057
4058 #if MILTER && SMFI_VERSION > 3
4059 if (smtp->sm_milterlist && smtp->sm_milterize &&
4060 !bitset(EF_DISCARD, e->e_flags))
4061 {
4062 char state;
4063 char *response;
4064 int savelogusrerrs = LogUsrErrs;
4065
4066 response = milter_data_cmd(e, &state);
4067 switch (state)
4068 {
4069 case SMFIR_REPLYCODE:
4070 if (MilterLogLevel > 3)
4071 {
4072 sm_syslog(LOG_INFO, e->e_id,
4073 "Milter: cmd=data, reject=%s",
4074 response);
4075 LogUsrErrs = false;
4076 }
4077 # if _FFR_MILTER_ENHSC
4078 if (ISSMTPCODE(response))
4079 (void) extenhsc(response + 4, ' ', e->e_enhsc);
4080 # endif
4081
4082 /* Can't use ("%s", ...) due to usrerr() requirements */
4083 usrerr(response);
4084 if (strncmp(response, "421 ", 4) == 0
4085 || strncmp(response, "421-", 4) == 0)
4086 {
4087 e->e_sendqueue = NULL;
4088 return false;
4089 }
4090 return true;
4091
4092 case SMFIR_REJECT:
4093 if (MilterLogLevel > 3)
4094 {
4095 sm_syslog(LOG_INFO, e->e_id,
4096 "Milter: cmd=data, reject=550 5.7.1 Command rejected");
4097 LogUsrErrs = false;
4098 }
4099 # if _FFR_MILTER_ENHSC
4100 (void) sm_strlcpy(e->e_enhsc, "5.7.1",
4101 sizeof(e->e_enhsc));
4102 # endif
4103 usrerr("550 5.7.1 Command rejected");
4104 return true;
4105
4106 case SMFIR_DISCARD:
4107 if (MilterLogLevel > 3)
4108 sm_syslog(LOG_INFO, e->e_id,
4109 "Milter: cmd=data, discard");
4110 e->e_flags |= EF_DISCARD;
4111 break;
4112
4113 case SMFIR_TEMPFAIL:
4114 if (MilterLogLevel > 3)
4115 {
4116 sm_syslog(LOG_INFO, e->e_id,
4117 "Milter: cmd=data, reject=%s",
4118 MSG_TEMPFAIL);
4119 LogUsrErrs = false;
4120 }
4121 # if _FFR_MILTER_ENHSC
4122 (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc);
4123 # endif
4124 /* Can't use ("%s", ...) due to usrerr() requirements */
4125 usrerr(MSG_TEMPFAIL);
4126 return true;
4127
4128 case SMFIR_SHUTDOWN:
4129 if (MilterLogLevel > 3)
4130 {
4131 sm_syslog(LOG_INFO, e->e_id,
4132 "Milter: cmd=data, reject=421 4.7.0 %s closing connection",
4133 MyHostName);
4134 LogUsrErrs = false;
4135 }
4136 usrerr("421 4.7.0 %s closing connection", MyHostName);
4137 e->e_sendqueue = NULL;
4138 return false;
4139 }
4140 LogUsrErrs = savelogusrerrs;
4141 if (response != NULL)
4142 sm_free(response); /* XXX */
4143 }
4144 #endif /* MILTER && SMFI_VERSION > 3 */
4145
4146 /* put back discard bit */
4147 if (smtp->sm_discard)
4148 e->e_flags |= EF_DISCARD;
4149
4150 /* check to see if we need to re-expand aliases */
4151 /* also reset QS_BADADDR on already-diagnosted addrs */
4152 doublequeue = false;
4153 for (a = e->e_sendqueue; a != NULL; a = a->q_next)
4154 {
4155 if (QS_IS_VERIFIED(a->q_state) &&
4156 !bitset(EF_DISCARD, e->e_flags))
4157 {
4158 /* need to re-expand aliases */
4159 doublequeue = true;
4160 }
4161 if (QS_IS_BADADDR(a->q_state))
4162 {
4163 /* make this "go away" */
4164 a->q_state = QS_DONTSEND;
4165 }
4166 }
4167
4168 /* collect the text of the message */
4169 SmtpPhase = "collect";
4170 buffer_errors();
4171
4172 collect(InChannel, SMTPMODE_LAX
4173 | (bitset(SRV_BARE_LF_421, e->e_features) ? SMTPMODE_LF_421 : 0)
4174 | (bitset(SRV_BARE_CR_421, e->e_features) ? SMTPMODE_CR_421 : 0)
4175 | (bitset(SRV_BARE_LF_SP, e->e_features) ? SMTPMODE_LF_SP : 0)
4176 | (bitset(SRV_BARE_CR_SP, e->e_features) ? SMTPMODE_CR_SP : 0)
4177 | (bitset(SRV_REQ_CRLF, e->e_features) ? SMTPMODE_CRLF : 0),
4178 NULL, e, true);
4179
4180 /* redefine message size */
4181 (void) sm_snprintf(buf, sizeof(buf), "%ld", PRT_NONNEGL(e->e_msgsize));
4182 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
4183
4184 /* rscheck() will set Errors or EF_DISCARD if it trips */
4185 (void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
4186 3, NULL, e->e_id, NULL, NULL);
4187
4188 #if MILTER
4189 milteraccept = true;
4190 if (smtp->sm_milterlist && smtp->sm_milterize &&
4191 Errors <= 0 &&
4192 !bitset(EF_DISCARD, e->e_flags))
4193 {
4194 char state;
4195 char *response;
4196
4197 response = milter_data(e, &state);
4198 switch (state)
4199 {
4200 case SMFIR_REPLYCODE:
4201 if (MilterLogLevel > 3)
4202 sm_syslog(LOG_INFO, e->e_id,
4203 "Milter: data, reject=%s",
4204 response);
4205 milteraccept = false;
4206 # if _FFR_MILTER_ENHSC
4207 if (ISSMTPCODE(response))
4208 (void) extenhsc(response + 4, ' ', e->e_enhsc);
4209 # endif
4210 /* Can't use ("%s", ...) due to usrerr() requirements */
4211 usrerr(response);
4212 if (strncmp(response, "421 ", 4) == 0
4213 || strncmp(response, "421-", 4) == 0)
4214 rv = false;
4215 break;
4216
4217 case SMFIR_REJECT:
4218 milteraccept = false;
4219 if (MilterLogLevel > 3)
4220 sm_syslog(LOG_INFO, e->e_id,
4221 "Milter: data, reject=554 5.7.1 Command rejected");
4222 usrerr("554 5.7.1 Command rejected");
4223 break;
4224
4225 case SMFIR_DISCARD:
4226 if (MilterLogLevel > 3)
4227 sm_syslog(LOG_INFO, e->e_id,
4228 "Milter: data, discard");
4229 milteraccept = false;
4230 e->e_flags |= EF_DISCARD;
4231 break;
4232
4233 case SMFIR_TEMPFAIL:
4234 if (MilterLogLevel > 3)
4235 sm_syslog(LOG_INFO, e->e_id,
4236 "Milter: data, reject=%s",
4237 MSG_TEMPFAIL);
4238 milteraccept = false;
4239 # if _FFR_MILTER_ENHSC
4240 (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc);
4241 # endif
4242 /* Can't use ("%s", ...) due to usrerr() requirements */
4243 usrerr(MSG_TEMPFAIL);
4244 break;
4245
4246 case SMFIR_SHUTDOWN:
4247 if (MilterLogLevel > 3)
4248 sm_syslog(LOG_INFO, e->e_id,
4249 "Milter: data, reject=421 4.7.0 %s closing connection",
4250 MyHostName);
4251 milteraccept = false;
4252 usrerr("421 4.7.0 %s closing connection", MyHostName);
4253 rv = false;
4254 break;
4255 }
4256 if (response != NULL)
4257 sm_free(response);
4258 }
4259
4260 /* Milter may have changed message size */
4261 (void) sm_snprintf(buf, sizeof(buf), "%ld", PRT_NONNEGL(e->e_msgsize));
4262 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
4263
4264 /* abort message filters that didn't get the body & log msg is OK */
4265 if (smtp->sm_milterlist && smtp->sm_milterize)
4266 {
4267 milter_abort(e);
4268 if (milteraccept && MilterLogLevel > 9)
4269 sm_syslog(LOG_INFO, e->e_id, "Milter accept: message");
4270 }
4271
4272 /*
4273 ** If SuperSafe is SAFE_REALLY_POSTMILTER, and we don't have milter or
4274 ** milter accepted message, sync it now
4275 **
4276 ** XXX This is almost a copy of the code in collect(): put it into
4277 ** a function that is called from both places?
4278 */
4279
4280 if (milteraccept && SuperSafe == SAFE_REALLY_POSTMILTER)
4281 {
4282 int afd;
4283 SM_FILE_T *volatile df;
4284 char *dfname;
4285
4286 df = e->e_dfp;
4287 dfname = queuename(e, DATAFL_LETTER);
4288 if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0
4289 && errno != EINVAL)
4290 {
4291 int save_errno;
4292
4293 save_errno = errno;
4294 if (save_errno == EEXIST)
4295 {
4296 struct stat st;
4297 int dfd;
4298
4299 if (stat(dfname, &st) < 0)
4300 st.st_size = -1;
4301 errno = EEXIST;
4302 syserr("@collect: bfcommit(%s): already on disk, size=%ld",
4303 dfname, (long) st.st_size);
4304 dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL);
4305 if (dfd >= 0)
4306 dumpfd(dfd, true, true);
4307 }
4308 errno = save_errno;
4309 dferror(df, "bfcommit", e);
4310 flush_errors(true);
4311 finis(save_errno != EEXIST, true, ExitStat);
4312 }
4313 else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0)
4314 {
4315 dferror(df, "sm_io_getinfo", e);
4316 flush_errors(true);
4317 finis(true, true, ExitStat);
4318 /* NOTREACHED */
4319 }
4320 else if (fsync(afd) < 0)
4321 {
4322 dferror(df, "fsync", e);
4323 flush_errors(true);
4324 finis(true, true, ExitStat);
4325 /* NOTREACHED */
4326 }
4327 else if (sm_io_close(df, SM_TIME_DEFAULT) < 0)
4328 {
4329 dferror(df, "sm_io_close", e);
4330 flush_errors(true);
4331 finis(true, true, ExitStat);
4332 /* NOTREACHED */
4333 }
4334
4335 /* Now reopen the df file */
4336 e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
4337 SM_IO_RDONLY, NULL);
4338 if (e->e_dfp == NULL)
4339 {
4340 /* we haven't acked receipt yet, so just chuck this */
4341 syserr("@Cannot reopen %s", dfname);
4342 finis(true, true, ExitStat);
4343 /* NOTREACHED */
4344 }
4345 }
4346 #endif /* MILTER */
4347
4348 /* Check if quarantining stats should be updated */
4349 if (e->e_quarmsg != NULL)
4350 markstats(e, NULL, STATS_QUARANTINE);
4351
4352 /*
4353 ** If a header/body check (header checks or milter)
4354 ** set EF_DISCARD, don't queueup the message --
4355 ** that would lose the EF_DISCARD bit and deliver
4356 ** the message.
4357 */
4358
4359 if (bitset(EF_DISCARD, e->e_flags))
4360 doublequeue = false;
4361
4362 aborting = Errors > 0;
4363 if (!(aborting || bitset(EF_DISCARD, e->e_flags)) &&
4364 (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) &&
4365 !split_by_recipient(e))
4366 aborting = bitset(EF_FATALERRS, e->e_flags);
4367
4368 if (aborting)
4369 {
4370 ADDRESS *q;
4371
4372 /* Log who the mail would have gone to */
4373 logundelrcpts(e, e->e_message, 8, false);
4374
4375 /*
4376 ** If something above refused the message, we still haven't
4377 ** accepted responsibility for it. Don't send DSNs.
4378 */
4379
4380 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
4381 q->q_flags &= ~Q_PINGFLAGS;
4382
4383 flush_errors(true);
4384 buffer_errors();
4385 goto abortmessage;
4386 }
4387
4388 /* from now on, we have to operate silently */
4389 buffer_errors();
4390
4391 #if 0
4392 /*
4393 ** Clear message, it may contain an error from the SMTP dialogue.
4394 ** This error must not show up in the queue.
4395 ** Some error message should show up, e.g., alias database
4396 ** not available, but others shouldn't, e.g., from check_rcpt.
4397 */
4398
4399 e->e_message = NULL;
4400 #endif /* 0 */
4401
4402 /*
4403 ** Arrange to send to everyone.
4404 ** If sending to multiple people, mail back
4405 ** errors rather than reporting directly.
4406 ** In any case, don't mail back errors for
4407 ** anything that has happened up to
4408 ** now (the other end will do this).
4409 ** Truncate our transcript -- the mail has gotten
4410 ** to us successfully, and if we have
4411 ** to mail this back, it will be easier
4412 ** on the reader.
4413 ** Then send to everyone.
4414 ** Finally give a reply code. If an error has
4415 ** already been given, don't mail a
4416 ** message back.
4417 ** We goose error returns by clearing error bit.
4418 */
4419
4420 SmtpPhase = "delivery";
4421 (void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL);
4422 id = e->e_id;
4423
4424 #if NAMED_BIND
4425 _res.retry = TimeOuts.res_retry[RES_TO_FIRST];
4426 _res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
4427 #endif
4428
4429 #if _FFR_PROXY
4430 if (SM_PROXY_REQ == e->e_sendmode)
4431 {
4432 /* is proxy mode possible? */
4433 if (e->e_sibling == NULL && e->e_nrcpts == 1
4434 && smtp->sm_nrcpts == 1
4435 && (a = e->e_sendqueue) != NULL && a->q_next == NULL)
4436 {
4437 a->q_flags &= ~(QPINGONFAILURE|QPINGONSUCCESS|
4438 QPINGONDELAY);
4439 e->e_errormode = EM_QUIET;
4440 e->e_sendmode = SM_PROXY;
4441 }
4442 else
4443 {
4444 if (tTd(87, 2))
4445 {
4446 a = e->e_sendqueue;
4447 sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, sm_nrcpts=%d, sendqueue=%p, next=%p\n",
4448 e->e_sendmode, e, e->e_sibling, e->e_nrcpts,
4449 smtp->sm_nrcpts, a,
4450 (a == NULL) ? (void *)0 : a->q_next);
4451 }
4452
4453 /* switch to interactive mode */
4454 e->e_sendmode = SM_DELIVER;
4455 if (LogLevel > 9)
4456 sm_syslog(LOG_DEBUG, e->e_id,
4457 "proxy mode requested but not possible");
4458 }
4459 }
4460 #endif /* _FFR_PROXY */
4461
4462 #if _FFR_DMTRIGGER
4463 if (SM_TRIGGER == e->e_sendmode)
4464 doublequeue = true;
4465 #endif
4466 for (ee = e; ee != NULL; ee = ee->e_sibling)
4467 {
4468 /* make sure we actually do delivery */
4469 ee->e_flags &= ~EF_CLRQUEUE;
4470
4471 /* from now on, operate silently */
4472 ee->e_errormode = EM_MAIL;
4473
4474 if (doublequeue)
4475 {
4476 unsigned int qup_flags;
4477
4478 qup_flags = QUP_FL_MSYNC;
4479 #if _FFR_DMTRIGGER
4480 if (IS_SM_TRIGGER(ee->e_sendmode))
4481 qup_flags |= QUP_FL_UNLOCK;
4482 #endif
4483 /* make sure it is in the queue */
4484 queueup(ee, qup_flags);
4485 }
4486 else
4487 {
4488 int mode;
4489
4490 /* send to all recipients */
4491 mode = SM_DEFAULT;
4492 #if _FFR_DM_ONE
4493 if (SM_DM_ONE == e->e_sendmode)
4494 {
4495 if (NotFirstDelivery)
4496 {
4497 mode = SM_QUEUE;
4498 e->e_sendmode = SM_QUEUE;
4499 }
4500 else
4501 {
4502 mode = SM_FORK;
4503 NotFirstDelivery = true;
4504 }
4505 }
4506 #endif /* _FFR_DM_ONE */
4507 sendall(ee, mode);
4508 }
4509 ee->e_to = NULL;
4510 }
4511
4512 /* put back id for SMTP logging in putoutmsg() */
4513 oldid = CurEnv->e_id;
4514 CurEnv->e_id = id;
4515
4516 #if _FFR_PROXY
4517 a = e->e_sendqueue;
4518 if (tTd(87, 1))
4519 {
4520 sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, msg=%s, sendqueue=%p, next=%p, state=%d, SmtpError=%s, rcode=%d, renhsc=%s, text=%s\n",
4521 e->e_sendmode, e, e->e_sibling, e->e_nrcpts, e->e_message, a,
4522 (a == NULL) ? (void *)0 : a->q_next,
4523 (a == NULL) ? -1 : a->q_state, SmtpError, e->e_rcode,
4524 e->e_renhsc, e->e_text);
4525 }
4526
4527 if (SM_PROXY == e->e_sendmode && a->q_state != QS_SENT &&
4528 a->q_state != QS_VERIFIED) /* discarded! */
4529 {
4530 char *m, *errtext;
4531 char replycode[4];
4532 char enhsc[10];
4533 int offset;
4534
4535 #define NN_MSG(e) (((e)->e_message != NULL) ? (e)->e_message : "")
4536 m = e->e_message;
4537 #define SM_MSG_DEFERRED "Deferred: "
4538 if (m != NULL && strncmp(SM_MSG_DEFERRED, m,
4539 sizeof(SM_MSG_DEFERRED) - 1) == 0)
4540 m += sizeof(SM_MSG_DEFERRED) - 1;
4541 offset = extsc(m, ' ', replycode, enhsc);
4542
4543 if (tTd(87, 2))
4544 {
4545 sm_dprintf("srv: SmtpError=%s, rcode=%d, renhsc=%s, replycode=%s, enhsc=%s, offset=%d\n",
4546 SmtpError, e->e_rcode, e->e_renhsc,
4547 replycode, enhsc, offset);
4548 }
4549
4550 #define DIG2CHAR(d) ((d) + '0')
4551 if (e->e_rcode != 0 && (replycode[0] == '\0' ||
4552 replycode[0] == DIG2CHAR(REPLYTYPE(e->e_rcode))))
4553 {
4554 replycode[0] = DIG2CHAR(REPLYTYPE(e->e_rcode));
4555 replycode[1] = DIG2CHAR(REPLYCLASS(e->e_rcode));
4556 replycode[2] = DIG2CHAR(REPLYMINOR(e->e_rcode));
4557 replycode[3] = '\0';
4558 if (e->e_renhsc[0] == replycode[0])
4559 sm_strlcpy(enhsc, e->e_renhsc, sizeof(enhsc));
4560 if (offset < 0)
4561 offset = 0;
4562 }
4563 if (e->e_text != NULL)
4564 {
4565 (void) strreplnonprt(e->e_text, '_');
4566 errtext = e->e_text;
4567 }
4568 else
4569 errtext = m + offset;
4570
4571 if (replycode[0] != '\0' && enhsc[0] != '\0')
4572 emessage(replycode, enhsc, "%s", errtext);
4573 else if (replycode[0] != '\0')
4574 emessage(replycode, smtptodsn(atoi(replycode)),
4575 "%s", errtext);
4576 else if (QS_IS_TEMPFAIL(a->q_state))
4577 {
4578 if (m != NULL)
4579 message("450 4.5.1 %s", m);
4580 else
4581 message("450 4.5.1 Temporary error");
4582 }
4583 else
4584 {
4585 if (m != NULL)
4586 message("550 5.5.1 %s", m);
4587 else
4588 message("550 5.0.0 Permanent error");
4589 }
4590 }
4591 else
4592 {
4593 #endif /* _FFR_PROXY */
4594 /* issue success message */
4595 #if _FFR_MSG_ACCEPT
4596 if (MessageAccept != NULL && *MessageAccept != '\0')
4597 {
4598 char msg[MAXLINE];
4599
4600 expand(MessageAccept, msg, sizeof(msg), e);
4601 message("250 2.0.0 %s", msg);
4602 }
4603 else
4604 #endif /* _FFR_MSG_ACCEPT */
4605 /* "else" in #if code above */
4606 message("250 2.0.0 %s Message accepted for delivery", id);
4607 #if _FFR_PROXY
4608 }
4609 #endif
4610 CurEnv->e_id = oldid;
4611
4612 /* if we just queued, poke it */
4613 if (doublequeue)
4614 {
4615 bool anything_to_send = false;
4616
4617 sm_getla();
4618 for (ee = e; ee != NULL; ee = ee->e_sibling)
4619 {
4620 #if _FFR_DMTRIGGER
4621 if (SM_TRIGGER == ee->e_sendmode)
4622 {
4623 sm_syslog(LOG_DEBUG, ee->e_id,
4624 "smtp: doublequeue, mode=%c", ee->e_sendmode);
4625 ee->e_sendmode = SM_DELIVER;
4626
4627 /* close all the queue files */
4628 /* almost the same as below */
4629 closexscript(ee);
4630 SM_CLOSE_FP(ee->e_dfp);
4631 continue;
4632 }
4633 #endif /* _FFR_DMTRIGGER */
4634 if (WILL_BE_QUEUED(ee->e_sendmode))
4635 continue;
4636 if (shouldqueue(ee->e_msgpriority, ee->e_ctime))
4637 {
4638 ee->e_sendmode = SM_QUEUE;
4639 continue;
4640 }
4641 else if (QueueMode != QM_QUARANTINE &&
4642 ee->e_quarmsg != NULL)
4643 {
4644 ee->e_sendmode = SM_QUEUE;
4645 continue;
4646 }
4647 anything_to_send = true;
4648
4649 /* close all the queue files */
4650 closexscript(ee);
4651 SM_CLOSE_FP(ee->e_dfp);
4652 unlockqueue(ee);
4653 }
4654 if (anything_to_send)
4655 {
4656 #if PIPELINING
4657 /*
4658 ** XXX if we don't do this, we get 250 twice
4659 ** because it is also flushed in the child.
4660 */
4661
4662 (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
4663 #endif /* PIPELINING */
4664 #if _FFR_DMTRIGGER
4665 sm_syslog(LOG_DEBUG, e->e_id, "smtp: doublequeue=send");
4666 #endif
4667 (void) doworklist(e, true, true);
4668 }
4669 }
4670
4671 abortmessage:
4672 if (tTd(92, 2))
4673 sm_dprintf("abortmessage: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",
4674 e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);
4675 if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
4676 logsender(e, NULL);
4677 e->e_flags &= ~EF_LOGSENDER;
4678
4679 /* clean up a bit */
4680 smtp->sm_gotmail = false;
4681
4682 /*
4683 ** Call dropenvelope if and only if the envelope is *not*
4684 ** being processed by the child process forked by doworklist().
4685 */
4686
4687 if (aborting || bitset(EF_DISCARD, e->e_flags))
4688 (void) dropenvelope(e, true, false);
4689 else
4690 {
4691 for (ee = e; ee != NULL; ee = ee->e_sibling)
4692 {
4693 if (!doublequeue &&
4694 QueueMode != QM_QUARANTINE &&
4695 ee->e_quarmsg != NULL)
4696 {
4697 (void) dropenvelope(ee, true, false);
4698 continue;
4699 }
4700 if (WILL_BE_QUEUED(ee->e_sendmode))
4701 (void) dropenvelope(ee, true, false);
4702 }
4703 }
4704
4705 CurEnv = e;
4706 features = e->e_features;
4707 sm_rpool_free(e->e_rpool);
4708 newenvelope(e, e, sm_rpool_new_x(NULL));
4709 e->e_flags = BlankEnvelope.e_flags;
4710 e->e_features = features;
4711
4712 /* restore connection quarantining */
4713 if (smtp->sm_quarmsg == NULL)
4714 {
4715 e->e_quarmsg = NULL;
4716 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), "");
4717 }
4718 else
4719 {
4720 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg);
4721 macdefine(&e->e_macro, A_PERM,
4722 macid("{quarantine}"), e->e_quarmsg);
4723 }
4724 return rv;
4725 }
4726 /*
4727 ** LOGUNDELRCPTS -- log undelivered (or all) recipients.
4728 **
4729 ** Parameters:
4730 ** e -- envelope.
4731 ** msg -- message for Stat=
4732 ** level -- log level.
4733 ** all -- log all recipients.
4734 **
4735 ** Returns:
4736 ** none.
4737 **
4738 ** Side Effects:
4739 ** logs undelivered (or all) recipients
4740 */
4741
4742 void
logundelrcpts(e,msg,level,all)4743 logundelrcpts(e, msg, level, all)
4744 ENVELOPE *e;
4745 char *msg;
4746 int level;
4747 bool all;
4748 {
4749 ADDRESS *a;
4750
4751 if (LogLevel <= level || msg == NULL || *msg == '\0')
4752 return;
4753
4754 /* Clear $h so relay= doesn't get mislogged by logdelivery() */
4755 macdefine(&e->e_macro, A_PERM, 'h', NULL);
4756
4757 /* Log who the mail would have gone to */
4758 for (a = e->e_sendqueue; a != NULL; a = a->q_next)
4759 {
4760 if (!QS_IS_UNDELIVERED(a->q_state) && !all)
4761 continue;
4762 e->e_to = a->q_paddr;
4763 logdelivery(NULL, NULL,
4764 #if _FFR_MILTER_ENHSC
4765 (a->q_status == NULL && e->e_enhsc[0] != '\0')
4766 ? e->e_enhsc :
4767 #endif
4768 /* not yet documented or tested */
4769 #if _FFR_USE_E_STATUS
4770 (NULL == a->q_status) ? e->e_status :
4771 #endif
4772 a->q_status,
4773 msg, NULL, (time_t) 0, e, a, EX_OK /* ??? */);
4774 }
4775 e->e_to = NULL;
4776 }
4777 /*
4778 ** CHECKSMTPATTACK -- check for denial-of-service attack by repetition
4779 **
4780 ** Parameters:
4781 ** pcounter -- pointer to a counter for this command.
4782 ** maxcount -- maximum value for this counter before we
4783 ** slow down.
4784 ** waitnow -- sleep now (in this routine)?
4785 ** cname -- command name for logging.
4786 ** e -- the current envelope.
4787 **
4788 ** Returns:
4789 ** time to wait,
4790 ** STOP_ATTACK if twice as many commands as allowed and
4791 ** MaxChildren > 0.
4792 **
4793 ** Side Effects:
4794 ** Slows down if we seem to be under attack.
4795 */
4796
4797 static time_t
checksmtpattack(pcounter,maxcount,waitnow,cname,e)4798 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
4799 volatile unsigned int *pcounter;
4800 unsigned int maxcount;
4801 bool waitnow;
4802 char *cname;
4803 ENVELOPE *e;
4804 {
4805 if (maxcount <= 0) /* no limit */
4806 return (time_t) 0;
4807
4808 if (++(*pcounter) >= maxcount)
4809 {
4810 unsigned int shift;
4811 time_t s;
4812
4813 if (*pcounter == maxcount && LogLevel > 5)
4814 {
4815 sm_syslog(LOG_INFO, e->e_id,
4816 "%s: possible SMTP attack: command=%.40s, count=%u",
4817 CurSmtpClient, cname, *pcounter);
4818 }
4819 shift = *pcounter - maxcount;
4820 s = 1 << shift;
4821 if (shift > MAXSHIFT || s >= MAXTIMEOUT || s <= 0)
4822 s = MAXTIMEOUT;
4823
4824 #define IS_ATTACK(s) ((MaxChildren > 0 && *pcounter >= maxcount * 2) \
4825 ? STOP_ATTACK : (time_t) s)
4826
4827 /* sleep at least 1 second before returning */
4828 (void) sleep(*pcounter / maxcount);
4829 s -= *pcounter / maxcount;
4830 if (s >= MAXTIMEOUT || s < 0)
4831 s = MAXTIMEOUT;
4832 if (waitnow && s > 0)
4833 {
4834 (void) sleep(s);
4835 return IS_ATTACK(0);
4836 }
4837 return IS_ATTACK(s);
4838 }
4839 return (time_t) 0;
4840 }
4841 /*
4842 ** SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
4843 **
4844 ** Parameters:
4845 ** none.
4846 **
4847 ** Returns:
4848 ** nothing.
4849 **
4850 ** Side Effects:
4851 ** may change I/O fd.
4852 */
4853
4854 static void
setup_smtpd_io()4855 setup_smtpd_io()
4856 {
4857 int inchfd, outchfd, outfd;
4858
4859 inchfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
4860 outchfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
4861 outfd = sm_io_getinfo(smioout, SM_IO_WHAT_FD, NULL);
4862 if (outchfd != outfd)
4863 {
4864 /* arrange for debugging output to go to remote host */
4865 (void) dup2(outchfd, outfd);
4866 }
4867
4868 /*
4869 ** if InChannel and OutChannel are stdin/stdout
4870 ** and connected to ttys
4871 ** and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT,
4872 ** then "chain" them together.
4873 */
4874
4875 if (inchfd == STDIN_FILENO && outchfd == STDOUT_FILENO &&
4876 isatty(inchfd) && isatty(outchfd))
4877 {
4878 int inmode, outmode;
4879
4880 inmode = fcntl(inchfd, F_GETFL, 0);
4881 if (inmode == -1)
4882 {
4883 if (LogLevel > 11)
4884 sm_syslog(LOG_INFO, NOQID,
4885 "fcntl(inchfd, F_GETFL) failed: %s",
4886 sm_errstring(errno));
4887 return;
4888 }
4889 outmode = fcntl(outchfd, F_GETFL, 0);
4890 if (outmode == -1)
4891 {
4892 if (LogLevel > 11)
4893 sm_syslog(LOG_INFO, NOQID,
4894 "fcntl(outchfd, F_GETFL) failed: %s",
4895 sm_errstring(errno));
4896 return;
4897 }
4898 if (bitset(O_NONBLOCK, inmode) ||
4899 bitset(O_NONBLOCK, outmode) ||
4900 fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1)
4901 return;
4902 outmode = fcntl(outchfd, F_GETFL, 0);
4903 if (outmode != -1 && bitset(O_NONBLOCK, outmode))
4904 {
4905 /* changing InChannel also changes OutChannel */
4906 sm_io_automode(OutChannel, InChannel);
4907 if (tTd(97, 4) && LogLevel > 9)
4908 sm_syslog(LOG_INFO, NOQID,
4909 "set automode for I (%d)/O (%d) in SMTP server",
4910 inchfd, outchfd);
4911 }
4912
4913 /* undo change of inchfd */
4914 (void) fcntl(inchfd, F_SETFL, inmode);
4915 }
4916 }
4917 /*
4918 ** SKIPWORD -- skip a fixed word.
4919 **
4920 ** Parameters:
4921 ** p -- place to start looking.
4922 ** w -- word to skip.
4923 **
4924 ** Returns:
4925 ** p following w.
4926 ** NULL on error.
4927 **
4928 ** Side Effects:
4929 ** clobbers the p data area.
4930 */
4931
4932 static char *
skipword(p,w)4933 skipword(p, w)
4934 register char *volatile p;
4935 char *w;
4936 {
4937 register char *q;
4938 char *firstp = p;
4939
4940 /* find beginning of word */
4941 SKIP_SPACE(p);
4942 q = p;
4943
4944 /* find end of word */
4945 while (*p != '\0' && *p != ':' && !(SM_ISSPACE(*p)))
4946 p++;
4947 while (SM_ISSPACE(*p))
4948 *p++ = '\0';
4949 if (*p != ':')
4950 {
4951 syntax:
4952 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
4953 SHOWSHRTCMDINREPLY(firstp));
4954 return NULL;
4955 }
4956 *p++ = '\0';
4957 SKIP_SPACE(p);
4958
4959 if (*p == '\0')
4960 goto syntax;
4961
4962 /* see if the input word matches desired word */
4963 if (sm_strcasecmp(q, w))
4964 goto syntax;
4965
4966 return p;
4967 }
4968
4969 /*
4970 ** RESET_MAIL_ESMTP_ARGS -- reset ESMTP arguments for MAIL
4971 **
4972 ** Parameters:
4973 ** e -- the envelope.
4974 **
4975 ** Returns:
4976 ** none.
4977 */
4978
4979 void
reset_mail_esmtp_args(e)4980 reset_mail_esmtp_args(e)
4981 ENVELOPE *e;
4982 {
4983 /* "size": no reset */
4984
4985 /* "body" */
4986 e->e_flags &= ~EF_7BITBODY;
4987 e->e_bodytype = NULL;
4988
4989 /* "envid" */
4990 e->e_envid = NULL;
4991 macdefine(&e->e_macro, A_PERM, macid("{dsn_envid}"), NULL);
4992
4993 /* "ret" */
4994 e->e_flags &= ~(EF_RET_PARAM|EF_NO_BODY_RETN);
4995 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), NULL);
4996
4997 #if SASL
4998 /* "auth" */
4999 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), NULL);
5000 e->e_auth_param = "";
5001 # if _FFR_AUTH_PASSING
5002 macdefine(&BlankEnvelope.e_macro, A_PERM,
5003 macid("{auth_author}"), NULL);
5004 # endif
5005 #endif /* SASL */
5006
5007 /* "by" */
5008 e->e_deliver_by = 0;
5009 e->e_dlvr_flag = 0;
5010 }
5011
5012 /*
5013 ** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
5014 **
5015 ** Parameters:
5016 ** a -- address (unused, for compatibility with rcpt_esmtp_args)
5017 ** kp -- the parameter key.
5018 ** vp -- the value of that parameter.
5019 ** e -- the envelope.
5020 **
5021 ** Returns:
5022 ** none.
5023 */
5024
5025 void
mail_esmtp_args(a,kp,vp,e)5026 mail_esmtp_args(a, kp, vp, e)
5027 ADDRESS *a;
5028 char *kp;
5029 char *vp;
5030 ENVELOPE *e;
5031 {
5032 if (SM_STRCASEEQ(kp, "size"))
5033 {
5034 if (vp == NULL)
5035 {
5036 usrerr("501 5.5.2 SIZE requires a value");
5037 /* NOTREACHED */
5038 }
5039 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp);
5040 errno = 0;
5041 e->e_msgsize = strtol(vp, (char **) NULL, 10);
5042 if (e->e_msgsize == LONG_MAX && errno == ERANGE)
5043 {
5044 usrerr("552 5.2.3 Message size exceeds maximum value");
5045 /* NOTREACHED */
5046 }
5047 if (e->e_msgsize < 0)
5048 {
5049 usrerr("552 5.2.3 Message size invalid");
5050 /* NOTREACHED */
5051 }
5052 }
5053 else if (SM_STRCASEEQ(kp, "body"))
5054 {
5055 if (vp == NULL)
5056 {
5057 usrerr("501 5.5.2 BODY requires a value");
5058 /* NOTREACHED */
5059 }
5060 else if (SM_STRCASEEQ(vp, "8bitmime"))
5061 ;
5062 else if (SM_STRCASEEQ(vp, "7bit"))
5063 e->e_flags |= EF_7BITBODY;
5064 else
5065 {
5066 usrerr("501 5.5.4 Unknown BODY type %s",
5067 SHOWCMDINREPLY(vp));
5068 /* NOTREACHED */
5069 }
5070 e->e_bodytype = sm_rpool_strdup_x(e->e_rpool, vp);
5071 }
5072 else if (SM_STRCASEEQ(kp, "envid"))
5073 {
5074 if (!bitset(SRV_OFFER_DSN, e->e_features))
5075 {
5076 usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
5077 /* NOTREACHED */
5078 }
5079 if (vp == NULL)
5080 {
5081 usrerr("501 5.5.2 ENVID requires a value");
5082 /* NOTREACHED */
5083 }
5084 if (!xtextok(vp))
5085 {
5086 usrerr("501 5.5.4 Syntax error in ENVID parameter value");
5087 /* NOTREACHED */
5088 }
5089 if (e->e_envid != NULL)
5090 {
5091 usrerr("501 5.5.0 Duplicate ENVID parameter");
5092 /* NOTREACHED */
5093 }
5094 e->e_envid = sm_rpool_strdup_x(e->e_rpool, vp);
5095 macdefine(&e->e_macro, A_PERM,
5096 macid("{dsn_envid}"), e->e_envid);
5097 }
5098 else if (SM_STRCASEEQ(kp, "ret"))
5099 {
5100 if (!bitset(SRV_OFFER_DSN, e->e_features))
5101 {
5102 usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
5103 /* NOTREACHED */
5104 }
5105 if (vp == NULL)
5106 {
5107 usrerr("501 5.5.2 RET requires a value");
5108 /* NOTREACHED */
5109 }
5110 if (bitset(EF_RET_PARAM, e->e_flags))
5111 {
5112 usrerr("501 5.5.0 Duplicate RET parameter");
5113 /* NOTREACHED */
5114 }
5115 e->e_flags |= EF_RET_PARAM;
5116 if (SM_STRCASEEQ(vp, "hdrs"))
5117 e->e_flags |= EF_NO_BODY_RETN;
5118 else if (sm_strcasecmp(vp, "full") != 0)
5119 {
5120 usrerr("501 5.5.2 Bad argument \"%s\" to RET",
5121 SHOWCMDINREPLY(vp));
5122 /* NOTREACHED */
5123 }
5124 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp);
5125 }
5126 #if SASL
5127 else if (SM_STRCASEEQ(kp, "auth"))
5128 {
5129 int len;
5130 char *q;
5131 char *auth_param; /* the value of the AUTH=x */
5132 bool saveQuickAbort = QuickAbort;
5133 bool saveSuprErrs = SuprErrs;
5134 bool saveExitStat = ExitStat;
5135
5136 if (vp == NULL)
5137 {
5138 usrerr("501 5.5.2 AUTH= requires a value");
5139 /* NOTREACHED */
5140 }
5141 if (e->e_auth_param != NULL)
5142 {
5143 usrerr("501 5.5.0 Duplicate AUTH parameter");
5144 /* NOTREACHED */
5145 }
5146 if ((q = strchr(vp, ' ')) != NULL)
5147 len = q - vp + 1;
5148 else
5149 len = strlen(vp) + 1;
5150 auth_param = xalloc(len);
5151 (void) sm_strlcpy(auth_param, vp, len);
5152 if (!xtextok(auth_param))
5153 {
5154 usrerr("501 5.5.4 Syntax error in AUTH parameter value");
5155 /* just a warning? */
5156 /* NOTREACHED */
5157 }
5158
5159 /* XXX define this always or only if trusted? */
5160 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"),
5161 auth_param);
5162
5163 /*
5164 ** call Strust_auth to find out whether
5165 ** auth_param is acceptable (trusted)
5166 ** we shouldn't trust it if not authenticated
5167 ** (required by RFC, leave it to ruleset?)
5168 */
5169
5170 SuprErrs = true;
5171 QuickAbort = false;
5172 if (strcmp(auth_param, "<>") != 0 &&
5173 (rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM, 9,
5174 NULL, NOQID, NULL, NULL) != EX_OK || Errors > 0))
5175 {
5176 if (tTd(95, 8))
5177 {
5178 q = e->e_auth_param;
5179 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
5180 auth_param, (q == NULL) ? "" : q);
5181 }
5182
5183 /* not trusted */
5184 e->e_auth_param = "<>";
5185 # if _FFR_AUTH_PASSING
5186 macdefine(&BlankEnvelope.e_macro, A_PERM,
5187 macid("{auth_author}"), NULL);
5188 # endif
5189 }
5190 else
5191 {
5192 if (tTd(95, 8))
5193 sm_dprintf("auth=\"%.100s\" trusted\n", auth_param);
5194 e->e_auth_param = sm_rpool_strdup_x(e->e_rpool,
5195 auth_param);
5196 }
5197 sm_free(auth_param); /* XXX */
5198
5199 /* reset values */
5200 Errors = 0;
5201 QuickAbort = saveQuickAbort;
5202 SuprErrs = saveSuprErrs;
5203 ExitStat = saveExitStat;
5204 }
5205 #endif /* SASL */
5206 #define PRTCHAR(c) ((isascii(c) && isprint(c)) ? (c) : '?')
5207
5208 /*
5209 ** "by" is only accepted if DeliverByMin >= 0.
5210 ** We maybe could add this to the list of server_features.
5211 */
5212
5213 else if (SM_STRCASEEQ(kp, "by") && DeliverByMin >= 0)
5214 {
5215 char *s;
5216
5217 if (vp == NULL)
5218 {
5219 usrerr("501 5.5.2 BY= requires a value");
5220 /* NOTREACHED */
5221 }
5222 errno = 0;
5223 e->e_deliver_by = strtol(vp, &s, 10);
5224 if (e->e_deliver_by == LONG_MIN ||
5225 e->e_deliver_by == LONG_MAX ||
5226 e->e_deliver_by > 999999999l ||
5227 e->e_deliver_by < -999999999l)
5228 {
5229 usrerr("501 5.5.2 BY=%s out of range",
5230 SHOWCMDINREPLY(vp));
5231 /* NOTREACHED */
5232 }
5233 if (s == NULL || *s != ';')
5234 {
5235 usrerr("501 5.5.2 BY= missing ';'");
5236 /* NOTREACHED */
5237 }
5238 e->e_dlvr_flag = 0;
5239 ++s; /* XXX: spaces allowed? */
5240 SKIP_SPACE(s);
5241 switch (tolower(*s))
5242 {
5243 case 'n':
5244 e->e_dlvr_flag = DLVR_NOTIFY;
5245 break;
5246 case 'r':
5247 e->e_dlvr_flag = DLVR_RETURN;
5248 if (e->e_deliver_by <= 0)
5249 {
5250 usrerr("501 5.5.4 mode R requires BY time > 0");
5251 /* NOTREACHED */
5252 }
5253 if (DeliverByMin > 0 && e->e_deliver_by > 0 &&
5254 e->e_deliver_by < DeliverByMin)
5255 {
5256 usrerr("555 5.5.2 time %ld less than %ld",
5257 e->e_deliver_by, (long) DeliverByMin);
5258 /* NOTREACHED */
5259 }
5260 break;
5261 default:
5262 usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s));
5263 /* NOTREACHED */
5264 }
5265 ++s; /* XXX: spaces allowed? */
5266 SKIP_SPACE(s);
5267 switch (tolower(*s))
5268 {
5269 case 't':
5270 e->e_dlvr_flag |= DLVR_TRACE;
5271 break;
5272 case '\0':
5273 break;
5274 default:
5275 usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s));
5276 /* NOTREACHED */
5277 }
5278
5279 /* XXX: check whether more characters follow? */
5280 }
5281 #if USE_EAI
5282 else if (SM_STRCASEEQ(kp, "smtputf8"))
5283 {
5284 if (!bitset(SRV_OFFER_EAI, e->e_features))
5285 {
5286 usrerr("504 5.7.0 Sorry, SMTPUTF8 not supported");
5287 /* NOTREACHED */
5288 }
5289 e->e_smtputf8 = true;
5290 }
5291 #endif
5292 else
5293 {
5294 usrerr("555 5.5.4 %s parameter unrecognized",
5295 SHOWCMDINREPLY(kp));
5296 /* NOTREACHED */
5297 }
5298 }
5299
5300 /*
5301 ** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
5302 **
5303 ** Parameters:
5304 ** a -- the address corresponding to the To: parameter.
5305 ** kp -- the parameter key.
5306 ** vp -- the value of that parameter.
5307 ** e -- the envelope.
5308 **
5309 ** Returns:
5310 ** none.
5311 */
5312
5313 void
rcpt_esmtp_args(a,kp,vp,e)5314 rcpt_esmtp_args(a, kp, vp, e)
5315 ADDRESS *a;
5316 char *kp;
5317 char *vp;
5318 ENVELOPE *e;
5319 {
5320 if (SM_STRCASEEQ(kp, "notify"))
5321 {
5322 char *p;
5323
5324 if (!bitset(SRV_OFFER_DSN, e->e_features))
5325 {
5326 usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
5327 /* NOTREACHED */
5328 }
5329 if (vp == NULL)
5330 {
5331 usrerr("501 5.5.2 NOTIFY requires a value");
5332 /* NOTREACHED */
5333 }
5334 a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
5335 a->q_flags |= QHASNOTIFY;
5336 macdefine(&e->e_macro, A_TEMP, macid("{dsn_notify}"), vp);
5337
5338 if (SM_STRCASEEQ(vp, "never"))
5339 return;
5340 for (p = vp; p != NULL; vp = p)
5341 {
5342 char *s;
5343
5344 s = p = strchr(p, ',');
5345 if (p != NULL)
5346 *p++ = '\0';
5347 if (SM_STRCASEEQ(vp, "success"))
5348 a->q_flags |= QPINGONSUCCESS;
5349 else if (SM_STRCASEEQ(vp, "failure"))
5350 a->q_flags |= QPINGONFAILURE;
5351 else if (SM_STRCASEEQ(vp, "delay"))
5352 a->q_flags |= QPINGONDELAY;
5353 else
5354 {
5355 usrerr("501 5.5.4 Bad argument \"%s\" to NOTIFY",
5356 SHOWCMDINREPLY(vp));
5357 /* NOTREACHED */
5358 }
5359 if (s != NULL)
5360 *s = ',';
5361 }
5362 }
5363 else if (SM_STRCASEEQ(kp, "orcpt"))
5364 {
5365 char *p;
5366
5367 if (!bitset(SRV_OFFER_DSN, e->e_features))
5368 {
5369 usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
5370 /* NOTREACHED */
5371 }
5372 if (vp == NULL)
5373 {
5374 usrerr("501 5.5.2 ORCPT requires a value");
5375 /* NOTREACHED */
5376 }
5377 if (a->q_orcpt != NULL)
5378 {
5379 usrerr("501 5.5.0 Duplicate ORCPT parameter");
5380 /* NOTREACHED */
5381 }
5382 p = strchr(vp, ';');
5383 if (p == NULL)
5384 {
5385 usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
5386 /* NOTREACHED */
5387 }
5388 *p = '\0';
5389 #if USE_EAI
5390 if (SM_STRCASEEQ(vp, "utf-8"))
5391 {
5392 /* XXX check syntax of p+1 ! */
5393 if (!xtextok(p + 1) &&
5394 uxtext_unquote(p + 1, NULL, MAXNAME_I) <= 0)
5395 {
5396 *p = ';';
5397 usrerr("501 5.5.4 Syntax error in UTF-8 ORCPT parameter value");
5398 /* NOTREACHED */
5399 }
5400 # if 0
5401 complicated... see grammar!
5402 RFC 6533 Internationalized Delivery Status and Disposition Notifications
5403 utf-8-enc-addr = utf-8-addr-xtext / utf-8-addr-unitext / utf-8-address
5404 # endif
5405 }
5406 else
5407 #endif /* USE_EAI */
5408 /* "else" in #if code above */
5409 if (!isatom(vp) || !xtextok(p + 1))
5410 {
5411 *p = ';';
5412 usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
5413 /* NOTREACHED */
5414 }
5415 *p = ';';
5416 a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp);
5417 }
5418 else
5419 {
5420 usrerr("555 5.5.4 %s parameter unrecognized",
5421 SHOWCMDINREPLY(kp));
5422 /* NOTREACHED */
5423 }
5424 }
5425 /*
5426 ** PRINTVRFYADDR -- print an entry in the verify queue
5427 **
5428 ** Parameters:
5429 ** a -- the address to print.
5430 ** last -- set if this is the last one.
5431 ** vrfy -- set if this is a VRFY command.
5432 **
5433 ** Returns:
5434 ** none.
5435 **
5436 ** Side Effects:
5437 ** Prints the appropriate 250 codes.
5438 */
5439 #define OFFF (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */
5440
5441 static void
printvrfyaddr(a,last,vrfy)5442 printvrfyaddr(a, last, vrfy)
5443 register ADDRESS *a;
5444 bool last;
5445 bool vrfy;
5446 {
5447 char fmtbuf[30];
5448
5449 if (vrfy && a->q_mailer != NULL &&
5450 !bitnset(M_VRFY250, a->q_mailer->m_flags))
5451 (void) sm_strlcpy(fmtbuf, "252", sizeof(fmtbuf));
5452 else
5453 (void) sm_strlcpy(fmtbuf, "250", sizeof(fmtbuf));
5454 fmtbuf[3] = last ? ' ' : '-';
5455 (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof(fmtbuf) - 4);
5456 if (a->q_fullname == NULL)
5457 {
5458 if ((a->q_mailer == NULL ||
5459 a->q_mailer->m_addrtype == NULL ||
5460 SM_STRCASEEQ(a->q_mailer->m_addrtype, "rfc822")) &&
5461 strchr(a->q_user, '@') == NULL)
5462 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>",
5463 sizeof(fmtbuf) - OFFF);
5464 else
5465 (void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
5466 sizeof(fmtbuf) - OFFF);
5467 message(fmtbuf, a->q_user, MyHostName);
5468 }
5469 else
5470 {
5471 if ((a->q_mailer == NULL ||
5472 a->q_mailer->m_addrtype == NULL ||
5473 SM_STRCASEEQ(a->q_mailer->m_addrtype, "rfc822")) &&
5474 strchr(a->q_user, '@') == NULL)
5475 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
5476 sizeof(fmtbuf) - OFFF);
5477 else
5478 (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
5479 sizeof(fmtbuf) - OFFF);
5480 message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
5481 }
5482 }
5483
5484 #if SASL
5485 /*
5486 ** SASLMECHS -- get list of possible AUTH mechanisms
5487 **
5488 ** Parameters:
5489 ** conn -- SASL connection info.
5490 ** mechlist -- output parameter for list of mechanisms.
5491 **
5492 ** Returns:
5493 ** number of mechs.
5494 */
5495
5496 static int
saslmechs(conn,mechlist)5497 saslmechs(conn, mechlist)
5498 sasl_conn_t *conn;
5499 char **mechlist;
5500 {
5501 int len, num, result;
5502
5503 /* "user" is currently unused */
5504 # if SASL >= 20000
5505 result = sasl_listmech(conn, NULL,
5506 "", " ", "", (const char **) mechlist,
5507 (unsigned int *)&len, &num);
5508 # else /* SASL >= 20000 */
5509 result = sasl_listmech(conn, "user", /* XXX */
5510 "", " ", "", mechlist,
5511 (unsigned int *)&len, (unsigned int *)&num);
5512 # endif /* SASL >= 20000 */
5513 if (result != SASL_OK)
5514 {
5515 if (LogLevel > 9)
5516 sm_syslog(LOG_WARNING, NOQID,
5517 "AUTH error: listmech=%d, num=%d",
5518 result, num);
5519 num = 0;
5520 }
5521 if (num > 0)
5522 {
5523 if (LogLevel > 11)
5524 sm_syslog(LOG_INFO, NOQID,
5525 "AUTH: available mech=%s, allowed mech=%s",
5526 *mechlist, AuthMechanisms);
5527 *mechlist = intersect(AuthMechanisms, *mechlist, NULL);
5528 }
5529 else
5530 {
5531 *mechlist = NULL; /* be paranoid... */
5532 if (result == SASL_OK && LogLevel > 9)
5533 sm_syslog(LOG_WARNING, NOQID,
5534 "AUTH warning: no mechanisms");
5535 }
5536 return num;
5537 }
5538
5539 # if SASL >= 20000
5540 /*
5541 ** PROXY_POLICY -- define proxy policy for AUTH
5542 **
5543 ** Parameters:
5544 ** conn -- unused.
5545 ** context -- unused.
5546 ** requested_user -- authorization identity.
5547 ** rlen -- authorization identity length.
5548 ** auth_identity -- authentication identity.
5549 ** alen -- authentication identity length.
5550 ** def_realm -- default user realm.
5551 ** urlen -- user realm length.
5552 ** propctx -- unused.
5553 **
5554 ** Returns:
5555 ** ok?
5556 **
5557 ** Side Effects:
5558 ** sets {auth_authen} macro.
5559 */
5560
5561 int
proxy_policy(conn,context,requested_user,rlen,auth_identity,alen,def_realm,urlen,propctx)5562 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen,
5563 def_realm, urlen, propctx)
5564 sasl_conn_t *conn;
5565 void *context;
5566 const char *requested_user;
5567 unsigned rlen;
5568 const char *auth_identity;
5569 unsigned alen;
5570 const char *def_realm;
5571 unsigned urlen;
5572 struct propctx *propctx;
5573 {
5574 if (auth_identity == NULL)
5575 return SASL_FAIL;
5576
5577 macdefine(&BlankEnvelope.e_macro, A_TEMP,
5578 macid("{auth_authen}"),
5579 xtextify((char *) auth_identity, "=<>\")"));
5580
5581 return SASL_OK;
5582 }
5583 # else /* SASL >= 20000 */
5584
5585 /*
5586 ** PROXY_POLICY -- define proxy policy for AUTH
5587 **
5588 ** Parameters:
5589 ** context -- unused.
5590 ** auth_identity -- authentication identity.
5591 ** requested_user -- authorization identity.
5592 ** user -- allowed user (output).
5593 ** errstr -- possible error string (output).
5594 **
5595 ** Returns:
5596 ** ok?
5597 */
5598
5599 int
proxy_policy(context,auth_identity,requested_user,user,errstr)5600 proxy_policy(context, auth_identity, requested_user, user, errstr)
5601 void *context;
5602 const char *auth_identity;
5603 const char *requested_user;
5604 const char **user;
5605 const char **errstr;
5606 {
5607 if (user == NULL || auth_identity == NULL)
5608 return SASL_FAIL;
5609 *user = newstr(auth_identity);
5610 return SASL_OK;
5611 }
5612 # endif /* SASL >= 20000 */
5613 #endif /* SASL */
5614
5615 #if STARTTLS
5616 /*
5617 ** INITSRVTLS -- initialize server side TLS
5618 **
5619 ** Parameters:
5620 ** tls_ok -- should tls initialization be done?
5621 **
5622 ** Returns:
5623 ** succeeded?
5624 **
5625 ** Side Effects:
5626 ** sets tls_ok_srv which is a static variable in this module.
5627 ** Do NOT remove assignments to it!
5628 */
5629
5630 bool
initsrvtls(tls_ok)5631 initsrvtls(tls_ok)
5632 bool tls_ok;
5633 {
5634 if (!tls_ok)
5635 return false;
5636
5637 /* do NOT remove assignment */
5638 tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, Srv_SSL_Options, true,
5639 SrvCertFile, SrvKeyFile,
5640 CACertPath, CACertFile, DHParams);
5641 return tls_ok_srv;
5642 }
5643 #endif /* STARTTLS */
5644 /*
5645 ** SRVFEATURES -- get features for SMTP server
5646 **
5647 ** Parameters:
5648 ** e -- envelope (should be session context).
5649 ** clientname -- name of client.
5650 ** features -- default features for this invocation.
5651 **
5652 ** Returns:
5653 ** server features.
5654 */
5655
5656 /* table with options: it uses just one character, how about strings? */
5657 static struct
5658 {
5659 char srvf_opt;
5660 unsigned long srvf_flag;
5661 unsigned long srvf_flag2;
5662 } srv_feat_table[] =
5663 {
5664 { 'A', SRV_OFFER_AUTH , 0 },
5665 { 'B', SRV_OFFER_VERB , 0 },
5666 { 'C', SRV_REQ_SEC , 0 },
5667 { 'D', SRV_OFFER_DSN , 0 },
5668 { 'E', SRV_OFFER_ETRN , 0 },
5669 { 'F', SRV_BAD_PIPELINE , 0 },
5670 { 'G', SRV_BARE_LF_421 , SRV_BARE_LF_SP },
5671 { 'H', SRV_NO_HTTP_CMD , 0 },
5672 #if USE_EAI
5673 { 'I', SRV_OFFER_EAI , 0 },
5674 #endif
5675 /* { 'J', 0 , 0 }, */
5676 /* { 'K', 0 , 0 }, */
5677 { 'L', SRV_REQ_AUTH , 0 },
5678 /* { 'M', 0 , 0 }, */
5679 #if PIPELINING && _FFR_NO_PIPE
5680 { 'N', SRV_NO_PIPE , 0 },
5681 #endif
5682 { 'O', SRV_REQ_CRLF , 0 }, /* eOl */
5683 #if PIPELINING
5684 { 'P', SRV_OFFER_PIPE , 0 },
5685 #endif
5686 /* { 'Q', 0 , 0 }, */
5687 { 'R', SRV_VRFY_CLT , 0 }, /* same as V; not documented */
5688 { 'S', SRV_OFFER_TLS , 0 },
5689 /* { 'T', SRV_TMP_FAIL , 0 }, */
5690 { 'U', SRV_BARE_CR_421 , SRV_BARE_CR_SP },
5691 { 'V', SRV_VRFY_CLT , 0 },
5692 /* { 'W', 0 , 0 }, */
5693 { 'X', SRV_OFFER_EXPN , 0 },
5694 /* { 'Y', SRV_OFFER_VRFY , 0 }, */
5695 /* { 'Z', 0 , 0 }, */
5696 { '\0', SRV_NONE , 0 }
5697 };
5698
5699 static unsigned long
srvfeatures(e,clientname,features)5700 srvfeatures(e, clientname, features)
5701 ENVELOPE *e;
5702 char *clientname;
5703 unsigned long features;
5704 {
5705 int r, i, j;
5706 char **pvp, c, opt;
5707 char pvpbuf[PSBUFSIZE];
5708
5709 pvp = NULL;
5710 r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf,
5711 sizeof(pvpbuf));
5712 if (r != EX_OK)
5713 return features;
5714 if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
5715 return features;
5716 if (pvp[1] != NULL && sm_strncasecmp(pvp[1], "temp", 4) == 0)
5717 return SRV_TMP_FAIL;
5718
5719 /*
5720 ** General rule (see sendmail.h, d_flags):
5721 ** lower case: required/offered, upper case: Not required/available
5722 **
5723 ** Since we can change some features per daemon, we have both
5724 ** cases here: turn on/off a feature.
5725 */
5726
5727 for (i = 1; pvp[i] != NULL; i++)
5728 {
5729 c = pvp[i][0];
5730 j = 0;
5731 for (;;)
5732 {
5733 if ((opt = srv_feat_table[j].srvf_opt) == '\0')
5734 {
5735 if (LogLevel > 9)
5736 sm_syslog(LOG_WARNING, e->e_id,
5737 "srv_features: unknown feature %s",
5738 pvp[i]);
5739 break;
5740 }
5741 if (c == opt)
5742 {
5743 features &= ~(srv_feat_table[j].srvf_flag);
5744 break;
5745 }
5746
5747 /*
5748 ** Note: the "noflag" code below works ONLY for
5749 ** the current situation:
5750 ** - _flag itself is set by default
5751 ** (drop session if bare CR or LF is found)
5752 ** - _flag2 is only "effective" if _flag is not set,
5753 ** hence using it turns off _flag.
5754 ** If that situation changes, the code must be changed!
5755 */
5756
5757 if (c == tolower(opt))
5758 {
5759 unsigned long flag, noflag;
5760
5761 c = pvp[i][1];
5762 flag = noflag = 0;
5763 if ('2' == c)
5764 {
5765 flag = srv_feat_table[j].srvf_flag2;
5766 noflag = srv_feat_table[j].srvf_flag;
5767 }
5768 else if ('\0' == c)
5769 flag = srv_feat_table[j].srvf_flag;
5770 if (0 != flag)
5771 {
5772 features |= flag;
5773 if (0 != noflag)
5774 features &= ~noflag;
5775 }
5776 else if (LogLevel > 9)
5777 sm_syslog(LOG_WARNING, e->e_id,
5778 "srv_features: unknown variant %s",
5779 pvp[i]);
5780 break;
5781 }
5782 ++j;
5783 }
5784 }
5785 return features;
5786 }
5787
5788 /*
5789 ** HELP -- implement the HELP command.
5790 **
5791 ** Parameters:
5792 ** topic -- the topic we want help for.
5793 ** e -- envelope.
5794 **
5795 ** Returns:
5796 ** none.
5797 **
5798 ** Side Effects:
5799 ** outputs the help file to message output.
5800 */
5801 #define HELPVSTR "#vers "
5802 #define HELPVERSION 2
5803
5804 void
help(topic,e)5805 help(topic, e)
5806 char *topic;
5807 ENVELOPE *e;
5808 {
5809 register SM_FILE_T *hf;
5810 register char *p;
5811 char *lstr;
5812 int len;
5813 bool noinfo;
5814 bool first = true;
5815 long sff = SFF_OPENASROOT|SFF_REGONLY;
5816 char buf[MAXLINE];
5817 char inp[MAXLINE];
5818 static int foundvers = -1;
5819 extern char Version[];
5820
5821 if (DontLockReadFiles)
5822 sff |= SFF_NOLOCK;
5823 if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
5824 sff |= SFF_SAFEDIRPATH;
5825
5826 if (HelpFile == NULL ||
5827 (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
5828 {
5829 /* no help */
5830 errno = 0;
5831 message("502 5.3.0 Sendmail %s -- HELP not implemented",
5832 Version);
5833 return;
5834 }
5835
5836 lstr = NULL;
5837 if (SM_IS_EMPTY(topic))
5838 {
5839 topic = "smtp";
5840 noinfo = false;
5841 }
5842 else
5843 {
5844
5845 lstr = makelower_a(&topic, NULL);
5846 if (lstr != topic)
5847 topic = lstr;
5848 else
5849 lstr = NULL;
5850 noinfo = true;
5851 }
5852
5853 len = strlen(topic);
5854
5855 while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
5856 {
5857 if (buf[0] == '#')
5858 {
5859 if (foundvers < 0 &&
5860 strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
5861 {
5862 int h;
5863
5864 if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d",
5865 &h) == 1)
5866 foundvers = h;
5867 }
5868 continue;
5869 }
5870 if (strncmp(buf, topic, len) == 0)
5871 {
5872 if (first)
5873 {
5874 first = false;
5875
5876 /* print version if no/old vers# in file */
5877 if (foundvers < 2 && !noinfo)
5878 message("214-2.0.0 This is Sendmail version %s", Version);
5879 }
5880 p = strpbrk(buf, " \t");
5881 if (p == NULL)
5882 p = buf + strlen(buf) - 1;
5883 else
5884 p++;
5885 fixcrlf(p, true);
5886 if (foundvers >= 2)
5887 {
5888 char *lbp;
5889 int lbs = sizeof(buf) - (p - buf);
5890
5891 lbp = translate_dollars(p, p, &lbs);
5892 expand(lbp, inp, sizeof(inp), e);
5893 if (p != lbp)
5894 sm_free(lbp);
5895 p = inp;
5896 }
5897 message("214-2.0.0 %s", p);
5898 noinfo = false;
5899 }
5900 }
5901
5902 if (noinfo)
5903 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
5904 else
5905 message("214 2.0.0 End of HELP info");
5906
5907 if (foundvers != 0 && foundvers < HELPVERSION)
5908 {
5909 if (LogLevel > 1)
5910 sm_syslog(LOG_WARNING, e->e_id,
5911 "%s too old (require version %d)",
5912 HelpFile, HELPVERSION);
5913
5914 /* avoid log next time */
5915 foundvers = 0;
5916 }
5917
5918 (void) sm_io_close(hf, SM_TIME_DEFAULT);
5919 SM_FREE(lstr);
5920 }
5921
5922 #if SASL
5923 /*
5924 ** RESET_SASLCONN -- reset SASL connection data
5925 **
5926 ** Parameters:
5927 ** conn -- SASL connection context
5928 ** hostname -- host name
5929 ** various connection data
5930 **
5931 ** Returns:
5932 ** SASL result
5933 */
5934
5935 #ifdef __STDC__
5936 static int
reset_saslconn(sasl_conn_t ** conn,char * hostname,char * remoteip,char * localip,char * auth_id,sasl_ssf_t * ext_ssf)5937 reset_saslconn(sasl_conn_t **conn, char *hostname,
5938 # if SASL >= 20000
5939 char *remoteip, char *localip,
5940 char *auth_id, sasl_ssf_t * ext_ssf)
5941 # else /* SASL >= 20000 */
5942 struct sockaddr_in *saddr_r, struct sockaddr_in *saddr_l,
5943 sasl_external_properties_t * ext_ssf)
5944 # endif /* SASL >= 20000 */
5945 #else /* __STDC__ */
5946 # error "SASL requires __STDC__"
5947 #endif /* __STDC__ */
5948 {
5949 int result;
5950
5951 sasl_dispose(conn);
5952 # if SASL >= 20000
5953 result = sasl_server_new("smtp", hostname, NULL, NULL, NULL,
5954 NULL, 0, conn);
5955 # elif SASL > 10505
5956 /* use empty realm: only works in SASL > 1.5.5 */
5957 result = sasl_server_new("smtp", hostname, "", NULL, 0, conn);
5958 # else /* SASL >= 20000 */
5959 /* use no realm -> realm is set to hostname by SASL lib */
5960 result = sasl_server_new("smtp", hostname, NULL, NULL, 0,
5961 conn);
5962 # endif /* SASL >= 20000 */
5963 if (result != SASL_OK)
5964 return result;
5965
5966 # if SASL >= 20000
5967 # if NETINET || NETINET6
5968 if (remoteip != NULL && *remoteip != '\0')
5969 result = sasl_setprop(*conn, SASL_IPREMOTEPORT, remoteip);
5970 if (result != SASL_OK)
5971 return result;
5972
5973 if (localip != NULL && *localip != '\0')
5974 result = sasl_setprop(*conn, SASL_IPLOCALPORT, localip);
5975 if (result != SASL_OK)
5976 return result;
5977 # endif /* NETINET || NETINET6 */
5978
5979 result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf);
5980 if (result != SASL_OK)
5981 return result;
5982
5983 result = sasl_setprop(*conn, SASL_AUTH_EXTERNAL, auth_id);
5984 if (result != SASL_OK)
5985 return result;
5986 # else /* SASL >= 20000 */
5987 # if NETINET
5988 if (saddr_r != NULL)
5989 result = sasl_setprop(*conn, SASL_IP_REMOTE, saddr_r);
5990 if (result != SASL_OK)
5991 return result;
5992
5993 if (saddr_l != NULL)
5994 result = sasl_setprop(*conn, SASL_IP_LOCAL, saddr_l);
5995 if (result != SASL_OK)
5996 return result;
5997 # endif /* NETINET */
5998
5999 result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf);
6000 if (result != SASL_OK)
6001 return result;
6002 # endif /* SASL >= 20000 */
6003 return SASL_OK;
6004 }
6005
6006 /*
6007 ** GET_SASL_USER -- extract user part from SASL reply
6008 **
6009 ** Parameters:
6010 ** val -- sasl reply (may contain NUL)
6011 ** len -- length of val
6012 ** auth_type -- auth_type (can be NULL)
6013 ** user -- output buffer for extract user
6014 ** user_len -- length of output buffer (user)
6015 **
6016 ** Returns:
6017 ** none.
6018 **
6019 ** Note: val is supplied by the client and hence may contain "bad"
6020 ** (non-printable) characters, but the returned value (user)
6021 ** is only used for logging which converts those characters.
6022 */
6023
6024 static void
get_sasl_user(val,len,auth_type,user,user_len)6025 get_sasl_user(val, len, auth_type, user, user_len)
6026 char *val;
6027 unsigned int len;
6028 const char *auth_type;
6029 char *user;
6030 size_t user_len;
6031 {
6032 unsigned int u;
6033
6034 SM_ASSERT(val != NULL);
6035 SM_ASSERT(user != NULL);
6036 SM_ASSERT(user_len > 0);
6037
6038 *user = '\0';
6039 if (SM_IS_EMPTY(auth_type))
6040 return;
6041 if (0 == len)
6042 return;
6043
6044 # define DIGMD5U "username=\""
6045 # define DIGMD5U_L (sizeof(DIGMD5U) - 1)
6046 if (SM_STRCASEEQ(auth_type, "digest-md5") &&
6047 strncmp(val, DIGMD5U, DIGMD5U_L) == 0)
6048 {
6049 char *s;
6050
6051 val += DIGMD5U_L;
6052 if (len <= DIGMD5U_L)
6053 return;
6054 len -= DIGMD5U_L;
6055
6056 /* format? could there be a quoted '"'? */
6057 for (s = val, u = 0; *s != '\0' && u < len; s++)
6058 {
6059 if ('"' == *s)
6060 {
6061 *s = '\0';
6062 break;
6063 }
6064 if ('\\' == *s)
6065 {
6066 ++s;
6067 if ('\0' == *s)
6068 break;
6069 }
6070 }
6071 }
6072 else if (SM_STRCASEEQ(auth_type, "cram-md5"))
6073 {
6074 char *s;
6075
6076 for (s = val, u = 0; *s != '\0' && u < len; s++)
6077 {
6078 if (' ' == *s)
6079 {
6080 *s = '\0';
6081 break;
6082 }
6083 }
6084 }
6085
6086 else if (SM_STRCASEEQ(auth_type, "plain") ||
6087 SM_STRCASEEQ(auth_type, "login"))
6088 {
6089 /*
6090 ** RFC 4616: The PLAIN Simple Authentication and
6091 ** Security Layer (SASL) Mechanism
6092 ** message = [authzid] UTF8NUL authcid UTF8NUL passwd
6093 ** each part: 1*SAFE ; MUST accept up to 255 octets
6094 ** UTF8NUL = %x00 ; UTF-8 encoded NUL character
6095 **
6096 ** draft-murchison-sasl-login: it's just username by its own
6097 */
6098
6099 for (u = 0; u < len; u++)
6100 {
6101 if (val[u] == '\0')
6102 {
6103 val[u] = '/';
6104 (void) sm_strlcpy(user,
6105 val + ((0 == u) ? 1 : 0),
6106 user_len);
6107 return;
6108 }
6109 }
6110 }
6111 else
6112 {
6113 /*
6114 ** Extracting the "user" from other mechanisms
6115 ** is currently not supported.
6116 */
6117
6118 return;
6119 }
6120
6121 /*
6122 ** Does the input buffer has an NUL in it so it can be treated
6123 ** as a C string?
6124 */
6125
6126 /* SM_ASSERT(len > 0); see above */
6127 u = len - 1;
6128 if (val[u] != '\0')
6129 {
6130 for (u = 0; u < len; u++)
6131 {
6132 if (val[u] == '\0')
6133 break;
6134 }
6135 }
6136 if (val[u] != '\0')
6137 user_len = SM_MIN(len, user_len);
6138
6139 (void) sm_strlcpy(user, val, user_len);
6140 }
6141 #endif /* SASL */
6142