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    char   *dest_addr;			/* for Dovecot AUTH */
83    struct sockaddr_storage sockaddr;	/* binary client endpoint */
84    SOCKADDR_SIZE sockaddr_len;		/* binary client endpoint */
85    int     name_status;		/* 2=ok 4=soft 5=hard 6=forged */
86    int     reverse_name_status;	/* 2=ok 4=soft 5=hard */
87    int     conn_count;			/* connections from this client */
88    int     conn_rate;			/* connection rate for this client */
89    int     error_count;		/* reset after DOT */
90    int     error_mask;			/* client errors */
91    int     notify_mask;		/* what to report to postmaster */
92    char   *helo_name;			/* client HELO/EHLO argument */
93    char   *queue_id;			/* from cleanup server/queue file */
94    VSTREAM *cleanup;			/* cleanup server/queue file handle */
95    MAIL_STREAM *dest;			/* another server/file handle */
96    int     rcpt_count;			/* number of accepted recipients */
97    char   *access_denied;		/* fixme */
98    ARGV   *history;			/* protocol transcript */
99    char   *reason;			/* cause of connection loss */
100    char   *sender;			/* sender address */
101    char   *encoding;			/* owned by mail_cmd() */
102    char   *verp_delims;		/* owned by mail_cmd() */
103    char   *recipient;			/* recipient address */
104    char   *etrn_name;			/* client ETRN argument */
105    char   *protocol;			/* SMTP or ESMTP */
106    char   *where;			/* protocol stage */
107    int     recursion;			/* Kellerspeicherpegelanzeiger */
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
211extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *);
212extern void smtpd_state_reset(SMTPD_STATE *);
213
214 /*
215  * Conversation stages.  This is used for "lost connection after XXX"
216  * diagnostics.
217  */
218#define SMTPD_AFTER_CONNECT	"CONNECT"
219#define SMTPD_AFTER_DATA	"DATA content"
220#define SMTPD_AFTER_DOT		"END-OF-MESSAGE"
221
222 /*
223  * Other stages. These are sometimes used to change the way information is
224  * logged or what information will be available for access control.
225  */
226#define SMTPD_CMD_HELO		"HELO"
227#define SMTPD_CMD_EHLO		"EHLO"
228#define SMTPD_CMD_STARTTLS	"STARTTLS"
229#define SMTPD_CMD_AUTH		"AUTH"
230#define SMTPD_CMD_MAIL		"MAIL"
231#define SMTPD_CMD_RCPT		"RCPT"
232#define SMTPD_CMD_DATA		"DATA"
233#define SMTPD_CMD_EOD		SMTPD_AFTER_DOT	/* XXX Was: END-OF-DATA */
234#define SMTPD_CMD_RSET		"RSET"
235#define SMTPD_CMD_NOOP		"NOOP"
236#define SMTPD_CMD_VRFY		"VRFY"
237#define SMTPD_CMD_ETRN		"ETRN"
238#define SMTPD_CMD_QUIT		"QUIT"
239#define SMTPD_CMD_XCLIENT	"XCLIENT"
240#define SMTPD_CMD_XFORWARD	"XFORWARD"
241#define SMTPD_CMD_UNKNOWN	"UNKNOWN"
242
243 /*
244  * Representation of unknown and non-existent client information. Throughout
245  * Postfix, we use the "unknown" string value for unknown client information
246  * (e.g., unknown remote client hostname), and we use the empty string, null
247  * pointer or "no queue file record" for non-existent client information
248  * (e.g., no HELO command, or local submission).
249  *
250  * Inside the SMTP server, unknown real client attributes are represented by
251  * the string "unknown", and non-existent HELO is represented as a null
252  * pointer. The SMTP server uses this same representation internally for
253  * forwarded client attributes; the XFORWARD syntax makes no distinction
254  * between unknown (remote submission) and non-existent (local submission).
255  *
256  * The SMTP client sends forwarded client attributes only when upstream client
257  * attributes exist (i.e. remote submission). Thus, local submissions will
258  * appear to come from an SMTP-based content filter, which is acceptable.
259  *
260  * Known/unknown client attribute values use the SMTP server's internal
261  * representation in queue files, in queue manager delivery requests, and in
262  * delivery agent $name expansions.
263  *
264  * Non-existent attribute values are never present in queue files. Non-existent
265  * information is represented as empty strings in queue manager delivery
266  * requests and in delivery agent $name expansions.
267  */
268#define CLIENT_ATTR_UNKNOWN	"unknown"
269
270#define CLIENT_NAME_UNKNOWN	CLIENT_ATTR_UNKNOWN
271#define CLIENT_ADDR_UNKNOWN	CLIENT_ATTR_UNKNOWN
272#define CLIENT_PORT_UNKNOWN	CLIENT_ATTR_UNKNOWN
273#define CLIENT_NAMADDR_UNKNOWN	CLIENT_ATTR_UNKNOWN
274#define CLIENT_HELO_UNKNOWN	0
275#define CLIENT_PROTO_UNKNOWN	CLIENT_ATTR_UNKNOWN
276#define CLIENT_IDENT_UNKNOWN	0
277#define CLIENT_DOMAIN_UNKNOWN	0
278#define CLIENT_LOGIN_UNKNOWN	0
279
280#define IS_AVAIL_CLIENT_ATTR(v)	((v) && strcmp((v), CLIENT_ATTR_UNKNOWN))
281
282#define IS_AVAIL_CLIENT_NAME(v)	IS_AVAIL_CLIENT_ATTR(v)
283#define IS_AVAIL_CLIENT_ADDR(v)	IS_AVAIL_CLIENT_ATTR(v)
284#define IS_AVAIL_CLIENT_PORT(v)	IS_AVAIL_CLIENT_ATTR(v)
285#define IS_AVAIL_CLIENT_NAMADDR(v) IS_AVAIL_CLIENT_ATTR(v)
286#define IS_AVAIL_CLIENT_HELO(v)	((v) != 0)
287#define IS_AVAIL_CLIENT_PROTO(v) IS_AVAIL_CLIENT_ATTR(v)
288#define IS_AVAIL_CLIENT_IDENT(v) ((v) != 0)
289#define IS_AVAIL_CLIENT_DOMAIN(v) ((v) != 0)
290
291 /*
292  * If running in stand-alone mode, do not try to talk to Postfix daemons but
293  * write to queue file instead.
294  */
295#define SMTPD_STAND_ALONE_STREAM(stream) \
296	(stream == VSTREAM_IN && getuid() != var_owner_uid)
297
298#define SMTPD_STAND_ALONE(state) \
299	(state->client == VSTREAM_IN && getuid() != var_owner_uid)
300
301 /*
302  * If running as proxy front-end, disable actions that require communication
303  * with the cleanup server.
304  */
305#define USE_SMTPD_PROXY(state) \
306	(SMTPD_STAND_ALONE(state) == 0 && *var_smtpd_proxy_filt)
307
308 /*
309  * Are we in a MAIL transaction?
310  */
311#define SMTPD_IN_MAIL_TRANSACTION(state) ((state)->sender != 0)
312
313 /*
314  * SMTPD peer information lookup.
315  */
316extern void smtpd_peer_init(SMTPD_STATE *state);
317extern void smtpd_peer_reset(SMTPD_STATE *state);
318extern int smtpd_peer_from_haproxy(SMTPD_STATE *state);
319
320#define	SMTPD_PEER_CODE_OK	2
321#define SMTPD_PEER_CODE_TEMP	4
322#define SMTPD_PEER_CODE_PERM	5
323#define SMTPD_PEER_CODE_FORGED	6
324
325 /*
326  * Construct name[addr] or name[addr]:port as appropriate
327  */
328#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \
329	concatenate((name), "[", (addr), "]", \
330		    var_smtpd_client_port_log ? ":" : (char *) 0, \
331		    (port), (char *) 0)
332
333 /*
334  * Don't mix information from the current SMTP session with forwarded
335  * information from an up-stream session.
336  */
337#define HAVE_FORWARDED_CLIENT_ATTR(s) \
338	((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK)
339
340#define FORWARD_CLIENT_ATTR(s, a) \
341	(HAVE_FORWARDED_CLIENT_ATTR(s) ? \
342	    (s)->xforward.a : (s)->a)
343
344#define FORWARD_ADDR(s)		FORWARD_CLIENT_ATTR((s), rfc_addr)
345#define FORWARD_NAME(s)		FORWARD_CLIENT_ATTR((s), name)
346#define FORWARD_NAMADDR(s)	FORWARD_CLIENT_ATTR((s), namaddr)
347#define FORWARD_PROTO(s)	FORWARD_CLIENT_ATTR((s), protocol)
348#define FORWARD_HELO(s)		FORWARD_CLIENT_ATTR((s), helo_name)
349#define FORWARD_PORT(s)		FORWARD_CLIENT_ATTR((s), port)
350
351 /*
352  * Mixing is not a problem with forwarded local message identifiers.
353  */
354#define HAVE_FORWARDED_IDENT(s) \
355	((s)->xforward.ident != 0)
356
357#define FORWARD_IDENT(s) \
358	(HAVE_FORWARDED_IDENT(s) ? \
359	    (s)->xforward.ident : (s)->queue_id)
360
361 /*
362  * Mixing is not a problem with forwarded address rewriting contexts.
363  */
364#define FORWARD_DOMAIN(s) \
365	(((s)->xforward.flags & SMTPD_STATE_XFORWARD_DOMAIN) ? \
366	    (s)->xforward.domain : (s)->rewrite_context)
367
368extern void smtpd_xforward_init(SMTPD_STATE *);
369extern void smtpd_xforward_preset(SMTPD_STATE *);
370extern void smtpd_xforward_reset(SMTPD_STATE *);
371
372 /*
373  * Transparency: before mail is queued, do we check for unknown recipients,
374  * do we allow address mapping, automatic bcc, header/body checks?
375  */
376extern int smtpd_input_transp_mask;
377
378 /*
379  * More Milter support.
380  */
381extern MILTERS *smtpd_milters;
382
383 /*
384  * Message size multiplication factor for free space check.
385  */
386extern double smtpd_space_multf;
387
388/* LICENSE
389/* .ad
390/* .fi
391/*	The Secure Mailer license must be distributed with this software.
392/* AUTHOR(S)
393/*	Wietse Venema
394/*	IBM T.J. Watson Research
395/*	P.O. Box 704
396/*	Yorktown Heights, NY 10598, USA
397/*
398/*	TLS support originally by:
399/*	Lutz Jaenicke
400/*	BTU Cottbus
401/*	Allgemeine Elektrotechnik
402/*	Universitaetsplatz 3-4
403/*	D-03044 Cottbus, Germany
404/*--*/
405