X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/7ade712cc84d7f822f04baf2f46daee81701174d..7e8793815bb43f97a022c6b71850206dbbd5d378:/src/src/macros.h diff --git a/src/src/macros.h b/src/src/macros.h index a8ab4f7ae..62b6290eb 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -2,7 +2,8 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2014 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -12,33 +13,39 @@ a string as a text string. This is sometimes useful for debugging output. */ #define mac_string(s) # s #define mac_expanded_string(s) mac_string(s) +/* Number of elements of an array */ +#define nelem(arr) (sizeof(arr) / sizeof(*arr)) + +/* Maximum of two items */ +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + /* When running in the test harness, the load average is fudged. */ #define OS_GETLOADAVG() \ - (running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg()) + (f.running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg()) -/* The address_item structure has a word full of 1-bit flags. These macros +/* The address_item structure has a struct full of 1-bit flags. These macros manipulate them. */ -#define setflag(addr,flag) addr->flags |= (flag) -#define clearflag(addr,flag) addr->flags &= ~(flag) +#define setflag(addr, flagname) addr->flags.flagname = TRUE +#define clearflag(addr, flagname) addr->flags.flagname = FALSE -#define testflag(addr,flag) ((addr->flags & (flag)) != 0) -#define testflagsall(addr,flag) ((addr->flags & (flag)) == (flag)) +#define testflag(addr, flagname) (addr->flags.flagname) -#define copyflag(addrnew,addrold,flag) \ - addrnew->flags = (addrnew->flags & ~(flag)) | (addrold->flags & (flag)) - -#define orflag(addrnew,addrold,flag) \ - addrnew->flags |= addrold->flags & (flag) +#define copyflag(addrnew, addrold, flagname) \ + addrnew->flags.flagname = addrold->flags.flagname /* For almost all calls to convert things to printing characters, we want to -allow tabs. A macro just makes life a bit easier. */ +allow tabs & spaces. A macro just makes life a bit easier. */ -#define string_printing(s) string_printing2((s), TRUE) +#define string_printing(s) string_printing2((s), 0) +#define SP_TAB BIT(0) +#define SP_SPACE BIT(1) /* We need a special return code for "no recipients and failed to send an error @@ -80,8 +87,8 @@ as unsigned. */ /* When built with TLS support, the act of flushing SMTP output becomes a no-op once an SSL session is in progress. */ -#ifdef SUPPORT_TLS -#define mac_smtp_fflush() if (tls_in.active < 0) fflush(smtp_out); +#ifndef DISABLE_TLS +#define mac_smtp_fflush() if (tls_in.active.sock < 0) fflush(smtp_out); #else #define mac_smtp_fflush() fflush(smtp_out); #endif @@ -103,15 +110,8 @@ don't make the file descriptors two-way. */ /* Debugging control */ -#define DEBUG(x) if ((debug_selector & (x)) != 0) -#define HDEBUG(x) if (host_checking || (debug_selector & (x)) != 0) - -#define PTR_CHK(ptr) \ -do { \ -if ((void *)ptr > (void *)store_get(0)) \ - debug_printf("BUG: ptr '%s' beyond arena at %s:%d\n", \ - mac_expanded_string(ptr), __FUNCTION__, __LINE__); \ -} while(0) +#define DEBUG(x) if (debug_selector & (x)) +#define HDEBUG(x) if (host_checking || (debug_selector & (x))) /* The default From: text for DSNs */ @@ -121,7 +121,7 @@ if ((void *)ptr > (void *)store_get(0)) \ verifying. This has to be explicit because it is referenced in more than one source module. */ -#define ADDRESS_EXPANSIONS_COUNT 18 +#define ADDRESS_EXPANSIONS_COUNT 19 /* The maximum permitted number of command-line (-D) macro definitions. We need a limit only to make it easier to generate argument vectors for re-exec @@ -140,7 +140,7 @@ changed, then the tables in expand.c for accessing them must be changed too. */ /* The size of the buffer holding the processing information string. */ -#define PROCESS_INFO_SIZE 256 +#define PROCESS_INFO_SIZE 384 /* The size of buffer to get for constructing log entries. Make it big enough to hold all the headers from a normal kind of message. */ @@ -150,20 +150,28 @@ enough to hold all the headers from a normal kind of message. */ /* The size of the circular buffer that remembers recent SMTP commands */ #define SMTP_HBUFF_SIZE 20 +#define SMTP_HBUFF_PREV(n) ((n) ? (n)-1 : SMTP_HBUFF_SIZE-1) /* The initial size of a big buffer for use in various places. It gets put into big_buffer_size and in some circumstances increased. It should be at least as long as the maximum path length. */ -#if defined PATH_MAX && PATH_MAX > 16384 -#define BIG_BUFFER_SIZE PATH_MAX -#elif defined MAXPATHLEN && MAXPATHLEN > 16384 -#define BIG_BUFFER_SIZE MAXPATHLEN +#ifdef AUTH_HEIMDAL_GSSAPI + /* RFC 4121 section 5.2, SHOULD support 64K input buffers */ +# define __BIG_BUFFER_SIZE 65536 #else -#define BIG_BUFFER_SIZE 16384 +# define __BIG_BUFFER_SIZE 16384 #endif -/* header size of pipe content +#if defined PATH_MAX && PATH_MAX > __BIG_BUFFER_SIZE +# define BIG_BUFFER_SIZE PATH_MAX +#elif defined MAXPATHLEN && MAXPATHLEN > __BIG_BUFFER_SIZE +# define BIG_BUFFER_SIZE MAXPATHLEN +#else +# define BIG_BUFFER_SIZE __BIG_BUFFER_SIZE +#endif + +/* header size of pipe content currently: char id, char subid, char[5] length */ #define PIPE_HEADER_SIZE 7 @@ -188,14 +196,6 @@ record. */ #define WAIT_NAME_MAX 50 -/* Wait this long before determining that a Proxy Protocol configured -host isn't speaking the protocol, and so is disallowed. Can be moved to -runtime configuration if per site settings become needed. */ -#ifdef EXPERIMENTAL_PROXY -#define PROXY_NEGOTIATION_TIMEOUT_SEC 3 -#define PROXY_NEGOTIATION_TIMEOUT_USEC 0 -#endif - /* Fixed option values for all PCRE functions */ #define PCRE_COPT 0 /* compile */ @@ -220,9 +220,9 @@ enum { tod_log, tod_log_bare, tod_log_zone, tod_log_datestamp_daily, /* For identifying types of driver */ enum { - DTYPE_NONE, - DTYPE_ROUTER, - DTYPE_TRANSPORT + EXIM_DTYPE_NONE, + EXIM_DTYPE_ROUTER, + EXIM_DTYPE_TRANSPORT }; /* Error numbers for generating error messages when reading a message on the @@ -241,7 +241,7 @@ enum { ERRMESS_TOOMANYRECIP, /* Too many recipients */ ERRMESS_LOCAL_SCAN, /* Rejected by local scan */ ERRMESS_LOCAL_ACL /* Rejected by non-SMTP ACL */ -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC ,ERRMESS_DMARC_FORENSIC /* DMARC Forensic Report */ #endif }; @@ -274,7 +274,9 @@ and some additional values are used only by non-driver functions. OK, FAIL, DEFER, ERROR, and FAIL_FORCED are also declared in local_scan.h for use in the local_scan() function and in ${dlfunc loaded functions. Do not -change them unilaterally. */ +change them unilaterally. + +Use rc_names[] for debug strings. */ #define OK 0 /* Successful match */ #define DEFER 1 /* Defer - some problem */ @@ -295,6 +297,7 @@ change them unilaterally. */ #define CANCELLED 13 /* Authentication cancelled */ #define FAIL_SEND 14 /* send() failed in authenticator */ #define FAIL_DROP 15 /* Fail and drop connection (used in ACL) */ +#define DANE 16 /* Deferred for domain mismatch (used in transport) */ /* Returns from the deliver_message() function */ @@ -303,7 +306,7 @@ change them unilaterally. */ #define DELIVER_MUA_FAILED 2 /* Failure when mua_wrapper is set */ #define DELIVER_NOT_ATTEMPTED 3 /* Not tried (no msg or is locked */ -/* Returns from DNS lookup functions. */ +/* Returns from DNS lookup functions. Use dns_rc_names[] for debug strings */ enum { DNS_SUCCEED, DNS_NOMATCH, DNS_NODATA, DNS_AGAIN, DNS_FAIL }; @@ -317,52 +320,100 @@ for having to swallow the rest of an SMTP message is whether the value is #define END_NOTENDED 3 /* Message reading not yet ended */ #define END_SIZE 4 /* Reading ended because message too big */ #define END_WERROR 5 /* Write error while reading the message */ +#define END_PROTOCOL 6 /* Protocol error in CHUNKING sequence */ + +/* result codes for bdat_getc() (which can also return EOF) */ + +#define EOD (-2) +#define ERR (-3) + + +/* Bit masks for debug and log selectors */ + +/* Assume words are 32 bits wide. Tiny waste of space on 64 bit +platforms, but this ensures bit vectors always work the same way. */ +#define BITWORDSIZE 32 + +/* This macro is for single-word bit vectors: the debug selector, +and the first word of the log selector. */ +#define BIT(n) (1UL << (n)) -/* Options bits for debugging; D_v and D_local_scan are also in local_scan.h */ - -#define D_v 0x00000001 -#define D_local_scan 0x00000002 - -#define D_acl 0x00000004 -#define D_auth 0x00000008 -#define D_deliver 0x00000010 -#define D_dns 0x00000020 -#define D_dnsbl 0x00000040 -#define D_exec 0x00000080 -#define D_expand 0x00000100 -#define D_filter 0x00000200 -#define D_hints_lookup 0x00000400 -#define D_host_lookup 0x00000800 -#define D_ident 0x00001000 -#define D_interface 0x00002000 -#define D_lists 0x00004000 -#define D_load 0x00008000 -#define D_lookup 0x00010000 -#define D_memory 0x00020000 -#define D_pid 0x00040000 -#define D_process_info 0x00080000 -#define D_queue_run 0x00100000 -#define D_receive 0x00200000 -#define D_resolver 0x00400000 -#define D_retry 0x00800000 -#define D_rewrite 0x01000000 -#define D_route 0x02000000 -#define D_timestamp 0x04000000 -#define D_tls 0x08000000 -#define D_transport 0x10000000 -#define D_uid 0x20000000 -#define D_verify 0x40000000 - -/* The D_all value must always have all bits set, as it is recognized specially -by the function that decodes debug and log selectors. This is to enable it to -set all the bits in a multi-word selector. Debug doesn't use this yet, but we -are getting close. In fact, we want to omit "memory" for -d+all, but can't -handle this here. It is fudged externally. */ +/* And these are for multi-word vectors. */ +#define BITWORD(n) ( (n) / BITWORDSIZE) +#define BITMASK(n) (1U << (n) % BITWORDSIZE) + +#define BIT_CLEAR(s,z,n) ((s)[BITWORD(n)] &= ~BITMASK(n)) +#define BIT_SET(s,z,n) ((s)[BITWORD(n)] |= BITMASK(n)) +#define BIT_TEST(s,z,n) (((s)[BITWORD(n)] & BITMASK(n)) != 0) + +/* Used in globals.c for initializing bit_table structures. T will be either +D or L corresponding to the debug and log selector bits declared below. */ + +#define BIT_TABLE(T,name) { US #name, T##i_##name } + +/* IOTA allows us to keep an implicit sequential count, like a simple enum, +but we can have sequentially numbered identifiers which are not declared +sequentially. We use this for more compact declarations of bit indexes and +masks, alternating between sequential bit index and corresponding mask. */ + +#define IOTA(iota) (__LINE__ - iota) +#define IOTA_INIT(zero) (__LINE__ - zero + 1) + +/* Options bits for debugging. DEBUG_BIT() declares both a bit index and the +corresponding mask. Di_all is a special value recognized by decode_bits(). +These must match the debug_options table in globals.c . + +Exim's code assumes in a number of places that the debug_selector is one +word, and this is exposed in the local_scan ABI. The D_v and D_local_scan bit +masks are part of the local_scan API so are #defined in local_scan.h */ + +#define DEBUG_BIT(name) Di_##name = IOTA(Di_iota), D_##name = (int)BIT(Di_##name) + +enum { + Di_all = -1, + Di_v = 0, + Di_local_scan = 1, + + Di_iota = IOTA_INIT(2), + DEBUG_BIT(acl), /* 2 */ + DEBUG_BIT(auth), + DEBUG_BIT(deliver), + DEBUG_BIT(dns), + DEBUG_BIT(dnsbl), + DEBUG_BIT(exec), /* 7 */ + DEBUG_BIT(expand), + DEBUG_BIT(filter), + DEBUG_BIT(hints_lookup), + DEBUG_BIT(host_lookup), + DEBUG_BIT(ident), + DEBUG_BIT(interface), + DEBUG_BIT(lists), + DEBUG_BIT(load), /* 15 */ + DEBUG_BIT(lookup), + DEBUG_BIT(memory), + DEBUG_BIT(noutf8), + DEBUG_BIT(pid), + DEBUG_BIT(process_info), + DEBUG_BIT(queue_run), + DEBUG_BIT(receive), + DEBUG_BIT(resolver), /* 23 */ + DEBUG_BIT(retry), + DEBUG_BIT(rewrite), + DEBUG_BIT(route), + DEBUG_BIT(timestamp), + DEBUG_BIT(tls), + DEBUG_BIT(transport), + DEBUG_BIT(uid), + DEBUG_BIT(verify), /* 31 */ +}; + +/* Multi-bit debug masks */ #define D_all 0xffffffff #define D_any (D_all & \ ~(D_v | \ + D_noutf8 | \ D_pid | \ D_timestamp) ) @@ -373,88 +424,88 @@ handle this here. It is fudged externally. */ D_load | \ D_local_scan | \ D_memory | \ + D_noutf8 | \ D_pid | \ D_timestamp | \ D_resolver)) -/* Options bits for logging. Those that will end up in log_write_selector have -values < 0x80000000. They can be used in calls to log_write(). The others have -values > 0x80000000 and are put into log_extra_selector (without the top bit). -These are only ever tested independently. "All" is a magic value that is used -only in the name table to set all options in both bit maps. */ - -/* The L_all value must always have all bits set, as it is recognized specially -by the function that decodes debug and log selectors. This is to enable it to -set all the bits in a multi-word selector. */ - -#define L_all 0xffffffff - -#define L_address_rewrite 0x00000001 -#define L_all_parents 0x00000002 -#define L_connection_reject 0x00000004 -#define L_delay_delivery 0x00000008 -#define L_dnslist_defer 0x00000010 -#define L_etrn 0x00000020 -#define L_host_lookup_failed 0x00000040 -#define L_lost_incoming_connection 0x00000080 -#define L_queue_run 0x00000100 -#define L_retry_defer 0x00000200 -#define L_size_reject 0x00000400 -#define L_skip_delivery 0x00000800 -#define L_smtp_connection 0x00001000 -#define L_smtp_incomplete_transaction 0x00002000 -#define L_smtp_protocol_error 0x00004000 -#define L_smtp_syntax_error 0x00008000 - -#define LX_acl_warn_skipped 0x80000001 -#define LX_arguments 0x80000002 -#define LX_deliver_time 0x80000004 -#define LX_delivery_size 0x80000008 -#define LX_ident_timeout 0x80000010 -#define LX_incoming_interface 0x80000020 -#define LX_incoming_port 0x80000040 -#define LX_outgoing_port 0x80000080 -#define LX_pid 0x80000100 -#define LX_queue_time 0x80000200 -#define LX_queue_time_overall 0x80000400 -#define LX_received_sender 0x80000800 -#define LX_received_recipients 0x80001000 -#define LX_rejected_header 0x80002000 -#define LX_return_path_on_delivery 0x80004000 -#define LX_sender_on_delivery 0x80008000 -#define LX_sender_verify_fail 0x80010000 -#define LX_smtp_confirmation 0x80020000 -#define LX_smtp_no_mail 0x80040000 -#define LX_subject 0x80080000 -#define LX_tls_certificate_verified 0x80100000 -#define LX_tls_cipher 0x80200000 -#define LX_tls_peerdn 0x80400000 -#define LX_tls_sni 0x80800000 -#define LX_unknown_in_list 0x81000000 -#define LX_8bitmime 0x82000000 -#define LX_smtp_mailauth 0x84000000 -#define LX_proxy 0x88000000 - -#define L_default (L_connection_reject | \ - L_delay_delivery | \ - L_dnslist_defer | \ - L_etrn | \ - L_host_lookup_failed | \ - L_lost_incoming_connection | \ - L_queue_run | \ - L_retry_defer | \ - L_size_reject | \ - L_skip_delivery) - -#define LX_default ((LX_acl_warn_skipped | \ - LX_rejected_header | \ - LX_sender_verify_fail | \ - LX_smtp_confirmation | \ - LX_tls_certificate_verified| \ - LX_tls_cipher) & 0x7fffffff) +/* Options bits for logging. Those that have values < BITWORDSIZE can be used +in calls to log_write(). The others are put into later words in log_selector +and are only ever tested independently, so they do not need bit mask +declarations. The Li_all value is recognized specially by decode_bits(). +Add also to log_options[] when creating new ones. */ + +#define LOG_BIT(name) Li_##name = IOTA(Li_iota), L_##name = BIT(Li_##name) + +enum logbit { + Li_all = -1, + + Li_iota = IOTA_INIT(0), + LOG_BIT(address_rewrite), + LOG_BIT(all_parents), + LOG_BIT(connection_reject), + LOG_BIT(delay_delivery), + LOG_BIT(dnslist_defer), + LOG_BIT(etrn), + LOG_BIT(host_lookup_failed), + LOG_BIT(lost_incoming_connection), + LOG_BIT(queue_run), + LOG_BIT(retry_defer), + LOG_BIT(size_reject), + LOG_BIT(skip_delivery), + LOG_BIT(smtp_connection), + LOG_BIT(smtp_incomplete_transaction), + LOG_BIT(smtp_protocol_error), + LOG_BIT(smtp_syntax_error), + + Li_8bitmime = BITWORDSIZE, + Li_acl_warn_skipped, + Li_arguments, + Li_deliver_time, + Li_delivery_size, + Li_dkim, + Li_dkim_verbose, + Li_dnssec, + Li_ident_timeout, + Li_incoming_interface, + Li_incoming_port, + Li_millisec, + Li_msg_id, + Li_msg_id_created, + Li_outgoing_interface, + Li_outgoing_port, + Li_pid, + Li_pipelining, + Li_protocol_detail, + Li_proxy, + Li_queue_time, + Li_queue_time_overall, + Li_receive_time, + Li_received_sender, + Li_received_recipients, + Li_rejected_header, + Li_return_path_on_delivery, + Li_sender_on_delivery, + Li_sender_verify_fail, + Li_smtp_confirmation, + Li_smtp_mailauth, + Li_smtp_no_mail, + Li_subject, + Li_tls_certificate_verified, + Li_tls_cipher, + Li_tls_peerdn, + Li_tls_resumption, + Li_tls_sni, + Li_unknown_in_list, + + log_selector_size = BITWORD(Li_unknown_in_list) + 1 +}; + +#define LOGGING(opt) BIT_TEST(log_selector, log_selector_size, Li_##opt) /* Private error numbers for delivery failures, set negative so as not -to conflict with system errno values. */ +to conflict with system errno values. Take care to maintain the string +table exim_errstrings[] in log.c */ #define ERRNO_UNKNOWNERROR (-1) #define ERRNO_USERSLASH (-2) @@ -504,19 +555,24 @@ to conflict with system errno values. */ #define ERRNO_DATA4XX (-46) /* DATA gave 4xx error */ #define ERRNO_PROXYFAIL (-47) /* Negotiation failed for proxy configured host */ #define ERRNO_AUTHPROB (-48) /* Authenticator "other" failure */ - -#ifdef EXPERIMENTAL_INTERNATIONAL -# define ERRNO_UTF8_FWD (-49) /* target not supporting SMTPUTF8 */ -#endif +#define ERRNO_UTF8_FWD (-49) /* target not supporting SMTPUTF8 */ +#define ERRNO_HOST_IS_LOCAL (-50) /* Transport refuses to talk to localhost */ +#define ERRNO_TAINT (-51) /* Transport refuses to talk use tainted filename */ /* These must be last, so all retry deferments can easily be identified */ -#define ERRNO_RETRY_BASE (-51) /* Base to test against */ -#define ERRNO_RRETRY (-51) /* Not time for routing */ -#define ERRNO_LRETRY (-52) /* Not time for local delivery */ -#define ERRNO_HRETRY (-53) /* Not time for any remote host */ -#define ERRNO_LOCAL_ONLY (-54) /* Local-only delivery */ -#define ERRNO_QUEUE_DOMAIN (-55) /* Domain in queue_domains */ +#define ERRNO_RETRY_BASE (-52) /* Base to test against */ +#define ERRNO_RRETRY (-52) /* Not time for routing */ + +#define ERRNO_WARN_BASE (-53) /* Base to test against */ +#define ERRNO_LRETRY (-53) /* Not time for local delivery */ +#define ERRNO_HRETRY (-54) /* Not time for any remote host */ +#define ERRNO_LOCAL_ONLY (-55) /* Local-only delivery */ +#define ERRNO_QUEUE_DOMAIN (-56) /* Domain in queue_domains */ +#define ERRNO_TRETRY (-57) /* Transport concurrency limit */ +#define ERRNO_EVENT (-58) /* Event processing request alternate response */ + + /* Special actions to take after failure or deferment. */ @@ -676,7 +732,9 @@ enum { v_none, v_sender, v_recipient, v_expn }; #define vopt_callout_no_cache 0x0040 /* disable callout cache */ #define vopt_callout_recipsender 0x0080 /* use real sender to verify recip */ #define vopt_callout_recippmaster 0x0100 /* use postmaster to verify recip */ -#define vopt_success_on_redirect 0x0200 +#define vopt_callout_hold 0x0200 /* lazy close connection */ +#define vopt_success_on_redirect 0x0400 +#define vopt_quota 0x0800 /* quota check, to local/appendfile */ /* Values for fields in callout cache records */ @@ -699,11 +757,17 @@ enum { hstatus_unknown, hstatus_usable, hstatus_unusable, /* Reasons why a host is unusable (for clearer log messages) */ -enum { hwhy_unknown, hwhy_retry, hwhy_failed, hwhy_deferred, hwhy_ignored }; +enum { hwhy_unknown, hwhy_retry, hwhy_insecure, hwhy_failed, hwhy_deferred, + hwhy_ignored }; /* Domain lookup types for routers */ -enum { lk_default, lk_byname, lk_bydns }; +#define LK_DEFAULT BIT(0) +#define LK_BYNAME BIT(1) +#define LK_BYDNS BIT(2) /* those 3 should be mutually exclusive */ + +#define LK_IPV4_ONLY BIT(3) +#define LK_IPV4_PREFER BIT(4) /* Values for the self_code fields */ @@ -754,7 +818,8 @@ most recent SMTP commands. Must be kept in step with the list of names in smtp_in.c that is used for creating the smtp_no_mail logging action. SCH_NONE is "empty". */ -enum { SCH_NONE, SCH_AUTH, SCH_DATA, SCH_EHLO, SCH_ETRN, SCH_EXPN, SCH_HELO, +enum { SCH_NONE, SCH_AUTH, SCH_DATA, SCH_BDAT, + SCH_EHLO, SCH_ETRN, SCH_EXPN, SCH_HELO, SCH_HELP, SCH_MAIL, SCH_NOOP, SCH_QUIT, SCH_RCPT, SCH_RSET, SCH_STARTTLS, SCH_VRFY }; @@ -763,6 +828,7 @@ enum { SCH_NONE, SCH_AUTH, SCH_DATA, SCH_EHLO, SCH_ETRN, SCH_EXPN, SCH_HELO, enum { HOST_FIND_FAILED, /* failed to find the host */ HOST_FIND_AGAIN, /* could not resolve at this time */ + HOST_FIND_SECURITY, /* dnssec required but not acheived */ HOST_FOUND, /* found host */ HOST_FOUND_LOCAL, /* found, but MX points to local host */ HOST_IGNORED /* found but ignored - used internally only */ @@ -770,17 +836,20 @@ enum { /* Flags for host_find_bydns() */ -#define HOST_FIND_BY_SRV 0x0001 -#define HOST_FIND_BY_MX 0x0002 -#define HOST_FIND_BY_A 0x0004 -#define HOST_FIND_QUALIFY_SINGLE 0x0008 -#define HOST_FIND_SEARCH_PARENTS 0x0010 +#define HOST_FIND_BY_SRV BIT(0) +#define HOST_FIND_BY_MX BIT(1) +#define HOST_FIND_BY_A BIT(2) +#define HOST_FIND_BY_AAAA BIT(3) +#define HOST_FIND_QUALIFY_SINGLE BIT(4) +#define HOST_FIND_SEARCH_PARENTS BIT(5) +#define HOST_FIND_IPV4_FIRST BIT(6) +#define HOST_FIND_IPV4_ONLY BIT(7) /* Actions applied to specific messages. */ enum { MSG_DELIVER, MSG_FREEZE, MSG_REMOVE, MSG_THAW, MSG_ADD_RECIPIENT, MSG_MARK_ALL_DELIVERED, MSG_MARK_DELIVERED, MSG_EDIT_SENDER, - MSG_SHOW_COPY, MSG_LOAD, + MSG_SHOW_COPY, MSG_LOAD, MSG_SETQUEUE, /* These ones must be last: a test for >= MSG_SHOW_BODY is used to test for actions that list individual spool files. */ MSG_SHOW_BODY, MSG_SHOW_HEADER, MSG_SHOW_LOG }; @@ -800,10 +869,22 @@ enum { #define topt_add_delivery_date 0x002 #define topt_add_envelope_to 0x004 #define topt_use_crlf 0x008 /* Terminate lines with CRLF */ -#define topt_end_dot 0x010 /* Send terminting dot line */ +#define topt_end_dot 0x010 /* Send terminating dot line */ #define topt_no_headers 0x020 /* Omit headers */ #define topt_no_body 0x040 /* Omit body */ #define topt_escape_headers 0x080 /* Apply escape check to headers */ +#define topt_use_bdat 0x100 /* prepend chunks with RFC3030 BDAT header */ +#define topt_output_string 0x200 /* create string rather than write to fd */ +#define topt_continuation 0x400 /* do not reset buffer */ +#define topt_not_socket 0x800 /* cannot do socket-only syscalls */ + +/* Options for smtp_write_command */ + +enum { + SCMD_FLUSH = 0, /* write to kernel */ + SCMD_MORE, /* write to kernel, but likely more soon */ + SCMD_BUFFER /* stash in application cmd output buffer */ +}; /* Flags for recipient_block, used in DSN support */ @@ -885,6 +966,37 @@ enum { ACL_WHERE_RCPT, /* Some controls are for RCPT only */ ACL_WHERE_UNKNOWN /* Currently used by a ${acl:name} expansion */ }; +#define ACL_BIT_RCPT BIT(ACL_WHERE_RCPT) +#define ACL_BIT_MAIL BIT(ACL_WHERE_MAIL) +#define ACL_BIT_PREDATA BIT(ACL_WHERE_PREDATA) +#define ACL_BIT_MIME BIT(ACL_WHERE_MIME) +#define ACL_BIT_DKIM BIT(ACL_WHERE_DKIM) +#define ACL_BIT_DATA BIT(ACL_WHERE_DATA) +#ifdef DISABLE_PRDR +# define ACL_BIT_PRDR 0 +#else +# define ACL_BIT_PRDR BIT(ACL_WHERE_PRDR) +#endif +#define ACL_BIT_NOTSMTP BIT(ACL_WHERE_NOTSMTP) +#define ACL_BIT_AUTH BIT(ACL_WHERE_AUTH) +#define ACL_BIT_CONNECT BIT(ACL_WHERE_CONNECT) +#define ACL_BIT_ETRN BIT(ACL_WHERE_ETRN) +#define ACL_BIT_EXPN BIT(ACL_WHERE_EXPN) +#define ACL_BIT_HELO BIT(ACL_WHERE_HELO) +#define ACL_BIT_MAILAUTH BIT(ACL_WHERE_MAILAUTH) +#define ACL_BIT_NOTSMTP_START BIT(ACL_WHERE_NOTSMTP_START) +#define ACL_BIT_NOTQUIT BIT(ACL_WHERE_NOTQUIT) +#define ACL_BIT_QUIT BIT(ACL_WHERE_QUIT) +#define ACL_BIT_STARTTLS BIT(ACL_WHERE_STARTTLS) +#define ACL_BIT_VRFY BIT(ACL_WHERE_VRFY) +#define ACL_BIT_DELIVERY BIT(ACL_WHERE_DELIVERY) +#define ACL_BIT_UNKNOWN BIT(ACL_WHERE_UNKNOWN) + +#define ACL_BITS_HAVEDATA (ACL_BIT_MIME | ACL_BIT_DKIM | ACL_BIT_DATA \ + | ACL_BIT_PRDR \ + | ACL_BIT_NOTSMTP | ACL_BIT_QUIT | ACL_BIT_NOTQUIT) + + /* Situations for spool_write_header() */ enum { SW_RECEIVING, SW_DELIVERING, SW_MODIFYING }; @@ -910,4 +1022,92 @@ explicit port number. */ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE }; +/* Codes for ESMTP facilities offered by peer */ + +#define OPTION_TLS BIT(0) +#define OPTION_IGNQ BIT(1) +#define OPTION_PRDR BIT(2) +#define OPTION_UTF8 BIT(3) +#define OPTION_DSN BIT(4) +#define OPTION_PIPE BIT(5) +#define OPTION_SIZE BIT(6) +#define OPTION_CHUNKING BIT(7) +#define OPTION_EARLY_PIPE BIT(8) + +/* Argument for *_getc */ + +#define GETC_BUFFER_UNLIMITED UINT_MAX + +/* UTF-8 chars for line-drawing */ + +#define UTF8_DOWN_RIGHT "\xE2\x95\xAD" +#define UTF8_VERT "\xE2\x94\x82" +#define UTF8_HORIZ "\xE2\x94\x80" +#define UTF8_VERT_RIGHT "\xE2\x94\x9C" +#define UTF8_UP_RIGHT "\xE2\x95\xB0" +#define UTF8_VERT_2DASH "\xE2\x95\x8E" + + +/* Options on tls_close */ +#define TLS_NO_SHUTDOWN 0 +#define TLS_SHUTDOWN_NOWAIT 1 +#define TLS_SHUTDOWN_WAIT 2 + + +#ifdef COMPILE_UTILITY +# define ALARM(seconds) alarm(seconds); +# define ALARM_CLR(seconds) alarm(seconds); +#else +/* For debugging of odd alarm-signal problems, stash caller info while the +alarm is active. Clear it down on cancelling the alarm so we can tell there +should not be one active. */ + +# define ALARM(seconds) \ + debug_selector & D_any \ + ? (sigalarm_setter = CUS __FUNCTION__, alarm(seconds)) : alarm(seconds); +# define ALARM_CLR(seconds) \ + debug_selector & D_any \ + ? (sigalarm_setter = NULL, alarm(seconds)) : alarm(seconds); +#endif + +#define AUTHS_REGEX US"\\n250[\\s\\-]AUTH\\s+([\\-\\w \\t]+)(?:\\n|$)" + +#define EARLY_PIPE_FEATURE_NAME "X_PIPE_CONNECT" +#define EARLY_PIPE_FEATURE_LEN 14 + + +/* Flags for auth_client_item() */ + +#define AUTH_ITEM_FIRST BIT(0) +#define AUTH_ITEM_LAST BIT(1) +#define AUTH_ITEM_IGN64 BIT(2) + + +/* Flags for tls_{in,out}_resumption */ +#define RESUME_SUPPORTED BIT(0) +#define RESUME_CLIENT_REQUESTED BIT(1) +#define RESUME_CLIENT_SUGGESTED BIT(2) +#define RESUME_SERVER_TICKET BIT(3) +#define RESUME_USED BIT(4) + +#define RESUME_DECODE_STRING \ + US"not requested or offered : 0x02 :client requested, no server ticket" \ + ": 0x04 : 0x05 : 0x06 :client offered session, no server action" \ + ": 0x08 :no client request: 0x0A :client requested new ticket, server provided" \ + ": 0x0C :client offered session, not used: 0x0E :client offered session, server only provided new ticket" \ + ": 0x10 :session resumed unasked: 0x12 :session resumed unasked" \ + ": 0x14 : 0x15 : 0x16 :session resumed" \ + ": 0x18 :session resumed unasked: 0x1A :session resumed unasked" \ + ": 0x1C :session resumed: 0x1E :session resumed, also new ticket" + +/* Flags for string_vformat */ +#define SVFMT_EXTEND BIT(0) +#define SVFMT_REBUFFER BIT(1) +#define SVFMT_TAINT_NOCHK BIT(2) + + +#define NOTIFIER_SOCKET_NAME "exim_daemon_notify" +#define NOTIFY_MSG_QRUN 1 /* Notify message types */ +#define NOTIFY_QUEUE_SIZE_REQ 2 + /* End of macros.h */