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