Postfix3.3.1
smtp.h
[詳解]
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  */
50 typedef 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 */
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 
93 typedef 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  */
106 extern void smtp_tls_list_init(void);
107 extern int smtp_tls_policy_cache_query(DSN_BUF *, SMTP_TLS_POLICY *, SMTP_ITERATOR *);
108 extern 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  */
142 typedef 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] != 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 #define SMTP_FEATURE_SMTPUTF8 (1<<21) /* RFC 6531 */
225 
226  /*
227  * Features that passivate under the endpoint.
228  */
229 #define SMTP_FEATURE_ENDPOINT_MASK \
230  (~(SMTP_FEATURE_BEST_MX | SMTP_FEATURE_RSET_REJECTED \
231  | SMTP_FEATURE_FROM_CACHE))
232 
233  /*
234  * Features that passivate under the logical destination.
235  */
236 #define SMTP_FEATURE_DESTINATION_MASK (SMTP_FEATURE_BEST_MX)
237 
238  /*
239  * Misc flags.
240  */
241 #define SMTP_MISC_FLAG_LOOP_DETECT (1<<0)
242 #define SMTP_MISC_FLAG_IN_STARTTLS (1<<1)
243 #define SMTP_MISC_FLAG_FIRST_NEXTHOP (1<<2)
244 #define SMTP_MISC_FLAG_FINAL_NEXTHOP (1<<3)
245 #define SMTP_MISC_FLAG_FINAL_SERVER (1<<4)
246 #define SMTP_MISC_FLAG_CONN_LOAD (1<<5)
247 #define SMTP_MISC_FLAG_CONN_STORE (1<<6)
248 #define SMTP_MISC_FLAG_COMPLETE_SESSION (1<<7)
249 #define SMTP_MISC_FLAG_PREF_IPV6 (1<<8)
250 #define SMTP_MISC_FLAG_PREF_IPV4 (1<<9)
251 
252 #define SMTP_MISC_FLAG_CONN_CACHE_MASK \
253  (SMTP_MISC_FLAG_CONN_LOAD | SMTP_MISC_FLAG_CONN_STORE)
254 
255  /*
256  * smtp.c
257  */
258 #define SMTP_HAS_DSN(why) (STR((why)->status)[0] != 0)
259 #define SMTP_HAS_SOFT_DSN(why) (STR((why)->status)[0] == '4')
260 #define SMTP_HAS_HARD_DSN(why) (STR((why)->status)[0] == '5')
261 #define SMTP_HAS_LOOP_DSN(why) \
262  (SMTP_HAS_DSN(why) && strcmp(STR((why)->status) + 1, ".4.6") == 0)
263 
264 #define SMTP_SET_SOFT_DSN(why) (STR((why)->status)[0] = '4')
265 #define SMTP_SET_HARD_DSN(why) (STR((why)->status)[0] = '5')
266 
267 extern int smtp_host_lookup_mask; /* host lookup methods to use */
268 
269 #define SMTP_HOST_FLAG_DNS (1<<0)
270 #define SMTP_HOST_FLAG_NATIVE (1<<1)
271 
272 extern int smtp_dns_support; /* dns support level */
273 
274 #define SMTP_DNS_INVALID (-1) /* smtp_dns_support_level = <bogus> */
275 #define SMTP_DNS_DISABLED 0 /* smtp_dns_support_level = disabled */
276 #define SMTP_DNS_ENABLED 1 /* smtp_dns_support_level = enabled */
277 #define SMTP_DNS_DNSSEC 2 /* smtp_dns_support_level = dnssec */
278 
279 extern SCACHE *smtp_scache; /* connection cache instance */
280 extern STRING_LIST *smtp_cache_dest; /* cached destinations */
281 
282 extern MAPS *smtp_ehlo_dis_maps; /* ehlo keyword filter */
283 
284 extern MAPS *smtp_pix_bug_maps; /* PIX workarounds */
285 
286 extern MAPS *smtp_generic_maps; /* make internal address valid */
287 extern int smtp_ext_prop_mask; /* address externsion propagation */
288 extern unsigned smtp_dns_res_opt; /* DNS query flags */
289 
290 #ifdef USE_TLS
291 
292 extern TLS_APPL_STATE *smtp_tls_ctx; /* client-side TLS engine */
293 extern int smtp_tls_insecure_mx_policy; /* DANE post insecure MX? */
294 
295 #endif
296 
297 extern HBC_CHECKS *smtp_header_checks; /* limited header checks */
298 extern HBC_CHECKS *smtp_body_checks; /* limited body checks */
299 
300  /*
301  * smtp_session.c
302  */
303 
304 typedef struct SMTP_SESSION {
305  VSTREAM *stream; /* network connection */
306  SMTP_ITERATOR *iterator; /* dest, host, addr, port */
307  char *namaddr; /* mail exchanger */
308  char *helo; /* helo response */
309  unsigned port; /* network byte order */
310  char *namaddrport; /* mail exchanger, incl. port */
311 
312  VSTRING *buffer; /* I/O buffer */
313  VSTRING *scratch; /* scratch buffer */
314  VSTRING *scratch2; /* scratch buffer */
315 
316  int features; /* server features */
317  off_t size_limit; /* server limit or unknown */
318 
319  ARGV *history; /* transaction log */
320  int error_mask; /* error classes */
321  struct MIME_STATE *mime_state; /* mime state machine */
322 
323  int send_proto_helo; /* XFORWARD support */
324 
325  time_t expire_time; /* session reuse expiration time */
326  int reuse_count; /* # of times reused (for logging) */
327  int forbidden; /* No further I/O allowed */
328 
329 #ifdef USE_SASL_AUTH
330  char *sasl_mechanism_list; /* server mechanism list */
331  char *sasl_username; /* client username */
332  char *sasl_passwd; /* client password */
333  struct XSASL_CLIENT *sasl_client; /* SASL internal state */
334  VSTRING *sasl_reply; /* client response */
335 #endif
336 
337  /*
338  * TLS related state, don't forget to initialize in session_tls_init()!
339  */
340 #ifdef USE_TLS
341  TLS_SESS_STATE *tls_context; /* TLS library session state */
342  char *tls_nexthop; /* Nexthop domain for cert checks */
343  int tls_retry_plain; /* Try plain when TLS handshake fails */
344 #endif
345 
346  SMTP_STATE *state; /* back link */
347 } SMTP_SESSION;
348 
349 extern SMTP_SESSION *smtp_session_alloc(VSTREAM *, SMTP_ITERATOR *, time_t, int);
350 extern void smtp_session_new_stream(SMTP_SESSION *, VSTREAM *, time_t, int);
351 extern int smtp_sess_plaintext_ok(SMTP_ITERATOR *, int);
352 extern void smtp_session_free(SMTP_SESSION *);
355 
356  /*
357  * What's in a name?
358  */
359 #define SMTP_HNAME(rr) (var_smtp_cname_overr ? (rr)->rname : (rr)->qname)
360 
361  /*
362  * smtp_connect.c
363  */
364 extern int smtp_connect(SMTP_STATE *);
365 
366  /*
367  * smtp_proto.c
368  */
369 extern void smtp_vrfy_init(void);
370 extern int smtp_helo(SMTP_STATE *);
371 extern int smtp_xfer(SMTP_STATE *);
372 extern int smtp_rset(SMTP_STATE *);
373 extern int smtp_quit(SMTP_STATE *);
374 
376 
377  /*
378  * A connection is re-usable if session->expire_time is > 0 and the
379  * expiration time has not been reached. This is subtle because the timer
380  * can expire between sending a command and receiving the reply for that
381  * command.
382  *
383  * But wait, there is more! When SMTP command pipelining is enabled, there are
384  * two protocol loops that execute at very different times: one loop that
385  * generates commands, and one loop that receives replies to those commands.
386  * These will be called "sender loop" and "receiver loop", respectively. At
387  * well-defined protocol synchronization points, the sender loop pauses to
388  * let the receiver loop catch up.
389  *
390  * When we choose to reuse a connection, both the sender and receiver protocol
391  * loops end with "." (mail delivery) or "RSET" (address probe). When we
392  * choose not to reuse, both the sender and receiver protocol loops end with
393  * "QUIT". The problem is that we must make the same protocol choices in
394  * both the sender and receiver loops, even though those loops may execute
395  * at completely different times.
396  *
397  * We "freeze" the choice in the sender loop, just before we generate "." or
398  * "RSET". The reader loop leaves the connection cacheable even if the timer
399  * expires by the time the response arrives. The connection cleanup code
400  * will call smtp_quit() for connections with an expired cache expiration
401  * timer.
402  *
403  * We could have made the programmer's life a lot simpler by not making a
404  * choice at all, and always leaving it up to the connection cleanup code to
405  * call smtp_quit() for connections with an expired cache expiration timer.
406  *
407  * As a general principle, neither the sender loop nor the receiver loop must
408  * modify the connection caching state, if that can affect the receiver
409  * state machine for not-yet processed replies to already-generated
410  * commands. This restriction does not apply when we have to exit the
411  * protocol loops prematurely due to e.g., timeout or connection loss, so
412  * that those pending replies will never be received.
413  *
414  * But wait, there is even more! Only the first good connection for a specific
415  * destination may be cached under both the next-hop destination name and
416  * the server address; connections to alternate servers must be cached under
417  * the server address alone. This means we must distinguish between bad
418  * connections and other reasons why connections cannot be cached.
419  */
420 #define THIS_SESSION_IS_CACHED \
421  (!THIS_SESSION_IS_FORBIDDEN && session->expire_time > 0)
422 
423 #define THIS_SESSION_IS_EXPIRED \
424  (THIS_SESSION_IS_CACHED \
425  && (session->expire_time < vstream_ftime(session->stream) \
426  || (var_smtp_reuse_count > 0 \
427  && session->reuse_count >= var_smtp_reuse_count)))
428 
429 #define THIS_SESSION_IS_THROTTLED \
430  (!THIS_SESSION_IS_FORBIDDEN && session->expire_time < 0)
431 
432 #define THIS_SESSION_IS_FORBIDDEN \
433  (session->forbidden != 0)
434 
435  /* Bring the bad news. */
436 
437 #define DONT_CACHE_THIS_SESSION \
438  (session->expire_time = 0)
439 
440 #define DONT_CACHE_THROTTLED_SESSION \
441  (session->expire_time = -1)
442 
443 #define DONT_USE_FORBIDDEN_SESSION \
444  (session->forbidden = 1)
445 
446  /* Initialization. */
447 
448 #define USE_NEWBORN_SESSION \
449  (session->forbidden = 0)
450 
451 #define CACHE_THIS_SESSION_UNTIL(when) \
452  (session->expire_time = (when))
453 
454  /*
455  * Encapsulate the following so that we don't expose details of of
456  * connection management and error handling to the SMTP protocol engine.
457  */
458 #ifdef USE_SASL_AUTH
459 #define HAVE_SASL_CREDENTIALS \
460  (var_smtp_sasl_enable \
461  && *var_smtp_sasl_passwd \
462  && smtp_sasl_passwd_lookup(session))
463 #else
464 #define HAVE_SASL_CREDENTIALS (0)
465 #endif
466 
467 #define PREACTIVE_DELAY \
468  (session->state->request->msg_stats.active_arrival.tv_sec - \
469  session->state->request->msg_stats.incoming_arrival.tv_sec)
470 
471 #define PLAINTEXT_FALLBACK_OK_AFTER_STARTTLS_FAILURE \
472  (session->tls_context == 0 \
473  && state->tls->level == TLS_LEV_MAY \
474  && PREACTIVE_DELAY >= var_min_backoff_time \
475  && !HAVE_SASL_CREDENTIALS)
476 
477 #define PLAINTEXT_FALLBACK_OK_AFTER_TLS_SESSION_FAILURE \
478  (session->tls_context != 0 \
479  && SMTP_RCPT_LEFT(state) > SMTP_RCPT_MARK_COUNT(state) \
480  && state->tls->level == TLS_LEV_MAY \
481  && PREACTIVE_DELAY >= var_min_backoff_time \
482  && !HAVE_SASL_CREDENTIALS)
483 
484  /*
485  * XXX The following will not retry recipients that were deferred while the
486  * SMTP_MISC_FLAG_FINAL_SERVER flag was already set. This includes the case
487  * when TLS fails in the middle of a delivery.
488  */
489 #define RETRY_AS_PLAINTEXT do { \
490  session->tls_retry_plain = 1; \
491  state->misc_flags &= ~SMTP_MISC_FLAG_FINAL_SERVER; \
492  } while (0)
493 
494  /*
495  * smtp_chat.c
496  */
497 typedef struct SMTP_RESP { /* server response */
498  int code; /* SMTP code */
499  const char *dsn; /* enhanced status */
500  char *str; /* full reply */
501  VSTRING *dsn_buf; /* status buffer */
502  VSTRING *str_buf; /* reply buffer */
503 } SMTP_RESP;
504 
505 extern void PRINTFLIKE(2, 3) smtp_chat_cmd(SMTP_SESSION *, const char *,...);
507 extern SMTP_RESP *smtp_chat_resp(SMTP_SESSION *);
508 extern void smtp_chat_init(SMTP_SESSION *);
509 extern void smtp_chat_reset(SMTP_SESSION *);
510 extern void smtp_chat_notify(SMTP_SESSION *);
511 
512 #define SMTP_RESP_FAKE(resp, _dsn) \
513  ((resp)->code = 0, \
514  (resp)->dsn = (_dsn), \
515  (resp)->str = DSN_BY_LOCAL_MTA, \
516  (resp))
517 
518 #define DSN_BY_LOCAL_MTA ((char *) 0) /* DSN issued by local MTA */
519 
520 #define SMTP_RESP_SET_DSN(resp, _dsn) do { \
521  vstring_strcpy((resp)->dsn_buf, (_dsn)); \
522  (resp)->dsn = STR((resp)->dsn_buf); \
523  } while (0)
524 
525  /*
526  * These operations implement a redundant mark-and-sweep algorithm that
527  * explicitly accounts for the fate of every recipient. The interface is
528  * documented in smtp_rcpt.c, which also implements the sweeping. The
529  * smtp_trouble.c module does most of the marking after failure.
530  *
531  * When a delivery fails or succeeds, take one of the following actions:
532  *
533  * - Mark the recipient as KEEP (deliver to alternate MTA) and do not update
534  * the delivery request status.
535  *
536  * - Mark the recipient as DROP (remove from delivery request), log whether
537  * delivery succeeded or failed, delete the recipient from the queue file
538  * and/or update defer or bounce logfiles, and update the delivery request
539  * status.
540  *
541  * At the end of a delivery attempt, all recipients must be marked one way or
542  * the other. Failure to do so will trigger a panic.
543  */
544 #define SMTP_RCPT_STATE_KEEP 1 /* send to backup host */
545 #define SMTP_RCPT_STATE_DROP 2 /* remove from request */
546 #define SMTP_RCPT_INIT(state) do { \
547  (state)->rcpt_drop = (state)->rcpt_keep = 0; \
548  (state)->rcpt_left = state->request->rcpt_list.len; \
549  } while (0)
550 
551 #define SMTP_RCPT_DROP(state, rcpt) do { \
552  (rcpt)->u.status = SMTP_RCPT_STATE_DROP; (state)->rcpt_drop++; \
553  } while (0)
554 
555 #define SMTP_RCPT_KEEP(state, rcpt) do { \
556  (rcpt)->u.status = SMTP_RCPT_STATE_KEEP; (state)->rcpt_keep++; \
557  } while (0)
558 
559 #define SMTP_RCPT_ISMARKED(rcpt) ((rcpt)->u.status != 0)
560 
561 #define SMTP_RCPT_LEFT(state) (state)->rcpt_left
562 
563 #define SMTP_RCPT_MARK_COUNT(state) ((state)->rcpt_drop + (state)->rcpt_keep)
564 
565 extern void smtp_rcpt_cleanup(SMTP_STATE *);
566 extern void smtp_rcpt_done(SMTP_STATE *, SMTP_RESP *, RECIPIENT *);
567 
568  /*
569  * smtp_trouble.c
570  */
571 #define SMTP_THROTTLE 1
572 #define SMTP_NOTHROTTLE 0
573 extern int smtp_sess_fail(SMTP_STATE *);
574 extern int PRINTFLIKE(5, 6) smtp_misc_fail(SMTP_STATE *, int, const char *,
575  SMTP_RESP *, const char *,...);
576 extern void PRINTFLIKE(5, 6) smtp_rcpt_fail(SMTP_STATE *, RECIPIENT *,
577  const char *, SMTP_RESP *,
578  const char *,...);
579 extern int smtp_stream_except(SMTP_STATE *, int, const char *);
580 
581 #define smtp_site_fail(state, mta, resp, ...) \
582  smtp_misc_fail((state), SMTP_THROTTLE, (mta), (resp), __VA_ARGS__)
583 #define smtp_mesg_fail(state, mta, resp, ...) \
584  smtp_misc_fail((state), SMTP_NOTHROTTLE, (mta), (resp), __VA_ARGS__)
585 
586  /*
587  * smtp_unalias.c
588  */
589 extern const char *smtp_unalias_name(const char *);
590 extern VSTRING *smtp_unalias_addr(VSTRING *, const char *);
591 
592  /*
593  * smtp_state.c
594  */
595 extern SMTP_STATE *smtp_state_alloc(void);
596 extern void smtp_state_free(SMTP_STATE *);
597 
598  /*
599  * smtp_map11.c
600  */
601 extern int smtp_map11_external(VSTRING *, MAPS *, int);
602 extern int smtp_map11_tree(TOK822 *, MAPS *, int);
603 extern int smtp_map11_internal(VSTRING *, MAPS *, int);
604 
605  /*
606  * smtp_key.c
607  */
608 char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
609 
610 #define SMTP_KEY_FLAG_SERVICE (1<<0) /* service name */
611 #define SMTP_KEY_FLAG_SENDER (1<<1) /* sender address */
612 #define SMTP_KEY_FLAG_REQ_NEXTHOP (1<<2) /* request nexthop */
613 #define SMTP_KEY_FLAG_NEXTHOP (1<<3) /* current nexthop */
614 #define SMTP_KEY_FLAG_HOSTNAME (1<<4) /* remote host name */
615 #define SMTP_KEY_FLAG_ADDR (1<<5) /* remote address */
616 #define SMTP_KEY_FLAG_PORT (1<<6) /* remote port */
617 
618 #define SMTP_KEY_MASK_ALL \
619  (SMTP_KEY_FLAG_SERVICE | SMTP_KEY_FLAG_SENDER | \
620  SMTP_KEY_FLAG_REQ_NEXTHOP | \
621  SMTP_KEY_FLAG_NEXTHOP | SMTP_KEY_FLAG_HOSTNAME | \
622  SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT)
623 
624  /*
625  * Conditional lookup-key flags for cached connections that may be
626  * SASL-authenticated with a per-{sender, nexthop, or hostname} credential.
627  * Each bit corresponds to one type of smtp_sasl_password_file lookup key,
628  * and is turned on only when the corresponding main.cf parameter is turned
629  * on.
630  */
631 #define COND_SASL_SMTP_KEY_FLAG_SENDER \
632  ((var_smtp_sender_auth && *var_smtp_sasl_passwd) ? \
633  SMTP_KEY_FLAG_SENDER : 0)
634 
635 #define COND_SASL_SMTP_KEY_FLAG_NEXTHOP \
636  (*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_NEXTHOP : 0)
637 
638 #define COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
639  (*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_HOSTNAME : 0)
640 
641  /*
642  * Connection-cache destination lookup key. The SENDER attribute is a proxy
643  * for sender-dependent SASL credentials (or absence thereof), and prevents
644  * false connection sharing when different SASL credentials may be required
645  * for different deliveries to the same domain and port. The SERVICE
646  * attribute is a proxy for all request-independent configuration details.
647  */
648 #define SMTP_KEY_MASK_SCACHE_DEST_LABEL \
649  (SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
650  | SMTP_KEY_FLAG_REQ_NEXTHOP)
651 
652  /*
653  * Connection-cache endpoint lookup key. The SENDER, NEXTHOP, and HOSTNAME
654  * attributes are proxies for SASL credentials (or absence thereof), and
655  * prevent false connection sharing when different SASL credentials may be
656  * required for different deliveries to the same IP address and port.
657  */
658 #define SMTP_KEY_MASK_SCACHE_ENDP_LABEL \
659  (SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
660  | COND_SASL_SMTP_KEY_FLAG_NEXTHOP | COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
661  | SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT)
662 
663  /*
664  * Silly little macros.
665  */
666 #define STR(s) vstring_str(s)
667 #define LEN(s) VSTRING_LEN(s)
668 
669 extern int smtp_mode;
670 
671 #define VAR_LMTP_SMTP(x) (smtp_mode ? VAR_SMTP_##x : VAR_LMTP_##x)
672 #define LMTP_SMTP_SUFFIX(x) (smtp_mode ? x##_SMTP : x##_LMTP)
673 
674 /* LICENSE
675 /* .ad
676 /* .fi
677 /* The Secure Mailer license must be distributed with this software.
678 /* AUTHOR(S)
679 /* Wietse Venema
680 /* IBM T.J. Watson Research
681 /* P.O. Box 704
682 /* Yorktown Heights, NY 10598, USA
683 /*
684 /* Wietse Venema
685 /* Google, Inc.
686 /* 111 8th Avenue
687 /* New York, NY 10011, USA
688 /*
689 /* TLS support originally by:
690 /* Lutz Jaenicke
691 /* BTU Cottbus
692 /* Allgemeine Elektrotechnik
693 /* Universitaetsplatz 3-4
694 /* D-03044 Cottbus, Germany
695 /*
696 /* Victor Duchovni
697 /* Morgan Stanley
698 /*--*/
VSTRING * dsn_buf
Definition: smtp.h:501
STRING_LIST * smtp_cache_dest
Definition: smtp.c:966
SMTP_SESSION * smtp_session_activate(int, SMTP_ITERATOR *, VSTRING *, VSTRING *)
Definition: smtp_session.c:277
VSTRING * endp_prop
Definition: smtp.h:170
ssize_t space_left
Definition: smtp.h:149
int status
Definition: smtp.h:148
SMTP_ITERATOR iterator[1]
Definition: smtp.h:154
off_t size_limit
Definition: smtp.h:317
char * str
Definition: smtp.h:500
struct SMTP_STATE * parent
Definition: smtp.h:61
struct SMTP_SESSION * session
Definition: smtp.h:147
unsigned port
Definition: smtp.h:56
int smtp_map11_external(VSTRING *, MAPS *, int)
Definition: smtp_map11.c:127
VSTREAM * src
Definition: smtp.h:144
VSTRING * request_nexthop
Definition: smtp.h:52
unsigned smtp_dns_res_opt
Definition: smtp.c:971
DSN_BUF * why
Definition: smtp.h:184
HTABLE * cache_used
Definition: smtp.h:166
int smtp_helo(SMTP_STATE *)
Definition: smtp_proto.c:291
Definition: argv.h:17
const char * dsn
Definition: smtp.h:499
int rcpt_left
Definition: smtp.h:177
#define STRING_LIST
Definition: string_list.h:22
struct DNS_RR * rr
Definition: smtp.h:57
DELIVER_REQUEST * request
Definition: smtp.h:146
Definition: tok822.h:27
VSTRING * saved_dest
Definition: smtp.h:60
Definition: maps.h:22
int smtp_rset(SMTP_STATE *)
Definition: smtp_proto.c:2304
int rcpt_drop
Definition: smtp.h:178
int misc_flags
Definition: smtp.h:143
int smtp_sess_fail(SMTP_STATE *)
Definition: smtp_trouble.c:291
int smtp_dns_support
Definition: smtp.c:965
unsigned port
Definition: smtp.h:309
SMTP_SESSION * smtp_session_alloc(VSTREAM *, SMTP_ITERATOR *, time_t, int)
Definition: smtp_session.c:118
Definition: htable.h:25
VSTRING * str_buf
Definition: smtp.h:502
VSTRING * dest
Definition: smtp.h:53
int forbidden
Definition: smtp.h:327
int error_mask
Definition: smtp.h:320
int rcpt_keep
Definition: smtp.h:179
MAPS * smtp_ehlo_dis_maps
Definition: smtp.c:968
void smtp_chat_init(SMTP_SESSION *)
Definition: smtp_chat.c:150
void smtp_chat_notify(SMTP_SESSION *)
Definition: smtp_chat.c:433
Definition: dict.h:78
HBC_CALL_BACKS smtp_hbc_callbacks[]
Definition: smtp_proto.c:266
int smtp_map11_tree(TOK822 *, MAPS *, int)
Definition: smtp_map11.c:109
ARGV * history
Definition: smtp.h:319
struct SMTP_RESP SMTP_RESP
int smtp_misc_fail(SMTP_STATE *state, int throttle, const char *mta_name, SMTP_RESP *resp, const char *format,...)
Definition: smtp_trouble.c:331
struct DNS_RR * mx
Definition: smtp.h:58
int reuse_count
Definition: smtp.h:326
void smtp_vrfy_init(void)
Definition: smtp_proto.c:275
struct SMTP_STATE SMTP_STATE
SMTP_STATE * smtp_state_alloc(void)
Definition: smtp_state.c:54
VSTRING * host
Definition: smtp.h:54
struct SMTP_ITERATOR SMTP_ITERATOR
VSTRING * addr
Definition: smtp.h:55
VSTREAM * stream
Definition: smtp.h:305
int send_proto_helo
Definition: smtp.h:323
int smtp_ext_prop_mask
Definition: smtp.c:970
void smtp_state_free(SMTP_STATE *)
Definition: smtp_state.c:89
HBC_CHECKS * smtp_header_checks
Definition: smtp.c:973
int smtp_map11_internal(VSTRING *, MAPS *, int)
Definition: smtp_map11.c:83
VSTRING * endp_label
Definition: smtp.h:169
const char * smtp_unalias_name(const char *)
Definition: smtp_unalias.c:65
const char * service
Definition: smtp.h:145
int smtp_xfer(SMTP_STATE *)
Definition: smtp_proto.c:2218
struct MIME_STATE * mime_state
Definition: smtp.h:321
char * helo
Definition: smtp.h:308
void smtp_session_new_stream(SMTP_SESSION *, VSTREAM *, time_t, int)
void PRINTFLIKE(2, 3) smtp_chat_cmd(SMTP_SESSION *
VSTRING * smtp_unalias_addr(VSTRING *, const char *)
Definition: smtp_unalias.c:102
VSTRING * dest_prop
Definition: smtp.h:168
VSTRING * scratch
Definition: smtp.h:313
SMTP_STATE * state
Definition: smtp.h:346
int const char SMTP_RESP const char void RECIPIENT const char SMTP_RESP const char int smtp_stream_except(SMTP_STATE *, int, const char *)
Definition: smtp_trouble.c:417
void smtp_rcpt_cleanup(SMTP_STATE *)
Definition: smtp_rcpt.c:194
void smtp_chat_cmd(SMTP_SESSION *session, const char *fmt,...)
Definition: smtp_chat.c:181
HBC_CHECKS * smtp_body_checks
Definition: smtp.c:974
void const char DICT * smtp_chat_resp_filter
Definition: smtp_chat.c:146
Definition: scache.h:103
int smtp_connect(SMTP_STATE *)
int smtp_mode
Definition: smtp.c:963
int code
Definition: smtp.h:498
char * namaddr
Definition: smtp.h:307
SMTP_RESP * smtp_chat_resp(SMTP_SESSION *)
Definition: smtp_chat.c:235
SCACHE * smtp_scache
Definition: smtp.c:967
int smtp_session_passivate(SMTP_SESSION *, VSTRING *, VSTRING *)
Definition: smtp_session.c:210
int smtp_sess_plaintext_ok(SMTP_ITERATOR *, int)
void smtp_rcpt_done(SMTP_STATE *, SMTP_RESP *, RECIPIENT *)
Definition: smtp_rcpt.c:137
VSTRING * scratch2
Definition: smtp.h:314
void smtp_chat_reset(SMTP_SESSION *)
Definition: smtp_chat.c:157
void smtp_rcpt_fail(SMTP_STATE *state, RECIPIENT *rcpt, const char *mta_name, SMTP_RESP *resp, const char *format,...)
Definition: smtp_trouble.c:354
MAPS * smtp_pix_bug_maps
Definition: smtp.c:972
VSTRING * buffer
Definition: smtp.h:312
int features
Definition: smtp.h:316
VSTRING * dest_label
Definition: smtp.h:167
void smtp_session_free(SMTP_SESSION *)
Definition: smtp_session.c:174
Definition: dns.h:139
int smtp_host_lookup_mask
Definition: smtp.c:964
MAPS * smtp_generic_maps
Definition: smtp.c:969
char * namaddrport
Definition: smtp.h:310
char * smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int)
Definition: smtp_key.c:146
time_t expire_time
Definition: smtp.h:325
int smtp_quit(SMTP_STATE *)
Definition: smtp_proto.c:2316
struct SMTP_SESSION SMTP_SESSION
SMTP_ITERATOR * iterator
Definition: smtp.h:306