Commit | Line | Data |
---|---|---|
059ec3d9 PH |
1 | /************************************************* |
2 | * Exim - an Internet mail transport agent * | |
3 | *************************************************/ | |
4 | ||
f9ba5e22 | 5 | /* Copyright (c) University of Cambridge 1995 - 2018 */ |
1e1ddfac | 6 | /* Copyright (c) The Exim Maintainers 2020 */ |
059ec3d9 PH |
7 | /* See the file NOTICE for conditions of use and distribution. */ |
8 | ||
9 | ||
10 | /* Definitions of various structures. In addition, those that are visible for | |
11 | the compilation of local_scan() are defined in local_scan.h. These are | |
12 | ||
13 | header_line | |
14 | optionlist | |
15 | recipient_item | |
16 | ||
17 | For those declared here, we have to pre-declare some because of mutually | |
18 | recursive definitions in the auths, routers, and transports blocks. */ | |
19 | ||
20 | struct address_item; | |
21 | struct auth_info; | |
22 | struct driver_info; | |
23 | struct director_info; | |
24 | struct smtp_inblock; | |
25 | struct smtp_outblock; | |
26 | struct transport_info; | |
27 | struct router_info; | |
28 | ||
acec9514 JH |
29 | /* Growable-string */ |
30 | typedef struct gstring { | |
31 | int size; /* Current capacity of string memory */ | |
32 | int ptr; /* Offset at which to append further chars */ | |
33 | uschar * s; /* The string memory */ | |
34 | } gstring; | |
35 | ||
1a7c9a48 JH |
36 | /* Structure for remembering macros for the configuration file */ |
37 | ||
38 | typedef struct macro_item { | |
39 | struct macro_item * next; | |
40 | BOOL command_line; | |
41 | unsigned namelen; | |
42 | unsigned replen; | |
43 | const uschar * name; | |
44 | const uschar * replacement; | |
45 | } macro_item; | |
46 | ||
059ec3d9 PH |
47 | /* Structure for bit tables for debugging and logging */ |
48 | ||
49 | typedef struct bit_table { | |
50 | uschar *name; | |
6c6d6e48 | 51 | int bit; |
059ec3d9 PH |
52 | } bit_table; |
53 | ||
54 | /* Block for holding a uid and gid, possibly unset, and an initgroups flag. */ | |
55 | ||
56 | typedef struct ugid_block { | |
57 | uid_t uid; | |
58 | gid_t gid; | |
59 | BOOL uid_set; | |
60 | BOOL gid_set; | |
61 | BOOL initgroups; | |
62 | } ugid_block; | |
63 | ||
7e3ce68e JH |
64 | typedef enum { CHUNKING_NOT_OFFERED = -1, |
65 | CHUNKING_OFFERED, | |
66 | CHUNKING_ACTIVE, | |
67 | CHUNKING_LAST} chunking_state_t; | |
18481de3 | 68 | |
06e272a3 | 69 | typedef enum { TFO_NOT_USED = 0, |
ee8b8090 JH |
70 | TFO_ATTEMPTED_NODATA, |
71 | TFO_ATTEMPTED_DATA, | |
72 | TFO_USED_NODATA, | |
73 | TFO_USED_DATA } tfo_state_t; | |
06e272a3 | 74 | |
059ec3d9 PH |
75 | /* Structure for holding information about a host for use mainly by routers, |
76 | but also used when checking lists of hosts and when transporting. Looking up | |
77 | host addresses is done using this structure. */ | |
78 | ||
783b385f JH |
79 | typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t; |
80 | ||
059ec3d9 PH |
81 | typedef struct host_item { |
82 | struct host_item *next; | |
55414b25 JH |
83 | const uschar *name; /* Host name */ |
84 | const uschar *address; /* IP address in text form */ | |
059ec3d9 PH |
85 | int port; /* port value in host order (if SRV lookup) */ |
86 | int mx; /* MX value if found via MX records */ | |
87 | int sort_key; /* MX*1000 plus random "fraction" */ | |
88 | int status; /* Usable, unusable, or unknown */ | |
89 | int why; /* Why host is unusable */ | |
90 | int last_try; /* Time of last try if known */ | |
783b385f | 91 | dnssec_status_t dnssec; |
059ec3d9 PH |
92 | } host_item; |
93 | ||
94 | /* Chain of rewrite rules, read from the rewrite config, or parsed from the | |
95 | rewrite_headers field of a transport. */ | |
96 | ||
97 | typedef struct rewrite_rule { | |
98 | struct rewrite_rule *next; | |
99 | int flags; | |
100 | uschar *key; | |
101 | uschar *replacement; | |
102 | } rewrite_rule; | |
103 | ||
104 | /* This structure is used to pass back configuration data from the smtp | |
105 | transport to the outside world. It is used during callback processing. If ever | |
106 | another remote transport were implemented, it could use the same structure. */ | |
107 | ||
108 | typedef struct transport_feedback { | |
109 | uschar *interface; | |
110 | uschar *port; | |
111 | uschar *protocol; | |
112 | uschar *hosts; | |
26da7e20 | 113 | uschar *helo_data; |
059ec3d9 PH |
114 | BOOL hosts_override; |
115 | BOOL hosts_randomize; | |
116 | BOOL gethostbyname; | |
117 | BOOL qualify_single; | |
118 | BOOL search_parents; | |
119 | } transport_feedback; | |
120 | ||
121 | /* Routers, transports, and authenticators have similar data blocks. Each | |
122 | driver that is compiled into the code is represented by a xxx_info block; the | |
123 | active drivers are represented by a chain of xxx_instance blocks. To make it | |
124 | possible to use the same code for reading the configuration files for all | |
125 | three, the layout of the start of the blocks is kept the same, and represented | |
126 | by the generic structures driver_info and driver_instance. */ | |
127 | ||
128 | typedef struct driver_instance { | |
129 | struct driver_instance *next; | |
130 | uschar *name; /* Instance name */ | |
131 | struct driver_info *info; /* Points to info for this driver */ | |
132 | void *options_block; /* Pointer to private options */ | |
133 | uschar *driver_name; /* All start with this generic option */ | |
134 | } driver_instance; | |
135 | ||
136 | typedef struct driver_info { | |
137 | uschar *driver_name; /* Name of driver */ | |
138 | optionlist *options; /* Table of private options names */ | |
139 | int *options_count; /* -> Number of entries in table */ | |
140 | void *options_block; /* Points to default private block */ | |
141 | int options_len; /* Length of same in bytes */ | |
142 | void (*init)( /* Initialization entry point */ | |
143 | struct driver_instance *); | |
144 | } driver_info; | |
145 | ||
146 | ||
147 | /* Structure for holding information about the configured transports. Some | |
148 | of the generally accessible options are set from the configuration file; others | |
149 | are set by transport initialization, since they can only be set for certain | |
150 | transports. They need to be generally accessible, however, as they are used by | |
151 | the main transport code. */ | |
152 | ||
153 | typedef struct transport_instance { | |
154 | struct transport_instance *next; | |
155 | uschar *name; /* Instance name */ | |
156 | struct transport_info *info; /* Info for this driver */ | |
157 | void *options_block; /* Pointer to private options */ | |
158 | uschar *driver_name; /* Must be first */ | |
159 | int (*setup)( /* Setup entry point */ | |
160 | struct transport_instance *, | |
161 | struct address_item *, | |
162 | struct transport_feedback *, /* For passing back config data */ | |
929ba01c PH |
163 | uid_t, /* The uid that will be used */ |
164 | gid_t, /* The gid that will be used */ | |
059ec3d9 PH |
165 | uschar **); /* For an error message */ |
166 | /**************************************/ | |
167 | int batch_max; /* ) */ | |
168 | uschar *batch_id; /* ) */ | |
169 | uschar *home_dir; /* ) Used only for local transports */ | |
170 | uschar *current_dir; /* ) */ | |
171 | /**************************************/ | |
506900af | 172 | uschar *expand_multi_domain; /* ) */ |
059ec3d9 PH |
173 | BOOL multi_domain; /* ) */ |
174 | BOOL overrides_hosts; /* ) Used only for remote transports */ | |
175 | int max_addresses; /* ) */ | |
176 | int connection_max_messages;/* ) */ | |
177 | /**************************************/ | |
178 | BOOL deliver_as_creator; /* Used only by pipe at present */ | |
179 | BOOL disable_logging; /* For very weird requirements */ | |
180 | BOOL initgroups; /* Initialize groups when setting uid */ | |
181 | BOOL uid_set; /* uid is set */ | |
182 | BOOL gid_set; /* gid is set */ | |
183 | uid_t uid; | |
184 | gid_t gid; | |
185 | uschar *expand_uid; /* Variable uid */ | |
186 | uschar *expand_gid; /* Variable gid */ | |
187 | uschar *warn_message; /* Used only by appendfile at present */ | |
188 | uschar *shadow; /* Name of shadow transport */ | |
189 | uschar *shadow_condition; /* Condition for running it */ | |
190 | uschar *filter_command; /* For on-the-fly-filtering */ | |
191 | uschar *add_headers; /* Add these headers */ | |
192 | uschar *remove_headers; /* Remove these headers */ | |
193 | uschar *return_path; /* Overriding (rewriting) return path */ | |
194 | uschar *debug_string; /* Debugging output */ | |
fa41615d | 195 | uschar *max_parallel; /* Number of concurrent instances */ |
059ec3d9 PH |
196 | uschar *message_size_limit; /* Biggest message this transport handles */ |
197 | uschar *headers_rewrite; /* Rules for rewriting headers */ | |
198 | rewrite_rule *rewrite_rules; /* Parsed rewriting rules */ | |
199 | int rewrite_existflags; /* Bits showing which headers are rewritten */ | |
200 | int filter_timeout; /* For transport filter timing */ | |
201 | BOOL body_only; /* Deliver only the body */ | |
202 | BOOL delivery_date_add; /* Add Delivery-Date header */ | |
203 | BOOL envelope_to_add; /* Add Envelope-To header */ | |
204 | BOOL headers_only; /* Deliver only the headers */ | |
205 | BOOL rcpt_include_affixes; /* TRUE to retain affixes in RCPT commands */ | |
206 | BOOL return_path_add; /* Add Return-Path header */ | |
207 | BOOL return_output; /* TRUE if output should always be returned */ | |
208 | BOOL return_fail_output; /* ditto, but only on failure */ | |
209 | BOOL log_output; /* Similarly for logging */ | |
210 | BOOL log_fail_output; | |
211 | BOOL log_defer_output; | |
212 | BOOL retry_use_local_part; /* Defaults true for local, false for remote */ | |
0cbf2b82 | 213 | #ifndef DISABLE_EVENT |
774ef2d7 | 214 | uschar *event_action; /* String to expand on notable events */ |
d68218c7 | 215 | #endif |
059ec3d9 PH |
216 | } transport_instance; |
217 | ||
218 | ||
219 | /* Structure for holding information about a type of transport. The first six | |
220 | fields must match driver_info above. */ | |
221 | ||
222 | typedef struct transport_info { | |
223 | uschar *driver_name; /* Driver name */ | |
224 | optionlist *options; /* Table of private options names */ | |
225 | int *options_count; /* -> Number of entries in table */ | |
226 | void *options_block; /* Points to default private block */ | |
227 | int options_len; /* Length of same in bytes */ | |
228 | void (*init)( /* Initialization function */ | |
229 | struct transport_instance *); | |
230 | /****/ | |
231 | BOOL (*code)( /* Main entry point */ | |
232 | transport_instance *, | |
233 | struct address_item *); | |
234 | void (*tidyup)( /* Tidyup function */ | |
235 | struct transport_instance *); | |
236 | void (*closedown)( /* For closing down a passed channel */ | |
237 | struct transport_instance *); | |
238 | BOOL local; /* TRUE for local transports */ | |
239 | } transport_info; | |
240 | ||
241 | ||
6d5c916c JH |
242 | /* smtp transport datachunk callback */ |
243 | ||
e027f545 | 244 | #define tc_reap_prev BIT(0) /* Flags: reap previous SMTP cmd responses */ |
58fc5fb2 | 245 | #define tc_chunk_last BIT(1) /* annotate chunk SMTP cmd as LAST */ |
e027f545 | 246 | |
6d5c916c | 247 | struct transport_context; |
d2aa036b | 248 | typedef int (*tpt_chunk_cmd_cb)(struct transport_context *, unsigned, unsigned); |
6d5c916c | 249 | |
65de12cc JH |
250 | /* Structure for information about a delivery-in-progress */ |
251 | ||
252 | typedef struct transport_context { | |
42055a33 JH |
253 | union { /* discriminated by option topt_output_string */ |
254 | int fd; /* file descriptor to write message to */ | |
acec9514 | 255 | gstring * msg; /* allocated string with written message */ |
42055a33 | 256 | } u; |
6d5c916c JH |
257 | transport_instance * tblock; /* transport */ |
258 | struct address_item * addr; | |
259 | uschar * check_string; /* string replacement */ | |
260 | uschar * escape_string; | |
261 | int options; /* output processing topt_* */ | |
262 | ||
263 | /* items below only used with option topt_use_bdat */ | |
264 | tpt_chunk_cmd_cb chunk_cb; /* per-datachunk callback */ | |
e9166683 | 265 | void * smtp_context; |
65de12cc JH |
266 | } transport_ctx; |
267 | ||
268 | ||
059ec3d9 | 269 | |
7cd171b7 JH |
270 | typedef struct { |
271 | uschar *request; | |
272 | uschar *require; | |
273 | } dnssec_domains; | |
274 | ||
059ec3d9 PH |
275 | /* Structure for holding information about the configured routers. */ |
276 | ||
277 | typedef struct router_instance { | |
278 | struct router_instance *next; | |
279 | uschar *name; | |
280 | struct router_info *info; | |
281 | void *options_block; /* Pointer to private options */ | |
282 | uschar *driver_name; /* Must be first */ | |
283 | ||
284 | uschar *address_data; /* Arbitrary data */ | |
8523533c TK |
285 | #ifdef EXPERIMENTAL_BRIGHTMAIL |
286 | uschar *bmi_rule; /* Brightmail AntiSpam rule checking */ | |
8e669ac1 | 287 | #endif |
059ec3d9 PH |
288 | uschar *cannot_route_message; /* Used when routing fails */ |
289 | uschar *condition; /* General condition */ | |
290 | uschar *current_directory; /* For use during delivery */ | |
291 | uschar *debug_string; /* Debugging output */ | |
292 | uschar *domains; /* Specific domains */ | |
293 | uschar *errors_to; /* Errors address */ | |
294 | uschar *expand_gid; /* Expanded gid string */ | |
295 | uschar *expand_uid; /* Expanded uid string */ | |
296 | uschar *expand_more; /* Expanded more string */ | |
297 | uschar *expand_unseen; /* Expanded unseen string */ | |
298 | uschar *extra_headers; /* Additional headers */ | |
299 | uschar *fallback_hosts; /* For remote transports (text list) */ | |
300 | uschar *home_directory; /* For use during delivery */ | |
301 | uschar *ignore_target_hosts; /* Target hosts to ignore */ | |
302 | uschar *local_parts; /* Specific local parts */ | |
303 | uschar *pass_router_name; /* Router for passed address */ | |
304 | uschar *prefix; /* Address prefix */ | |
305 | uschar *redirect_router_name; /* Router for generated address */ | |
306 | uschar *remove_headers; /* Removed headers */ | |
307 | uschar *require_files; /* File checks before router is run */ | |
308 | uschar *router_home_directory; /* For use while routing */ | |
309 | uschar *self; /* Text option for handling self reference */ | |
310 | uschar *senders; /* Specific senders */ | |
311 | uschar *suffix; /* Address suffix */ | |
312 | uschar *translate_ip_address; /* IP address translation fudgery */ | |
313 | uschar *transport_name; /* Transport name */ | |
314 | ||
315 | BOOL address_test; /* Use this router when testing addresses */ | |
8523533c TK |
316 | #ifdef EXPERIMENTAL_BRIGHTMAIL |
317 | BOOL bmi_deliver_alternate; /* TRUE => BMI said that message should be delivered to alternate location */ | |
318 | BOOL bmi_deliver_default; /* TRUE => BMI said that message should be delivered to default location */ | |
319 | BOOL bmi_dont_deliver; /* TRUE => BMI said that message should not be delivered at all */ | |
320 | #endif | |
059ec3d9 PH |
321 | BOOL expn; /* Use this router when processing EXPN */ |
322 | BOOL caseful_local_part; /* TRUE => don't lowercase */ | |
323 | BOOL check_local_user; /* TRUE => check local user */ | |
324 | BOOL disable_logging; /* For very weird requirements */ | |
325 | BOOL fail_verify_recipient; /* Fail verify if recipient match this router */ | |
326 | BOOL fail_verify_sender; /* Fail verify if sender match this router */ | |
327 | BOOL gid_set; /* Flag to indicate gid is set */ | |
328 | BOOL initgroups; /* TRUE if initgroups is required */ | |
329 | BOOL log_as_local; /* TRUE logs as a local delivery */ | |
330 | BOOL more; /* If FALSE, do no more if this one fails */ | |
331 | BOOL pass_on_timeout; /* Treat timeout DEFERs as fails */ | |
332 | BOOL prefix_optional; /* Just what it says */ | |
333 | BOOL repeat_use; /* If FALSE, skip if ancestor used it */ | |
334 | BOOL retry_use_local_part; /* Just what it says */ | |
335 | BOOL same_domain_copy_routing; /* TRUE => copy routing for same domain */ | |
336 | BOOL self_rewrite; /* TRUE to rewrite headers if making local */ | |
fa7b17bd | 337 | uschar *set; /* Variable = value to set; list */ |
059ec3d9 PH |
338 | BOOL suffix_optional; /* As it says */ |
339 | BOOL verify_only; /* Skip this router if not verifying */ | |
340 | BOOL verify_recipient; /* Use this router when verifying a recipient*/ | |
341 | BOOL verify_sender; /* Use this router when verifying a sender */ | |
342 | BOOL uid_set; /* Flag to indicate uid is set */ | |
343 | BOOL unseen; /* If TRUE carry on, even after success */ | |
6c1c3d1d | 344 | BOOL dsn_lasthop; /* If TRUE, this router is a DSN endpoint */ |
059ec3d9 PH |
345 | |
346 | int self_code; /* Encoded version of "self" */ | |
347 | uid_t uid; /* Fixed uid value */ | |
348 | gid_t gid; /* Fixed gid value */ | |
349 | ||
350 | host_item *fallback_hostlist; /* For remote transport (block chain) */ | |
351 | transport_instance *transport; /* Transport block (when found) */ | |
352 | struct router_instance *pass_router; /* Actual router for passed address */ | |
353 | struct router_instance *redirect_router; /* Actual router for generated address */ | |
7cd171b7 JH |
354 | |
355 | dnssec_domains dnssec; | |
059ec3d9 PH |
356 | } router_instance; |
357 | ||
358 | ||
359 | /* Structure for holding information about a type of router. The first six | |
360 | fields must match driver_info above. */ | |
361 | ||
362 | typedef struct router_info { | |
363 | uschar *driver_name; | |
364 | optionlist *options; /* Table of private options names */ | |
365 | int *options_count; /* -> Number of entries in table */ | |
366 | void *options_block; /* Points to default private block */ | |
367 | int options_len; /* Length of same in bytes */ | |
368 | void (*init)( /* Initialization function */ | |
369 | struct router_instance *); | |
370 | /****/ | |
371 | int (*code)( /* Main entry point */ | |
372 | router_instance *, | |
373 | struct address_item *, | |
374 | struct passwd *, | |
fd6de02e | 375 | int, |
059ec3d9 PH |
376 | struct address_item **, |
377 | struct address_item **, | |
378 | struct address_item **, | |
379 | struct address_item **); | |
380 | void (*tidyup)( /* Tidyup function */ | |
381 | struct router_instance *); | |
382 | int ri_flags; /* Descriptive flags */ | |
383 | } router_info; | |
384 | ||
385 | ||
386 | /* Structure for holding information about a lookup type. */ | |
387 | ||
e6d225ae | 388 | #include "lookupapi.h" |
059ec3d9 PH |
389 | |
390 | ||
391 | /* Structure for holding information about the configured authentication | |
392 | mechanisms */ | |
393 | ||
394 | typedef struct auth_instance { | |
395 | struct auth_instance *next; | |
396 | uschar *name; /* Exim instance name */ | |
397 | struct auth_info *info; /* Pointer to driver info block */ | |
398 | void *options_block; /* Pointer to private options */ | |
399 | uschar *driver_name; /* Must be first */ | |
400 | uschar *advertise_condition; /* Are we going to advertise this?*/ | |
6c512171 | 401 | uschar *client_condition; /* Should the client try this? */ |
059ec3d9 | 402 | uschar *public_name; /* Advertised name */ |
6f123593 JH |
403 | uschar *set_id; /* String to set when server as authenticated id */ |
404 | uschar *set_client_id; /* String to set when client as client_authenticated id */ | |
059ec3d9 PH |
405 | uschar *mail_auth_condition; /* Condition for AUTH on MAIL command */ |
406 | uschar *server_debug_string; /* Debugging output */ | |
16ff981e | 407 | uschar *server_condition; /* Authorization condition */ |
059ec3d9 PH |
408 | BOOL client; /* TRUE if client option(s) set */ |
409 | BOOL server; /* TRUE if server options(s) set */ | |
410 | BOOL advertised; /* Set TRUE when advertised */ | |
411 | } auth_instance; | |
412 | ||
413 | ||
414 | /* Structure for holding information about an authentication mechanism. The | |
415 | first six fields must match driver_info above. */ | |
416 | ||
417 | typedef struct auth_info { | |
418 | uschar *driver_name; /* e.g. "condition" */ | |
419 | optionlist *options; /* Table of private options names */ | |
420 | int *options_count; /* -> Number of entries in table */ | |
421 | void *options_block; /* Points to default private block */ | |
422 | int options_len; /* Length of same in bytes */ | |
423 | void (*init)( /* initialization function */ | |
424 | struct auth_instance *); | |
425 | /****/ | |
426 | int (*servercode)( /* server function */ | |
427 | auth_instance *, /* the instance data */ | |
428 | uschar *); /* rest of AUTH command */ | |
429 | int (*clientcode)( /* client function */ | |
430 | struct auth_instance *, | |
251b9eb4 | 431 | void *, /* smtp conn, with socket, output and input buffers */ |
059ec3d9 PH |
432 | int, /* command timeout */ |
433 | uschar *, /* buffer for reading response */ | |
434 | int); /* sizeof buffer */ | |
44bbabb5 PP |
435 | void (*version_report)( /* diagnostic version reporting */ |
436 | FILE *); /* I/O stream to print to */ | |
25bd12fd | 437 | void (*macros_create)(void); /* feature-macro creation */ |
059ec3d9 PH |
438 | } auth_info; |
439 | ||
440 | ||
441 | /* Structure for holding a single IP address and port; used for the chain of | |
442 | addresses and ports for the local host. Make the char string large enough to | |
443 | hold an IPv6 address. */ | |
444 | ||
445 | typedef struct ip_address_item { | |
446 | struct ip_address_item *next; | |
447 | int port; | |
448 | BOOL v6_include_v4; /* Used in the daemon */ | |
449 | uschar address[46]; | |
254f38d1 | 450 | uschar * log; /* portion of "listening on" log line */ |
059ec3d9 PH |
451 | } ip_address_item; |
452 | ||
453 | /* Structure for chaining together arbitrary strings. */ | |
454 | ||
455 | typedef struct string_item { | |
456 | struct string_item *next; | |
457 | uschar *text; | |
458 | } string_item; | |
459 | ||
460 | /* Information about a soft delivery failure, for use when calculating | |
461 | retry information. It's separate from the address block, because there | |
462 | can be a chain of them for SMTP deliveries where multiple IP addresses | |
463 | can be tried. */ | |
464 | ||
465 | typedef struct retry_item { | |
466 | struct retry_item *next; /* for chaining */ | |
467 | uschar *key; /* string identifying host/address/message */ | |
468 | int basic_errno; /* error code for this destination */ | |
469 | int more_errno; /* additional error information */ | |
470 | uschar *message; /* local error message */ | |
471 | int flags; /* see below */ | |
472 | } retry_item; | |
473 | ||
474 | /* Retry data flags */ | |
475 | ||
476 | #define rf_delete 0x0001 /* retry info is to be deleted */ | |
477 | #define rf_host 0x0002 /* retry info is for a remote host */ | |
478 | #define rf_message 0x0004 /* retry info is for a host+message */ | |
479 | ||
480 | /* Information about a constructed message that is to be sent using the | |
481 | autoreply transport. This is pointed to from the address block. */ | |
482 | ||
483 | typedef struct reply_item { | |
484 | uschar *from; /* ) */ | |
485 | uschar *reply_to; /* ) */ | |
486 | uschar *to; /* ) */ | |
487 | uschar *cc; /* ) specific header fields */ | |
488 | uschar *bcc; /* ) */ | |
489 | uschar *subject; /* ) */ | |
490 | uschar *headers; /* misc other headers, concatenated */ | |
491 | uschar *text; /* text string body */ | |
492 | uschar *file; /* file body */ | |
493 | BOOL file_expand; /* expand the body */ | |
494 | int expand_forbid; /* expansion lockout flags */ | |
495 | uschar *logfile; /* file to keep a log in */ | |
496 | uschar *oncelog; /* file to keep records in for once only */ | |
497 | time_t once_repeat; /* time to repeat "once only" */ | |
498 | BOOL return_message; /* send back the original message */ | |
499 | } reply_item; | |
500 | ||
501 | ||
502 | /* The address_item structure contains many fields which are used at various | |
503 | times while delivering a message. Some are used only for remote deliveries; | |
504 | some only for local. A particular set of fields is copied whenever a child | |
505 | address is created. For convenience, we keep those fields in a separate | |
506 | sub-structure so they can be copied in one go. This also means I won't forget | |
507 | to edit the various copying places when new to-be-copied fields are added. */ | |
508 | ||
509 | typedef struct address_item_propagated { | |
510 | uschar *address_data; /* arbitrary data to keep with the address */ | |
511 | uschar *domain_data; /* from "domains" lookup */ | |
512 | uschar *localpart_data; /* from "local_parts" lookup */ | |
513 | uschar *errors_address; /* where to send errors (NULL => sender) */ | |
514 | header_line *extra_headers; /* additional headers */ | |
515 | uschar *remove_headers; /* list of those to remove */ | |
b4f579d1 | 516 | void *variables; /* router-vasriables */ |
384152a6 | 517 | |
b4f579d1 | 518 | #ifdef EXPERIMENTAL_SRS |
384152a6 | 519 | uschar *srs_sender; /* Change return path when delivering */ |
b4f579d1 | 520 | #endif |
7eb0e5d2 | 521 | BOOL ignore_error:1; /* ignore delivery error */ |
b4f579d1 | 522 | #ifdef SUPPORT_I18N |
3c8b3577 JH |
523 | BOOL utf8_msg:1; /* requires SMTPUTF8 processing */ |
524 | BOOL utf8_downcvt:1; /* mandatory downconvert on delivery */ | |
525 | BOOL utf8_downcvt_maybe:1; /* optional downconvert on delivery */ | |
b4f579d1 | 526 | #endif |
059ec3d9 PH |
527 | } address_item_propagated; |
528 | ||
059ec3d9 PH |
529 | |
530 | /* The main address structure. Note that fields that are to be copied to | |
531 | generated addresses should be put in the address_item_propagated structure (see | |
532 | above) rather than directly into the address_item structure. */ | |
533 | ||
534 | typedef struct address_item { | |
535 | struct address_item *next; /* for chaining addresses */ | |
536 | struct address_item *parent; /* parent address */ | |
537 | struct address_item *first; /* points to first after group delivery */ | |
538 | struct address_item *dupof; /* points to address this is a duplicate of */ | |
539 | ||
540 | router_instance *start_router; /* generated address starts here */ | |
541 | router_instance *router; /* the router that routed */ | |
542 | transport_instance *transport; /* the transport to use */ | |
543 | ||
544 | host_item *host_list; /* host data for the transport */ | |
545 | host_item *host_used; /* host that took delivery or failed hard */ | |
546 | host_item *fallback_hosts; /* to try if delivery defers */ | |
547 | ||
548 | reply_item *reply; /* data for autoreply */ | |
549 | retry_item *retries; /* chain of retry information */ | |
550 | ||
551 | uschar *address; /* address being delivered or routed */ | |
552 | uschar *unique; /* used for disambiguating */ | |
553 | uschar *cc_local_part; /* caseful local part */ | |
554 | uschar *lc_local_part; /* lowercased local part */ | |
555 | uschar *local_part; /* points to cc or lc version */ | |
37c0e209 | 556 | uschar *local_part_verified; /* result from check_local_user */ |
059ec3d9 | 557 | uschar *prefix; /* stripped prefix of local part */ |
759502e5 | 558 | uschar *prefix_v; /* variable part of above */ |
059ec3d9 | 559 | uschar *suffix; /* stripped suffix of local part */ |
759502e5 | 560 | uschar *suffix_v; /* variable part of above */ |
55414b25 | 561 | const uschar *domain; /* working domain (lower cased) */ |
059ec3d9 PH |
562 | |
563 | uschar *address_retry_key; /* retry key including full address */ | |
564 | uschar *domain_retry_key; /* retry key for domain only */ | |
565 | ||
566 | uschar *current_dir; /* current directory for transporting */ | |
567 | uschar *home_dir; /* home directory for transporting */ | |
568 | uschar *message; /* error message */ | |
569 | uschar *user_message; /* error message that can be sent over SMTP | |
570 | or quoted in bounce message */ | |
571 | uschar *onetime_parent; /* saved original parent for onetime */ | |
572 | uschar **pipe_expandn; /* numeric expansions for pipe from filter */ | |
573 | uschar *return_filename; /* name of return file */ | |
574 | uschar *self_hostname; /* after self=pass */ | |
575 | uschar *shadow_message; /* info about shadow transporting */ | |
576 | ||
01603eec | 577 | #ifndef DISABLE_TLS |
5b195d6b | 578 | const uschar *tlsver; /* version used for transport */ |
059ec3d9 | 579 | uschar *cipher; /* Cipher used for transport */ |
9d1c15ef JH |
580 | void *ourcert; /* Certificate offered to peer, binary */ |
581 | void *peercert; /* Certificate from peer, binary */ | |
059ec3d9 | 582 | uschar *peerdn; /* DN of server's certificate */ |
018058b2 | 583 | int ocsp; /* OCSP status of peer cert */ |
895fbaf2 JH |
584 | #endif |
585 | ||
586 | #ifdef EXPERIMENTAL_DSN_INFO | |
587 | const uschar *smtp_greeting; /* peer self-identification */ | |
588 | const uschar *helo_response; /* peer message */ | |
589 | #endif | |
059ec3d9 | 590 | |
018c60d7 JH |
591 | uschar *authenticator; /* auth driver name used by transport */ |
592 | uschar *auth_id; /* auth "login" name used by transport */ | |
593 | uschar *auth_sndr; /* AUTH arg to SMTP MAIL, used by transport */ | |
594 | ||
6c1c3d1d WB |
595 | uschar *dsn_orcpt; /* DSN orcpt value */ |
596 | int dsn_flags; /* DSN flags */ | |
597 | int dsn_aware; /* DSN aware flag */ | |
6c1c3d1d | 598 | |
059ec3d9 PH |
599 | uid_t uid; /* uid for transporting */ |
600 | gid_t gid; /* gid for transporting */ | |
601 | ||
7eb0e5d2 JH |
602 | /* flags */ |
603 | struct { | |
604 | BOOL af_allow_file:1; /* allow file in generated address */ | |
605 | BOOL af_allow_pipe:1; /* allow pipe in generated address */ | |
606 | BOOL af_allow_reply:1; /* allow autoreply in generated address */ | |
607 | BOOL af_dr_retry_exists:1; /* router retry record exists */ | |
608 | BOOL af_expand_pipe:1; /* expand pipe arguments */ | |
609 | BOOL af_file:1; /* file delivery; always with pfr */ | |
610 | BOOL af_gid_set:1; /* gid field is set */ | |
611 | BOOL af_home_expanded:1; /* home_dir is already expanded */ | |
612 | BOOL af_initgroups:1; /* use initgroups() for local transporting */ | |
613 | BOOL af_local_host_removed:1; /* local host was backup */ | |
614 | BOOL af_lt_retry_exists:1; /* local transport retry exists */ | |
615 | BOOL af_pfr:1; /* pipe or file or reply delivery */ | |
616 | BOOL af_retry_skipped:1; /* true if retry caused some skipping */ | |
617 | BOOL af_retry_timedout:1; /* true if retry timed out */ | |
618 | BOOL af_uid_set:1; /* uid field is set */ | |
619 | BOOL af_hide_child:1; /* hide child in bounce/defer msgs */ | |
620 | BOOL af_sverify_told:1; /* sender verify failure notified */ | |
621 | BOOL af_verify_pmfail:1; /* verify failure was postmaster callout */ | |
622 | BOOL af_verify_nsfail:1; /* verify failure was null sender callout */ | |
623 | BOOL af_homonym:1; /* an ancestor has same address */ | |
624 | BOOL af_verify_routed:1; /* for cached sender verify: routed OK */ | |
625 | BOOL af_verify_callout:1; /* for cached sender verify: callout was specified */ | |
626 | BOOL af_include_affixes:1; /* delivered with affixes in RCPT */ | |
627 | BOOL af_cert_verified:1; /* delivered with verified TLS cert */ | |
628 | BOOL af_pass_message:1; /* pass message in bounces */ | |
629 | BOOL af_bad_reply:1; /* filter could not generate autoreply */ | |
1ccd5f67 | 630 | BOOL af_tcp_fastopen_conn:1; /* delivery connection used TCP Fast Open */ |
7c576fca | 631 | BOOL af_tcp_fastopen:1; /* delivery usefully used TCP Fast Open */ |
ee8b8090 | 632 | BOOL af_tcp_fastopen_data:1; /* delivery sent SMTP commands on TCP Fast Open */ |
7c576fca | 633 | BOOL af_pipelining:1; /* delivery used (traditional) pipelining */ |
81344b40 | 634 | #ifndef DISABLE_PIPE_CONNECT |
ee8b8090 JH |
635 | BOOL af_early_pipe:1; /* delivery used connect-time pipelining */ |
636 | #endif | |
7eb0e5d2 JH |
637 | #ifndef DISABLE_PRDR |
638 | BOOL af_prdr_used:1; /* delivery used SMTP PRDR */ | |
639 | #endif | |
640 | BOOL af_chunking_used:1; /* delivery used SMTP CHUNKING */ | |
641 | BOOL af_force_command:1; /* force_command in pipe transport */ | |
c0635b6d | 642 | #ifdef SUPPORT_DANE |
7eb0e5d2 JH |
643 | BOOL af_dane_verified:1; /* TLS cert verify done with DANE */ |
644 | #endif | |
645 | #ifdef SUPPORT_I18N | |
646 | BOOL af_utf8_downcvt:1; /* downconvert was done for delivery */ | |
b10c87b3 JH |
647 | #endif |
648 | #ifdef EXPERIMENTAL_TLS_RESUME | |
649 | BOOL af_tls_resume:1; /* TLS used a resumed session */ | |
7eb0e5d2 JH |
650 | #endif |
651 | } flags; | |
652 | ||
059ec3d9 PH |
653 | unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32]; |
654 | unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32]; | |
655 | int mode; /* mode for local transporting to a file */ | |
377da043 | 656 | int basic_errno; /* status after failure */ |
059ec3d9 | 657 | int more_errno; /* additional error information */ |
a55697ac | 658 | struct timeval delivery_time; /* time taken to do delivery/attempt */ |
059ec3d9 | 659 | |
82f90600 | 660 | unsigned short child_count; /* number of child addresses */ |
059ec3d9 PH |
661 | short int return_file; /* fileno of return data file */ |
662 | short int special_action; /* ( used when when deferred or failed */ | |
663 | /* ( also */ | |
664 | /* ( contains = or - when successful SMTP delivered */ | |
665 | /* ( also */ | |
666 | /* ( contains verify rc in sender verify cache */ | |
667 | short int transport_return; /* result of delivery attempt */ | |
d43cbe25 | 668 | address_item_propagated prop; /* fields that are propagated to children */ |
059ec3d9 PH |
669 | } address_item; |
670 | ||
671 | /* The table of header names consists of items of this type */ | |
672 | ||
673 | typedef struct { | |
674 | uschar *name; | |
675 | int len; | |
676 | BOOL allow_resent; | |
677 | int htype; | |
678 | } header_name; | |
679 | ||
680 | /* Chain of information about errors (e.g. bad addresses) */ | |
681 | ||
682 | typedef struct error_block { | |
683 | struct error_block *next; | |
55414b25 | 684 | const uschar *text1; |
059ec3d9 PH |
685 | uschar *text2; |
686 | } error_block; | |
687 | ||
688 | /* Chain of file names when processing the queue */ | |
689 | ||
690 | typedef struct queue_filename { | |
691 | struct queue_filename *next; | |
692 | uschar dir_uschar; | |
693 | uschar text[1]; | |
694 | } queue_filename; | |
695 | ||
696 | /* Chain of items of retry information, read from the retry config. */ | |
697 | ||
698 | typedef struct retry_rule { | |
699 | struct retry_rule *next; | |
700 | int rule; | |
701 | int timeout; | |
702 | int p1; | |
703 | int p2; | |
704 | } retry_rule; | |
705 | ||
706 | typedef struct retry_config { | |
707 | struct retry_config *next; | |
708 | uschar *pattern; | |
709 | int basic_errno; | |
710 | int more_errno; | |
711 | uschar *senders; | |
712 | retry_rule *rules; | |
713 | } retry_config; | |
714 | ||
715 | /* Structure for each node in a tree, of which there are various kinds */ | |
716 | ||
717 | typedef struct tree_node { | |
718 | struct tree_node *left; /* pointer to left child */ | |
719 | struct tree_node *right; /* pointer to right child */ | |
720 | union | |
721 | { | |
722 | void *ptr; /* pointer to data */ | |
723 | int val; /* or integer data */ | |
724 | } data; | |
725 | uschar balance; /* balancing factor */ | |
726 | uschar name[1]; /* node name - variable length */ | |
727 | } tree_node; | |
728 | ||
14b3c5bc JH |
729 | /* Structure for holding time-limited data such as DNS returns. |
730 | We use this rather than extending tree_node to avoid wasting | |
731 | space for most tree use (variables...) at the cost of complexity | |
a5dc727a JH |
732 | for the lookups cache. |
733 | We also store any options used for the lookup. */ | |
14b3c5bc JH |
734 | |
735 | typedef struct expiring_data { | |
a5dc727a JH |
736 | time_t expiry; /* if nonzero, data invalid after this time */ |
737 | const uschar * opts; /* options, or NULL */ | |
7d8d08c4 JH |
738 | union |
739 | { | |
a5dc727a JH |
740 | void * ptr; /* pointer to data */ |
741 | int val; /* or integer data */ | |
7d8d08c4 | 742 | } data; |
14b3c5bc JH |
743 | } expiring_data; |
744 | ||
059ec3d9 PH |
745 | /* Structure for holding the handle and the cached last lookup for searches. |
746 | This block is pointed to by the tree entry for the file. The file can get | |
747 | closed if too many are opened at once. There is a LRU chain for deciding which | |
748 | to close. */ | |
749 | ||
750 | typedef struct search_cache { | |
751 | void *handle; /* lookup handle, or NULL if closed */ | |
752 | int search_type; /* search type */ | |
753 | tree_node *up; /* LRU up pointer */ | |
754 | tree_node *down; /* LRU down pointer */ | |
755 | tree_node *item_cache; /* tree of cached results */ | |
756 | } search_cache; | |
757 | ||
758 | /* Structure for holding a partially decoded DNS record; the name has been | |
759 | uncompressed, but the data pointer is into the raw data. */ | |
760 | ||
761 | typedef struct { | |
dd708fd7 JH |
762 | uschar name[DNS_MAXNAME]; /* domain name */ |
763 | int type; /* record type */ | |
764 | unsigned short ttl; /* time-to-live, seconds */ | |
765 | int size; /* size of data */ | |
766 | const uschar *data; /* pointer to data */ | |
059ec3d9 PH |
767 | } dns_record; |
768 | ||
75c121f0 JH |
769 | /* Structure for holding the result of a DNS query. A touch over |
770 | 64k big, so take care to release as soon as possible. */ | |
059ec3d9 PH |
771 | |
772 | typedef struct { | |
773 | int answerlen; /* length of the answer */ | |
75c121f0 | 774 | uschar answer[NS_MAXMSG]; /* the answer itself */ |
059ec3d9 PH |
775 | } dns_answer; |
776 | ||
777 | /* Structure for holding the intermediate data while scanning a DNS answer | |
778 | block. */ | |
779 | ||
780 | typedef struct { | |
dd708fd7 JH |
781 | int rrcount; /* count of RRs in the answer */ |
782 | const uschar *aptr; /* pointer in the answer while scanning */ | |
783 | dns_record srr; /* data from current record in scan */ | |
059ec3d9 PH |
784 | } dns_scan; |
785 | ||
786 | /* Structure for holding a chain of IP addresses that are extracted from | |
787 | an A, AAAA, or A6 record. For the first two, there is only ever one address, | |
788 | but the chaining feature of A6 allows for several addresses to be realized from | |
789 | a single initial A6 record. The structure defines the address field of length | |
790 | 1. In use, a suitable sized block is obtained to hold the complete textual | |
791 | address. */ | |
792 | ||
793 | typedef struct dns_address { | |
794 | struct dns_address *next; | |
795 | uschar address[1]; | |
796 | } dns_address; | |
797 | ||
798 | /* Structure used for holding intermediate data during MD5 computations. */ | |
799 | ||
800 | typedef struct md5 { | |
801 | unsigned int length; | |
802 | unsigned int abcd[4]; | |
803 | } | |
804 | md5; | |
805 | ||
806 | /* Structure used for holding intermediate data during SHA-1 computations. */ | |
807 | ||
808 | typedef struct sha1 { | |
809 | unsigned int H[5]; | |
810 | unsigned int length; | |
74f1a423 JH |
811 | } sha1; |
812 | ||
ee8b8090 JH |
813 | /* Information for making an smtp connection */ |
814 | typedef struct { | |
815 | transport_instance * tblock; | |
816 | void * ob; /* smtp_transport_options_block * */ | |
817 | host_item * host; | |
818 | int host_af; | |
819 | uschar * interface; | |
c05bdbd6 | 820 | |
21ee816d | 821 | #ifdef SUPPORT_DANE |
c05bdbd6 | 822 | BOOL dane:1; /* connection must do dane */ |
8743d3ac | 823 | dns_answer tlsa_dnsa; /* strictly, this should use tainted mem */ |
c05bdbd6 | 824 | #endif |
ee8b8090 JH |
825 | } smtp_connect_args; |
826 | ||
74f1a423 JH |
827 | /* A client-initiated connection. If TLS, the second element is non-NULL */ |
828 | typedef struct { | |
829 | int sock; | |
830 | void * tls_ctx; | |
831 | } client_conn_ctx; | |
832 | ||
059ec3d9 PH |
833 | |
834 | /* Structure used to hold incoming packets of SMTP responses for a specific | |
835 | socket. The packets which may contain multiple lines (and in some cases, | |
836 | multiple responses). */ | |
837 | ||
838 | typedef struct smtp_inblock { | |
74f1a423 | 839 | client_conn_ctx * cctx; /* the connection */ |
059ec3d9 PH |
840 | int buffersize; /* the size of the buffer */ |
841 | uschar *ptr; /* current position in the buffer */ | |
842 | uschar *ptrend; /* end of data in the buffer */ | |
843 | uschar *buffer; /* the buffer itself */ | |
844 | } smtp_inblock; | |
845 | ||
846 | /* Structure used to hold buffered outgoing packets of SMTP commands for a | |
847 | specific socket. The packets which may contain multiple lines when pipelining | |
848 | is in use. */ | |
849 | ||
850 | typedef struct smtp_outblock { | |
74f1a423 | 851 | client_conn_ctx * cctx; /* the connection */ |
059ec3d9 PH |
852 | int cmd_count; /* count of buffered commands */ |
853 | int buffersize; /* the size of the buffer */ | |
854 | BOOL authenticating; /* TRUE when authenticating */ | |
855 | uschar *ptr; /* current position in the buffer */ | |
856 | uschar *buffer; /* the buffer itself */ | |
ee8b8090 JH |
857 | |
858 | smtp_connect_args * conn_args; /* to make connection, if not yet made */ | |
059ec3d9 PH |
859 | } smtp_outblock; |
860 | ||
861 | /* Structure to hold information about the source of redirection information */ | |
862 | ||
863 | typedef struct redirect_block { | |
864 | uschar *string; /* file name or string */ | |
865 | uid_t *owners; /* allowed file owners */ | |
866 | gid_t *owngroups; /* allowed file groups */ | |
867 | struct passwd *pw; /* possible owner if not NULL */ | |
868 | int modemask; /* forbidden bits */ | |
869 | BOOL isfile; /* TRUE if string is a file name */ | |
870 | BOOL check_owner; /* TRUE, FALSE, or TRUE_UNSET */ | |
871 | BOOL check_group; /* TRUE, FALSE, or TRUE_UNSET */ | |
872 | } redirect_block; | |
873 | ||
874 | /* Structure for passing arguments to check_host() */ | |
875 | ||
876 | typedef struct check_host_block { | |
55414b25 JH |
877 | const uschar *host_name; |
878 | const uschar *host_address; | |
879 | const uschar *host_ipv4; | |
059ec3d9 PH |
880 | BOOL negative; |
881 | } check_host_block; | |
882 | ||
883 | /* Structure for remembering lookup data when caching the result of | |
884 | a lookup in a named list. */ | |
885 | ||
886 | typedef struct namedlist_cacheblock { | |
887 | struct namedlist_cacheblock *next; | |
888 | uschar *key; | |
889 | uschar *data; | |
890 | } namedlist_cacheblock; | |
891 | ||
892 | /* Structure for holding data for an entry in a named list */ | |
893 | ||
894 | typedef struct namedlist_block { | |
8c2a478b JH |
895 | const uschar *string; /* the list string */ |
896 | namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ | |
94effde9 JH |
897 | short number; /* the number of the list for caching */ |
898 | BOOL hide; /* -bP does not display value */ | |
059ec3d9 PH |
899 | } namedlist_block; |
900 | ||
901 | /* Structures for Access Control Lists */ | |
902 | ||
903 | typedef struct acl_condition_block { | |
897024f1 JH |
904 | struct acl_condition_block * next; |
905 | uschar * arg; | |
906 | int type; | |
059ec3d9 | 907 | union { |
897024f1 JH |
908 | BOOL negated; |
909 | uschar * varname; | |
059ec3d9 PH |
910 | } u; |
911 | } acl_condition_block; | |
912 | ||
913 | typedef struct acl_block { | |
897024f1 JH |
914 | struct acl_block * next; |
915 | acl_condition_block * condition; | |
916 | int verb; | |
917 | int srcline; | |
918 | const uschar * srcfile; | |
059ec3d9 PH |
919 | } acl_block; |
920 | ||
a39bd74d JB |
921 | /* smtp transport calc outbound_ip */ |
922 | typedef BOOL (*oicf) (uschar *message_id, void *data); | |
923 | ||
ff5aac2b JH |
924 | /* DKIM information for transport */ |
925 | struct ob_dkim { | |
926 | uschar *dkim_domain; | |
7c6ec81b | 927 | uschar *dkim_identity; |
ff5aac2b JH |
928 | uschar *dkim_private_key; |
929 | uschar *dkim_selector; | |
930 | uschar *dkim_canon; | |
931 | uschar *dkim_sign_headers; | |
932 | uschar *dkim_strict; | |
d73e45df | 933 | uschar *dkim_hash; |
2bc0f45e | 934 | uschar *dkim_timestamps; |
e983e85a | 935 | BOOL dot_stuffed; |
617d3932 JH |
936 | BOOL force_bodyhash; |
937 | #ifdef EXPERIMENTAL_ARC | |
938 | uschar *arc_signspec; | |
939 | #endif | |
e983e85a | 940 | }; |
ff5aac2b | 941 | |
059ec3d9 | 942 | /* End of structs.h */ |