1/*++
2/* NAME
3/*	smtpd 3h
4/* SUMMARY
5/*	smtp server
6/* SYNOPSIS
7/*	include "smtpd.h"
8/* DESCRIPTION
9/* .nf
10
11 /*
12  * System library.
13  */
14#include <sys/time.h>
15#include <unistd.h>
16
17 /*
18  * Utility library.
19  */
20#include <vstream.h>
21#include <vstring.h>
22#include <argv.h>
23#include <myaddrinfo.h>
24
25 /*
26  * Global library.
27  */
28#include <mail_stream.h>
29
30 /*
31  * Postfix TLS library.
32  */
33#include <tls.h>
34
35 /*
36  * Milter library.
37  */
38#include <milter.h>
39
40 /*
41  * Variables that keep track of conversation state. There is only one SMTP
42  * conversation at a time, so the state variables can be made global. And
43  * some of this has to be global anyway, so that the run-time error handler
44  * can clean up in case of a fatal error deep down in some library routine.
45  */
46typedef struct SMTPD_DEFER {
47    int     active;			/* is this active */
48    VSTRING *reason;			/* reason for deferral */
49    VSTRING *dsn;			/* DSN detail */
50    int     code;			/* SMTP reply code */
51    int     class;			/* error notification class */
52} SMTPD_DEFER;
53
54typedef struct {
55    int     flags;			/* XFORWARD server state */
56    char   *name;			/* name for access control */
57    char   *addr;			/* address for access control */
58    char   *port;			/* port for logging */
59    char   *namaddr;			/* name[address]:port */
60    char   *rfc_addr;			/* address for RFC 2821 */
61    char   *protocol;			/* email protocol */
62    char   *helo_name;			/* helo/ehlo parameter */
63    char   *ident;			/* local message identifier */
64    char   *domain;			/* rewrite context */
65} SMTPD_XFORWARD_ATTR;
66
67typedef struct {
68    int     flags;			/* see below */
69    int     err;			/* cleanup server/queue file errors */
70    VSTREAM *client;			/* SMTP client handle */
71    VSTRING *buffer;			/* SMTP client buffer */
72    VSTRING *addr_buf;			/* internalized address buffer */
73    char   *service;			/* for event rate control */
74    struct timeval arrival_time;	/* start of MAIL FROM transaction */
75    char   *name;			/* verified client hostname */
76    char   *reverse_name;		/* unverified client hostname */
77    char   *addr;			/* client host address string */
78    char   *port;			/* port for logging */
79    char   *namaddr;			/* name[address]:port */
80    char   *rfc_addr;			/* address for RFC 2821 */
81    int     addr_family;		/* address family */
82    struct sockaddr_storage sockaddr;	/* binary client endpoint */
83    int     name_status;		/* 2=ok 4=soft 5=hard 6=forged */
84    int     reverse_name_status;	/* 2=ok 4=soft 5=hard */
85    int     conn_count;			/* connections from this client */
86    int     conn_rate;			/* connection rate for this client */
87    int     error_count;		/* reset after DOT */
88    int     error_mask;			/* client errors */
89    int     notify_mask;		/* what to report to postmaster */
90    char   *helo_name;			/* client HELO/EHLO argument */
91    char   *queue_id;			/* from cleanup server/queue file */
92    VSTREAM *cleanup;			/* cleanup server/queue file handle */
93    MAIL_STREAM *dest;			/* another server/file handle */
94    int     rcpt_count;			/* number of accepted recipients */
95    char   *access_denied;		/* fixme */
96    ARGV   *history;			/* protocol transcript */
97    char   *reason;			/* cause of connection loss */
98    char   *sender;			/* sender address */
99    char   *encoding;			/* owned by mail_cmd() */
100    char   *verp_delims;		/* owned by mail_cmd() */
101    char   *recipient;			/* recipient address */
102    char   *etrn_name;			/* client ETRN argument */
103    char   *protocol;			/* SMTP or ESMTP */
104    char   *where;			/* protocol stage */
105    int     recursion;			/* Kellerspeicherpegelanzeiger */
106    int	    chunking;			/* APPLE - RFC 3030 */
107    void   *chunking_context;		/* APPLE - RFC 3030 */
108    off_t   msg_size;			/* MAIL FROM message size */
109    off_t   act_size;			/* END-OF-DATA message size */
110    int     junk_cmds;			/* counter */
111    int     rcpt_overshoot;		/* counter */
112    char   *rewrite_context;		/* address rewriting context */
113
114    /*
115     * SASL specific.
116     */
117#ifdef USE_SASL_AUTH
118    struct XSASL_SERVER *sasl_server;
119    VSTRING *sasl_reply;
120    char   *sasl_mechanism_list;
121    char   *sasl_method;
122    char   *sasl_username;
123    char   *sasl_sender;
124#endif
125
126    /*
127     * Specific to smtpd access checks.
128     */
129    int     sender_rcptmap_checked;	/* sender validated against maps */
130    int     recipient_rcptmap_checked;	/* recipient validated against maps */
131    int     warn_if_reject;		/* force reject into warning */
132    SMTPD_DEFER defer_if_reject;	/* force reject into deferral */
133    SMTPD_DEFER defer_if_permit;	/* force permit into deferral */
134    int     defer_if_permit_client;	/* force permit into warning */
135    int     defer_if_permit_helo;	/* force permit into warning */
136    int     defer_if_permit_sender;	/* force permit into warning */
137    int     discard;			/* discard message */
138    char   *saved_filter;		/* postponed filter action */
139    char   *saved_redirect;		/* postponed redirect action */
140    char   *saved_bcc;			/* postponed bcc action */
141    int     saved_flags;		/* postponed hold/discard */
142#ifdef DELAY_ACTION
143    int     saved_delay;		/* postponed deferred delay */
144#endif
145    VSTRING *expand_buf;		/* scratch space for $name expansion */
146    ARGV   *prepend;			/* prepended headers */
147    VSTRING *instance;			/* policy query correlation */
148    int     seqno;			/* policy query correlation */
149    int     ehlo_discard_mask;		/* suppressed EHLO features */
150    char   *dsn_envid;			/* temporary MAIL FROM state */
151    int     dsn_ret;			/* temporary MAIL FROM state */
152    VSTRING *dsn_buf;			/* scratch space for xtext expansion */
153    VSTRING *dsn_orcpt_buf;		/* scratch space for ORCPT parsing */
154
155    /*
156     * Pass-through proxy client.
157     */
158    struct SMTPD_PROXY *proxy;
159    char   *proxy_mail;			/* owned by mail_cmd() */
160
161    /*
162     * XFORWARD server state.
163     */
164    SMTPD_XFORWARD_ATTR xforward;	/* up-stream logging info */
165
166    /*
167     * TLS related state.
168     */
169#ifdef USE_TLS
170#ifdef USE_TLSPROXY
171    VSTREAM *tlsproxy;			/* tlsproxy(8) temp. handle */
172#endif
173    TLS_SESS_STATE *tls_context;	/* TLS session state */
174#endif
175
176    /*
177     * Milter support.
178     */
179    const char **milter_argv;		/* SMTP command vector */
180    ssize_t milter_argc;		/* SMTP command vector */
181    const char *milter_reject_text;	/* input to call-back from Milter */
182
183    /*
184     * EHLO temporary space.
185     */
186    VSTRING *ehlo_buf;
187    ARGV   *ehlo_argv;
188} SMTPD_STATE;
189
190#define SMTPD_FLAG_HANGUP	   (1<<0)	/* 421/521 disconnect */
191#define SMTPD_FLAG_ILL_PIPELINING  (1<<1)	/* inappropriate pipelining */
192#define SMTPD_FLAG_AUTH_USED	   (1<<2)	/* don't reuse SASL state */
193
194 /* Security: don't reset SMTPD_FLAG_AUTH_USED. */
195#define SMTPD_MASK_MAIL_KEEP		~0	/* keep all after MAIL reset */
196
197#define SMTPD_STATE_XFORWARD_INIT  (1<<0)	/* xforward preset done */
198#define SMTPD_STATE_XFORWARD_NAME  (1<<1)	/* client name received */
199#define SMTPD_STATE_XFORWARD_ADDR  (1<<2)	/* client address received */
200#define SMTPD_STATE_XFORWARD_PROTO (1<<3)	/* protocol received */
201#define SMTPD_STATE_XFORWARD_HELO  (1<<4)	/* client helo received */
202#define SMTPD_STATE_XFORWARD_IDENT (1<<5)	/* message identifier */
203#define SMTPD_STATE_XFORWARD_DOMAIN (1<<6)	/* address context */
204#define SMTPD_STATE_XFORWARD_PORT  (1<<7)	/* client port received */
205
206#define SMTPD_STATE_XFORWARD_CLIENT_MASK \
207	(SMTPD_STATE_XFORWARD_NAME | SMTPD_STATE_XFORWARD_ADDR \
208	| SMTPD_STATE_XFORWARD_PROTO | SMTPD_STATE_XFORWARD_HELO \
209	| SMTPD_STATE_XFORWARD_PORT)
210
211/* APPLE - RFC 3030 */
212#define SMTPD_CHUNKING		    (1 << 0)	/* BURL or BDAT used */
213#define SMTPD_CHUNKING_CONT	    (1 << 1)	/* non-LAST used */
214#define SMTPD_CHUNKING_LAST	    (1 << 2)	/* LAST */
215#define SMTPD_CHUNKING_BINARYMIME   (1 << 3)	/* BODY=BINARYMIME */
216#define SMTPD_CHUNKING_NONZERO	    (1 << 4)	/* read >= 1 byte */
217
218extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *);
219extern void smtpd_state_reset(SMTPD_STATE *);
220
221 /*
222  * Conversation stages.  This is used for "lost connection after XXX"
223  * diagnostics.
224  */
225#define SMTPD_AFTER_CONNECT	"CONNECT"
226#define SMTPD_AFTER_DATA	"DATA content"
227#define SMTPD_AFTER_DOT		"END-OF-MESSAGE"
228
229 /*
230  * Other stages. These are sometimes used to change the way information is
231  * logged or what information will be available for access control.
232  */
233#define SMTPD_CMD_HELO		"HELO"
234#define SMTPD_CMD_EHLO		"EHLO"
235#define SMTPD_CMD_STARTTLS	"STARTTLS"
236#define SMTPD_CMD_AUTH		"AUTH"
237#define SMTPD_CMD_MAIL		"MAIL"
238#define SMTPD_CMD_RCPT		"RCPT"
239#define SMTPD_CMD_DATA		"DATA"
240#define SMTPD_CMD_BURL		"BURL"			/* APPLE - burl */
241#define SMTPD_CMD_BDAT		"BDAT"			/* APPLE - RFC 3030 */
242#define SMTPD_CMD_EOD		SMTPD_AFTER_DOT	/* XXX Was: END-OF-DATA */
243#define SMTPD_CMD_RSET		"RSET"
244#define SMTPD_CMD_NOOP		"NOOP"
245#define SMTPD_CMD_VRFY		"VRFY"
246#define SMTPD_CMD_ETRN		"ETRN"
247#define SMTPD_CMD_QUIT		"QUIT"
248#define SMTPD_CMD_XCLIENT	"XCLIENT"
249#define SMTPD_CMD_XFORWARD	"XFORWARD"
250#define SMTPD_CMD_UNKNOWN	"UNKNOWN"
251
252 /*
253  * Representation of unknown and non-existent client information. Throughout
254  * Postfix, we use the "unknown" string value for unknown client information
255  * (e.g., unknown remote client hostname), and we use the empty string, null
256  * pointer or "no queue file record" for non-existent client information
257  * (e.g., no HELO command, or local submission).
258  *
259  * Inside the SMTP server, unknown real client attributes are represented by
260  * the string "unknown", and non-existent HELO is represented as a null
261  * pointer. The SMTP server uses this same representation internally for
262  * forwarded client attributes; the XFORWARD syntax makes no distinction
263  * between unknown (remote submission) and non-existent (local submission).
264  *
265  * The SMTP client sends forwarded client attributes only when upstream client
266  * attributes exist (i.e. remote submission). Thus, local submissions will
267  * appear to come from an SMTP-based content filter, which is acceptable.
268  *
269  * Known/unknown client attribute values use the SMTP server's internal
270  * representation in queue files, in queue manager delivery requests, and in
271  * delivery agent $name expansions.
272  *
273  * Non-existent attribute values are never present in queue files. Non-existent
274  * information is represented as empty strings in queue manager delivery
275  * requests and in delivery agent $name expansions.
276  */
277#define CLIENT_ATTR_UNKNOWN	"unknown"
278
279#define CLIENT_NAME_UNKNOWN	CLIENT_ATTR_UNKNOWN
280#define CLIENT_ADDR_UNKNOWN	CLIENT_ATTR_UNKNOWN
281#define CLIENT_PORT_UNKNOWN	CLIENT_ATTR_UNKNOWN
282#define CLIENT_NAMADDR_UNKNOWN	CLIENT_ATTR_UNKNOWN
283#define CLIENT_HELO_UNKNOWN	0
284#define CLIENT_PROTO_UNKNOWN	CLIENT_ATTR_UNKNOWN
285#define CLIENT_IDENT_UNKNOWN	0
286#define CLIENT_DOMAIN_UNKNOWN	0
287#define CLIENT_LOGIN_UNKNOWN	0
288
289#define IS_AVAIL_CLIENT_ATTR(v)	((v) && strcmp((v), CLIENT_ATTR_UNKNOWN))
290
291#define IS_AVAIL_CLIENT_NAME(v)	IS_AVAIL_CLIENT_ATTR(v)
292#define IS_AVAIL_CLIENT_ADDR(v)	IS_AVAIL_CLIENT_ATTR(v)
293#define IS_AVAIL_CLIENT_PORT(v)	IS_AVAIL_CLIENT_ATTR(v)
294#define IS_AVAIL_CLIENT_NAMADDR(v) IS_AVAIL_CLIENT_ATTR(v)
295#define IS_AVAIL_CLIENT_HELO(v)	((v) != 0)
296#define IS_AVAIL_CLIENT_PROTO(v) IS_AVAIL_CLIENT_ATTR(v)
297#define IS_AVAIL_CLIENT_IDENT(v) ((v) != 0)
298#define IS_AVAIL_CLIENT_DOMAIN(v) ((v) != 0)
299
300 /*
301  * If running in stand-alone mode, do not try to talk to Postfix daemons but
302  * write to queue file instead.
303  */
304#define SMTPD_STAND_ALONE_STREAM(stream) \
305	(stream == VSTREAM_IN && getuid() != var_owner_uid)
306
307#define SMTPD_STAND_ALONE(state) \
308	(state->client == VSTREAM_IN && getuid() != var_owner_uid)
309
310 /*
311  * If running as proxy front-end, disable actions that require communication
312  * with the cleanup server.
313  */
314#define USE_SMTPD_PROXY(state) \
315	(SMTPD_STAND_ALONE(state) == 0 && *var_smtpd_proxy_filt)
316
317 /*
318  * SMTPD peer information lookup.
319  */
320extern void smtpd_peer_init(SMTPD_STATE *state);
321extern void smtpd_peer_reset(SMTPD_STATE *state);
322
323#define	SMTPD_PEER_CODE_OK	2
324#define SMTPD_PEER_CODE_TEMP	4
325#define SMTPD_PEER_CODE_PERM	5
326#define SMTPD_PEER_CODE_FORGED	6
327
328 /*
329  * Construct name[addr] or name[addr]:port as appropriate
330  */
331#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \
332	concatenate((name), "[", (addr), "]", \
333		    var_smtpd_client_port_log ? ":" : (char *) 0, \
334		    (port), (char *) 0)
335
336 /*
337  * Don't mix information from the current SMTP session with forwarded
338  * information from an up-stream session.
339  */
340#define HAVE_FORWARDED_CLIENT_ATTR(s) \
341	((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK)
342
343#define FORWARD_CLIENT_ATTR(s, a) \
344	(HAVE_FORWARDED_CLIENT_ATTR(s) ? \
345	    (s)->xforward.a : (s)->a)
346
347#define FORWARD_ADDR(s)		FORWARD_CLIENT_ATTR((s), rfc_addr)
348#define FORWARD_NAME(s)		FORWARD_CLIENT_ATTR((s), name)
349#define FORWARD_NAMADDR(s)	FORWARD_CLIENT_ATTR((s), namaddr)
350#define FORWARD_PROTO(s)	FORWARD_CLIENT_ATTR((s), protocol)
351#define FORWARD_HELO(s)		FORWARD_CLIENT_ATTR((s), helo_name)
352#define FORWARD_PORT(s)		FORWARD_CLIENT_ATTR((s), port)
353
354 /*
355  * Mixing is not a problem with forwarded local message identifiers.
356  */
357#define HAVE_FORWARDED_IDENT(s) \
358	((s)->xforward.ident != 0)
359
360#define FORWARD_IDENT(s) \
361	(HAVE_FORWARDED_IDENT(s) ? \
362	    (s)->xforward.ident : (s)->queue_id)
363
364 /*
365  * Mixing is not a problem with forwarded address rewriting contexts.
366  */
367#define FORWARD_DOMAIN(s) \
368	(((s)->xforward.flags & SMTPD_STATE_XFORWARD_DOMAIN) ? \
369	    (s)->xforward.domain : (s)->rewrite_context)
370
371extern void smtpd_xforward_init(SMTPD_STATE *);
372extern void smtpd_xforward_preset(SMTPD_STATE *);
373extern void smtpd_xforward_reset(SMTPD_STATE *);
374
375 /*
376  * Transparency: before mail is queued, do we check for unknown recipients,
377  * do we allow address mapping, automatic bcc, header/body checks?
378  */
379extern int smtpd_input_transp_mask;
380
381 /*
382  * More Milter support.
383  */
384extern MILTERS *smtpd_milters;
385
386 /*
387  * Message size multiplication factor for free space check.
388  */
389extern double smtpd_space_multf;
390
391#ifdef __APPLE_OS_X_SERVER__
392#define PW_SERVER_NONE			0x0000
393#define PW_SERVER_LOGIN			0x0001
394#define PW_SERVER_PLAIN			0x0002
395#define PW_SERVER_CRAM_MD5		0x0004
396#define PW_SERVER_DIGEST_MD5		0x0008
397#define PW_SERVER_GSSAPI		0x0010
398
399extern int		smtpd_pw_server_sasl_opts;
400#endif /* __APPLE_OS_X_SERVER__ */
401
402/* LICENSE
403/* .ad
404/* .fi
405/*	The Secure Mailer license must be distributed with this software.
406/* AUTHOR(S)
407/*	Wietse Venema
408/*	IBM T.J. Watson Research
409/*	P.O. Box 704
410/*	Yorktown Heights, NY 10598, USA
411/*
412/*	TLS support originally by:
413/*	Lutz Jaenicke
414/*	BTU Cottbus
415/*	Allgemeine Elektrotechnik
416/*	Universitaetsplatz 3-4
417/*	D-03044 Cottbus, Germany
418/*--*/
419