1/*++
2/* NAME
3/*	smtp 3h
4/* SUMMARY
5/*	smtp client program
6/* SYNOPSIS
7/*	#include "smtp.h"
8/* DESCRIPTION
9/* .nf
10
11 /*
12  * System library.
13  */
14#include <string.h>
15
16 /*
17  * Utility library.
18  */
19#include <vstream.h>
20#include <vstring.h>
21#include <argv.h>
22#include <htable.h>
23#include <dict.h>
24
25 /*
26  * Global library.
27  */
28#include <deliver_request.h>
29#include <scache.h>
30#include <string_list.h>
31#include <maps.h>
32#include <tok822.h>
33#include <dsn_buf.h>
34#include <header_body_checks.h>
35
36 /*
37  * Postfix TLS library.
38  */
39#include <tls.h>
40
41 /*
42  * Global iterator support. This is updated by the connection-management
43  * loop, and contains dynamic context that appears in lookup keys for SASL
44  * passwords, TLS policy, cached SMTP connections, and cached TLS session
45  * keys.
46  *
47  * For consistency and maintainability, context that is used in more than one
48  * lookup key is formatted with smtp_key_format().
49  */
50typedef struct SMTP_ITERATOR {
51    /* Public members. */
52    VSTRING *request_nexthop;		/* request nexhop or empty */
53    VSTRING *dest;			/* current nexthop */
54    VSTRING *host;			/* hostname or empty */
55    VSTRING *addr;			/* printable address or empty */
56    unsigned port;			/* network byte order or null */
57    struct DNS_RR *rr;			/* DNS resource record or null */
58    struct DNS_RR *mx;			/* DNS resource record or null */
59    /* Private members. */
60    VSTRING *saved_dest;		/* saved current nexthop */
61    struct SMTP_STATE *parent;		/* parent linkage */
62} SMTP_ITERATOR;
63
64#define SMTP_ITER_INIT(iter, _dest, _host, _addr, _port, state) do { \
65	vstring_strcpy((iter)->dest, (_dest)); \
66	vstring_strcpy((iter)->host, (_host)); \
67	vstring_strcpy((iter)->addr, (_addr)); \
68	(iter)->port = (_port); \
69	(iter)->mx = (iter)->rr = 0; \
70	vstring_strcpy((iter)->saved_dest, ""); \
71	(iter)->parent = (state); \
72    } while (0)
73
74#define SMTP_ITER_CLOBBER(iter, _dest, _host, _addr) do { \
75	vstring_strcpy((iter)->dest, (_dest)); \
76	vstring_strcpy((iter)->host, (_host)); \
77	vstring_strcpy((iter)->addr, (_addr)); \
78    } while (0)
79
80#define SMTP_ITER_SAVE_DEST(iter) do { \
81	vstring_strcpy((iter)->saved_dest, STR((iter)->dest)); \
82    } while (0)
83
84#define SMTP_ITER_RESTORE_DEST(iter) do { \
85	vstring_strcpy((iter)->dest, STR((iter)->saved_dest)); \
86    } while (0)
87
88 /*
89  * TLS Policy support.
90  */
91#ifdef USE_TLS
92
93typedef struct SMTP_TLS_POLICY {
94    int     level;			/* TLS enforcement level */
95    char   *protocols;			/* Acceptable SSL protocols */
96    char   *grade;			/* Cipher grade: "export", ... */
97    VSTRING *exclusions;		/* Excluded SSL ciphers */
98    ARGV   *matchargv;			/* Cert match patterns */
99    DSN_BUF *why;			/* Lookup error status */
100    TLS_DANE *dane;			/* DANE TLSA digests */
101} SMTP_TLS_POLICY;
102
103 /*
104  * smtp_tls_policy.c
105  */
106extern void smtp_tls_list_init(void);
107extern int smtp_tls_policy_cache_query(DSN_BUF *, SMTP_TLS_POLICY *, SMTP_ITERATOR *);
108extern void smtp_tls_policy_cache_flush(void);
109
110 /*
111  * Macros must use distinct names for local temporary variables, otherwise
112  * there will be bugs due to shadowing. This happened when an earlier
113  * version of smtp_tls_policy_dummy() invoked smtp_tls_policy_init(), but it
114  * could also happen without macro nesting.
115  *
116  * General principle: use all or part of the macro name in each temporary
117  * variable name. Then, append suffixes to the names if needed.
118  */
119#define smtp_tls_policy_dummy(t) do { \
120	SMTP_TLS_POLICY *_tls_policy_dummy_tmp = (t); \
121	smtp_tls_policy_init(_tls_policy_dummy_tmp, (DSN_BUF *) 0); \
122	_tls_policy_dummy_tmp->level = TLS_LEV_NONE; \
123    } while (0)
124
125 /* This macro is not part of the module external interface. */
126#define smtp_tls_policy_init(t, w) do { \
127	SMTP_TLS_POLICY *_tls_policy_init_tmp = (t); \
128	_tls_policy_init_tmp->protocols = 0; \
129	_tls_policy_init_tmp->grade = 0; \
130	_tls_policy_init_tmp->exclusions = 0; \
131	_tls_policy_init_tmp->matchargv = 0; \
132	_tls_policy_init_tmp->why = (w); \
133	_tls_policy_init_tmp->dane = 0; \
134    } while (0)
135
136#endif
137
138 /*
139  * State information associated with each SMTP delivery request.
140  * Session-specific state is stored separately.
141  */
142typedef struct SMTP_STATE {
143    int     misc_flags;			/* processing flags, see below */
144    VSTREAM *src;			/* queue file stream */
145    const char *service;		/* transport name */
146    DELIVER_REQUEST *request;		/* envelope info, offsets */
147    struct SMTP_SESSION *session;	/* network connection */
148    int     status;			/* delivery status */
149    ssize_t space_left;			/* output length control */
150
151    /*
152     * Global iterator.
153     */
154    SMTP_ITERATOR iterator[1];		/* Usage: state->iterator->member */
155
156    /*
157     * Global iterator.
158     */
159#ifdef USE_TLS
160    SMTP_TLS_POLICY tls[1];		/* Usage: state->tls->member */
161#endif
162
163    /*
164     * Connection cache support.
165     */
166    HTABLE *cache_used;			/* cached addresses that were used */
167    VSTRING *dest_label;		/* cached logical/physical binding */
168    VSTRING *dest_prop;			/* binding properties, passivated */
169    VSTRING *endp_label;		/* cached session physical endpoint */
170    VSTRING *endp_prop;			/* endpoint properties, passivated */
171
172    /*
173     * Flags and counters to control the handling of mail delivery errors.
174     * There is some redundancy for sanity checking. At the end of an SMTP
175     * session all recipients should be marked one way or the other.
176     */
177    int     rcpt_left;			/* recipients left over */
178    int     rcpt_drop;			/* recipients marked as drop */
179    int     rcpt_keep;			/* recipients marked as keep */
180
181    /*
182     * DSN Support introduced major bloat in error processing.
183     */
184    DSN_BUF *why;			/* on-the-fly formatting buffer */
185} SMTP_STATE;
186
187 /*
188  * TODO: use the new SMTP_ITER name space.
189  */
190#define SET_NEXTHOP_STATE(state, nexthop) { \
191	vstring_strcpy((state)->iterator->request_nexthop, nexthop); \
192    }
193
194#define FREE_NEXTHOP_STATE(state) { \
195	STR((state)->iterator->request_nexthop)[0] = 0; \
196    }
197
198#define HAVE_NEXTHOP_STATE(state) (STR((state)->iterator->request_nexthop) != 0)
199
200
201 /*
202  * Server features.
203  */
204#define SMTP_FEATURE_ESMTP		(1<<0)
205#define SMTP_FEATURE_8BITMIME		(1<<1)
206#define SMTP_FEATURE_PIPELINING		(1<<2)
207#define SMTP_FEATURE_SIZE		(1<<3)
208#define SMTP_FEATURE_STARTTLS		(1<<4)
209#define SMTP_FEATURE_AUTH		(1<<5)
210#define SMTP_FEATURE_XFORWARD_NAME	(1<<7)
211#define SMTP_FEATURE_XFORWARD_ADDR	(1<<8)
212#define SMTP_FEATURE_XFORWARD_PROTO	(1<<9)
213#define SMTP_FEATURE_XFORWARD_HELO	(1<<10)
214#define SMTP_FEATURE_XFORWARD_DOMAIN	(1<<11)
215#define SMTP_FEATURE_BEST_MX		(1<<12)	/* for next-hop or fall-back */
216#define SMTP_FEATURE_RSET_REJECTED	(1<<13)	/* RSET probe rejected */
217#define SMTP_FEATURE_FROM_CACHE		(1<<14)	/* cached connection */
218#define SMTP_FEATURE_DSN		(1<<15)	/* DSN supported */
219#define SMTP_FEATURE_PIX_NO_ESMTP	(1<<16)	/* PIX smtp fixup mode */
220#define SMTP_FEATURE_PIX_DELAY_DOTCRLF	(1<<17)	/* PIX smtp fixup mode */
221#define SMTP_FEATURE_XFORWARD_PORT	(1<<18)
222#define SMTP_FEATURE_EARLY_TLS_MAIL_REPLY (1<<19)	/* CVE-2009-3555 */
223#define SMTP_FEATURE_XFORWARD_IDENT	(1<<20)
224
225 /*
226  * Features that passivate under the endpoint.
227  */
228#define SMTP_FEATURE_ENDPOINT_MASK \
229	(~(SMTP_FEATURE_BEST_MX | SMTP_FEATURE_RSET_REJECTED \
230	| SMTP_FEATURE_FROM_CACHE))
231
232 /*
233  * Features that passivate under the logical destination.
234  */
235#define SMTP_FEATURE_DESTINATION_MASK (SMTP_FEATURE_BEST_MX)
236
237 /*
238  * Misc flags.
239  */
240#define SMTP_MISC_FLAG_LOOP_DETECT	(1<<0)
241#define	SMTP_MISC_FLAG_IN_STARTTLS	(1<<1)
242#define SMTP_MISC_FLAG_FIRST_NEXTHOP	(1<<2)
243#define SMTP_MISC_FLAG_FINAL_NEXTHOP	(1<<3)
244#define SMTP_MISC_FLAG_FINAL_SERVER	(1<<4)
245#define SMTP_MISC_FLAG_CONN_LOAD	(1<<5)
246#define SMTP_MISC_FLAG_CONN_STORE	(1<<6)
247#define SMTP_MISC_FLAG_COMPLETE_SESSION	(1<<7)
248#define SMTP_MISC_FLAG_PREF_IPV6	(1<<8)
249#define SMTP_MISC_FLAG_PREF_IPV4	(1<<9)
250
251#define SMTP_MISC_FLAG_CONN_CACHE_MASK \
252	(SMTP_MISC_FLAG_CONN_LOAD | SMTP_MISC_FLAG_CONN_STORE)
253
254 /*
255  * smtp.c
256  */
257#define SMTP_HAS_DSN(why)	(STR((why)->status)[0] != 0)
258#define SMTP_HAS_SOFT_DSN(why)	(STR((why)->status)[0] == '4')
259#define SMTP_HAS_HARD_DSN(why)	(STR((why)->status)[0] == '5')
260#define SMTP_HAS_LOOP_DSN(why) \
261    (SMTP_HAS_DSN(why) && strcmp(STR((why)->status) + 1, ".4.6") == 0)
262
263#define SMTP_SET_SOFT_DSN(why)	(STR((why)->status)[0] = '4')
264#define SMTP_SET_HARD_DSN(why)	(STR((why)->status)[0] = '5')
265
266extern int smtp_host_lookup_mask;	/* host lookup methods to use */
267
268#define SMTP_HOST_FLAG_DNS	(1<<0)
269#define SMTP_HOST_FLAG_NATIVE	(1<<1)
270
271extern int smtp_dns_support;		/* dns support level */
272
273#define SMTP_DNS_INVALID	(-1)	/* smtp_dns_support_level = <bogus> */
274#define SMTP_DNS_DISABLED	0	/* smtp_dns_support_level = disabled */
275#define SMTP_DNS_ENABLED	1	/* smtp_dns_support_level = enabled */
276#define SMTP_DNS_DNSSEC		2	/* smtp_dns_support_level = dnssec */
277
278extern SCACHE *smtp_scache;		/* connection cache instance */
279extern STRING_LIST *smtp_cache_dest;	/* cached destinations */
280
281extern MAPS *smtp_ehlo_dis_maps;	/* ehlo keyword filter */
282
283extern MAPS *smtp_pix_bug_maps;		/* PIX workarounds */
284
285extern MAPS *smtp_generic_maps;		/* make internal address valid */
286extern int smtp_ext_prop_mask;		/* address externsion propagation */
287extern unsigned smtp_dns_res_opt;	/* DNS query flags */
288
289#ifdef USE_TLS
290
291extern TLS_APPL_STATE *smtp_tls_ctx;	/* client-side TLS engine */
292
293#endif
294
295extern HBC_CHECKS *smtp_header_checks;	/* limited header checks */
296extern HBC_CHECKS *smtp_body_checks;	/* limited body checks */
297
298 /*
299  * smtp_session.c
300  */
301
302typedef struct SMTP_SESSION {
303    VSTREAM *stream;			/* network connection */
304    SMTP_ITERATOR *iterator;		/* dest, host, addr, port */
305    char   *namaddr;			/* mail exchanger */
306    char   *helo;			/* helo response */
307    unsigned port;			/* network byte order */
308    char   *namaddrport;		/* mail exchanger, incl. port */
309
310    VSTRING *buffer;			/* I/O buffer */
311    VSTRING *scratch;			/* scratch buffer */
312    VSTRING *scratch2;			/* scratch buffer */
313
314    int     features;			/* server features */
315    off_t   size_limit;			/* server limit or unknown */
316
317    ARGV   *history;			/* transaction log */
318    int     error_mask;			/* error classes */
319    struct MIME_STATE *mime_state;	/* mime state machine */
320
321    int     send_proto_helo;		/* XFORWARD support */
322
323    time_t  expire_time;		/* session reuse expiration time */
324    int     reuse_count;		/* # of times reused (for logging) */
325    int     dead;			/* No further I/O allowed */
326
327#ifdef USE_SASL_AUTH
328    char   *sasl_mechanism_list;	/* server mechanism list */
329    char   *sasl_username;		/* client username */
330    char   *sasl_passwd;		/* client password */
331    struct XSASL_CLIENT *sasl_client;	/* SASL internal state */
332    VSTRING *sasl_reply;		/* client response */
333#endif
334
335    /*
336     * TLS related state, don't forget to initialize in session_tls_init()!
337     */
338#ifdef USE_TLS
339    TLS_SESS_STATE *tls_context;	/* TLS library session state */
340    char   *tls_nexthop;		/* Nexthop domain for cert checks */
341    int     tls_retry_plain;		/* Try plain when TLS handshake fails */
342    SMTP_TLS_POLICY *tls;		/* TEMPORARY */
343#endif
344
345    SMTP_STATE *state;			/* back link */
346} SMTP_SESSION;
347
348extern SMTP_SESSION *smtp_session_alloc(VSTREAM *, SMTP_ITERATOR *, time_t, int);
349extern void smtp_session_new_stream(SMTP_SESSION *, VSTREAM *, time_t, int);
350extern int smtp_sess_plaintext_ok(SMTP_ITERATOR *, int);
351extern void smtp_session_free(SMTP_SESSION *);
352extern int smtp_session_passivate(SMTP_SESSION *, VSTRING *, VSTRING *);
353extern SMTP_SESSION *smtp_session_activate(int, SMTP_ITERATOR *, VSTRING *, VSTRING *);
354
355 /*
356  * What's in a name?
357  */
358#define SMTP_HNAME(rr) (var_smtp_cname_overr ? (rr)->rname : (rr)->qname)
359
360 /*
361  * smtp_connect.c
362  */
363extern int smtp_connect(SMTP_STATE *);
364
365 /*
366  * smtp_proto.c
367  */
368extern int smtp_helo(SMTP_STATE *);
369extern int smtp_xfer(SMTP_STATE *);
370extern int smtp_rset(SMTP_STATE *);
371extern int smtp_quit(SMTP_STATE *);
372
373extern HBC_CALL_BACKS smtp_hbc_callbacks[];
374
375 /*
376  * A connection is re-usable if session->expire_time is > 0 and the
377  * expiration time has not been reached.  This is subtle because the timer
378  * can expire between sending a command and receiving the reply for that
379  * command.
380  *
381  * But wait, there is more! When SMTP command pipelining is enabled, there are
382  * two protocol loops that execute at very different times: one loop that
383  * generates commands, and one loop that receives replies to those commands.
384  * These will be called "sender loop" and "receiver loop", respectively. At
385  * well-defined protocol synchronization points, the sender loop pauses to
386  * let the receiver loop catch up.
387  *
388  * When we choose to reuse a connection, both the sender and receiver protocol
389  * loops end with "." (mail delivery) or "RSET" (address probe). When we
390  * choose not to reuse, both the sender and receiver protocol loops end with
391  * "QUIT". The problem is that we must make the same protocol choices in
392  * both the sender and receiver loops, even though those loops may execute
393  * at completely different times.
394  *
395  * We "freeze" the choice in the sender loop, just before we generate "." or
396  * "RSET". The reader loop leaves the connection cachable even if the timer
397  * expires by the time the response arrives. The connection cleanup code
398  * will call smtp_quit() for connections with an expired cache expiration
399  * timer.
400  *
401  * We could have made the programmer's life a lot simpler by not making a
402  * choice at all, and always leaving it up to the connection cleanup code to
403  * call smtp_quit() for connections with an expired cache expiration timer.
404  *
405  * As a general principle, neither the sender loop nor the receiver loop must
406  * modify the connection caching state, if that can affect the receiver
407  * state machine for not-yet processed replies to already-generated
408  * commands. This restriction does not apply when we have to exit the
409  * protocol loops prematurely due to e.g., timeout or connection loss, so
410  * that those pending replies will never be received.
411  *
412  * But wait, there is even more! Only the first good connection for a specific
413  * destination may be cached under both the next-hop destination name and
414  * the server address; connections to alternate servers must be cached under
415  * the server address alone. This means we must distinguish between bad
416  * connections and other reasons why connections cannot be cached.
417  */
418#define THIS_SESSION_IS_CACHED \
419	(!THIS_SESSION_IS_DEAD && session->expire_time > 0)
420
421#define THIS_SESSION_IS_EXPIRED \
422	(THIS_SESSION_IS_CACHED \
423	    && (session->expire_time < vstream_ftime(session->stream) \
424		|| (var_smtp_reuse_count > 0 \
425		    && session->reuse_count >= var_smtp_reuse_count)))
426
427#define THIS_SESSION_IS_BAD \
428	(!THIS_SESSION_IS_DEAD && session->expire_time < 0)
429
430#define THIS_SESSION_IS_DEAD \
431	(session->dead != 0)
432
433 /* Bring the bad news. */
434
435#define DONT_CACHE_THIS_SESSION \
436	(session->expire_time = 0)
437
438#define DONT_CACHE_BAD_SESSION \
439	(session->expire_time = -1)
440
441#define DONT_USE_DEAD_SESSION \
442	(session->dead = 1)
443
444 /* Initialization. */
445
446#define USE_NEWBORN_SESSION \
447	(session->dead = 0)
448
449#define CACHE_THIS_SESSION_UNTIL(when) \
450	(session->expire_time = (when))
451
452 /*
453  * Encapsulate the following so that we don't expose details of of
454  * connection management and error handling to the SMTP protocol engine.
455  */
456#define RETRY_AS_PLAINTEXT do { \
457	session->tls_retry_plain = 1; \
458	state->misc_flags &= ~SMTP_MISC_FLAG_FINAL_SERVER; \
459    } while (0)
460
461 /*
462  * smtp_chat.c
463  */
464typedef struct SMTP_RESP {		/* server response */
465    int     code;			/* SMTP code */
466    const char *dsn;			/* enhanced status */
467    char   *str;			/* full reply */
468    VSTRING *dsn_buf;			/* status buffer */
469    VSTRING *str_buf;			/* reply buffer */
470} SMTP_RESP;
471
472extern void PRINTFLIKE(2, 3) smtp_chat_cmd(SMTP_SESSION *, const char *,...);
473extern DICT *smtp_chat_resp_filter;
474extern SMTP_RESP *smtp_chat_resp(SMTP_SESSION *);
475extern void smtp_chat_init(SMTP_SESSION *);
476extern void smtp_chat_reset(SMTP_SESSION *);
477extern void smtp_chat_notify(SMTP_SESSION *);
478
479#define SMTP_RESP_FAKE(resp, _dsn) \
480    ((resp)->code = 0, \
481     (resp)->dsn = (_dsn), \
482     (resp)->str = DSN_BY_LOCAL_MTA, \
483     (resp))
484
485#define DSN_BY_LOCAL_MTA	((char *) 0)	/* DSN issued by local MTA */
486
487 /*
488  * These operations implement a redundant mark-and-sweep algorithm that
489  * explicitly accounts for the fate of every recipient. The interface is
490  * documented in smtp_rcpt.c, which also implements the sweeping. The
491  * smtp_trouble.c module does most of the marking after failure.
492  *
493  * When a delivery fails or succeeds, take one of the following actions:
494  *
495  * - Mark the recipient as KEEP (deliver to alternate MTA) and do not update
496  * the delivery request status.
497  *
498  * - Mark the recipient as DROP (remove from delivery request), log whether
499  * delivery succeeded or failed, delete the recipient from the queue file
500  * and/or update defer or bounce logfiles, and update the delivery request
501  * status.
502  *
503  * At the end of a delivery attempt, all recipients must be marked one way or
504  * the other. Failure to do so will trigger a panic.
505  */
506#define SMTP_RCPT_STATE_KEEP	1	/* send to backup host */
507#define SMTP_RCPT_STATE_DROP	2	/* remove from request */
508#define SMTP_RCPT_INIT(state) do { \
509	    (state)->rcpt_drop = (state)->rcpt_keep = 0; \
510	    (state)->rcpt_left = state->request->rcpt_list.len; \
511	} while (0)
512
513#define SMTP_RCPT_DROP(state, rcpt) do { \
514	    (rcpt)->u.status = SMTP_RCPT_STATE_DROP; (state)->rcpt_drop++; \
515	} while (0)
516
517#define SMTP_RCPT_KEEP(state, rcpt) do { \
518	    (rcpt)->u.status = SMTP_RCPT_STATE_KEEP; (state)->rcpt_keep++; \
519	} while (0)
520
521#define SMTP_RCPT_ISMARKED(rcpt) ((rcpt)->u.status != 0)
522
523#define SMTP_RCPT_LEFT(state) (state)->rcpt_left
524
525extern void smtp_rcpt_cleanup(SMTP_STATE *);
526extern void smtp_rcpt_done(SMTP_STATE *, SMTP_RESP *, RECIPIENT *);
527
528 /*
529  * smtp_trouble.c
530  */
531extern int smtp_sess_fail(SMTP_STATE *);
532extern int PRINTFLIKE(4, 5) smtp_site_fail(SMTP_STATE *, const char *,
533				             SMTP_RESP *, const char *,...);
534extern int PRINTFLIKE(4, 5) smtp_mesg_fail(SMTP_STATE *, const char *,
535				             SMTP_RESP *, const char *,...);
536extern void PRINTFLIKE(5, 6) smtp_rcpt_fail(SMTP_STATE *, RECIPIENT *,
537					          const char *, SMTP_RESP *,
538					            const char *,...);
539extern int smtp_stream_except(SMTP_STATE *, int, const char *);
540
541 /*
542  * smtp_unalias.c
543  */
544extern const char *smtp_unalias_name(const char *);
545extern VSTRING *smtp_unalias_addr(VSTRING *, const char *);
546
547 /*
548  * smtp_state.c
549  */
550extern SMTP_STATE *smtp_state_alloc(void);
551extern void smtp_state_free(SMTP_STATE *);
552
553 /*
554  * smtp_map11.c
555  */
556extern int smtp_map11_external(VSTRING *, MAPS *, int);
557extern int smtp_map11_tree(TOK822 *, MAPS *, int);
558extern int smtp_map11_internal(VSTRING *, MAPS *, int);
559
560 /*
561  * smtp_key.c
562  */
563char   *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
564
565#define SMTP_KEY_FLAG_SERVICE		(1<<0)	/* service name */
566#define SMTP_KEY_FLAG_SENDER		(1<<1)	/* sender address */
567#define SMTP_KEY_FLAG_REQ_NEXTHOP	(1<<2)	/* request nexthop */
568#define SMTP_KEY_FLAG_NEXTHOP		(1<<3)	/* current nexthop */
569#define SMTP_KEY_FLAG_HOSTNAME		(1<<4)	/* remote host name */
570#define SMTP_KEY_FLAG_ADDR		(1<<5)	/* remote address */
571#define SMTP_KEY_FLAG_PORT		(1<<6)	/* remote port */
572
573#define SMTP_KEY_MASK_ALL \
574	(SMTP_KEY_FLAG_SERVICE | SMTP_KEY_FLAG_SENDER | \
575	SMTP_KEY_FLAG_REQ_NEXTHOP | \
576	SMTP_KEY_FLAG_NEXTHOP | SMTP_KEY_FLAG_HOSTNAME | \
577	SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT)
578
579 /*
580  * Conditional lookup-key flags for cached connections that may be
581  * SASL-authenticated with a per-{sender, nexthop, or hostname} credential.
582  * Each bit corresponds to one type of smtp_sasl_password_file lookup key,
583  * and is turned on only when the corresponding main.cf parameter is turned
584  * on.
585  */
586#define COND_SASL_SMTP_KEY_FLAG_SENDER \
587	((var_smtp_sender_auth && *var_smtp_sasl_passwd) ? \
588	    SMTP_KEY_FLAG_SENDER : 0)
589
590#define COND_SASL_SMTP_KEY_FLAG_NEXTHOP \
591	(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_NEXTHOP : 0)
592
593#define COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
594	(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_HOSTNAME : 0)
595
596 /*
597  * Connection-cache destination lookup key. The SENDER attribute is a proxy
598  * for sender-dependent SASL credentials (or absence thereof), and prevents
599  * false connection sharing when different SASL credentials may be required
600  * for different deliveries to the same domain and port. The SERVICE
601  * attribute is a proxy for all request-independent configuration details.
602  */
603#define SMTP_KEY_MASK_SCACHE_DEST_LABEL \
604	(SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
605	| SMTP_KEY_FLAG_REQ_NEXTHOP)
606
607 /*
608  * Connection-cache endpoint lookup key. The SENDER, NEXTHOP, and HOSTNAME
609  * attributes are proxies for SASL credentials (or absence thereof), and
610  * prevent false connection sharing when different SASL credentials may be
611  * required for different deliveries to the same IP address and port.
612  */
613#define SMTP_KEY_MASK_SCACHE_ENDP_LABEL \
614	(SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
615	| COND_SASL_SMTP_KEY_FLAG_NEXTHOP | COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
616	| SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT)
617
618 /*
619  * Silly little macros.
620  */
621#define STR(s) vstring_str(s)
622#define LEN(s) VSTRING_LEN(s)
623
624extern int smtp_mode;
625
626#define SMTP_X(x) (smtp_mode ? VAR_SMTP_##x : VAR_LMTP_##x)
627#define X_SMTP(x) (smtp_mode ? x##_SMTP : x##_LMTP)
628
629/* LICENSE
630/* .ad
631/* .fi
632/*	The Secure Mailer license must be distributed with this software.
633/* AUTHOR(S)
634/*	Wietse Venema
635/*	IBM T.J. Watson Research
636/*	P.O. Box 704
637/*	Yorktown Heights, NY 10598, USA
638/*
639/*	TLS support originally by:
640/*	Lutz Jaenicke
641/*	BTU Cottbus
642/*	Allgemeine Elektrotechnik
643/*	Universitaetsplatz 3-4
644/*	D-03044 Cottbus, Germany
645/*
646/*	Victor Duchovni
647/*	Morgan Stanley
648/*--*/
649