X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/bfe645c1570343d3adca657ab67998e122ca8792..6e48a63849cd3f1dfb3555fe57094954b3f7f092:/src/src/structs.h diff --git a/src/src/structs.h b/src/src/structs.h index 78f5a8087..8c103caa8 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -2,7 +2,8 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -25,13 +26,22 @@ struct smtp_outblock; struct transport_info; struct router_info; +/* Growable-string */ +typedef struct gstring { + int size; /* Current capacity of string memory */ + int ptr; /* Offset at which to append further chars */ + uschar * s; /* The string memory */ +} gstring; + /* Structure for remembering macros for the configuration file */ typedef struct macro_item { - struct macro_item *next; - BOOL command_line; - uschar *replacement; - uschar name[1]; + struct macro_item * next; + BOOL command_line; + unsigned namelen; + unsigned replen; + const uschar * name; + const uschar * replacement; } macro_item; /* Structure for bit tables for debugging and logging */ @@ -51,6 +61,17 @@ typedef struct ugid_block { BOOL initgroups; } ugid_block; +typedef enum { CHUNKING_NOT_OFFERED = -1, + CHUNKING_OFFERED, + CHUNKING_ACTIVE, + CHUNKING_LAST} chunking_state_t; + +typedef enum { TFO_NOT_USED = 0, + TFO_ATTEMPTED_NODATA, + TFO_ATTEMPTED_DATA, + TFO_USED_NODATA, + TFO_USED_DATA } tfo_state_t; + /* Structure for holding information about a host for use mainly by routers, but also used when checking lists of hosts and when transporting. Looking up host addresses is done using this structure. */ @@ -59,14 +80,17 @@ typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t; typedef struct host_item { struct host_item *next; - const uschar *name; /* Host name */ - const uschar *address; /* IP address in text form */ - int port; /* port value in host order (if SRV lookup) */ - int mx; /* MX value if found via MX records */ - int sort_key; /* MX*1000 plus random "fraction" */ - int status; /* Usable, unusable, or unknown */ - int why; /* Why host is unusable */ - int last_try; /* Time of last try if known */ + const uschar *name; /* Host name */ +#ifndef DISABLE_TLS + const uschar *certname; /* Name used for certificate checks */ +#endif + const uschar *address; /* IP address in text form */ + int port; /* port value in host order (if SRV lookup) */ + int mx; /* MX value if found via MX records */ + int sort_key; /* MX*1000 plus random "fraction" */ + int status; /* Usable, unusable, or unknown */ + int why; /* Why host is unusable */ + int last_try; /* Time of last try if known */ dnssec_status_t dnssec; } host_item; @@ -109,11 +133,15 @@ typedef struct driver_instance { uschar *name; /* Instance name */ struct driver_info *info; /* Points to info for this driver */ void *options_block; /* Pointer to private options */ + uschar *driver_name; /* All start with this generic option */ + const uschar *srcfile; /* and config source info for errors */ + int srcline; } driver_instance; typedef struct driver_info { uschar *driver_name; /* Name of driver */ + optionlist *options; /* Table of private options names */ int *options_count; /* -> Number of entries in table */ void *options_block; /* Points to default private block */ @@ -135,6 +163,9 @@ typedef struct transport_instance { struct transport_info *info; /* Info for this driver */ void *options_block; /* Pointer to private options */ uschar *driver_name; /* Must be first */ + const uschar *srcfile; + int srcline; + int (*setup)( /* Setup entry point */ struct transport_instance *, struct address_item *, @@ -218,6 +249,33 @@ typedef struct transport_info { } transport_info; +/* smtp transport datachunk callback */ + +#define tc_reap_prev BIT(0) /* Flags: reap previous SMTP cmd responses */ +#define tc_chunk_last BIT(1) /* annotate chunk SMTP cmd as LAST */ + +struct transport_context; +typedef int (*tpt_chunk_cmd_cb)(struct transport_context *, unsigned, unsigned); + +/* Structure for information about a delivery-in-progress */ + +typedef struct transport_context { + union { /* discriminated by option topt_output_string */ + int fd; /* file descriptor to write message to */ + gstring * msg; /* allocated string with written message */ + } u; + transport_instance * tblock; /* transport */ + struct address_item * addr; + uschar * check_string; /* string replacement */ + uschar * escape_string; + int options; /* output processing topt_* */ + + /* items below only used with option topt_use_bdat */ + tpt_chunk_cmd_cb chunk_cb; /* per-datachunk callback */ + void * smtp_context; +} transport_ctx; + + typedef struct { uschar *request; @@ -232,6 +290,8 @@ typedef struct router_instance { struct router_info *info; void *options_block; /* Pointer to private options */ uschar *driver_name; /* Must be first */ + const uschar *srcfile; + int srcline; uschar *address_data; /* Arbitrary data */ #ifdef EXPERIMENTAL_BRIGHTMAIL @@ -286,6 +346,7 @@ typedef struct router_instance { BOOL retry_use_local_part; /* Just what it says */ BOOL same_domain_copy_routing; /* TRUE => copy routing for same domain */ BOOL self_rewrite; /* TRUE to rewrite headers if making local */ + uschar *set; /* Variable = value to set; list */ BOOL suffix_optional; /* As it says */ BOOL verify_only; /* Skip this router if not verifying */ BOOL verify_recipient; /* Use this router when verifying a recipient*/ @@ -348,6 +409,9 @@ typedef struct auth_instance { struct auth_info *info; /* Pointer to driver info block */ void *options_block; /* Pointer to private options */ uschar *driver_name; /* Must be first */ + const uschar *srcfile; + int srcline; + uschar *advertise_condition; /* Are we going to advertise this?*/ uschar *client_condition; /* Should the client try this? */ uschar *public_name; /* Advertised name */ @@ -379,13 +443,13 @@ typedef struct auth_info { uschar *); /* rest of AUTH command */ int (*clientcode)( /* client function */ struct auth_instance *, - struct smtp_inblock *, /* socket and input buffer */ - struct smtp_outblock *, /* socket and output buffer */ + void *, /* smtp conn, with socket, output and input buffers */ int, /* command timeout */ uschar *, /* buffer for reading response */ int); /* sizeof buffer */ - void (*version_report)( /* diagnostic version reporting */ - FILE *); /* I/O stream to print to */ + gstring * (*version_report)( /* diagnostic version reporting */ + gstring *); /* string to append to */ + void (*macros_create)(void); /* feature-macro creation */ } auth_info; @@ -398,6 +462,7 @@ typedef struct ip_address_item { int port; BOOL v6_include_v4; /* Used in the daemon */ uschar address[46]; + uschar * log; /* portion of "listening on" log line */ } ip_address_item; /* Structure for chaining together arbitrary strings. */ @@ -463,60 +528,16 @@ typedef struct address_item_propagated { uschar *errors_address; /* where to send errors (NULL => sender) */ header_line *extra_headers; /* additional headers */ uschar *remove_headers; /* list of those to remove */ + void *variables; /* router-vasriables */ - #ifdef EXPERIMENTAL_SRS - uschar *srs_sender; /* Change return path when delivering */ - #endif - #ifdef SUPPORT_I18N + BOOL ignore_error:1; /* ignore delivery error */ +#ifdef SUPPORT_I18N BOOL utf8_msg:1; /* requires SMTPUTF8 processing */ BOOL utf8_downcvt:1; /* mandatory downconvert on delivery */ BOOL utf8_downcvt_maybe:1; /* optional downconvert on delivery */ - #endif -} address_item_propagated; - -/* Bits for the flags field below */ - -#define af_allow_file 0x00000001 /* allow file in generated address */ -#define af_allow_pipe 0x00000002 /* allow pipe in generated address */ -#define af_allow_reply 0x00000004 /* allow autoreply in generated address */ -#define af_dr_retry_exists 0x00000008 /* router retry record exists */ -#define af_expand_pipe 0x00000010 /* expand pipe arguments */ -#define af_file 0x00000020 /* file delivery; always with pfr */ -#define af_gid_set 0x00000040 /* gid field is set */ -#define af_home_expanded 0x00000080 /* home_dir is already expanded */ -#define af_ignore_error 0x00000100 /* ignore delivery error */ -#define af_initgroups 0x00000200 /* use initgroups() for local transporting */ -#define af_local_host_removed 0x00000400 /* local host was backup */ -#define af_lt_retry_exists 0x00000800 /* local transport retry exists */ -#define af_pfr 0x00001000 /* pipe or file or reply delivery */ -#define af_retry_skipped 0x00002000 /* true if retry caused some skipping */ -#define af_retry_timedout 0x00004000 /* true if retry timed out */ -#define af_uid_set 0x00008000 /* uid field is set */ -#define af_hide_child 0x00010000 /* hide child in bounce/defer msgs */ -#define af_sverify_told 0x00020000 /* sender verify failure notified */ -#define af_verify_pmfail 0x00040000 /* verify failure was postmaster callout */ -#define af_verify_nsfail 0x00080000 /* verify failure was null sender callout */ -#define af_homonym 0x00100000 /* an ancestor has same address */ -#define af_verify_routed 0x00200000 /* for cached sender verify: routed OK */ -#define af_verify_callout 0x00400000 /* for cached sender verify: callout was specified */ -#define af_include_affixes 0x00800000 /* delivered with affixes in RCPT */ -#define af_cert_verified 0x01000000 /* delivered with verified TLS cert */ -#define af_pass_message 0x02000000 /* pass message in bounces */ -#define af_bad_reply 0x04000000 /* filter could not generate autoreply */ -#ifndef DISABLE_PRDR -# define af_prdr_used 0x08000000 /* delivery used SMTP PRDR */ -#endif -#define af_force_command 0x10000000 /* force_command in pipe transport */ -#ifdef EXPERIMENTAL_DANE -# define af_dane_verified 0x20000000 /* TLS cert verify done with DANE */ -#endif -#ifdef SUPPORT_I18N -# define af_utf8_downcvt 0x40000000 /* downconvert was done for delivery */ #endif +} address_item_propagated; -/* These flags must be propagated when a child is created */ - -#define af_propagate (af_ignore_error) /* The main address structure. Note that fields that are to be copied to generated addresses should be put in the address_item_propagated structure (see @@ -545,7 +566,9 @@ typedef struct address_item { uschar *lc_local_part; /* lowercased local part */ uschar *local_part; /* points to cc or lc version */ uschar *prefix; /* stripped prefix of local part */ + uschar *prefix_v; /* variable part of above */ uschar *suffix; /* stripped suffix of local part */ + uschar *suffix_v; /* variable part of above */ const uschar *domain; /* working domain (lower cased) */ uschar *address_retry_key; /* retry key including full address */ @@ -562,7 +585,8 @@ typedef struct address_item { uschar *self_hostname; /* after self=pass */ uschar *shadow_message; /* info about shadow transporting */ -#ifdef SUPPORT_TLS +#ifndef DISABLE_TLS + const uschar *tlsver; /* version used for transport */ uschar *cipher; /* Cipher used for transport */ void *ourcert; /* Certificate offered to peer, binary */ void *peercert; /* Certificate from peer, binary */ @@ -586,15 +610,67 @@ typedef struct address_item { uid_t uid; /* uid for transporting */ gid_t gid; /* gid for transporting */ - unsigned int flags; /* a row of bits, defined above */ + /* flags */ + struct { + BOOL af_allow_file:1; /* allow file in generated address */ + BOOL af_allow_pipe:1; /* allow pipe in generated address */ + BOOL af_allow_reply:1; /* allow autoreply in generated address */ + BOOL af_dr_retry_exists:1; /* router retry record exists */ + BOOL af_expand_pipe:1; /* expand pipe arguments */ + BOOL af_file:1; /* file delivery; always with pfr */ + BOOL af_gid_set:1; /* gid field is set */ + BOOL af_home_expanded:1; /* home_dir is already expanded */ + BOOL af_initgroups:1; /* use initgroups() for local transporting */ + BOOL af_local_host_removed:1; /* local host was backup */ + BOOL af_lt_retry_exists:1; /* local transport retry exists */ + BOOL af_pfr:1; /* pipe or file or reply delivery */ + BOOL af_retry_skipped:1; /* true if retry caused some skipping */ + BOOL af_retry_timedout:1; /* true if retry timed out */ + BOOL af_uid_set:1; /* uid field is set */ + BOOL af_hide_child:1; /* hide child in bounce/defer msgs */ + BOOL af_sverify_told:1; /* sender verify failure notified */ + BOOL af_verify_pmfail:1; /* verify failure was postmaster callout */ + BOOL af_verify_nsfail:1; /* verify failure was null sender callout */ + BOOL af_homonym:1; /* an ancestor has same address */ + BOOL af_verify_routed:1; /* for cached sender verify: routed OK */ + BOOL af_verify_callout:1; /* for cached sender verify: callout was specified */ + BOOL af_include_affixes:1; /* delivered with affixes in RCPT */ + BOOL af_new_conn:1; /* delivered on an fresh TCP conn */ + BOOL af_cont_conn:1; /* delivered (with new MAIL cmd) on an existing TCP conn */ + BOOL af_cert_verified:1; /* delivered with verified TLS cert */ + BOOL af_pass_message:1; /* pass message in bounces */ + BOOL af_bad_reply:1; /* filter could not generate autoreply */ + BOOL af_tcp_fastopen_conn:1; /* delivery connection used TCP Fast Open */ + BOOL af_tcp_fastopen:1; /* delivery usefully used TCP Fast Open */ + BOOL af_tcp_fastopen_data:1; /* delivery sent SMTP commands on TCP Fast Open */ + BOOL af_pipelining:1; /* delivery used (traditional) pipelining */ +#ifndef DISABLE_PIPE_CONNECT + BOOL af_early_pipe:1; /* delivery used connect-time pipelining */ +#endif +#ifndef DISABLE_PRDR + BOOL af_prdr_used:1; /* delivery used SMTP PRDR */ +#endif + BOOL af_chunking_used:1; /* delivery used SMTP CHUNKING */ + BOOL af_force_command:1; /* force_command in pipe transport */ +#ifdef SUPPORT_DANE + BOOL af_dane_verified:1; /* TLS cert verify done with DANE */ +#endif +#ifdef SUPPORT_I18N + BOOL af_utf8_downcvt:1; /* downconvert was done for delivery */ +#endif +#ifndef DISABLE_TLS_RESUME + BOOL af_tls_resume:1; /* TLS used a resumed session */ +#endif + } flags; + unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32]; unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32]; int mode; /* mode for local transporting to a file */ + int basic_errno; /* status after failure */ int more_errno; /* additional error information */ - /* (may need to hold a timestamp) */ + struct timeval delivery_time; /* time taken to do delivery/attempt */ - short int basic_errno; /* status after failure */ - short int child_count; /* number of child addresses */ + unsigned short child_count; /* number of child addresses */ short int return_file; /* fileno of return data file */ short int special_action; /* ( used when when deferred or failed */ /* ( also */ @@ -666,11 +742,17 @@ typedef struct tree_node { /* Structure for holding time-limited data such as DNS returns. We use this rather than extending tree_node to avoid wasting space for most tree use (variables...) at the cost of complexity -for the lookups cache */ +for the lookups cache. +We also store any options used for the lookup. */ typedef struct expiring_data { - time_t expiry; /* if nonzero, data invalid after this time */ - void *ptr; /* pointer to data */ + time_t expiry; /* if nonzero, data invalid after this time */ + const uschar * opts; /* options, or NULL */ + union + { + void * ptr; /* pointer to data */ + int val; /* or integer data */ + } data; } expiring_data; /* Structure for holding the handle and the cached last lookup for searches. @@ -690,27 +772,28 @@ typedef struct search_cache { uncompressed, but the data pointer is into the raw data. */ typedef struct { - uschar name[DNS_MAXNAME]; /* domain name */ - int type; /* record type */ - unsigned short ttl; /* time-to-live, seconds */ - int size; /* size of data */ - uschar *data; /* pointer to data */ + uschar name[DNS_MAXNAME]; /* domain name */ + int type; /* record type */ + unsigned short ttl; /* time-to-live, seconds */ + int size; /* size of data */ + const uschar *data; /* pointer to data */ } dns_record; -/* Structure for holding the result of a DNS query. */ +/* Structure for holding the result of a DNS query. A touch over +64k big, so take care to release as soon as possible. */ typedef struct { int answerlen; /* length of the answer */ - uschar answer[MAXPACKET]; /* the answer itself */ + uschar answer[NS_MAXMSG]; /* the answer itself */ } dns_answer; /* Structure for holding the intermediate data while scanning a DNS answer block. */ typedef struct { - int rrcount; /* count of RRs in the answer */ - uschar *aptr; /* pointer in the answer while scanning */ - dns_record srr; /* data from current record in scan */ + int rrcount; /* count of RRs in the answer */ + const uschar *aptr; /* pointer in the answer while scanning */ + dns_record srr; /* data from current record in scan */ } dns_scan; /* Structure for holding a chain of IP addresses that are extracted from @@ -738,15 +821,35 @@ md5; typedef struct sha1 { unsigned int H[5]; unsigned int length; - } -sha1; +} sha1; + +/* Information for making an smtp connection */ +typedef struct { + transport_instance * tblock; + void * ob; /* smtp_transport_options_block * */ + host_item * host; + int host_af; + uschar * interface; + +#ifdef SUPPORT_DANE + BOOL dane:1; /* connection must do dane */ + dns_answer tlsa_dnsa; /* strictly, this should use tainted mem */ +#endif +} smtp_connect_args; + +/* A client-initiated connection. If TLS, the second element is non-NULL */ +typedef struct { + int sock; + void * tls_ctx; +} client_conn_ctx; + /* Structure used to hold incoming packets of SMTP responses for a specific socket. The packets which may contain multiple lines (and in some cases, multiple responses). */ typedef struct smtp_inblock { - int sock; /* the socket */ + client_conn_ctx * cctx; /* the connection */ int buffersize; /* the size of the buffer */ uschar *ptr; /* current position in the buffer */ uschar *ptrend; /* end of data in the buffer */ @@ -758,12 +861,14 @@ specific socket. The packets which may contain multiple lines when pipelining is in use. */ typedef struct smtp_outblock { - int sock; /* the socket */ + client_conn_ctx * cctx; /* the connection */ int cmd_count; /* count of buffered commands */ int buffersize; /* the size of the buffer */ BOOL authenticating; /* TRUE when authenticating */ uschar *ptr; /* current position in the buffer */ uschar *buffer; /* the buffer itself */ + + smtp_connect_args * conn_args; /* to make connection, if not yet made */ } smtp_outblock; /* Structure to hold information about the source of redirection information */ @@ -800,30 +905,51 @@ typedef struct namedlist_cacheblock { /* Structure for holding data for an entry in a named list */ typedef struct namedlist_block { - const uschar *string; /* the list string */ - namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ - int number; /* the number of the list for caching */ + const uschar *string; /* the list string */ + namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ + short number; /* the number of the list for caching */ + BOOL hide; /* -bP does not display value */ } namedlist_block; /* Structures for Access Control Lists */ typedef struct acl_condition_block { - struct acl_condition_block *next; - uschar *arg; - int type; + struct acl_condition_block * next; + uschar * arg; + int type; union { - BOOL negated; - uschar *varname; + BOOL negated; + uschar * varname; } u; } acl_condition_block; typedef struct acl_block { - struct acl_block *next; - acl_condition_block *condition; - int verb; + struct acl_block * next; + acl_condition_block * condition; + int verb; + int srcline; + const uschar * srcfile; } acl_block; /* smtp transport calc outbound_ip */ typedef BOOL (*oicf) (uschar *message_id, void *data); +/* DKIM information for transport */ +struct ob_dkim { + uschar *dkim_domain; + uschar *dkim_identity; + uschar *dkim_private_key; + uschar *dkim_selector; + uschar *dkim_canon; + uschar *dkim_sign_headers; + uschar *dkim_strict; + uschar *dkim_hash; + uschar *dkim_timestamps; + BOOL dot_stuffed; + BOOL force_bodyhash; +#ifdef EXPERIMENTAL_ARC + uschar *arc_signspec; +#endif +}; + /* End of structs.h */