diff options
Diffstat (limited to 'src/exim.h')
-rw-r--r-- | src/exim.h | 671 |
1 files changed, 671 insertions, 0 deletions
diff --git a/src/exim.h b/src/exim.h new file mode 100644 index 0000000..61642b5 --- /dev/null +++ b/src/exim.h @@ -0,0 +1,671 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) The Exim Maintainers 2021 - 2022 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ +/* See the file NOTICE for conditions of use and distribution. */ + + +/* Source files for exim all #include this header, which drags in everything +that is needed. They don't all need everything, of course, but it's far too +messy to have each one importing its own list, and anyway, most of them need +most of these includes. */ + +#ifndef EXIM_H +#define EXIM_H + +/* Assume most systems have statfs() unless os.h undefines this macro */ + +#define HAVE_STATFS + +/* Similarly, assume most systems have srandom() unless os.h undefines it. +This call dates back at least as far as SUSv2. */ + +#define HAVE_SRANDOM + +/* This is primarily for the Gnu C library; we define it before os.h so that +os.h has a chance to hurriedly undef it, Just In Case. We need C99 for some +64-bit math support, and defining _ISOC99_SOURCE breaks <resolv.h> and friends. +*/ + +#define _GNU_SOURCE 1 + +/* First of all include the os-specific header, which might set things that +are needed by any of the other headers, including system headers. */ + +#include "os.h" + +/* If it didn't define os_find_running_interfaces, use the common function. */ + +#ifndef os_find_running_interfaces +# define os_find_running_interfaces os_common_find_running_interfaces +#endif + +/* If it didn't define the base for "base 62" numbers, we really do use 62. +This is the case for all real Unix and Unix-like OS. It's only Cygwin and +Darwin, with their case-insensitive file systems, that can't use base 62 for +making unique names. */ + +#ifndef BASE_62 +# define BASE_62 62 +#endif + +/* The maximum value of localhost_number depends on the base being used */ + +#if BASE_62 == 62 +# define LOCALHOST_MAX 16 +#else +# define LOCALHOST_MAX 10 +#endif + +/* If not overridden by os.h, dynamic libraries have filenames ending .so */ +#ifndef DYNLIB_FN_EXT +# define DYNLIB_FN_EXT "so" +#endif + +/* ANSI C standard includes */ + +#include <ctype.h> +#include <locale.h> +#include <math.h> +#include <signal.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +/* Unix includes */ + +#include <errno.h> +#if defined(__svr4__) && defined(__sparc) && ! defined(__EXTENSIONS__) +# define __EXTENSIONS__ /* so that SunOS 5 gets NGROUPS_MAX */ +# include <limits.h> +# undef __EXTENSIONS__ +#else +# include <limits.h> +#endif + +#ifdef EXIM_HAVE_INOTIFY +# include <sys/inotify.h> +#endif +#ifdef EXIM_HAVE_KEVENT +# include <sys/event.h> +#endif + +/* C99 integer types, figure out how to undo this if needed for older systems */ + +#include <inttypes.h> + +/* Just in case some aged system doesn't define them... */ + +#ifndef INT_MAX +# define INT_MAX 2147483647 +#endif + +#ifndef INT_MIN +# define INT_MIN (-INT_MAX - 1) +#endif + +#ifndef SHRT_MAX +# define SHRT_MAX 32767 +#endif + +#ifndef UCHAR_MAX +# define UCHAR_MAX 255 +#endif + + +/* To match int_eximarith_t. Define in OS/os.h-<your-system> to override. */ +#ifndef EXIM_ARITH_MAX +# define EXIM_ARITH_MAX ((int_eximarith_t)9223372036854775807LL) +#endif +#ifndef EXIM_ARITH_MIN +# define EXIM_ARITH_MIN (-EXIM_ARITH_MAX - 1) +#endif + +/* Some systems have PATH_MAX and some have MAX_PATH_LEN. */ + +#ifndef PATH_MAX +# ifdef MAX_PATH_LEN +# define PATH_MAX MAX_PATH_LEN +# else +# define PATH_MAX 1024 +# endif +#endif + +/* RFC 5321 specifies that the maximum length of a local-part is 64 octets +and the maximum length of a domain is 255 octets, but then also defines +the maximum length of a forward/reverse path as 256 not 64+1+255. +For an IP address, the maximum is 45 without a scope and we don't work +with scoped addresses, so go with that. (IPv6 with mapped IPv4). + +A hostname maximum length is in practice the same as the domainname, for +the same core reasons (maximum length of a DNS name), but the semantics +are different and seeing "DOMAIN" in source is confusing when talking about +hostnames; so we define a second macro. We'll use RFC 2181 as the reference +for this one. + +There is no known (to me) specification on the maximum length of a human name +in email addresses and we should be careful about imposing such a limit on +received email, but in terms of limiting what untrusted callers specify, or +local generation, having a limit makes sense. Err on the side of generosity. + +For a display mail address, we have a human name, an email in brackets, +possibly some (Comments), so it needs to be at least 512+3 and some more to +avoid extraneous errors. +Since the sane SMTP line length limit is 998, constraining such parameters to +be 1024 seems generous and unlikely to spuriously reject legitimate +invocations. + +The driver name is a name of a router/transport/authenticator etc in the +configuration file. We also use this for some other short strings, such +as queue names. +Also TLS ciphersuite name (no real known limit since the protocols use +integers, but max seen in reality is 45 octets). + +RFC 1413 gives us the 512 limit on IDENT protocol userids. +*/ + +#define EXIM_EMAILADDR_MAX 256 +#define EXIM_LOCALPART_MAX 64 +#define EXIM_DOMAINNAME_MAX 255 +#define EXIM_IPADDR_MAX 45 +#define EXIM_HOSTNAME_MAX 255 +#define EXIM_HUMANNAME_MAX 256 +#define EXIM_DISPLAYMAIL_MAX 1024 +#define EXIM_DRIVERNAME_MAX 64 +#define EXIM_CIPHERNAME_MAX 64 +#define EXIM_IDENTUSER_MAX 512 + + +#include <sys/types.h> +#include <sys/file.h> +#include <dirent.h> +#include <netdb.h> +#ifndef NO_POLL_H +# include <poll.h> +#endif +#include <pwd.h> +#include <grp.h> +#include <syslog.h> + +/* Not all systems have flock() available. Those that do must define LOCK_SH +in sys/file.h. */ + +#ifndef LOCK_SH +# define NO_FLOCK +#endif + +#ifndef NO_SYSEXITS /* some OS don't have this */ +# include <sysexits.h> +#endif + +/* A few OS don't have socklen_t; their os.h files define EXIM_SOCKLEN_T to +be size_t or whatever. We used to use SOCKLEN_T, but then it was discovered +that this is used by the AIX include files. */ + +#ifndef EXIM_SOCKLEN_T +# define EXIM_SOCKLEN_T socklen_t +#endif + +/* Ensure that the sysexits we reference are defined */ + +#ifndef EX_UNAVAILABLE +# define EX_UNAVAILABLE 69 /* service unavailable; used for execv fail */ +#endif +#ifndef EX_CANTCREAT +# define EX_CANTCREAT 73 /* can't create file: treat as temporary */ +#endif +#ifndef EX_TEMPFAIL +# define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#endif +#ifndef EX_CONFIG +# define EX_CONFIG 78 /* configuration error */ +#endif + +/* This one is not in any sysexits file that I've come across */ + +#define EX_EXECFAILED 127 /* execve() failed */ + + +#include <sys/time.h> +#include <sys/param.h> + +#ifndef NO_SYS_RESOURCE_H /* QNX doesn't have this */ +# include <sys/resource.h> +#endif + +#include <sys/socket.h> + +/* If we are on an IPv6 system, the macro AF_INET6 will have been defined in +the sys/socket.h header. It is helpful to have this defined on an IPv4 system +so that it can appear in the code, even if it is never actually used when +the code is run. It saves some #ifdef occurrences. */ + +#ifndef AF_INET6 +# define AF_INET6 24 +#endif + +#include <sys/ioctl.h> + +/* The new standard is statvfs; some OS have statfs. For statvfs the block +counts must be multiplied by the "fragment size" f_frsize to get the actual +size. In other cases the value seems to be f_bsize (which is sometimes the only +block size), so we use a macro to get that instead. + +Also arrange to be able to cut it out altogether for way-out OS that don't have +anything. I've indented a bit here to try to make the mess a bit more +intelligible. Note that simply defining one name to be another when +HAVE_SYS_STATVFS_H is not set will not work if the system has a statvfs macro +or a macro with entries f_frsize and f_bsize. */ + +#ifdef HAVE_STATFS + #ifdef HAVE_SYS_STATVFS_H + #include <sys/statvfs.h> + #define STATVFS statvfs + #define F_FRSIZE f_frsize + #else + #define STATVFS statfs + #define F_FRSIZE f_bsize + #ifdef HAVE_SYS_VFS_H + #include <sys/vfs.h> + #ifdef HAVE_SYS_STATFS_H + #include <sys/statfs.h> + #endif + #endif + #ifdef HAVE_SYS_MOUNT_H + #include <sys/mount.h> + #endif + #endif + + /* Macros for the fields for the available space for non-superusers; define + these only if the OS header has not. Not all OS have f_favail; those that + are known to have it define F_FAVAIL as f_favail. The default is to use + f_free. */ + + #ifndef F_BAVAIL + # define F_BAVAIL f_bavail + #endif + + #ifndef F_FAVAIL + # define F_FAVAIL f_ffree + #endif + + /* All the systems I've been able to look at seem to have F_FILES */ + + #ifndef F_FILES + # define F_FILES f_files + #endif + +#endif + + +#ifndef SIOCGIFCONF /* HACK for SunOS 5 */ +# include <sys/sockio.h> +#endif + +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/utsname.h> +#include <fcntl.h> + +/* There's a shambles in IRIX6 - it defines EX_OK in unistd.h which conflicts +with the definition in sysexits.h. Exim does not actually use this macro, so we +just undefine it. It would be nice to be able to re-instate the definition from +sysexits.h if there is no definition in unistd.h, but I do not think there is a +way to do this in C because macro definitions are not scanned for other macros +at definition time. [The code here used to assume they were, until I was +disabused of the notion. Luckily, since EX_OK is not used, it didn't matter.] */ + +#ifdef EX_OK +# undef EX_OK +#endif + +#include <unistd.h> + +#include <utime.h> +#ifndef NO_NET_IF_H +# include <net/if.h> +#endif +#include <sys/un.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + + +/* While IPv6 is still young the definitions of T_AAAA and T_A6 may not be +included in arpa/nameser.h. Fudge them here. */ + +#ifndef T_AAAA +#define T_AAAA 28 +#endif + +#ifndef T_A6 +#define T_A6 38 +#endif + +/* Ancient systems (e.g. SunOS4) don't appear to have T_TXT defined in their +header files. I don't suppose they have T_SRV either. */ + +#ifndef T_TXT +# define T_TXT 16 +#endif + +#ifndef T_SRV +# define T_SRV 33 +#endif + +/* Many systems do not have T_SPF. */ + +#ifndef T_SPF +# define T_SPF 99 +#endif + +/* New TLSA record for DANE */ +#ifndef T_TLSA +# define T_TLSA 52 +#endif +#define MAX_TLSA_EXPANDED_SIZE 8192 + +/* It seems that some versions of arpa/nameser.h don't define *any* of the +T_xxx macros, which seem to be non-standard nowadays. Just to be on the safe +side, put in definitions for all the ones that Exim uses. */ + +#ifndef T_A +# define T_A 1 +#endif + +#ifndef T_CNAME +# define T_CNAME 5 +#endif + +#ifndef T_SOA +# define T_SOA 6 +#endif + +#ifndef T_MX +# define T_MX 15 +#endif + +#ifndef T_NS +# define T_NS 2 +#endif + +#ifndef T_PTR +# define T_PTR 12 +#endif + + +/* We define a few private types for special DNS lookups: + + . T_ZNS gets the nameservers of the enclosing zone of a domain + + . T_MXH gets the MX hostnames only (without their priorities) + + . T_CSA gets the domain's Client SMTP Authorization SRV record + + . T_ADDRESSES looks up both AAAA (or A6) and A records + +If any of these names appear in the RRtype list at: + <http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml> +then we should rename Exim's private type away from the conflict. +*/ + +#define T_ZNS (-1) +#define T_MXH (-2) +#define T_CSA (-3) +#define T_ADDRESSES (-4) + +/* The resolv.h header defines __P(x) on some Solaris 2.5.1 systems (without +checking that it is already defined, in fact). This conflicts with other +headers that behave likewise (see below), leading to compiler warnings. Arrange +to undefine it if resolv.h defines it. */ + +#if defined(__P) +# define __P_WAS_DEFINED_BEFORE_RESOLV +#endif + +#include <resolv.h> + +#if defined(__P) && ! defined (__P_WAS_DEFINED_BEFORE_RESOLV) +# undef __P +#endif + +/* If not defined by os.h, we do nothing special to push DNS resolver state +back to be available by the classic resolver routines. Also, provide +prototype for our get routine, unless defined away. */ + +#ifndef os_put_dns_resolver_res +# define os_put_dns_resolver_res(R) do {/**/} while(0) +#endif +#ifndef os_get_dns_resolver_res +res_state os_get_dns_resolver_res(void); +#endif + +/* These three are to support the IP option logging code. Linux is +different to everyone else and there are also other systems which don't +have netinet/ip_var.h, so there's a general macro to control its inclusion. */ + +#include <netinet/in_systm.h> +#include <netinet/ip.h> + +#ifndef NO_IP_VAR_H +# include <netinet/ip_var.h> +#endif + +/* Linux (and some others) uses a different type for the 2nd argument of +iconv(). It's os.h file defines ICONV_ARG2_TYPE. For the rest, define a default +here. */ + +#ifndef ICONV_ARG2_TYPE +# define ICONV_ARG2_TYPE char ** +#endif + +/* One OS uses a different type for the 5th argument of getsockopt */ + +#ifndef GETSOCKOPT_ARG5_TYPE +# define GETSOCKOPT_ARG5_TYPE socklen_t * +#endif + +/* One operating system uses a different type for the 2nd argument of select(). +Its os.h file defines SELECT_ARG2_TYPE. For the rest, define a default here. */ + +#ifndef SELECT_ARG2_TYPE +# define SELECT_ARG2_TYPE fd_set +#endif + +/* One operating system uses a different type for the 4th argument of +dn_expand(). Its os.h file defines DN_EXPAND_ARG4_TYPE. For the rest, define a +default here. */ + +#ifndef DN_EXPAND_ARG4_TYPE +# define DN_EXPAND_ARG4_TYPE char * +#endif + +/* One operating system defines a different type for the yield of inet_addr(). +In Exim code, its value is always assigned to the s_addr members of address +structures. Casting the yield to the type of s_addr should fix the problem, +since the size of the data is correct. Just in case this ever has to be +changed, use a macro for the type, and define it here so that it is possible to +use different values for specific OS if ever necessary. */ + +#ifndef S_ADDR_TYPE +# define S_ADDR_TYPE u_long +#endif + +/* (At least) one operating system (Solaris) defines a different type for the +second argument of pam_converse() - the difference is the absence of "const". +Its os.h file defines PAM_CONVERSE_ARG2_TYPE. For the rest, define a default +here. */ + +#ifndef PAM_CONVERSE_ARG2_TYPE +# define PAM_CONVERSE_ARG2_TYPE const struct pam_message +#endif + +/* One operating system (SunOS4) defines getc, ungetc, feof, and ferror as +macros and not as functions. Exim needs them to be assignable functions. This +flag gets set to cause this to be sorted out here. */ + +#ifdef FUDGE_GETC_AND_FRIENDS +# undef getc +extern int getc(FILE *); +# undef ungetc +extern int ungetc(int, FILE *); +# undef feof +extern int feof(FILE *); +# undef ferror +extern int ferror(FILE *); +#endif + +/* The header from the PCRE regex package */ + +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> + +/* Exim includes are in several files. Note that local_scan.h #includes +config.h, mytypes.h, and store.h, so we don't need to mention them explicitly. +*/ + +#include "local_scan.h" +#include "macros.h" +#include "hintsdb.h" +#include "hintsdb_structs.h" +#include "structs.h" +#include "blob.h" +#include "hash.h" +#include "globals.h" +#include "functions.h" +#include "dbfunctions.h" +#include "osfunctions.h" + +#ifdef EXPERIMENTAL_BRIGHTMAIL +# include "bmi_spam.h" +#endif +#ifdef SUPPORT_SPF +# include "spf.h" +#endif +#ifndef DISABLE_DKIM +# include "dkim.h" +#endif +#ifdef SUPPORT_DMARC +# include "dmarc.h" +# include <opendmarc/dmarc.h> +#endif + +/* The following stuff must follow the inclusion of config.h because it +requires various things that are set therein. */ + +#if HAVE_ICONV /* Not all OS have this */ +# include <iconv.h> +#endif + +#if defined(USE_READLINE) || defined(EXPAND_DLFUNC) || defined (LOOKUP_MODULE_DIR) +# include <dlfcn.h> +#endif + +#ifdef ENABLE_DISABLE_FSYNC +# define EXIMfsync(f) (disable_fsync? 0 : fsync(f)) +#else +# define EXIMfsync(f) fsync(f) +#endif + +/* Backward compatibility; LOOKUP_LSEARCH now includes all three */ + +#if (!defined LOOKUP_LSEARCH) && (defined LOOKUP_WILDLSEARCH || defined LOOKUP_NWILDLSEARCH) +# define LOOKUP_LSEARCH yes +#endif + +/* Define a union to hold either an IPv4 or an IPv6 sockaddr structure; this +simplifies some of the coding. We include the sockaddr to reduce type-punning +issues in C99. */ + +union sockaddr_46 { + struct sockaddr_in v4; + #if HAVE_IPV6 + struct sockaddr_in6 v6; + #endif + struct sockaddr v0; +}; + +/* If DISABLE_TLS is defined, ensure that USE_GNUTLS is not defined +so that if USE_GNUTLS *is* set, we can assume DISABLE_TLS is not set. +Ditto USE_OPENSSL. +Likewise, OSCP, AUTH_TLS and CERTNAMES cannot be supported. */ + +#ifdef DISABLE_TLS +# undef USE_OPENSSL +# undef USE_GNUTLS +# ifndef DISABLE_OCSP +# define DISABLE_OCSP +# endif +# undef EXPERIMENTAL_CERTNAMES +# undef AUTH_TLS +#endif + +/* If SPOOL_DIRECTORY, LOG_FILE_PATH or PID_FILE_PATH have not been defined, +set them to the null string. */ + +#ifndef SPOOL_DIRECTORY + #define SPOOL_DIRECTORY "" +#endif +#ifndef LOG_FILE_PATH + #define LOG_FILE_PATH "" +#endif +#ifndef PID_FILE_PATH + #define PID_FILE_PATH "" +#endif + +/* The EDQUOT error code isn't universally available, though it is widespread. +There is a particular shambles in SunOS5, where it did not exist originally, +but got installed with a particular patch for Solaris 2.4. There is a +configuration variable for specifying what the system's "over quota" error is, +which will end up in config.h if supplied in OS/Makefile-xxx. If it is not set, +default to EDQUOT if it exists, otherwise ENOSPC. */ + +#ifndef ERRNO_QUOTA +# ifdef EDQUOT +# define ERRNO_QUOTA EDQUOT +# else +# define ERRNO_QUOTA ENOSPC +# endif +#endif + +/* DANE w/o DNSSEC is useless */ +#if defined(SUPPORT_DANE) && defined(DISABLE_DNSSEC) +# error DANE support requires DNSSEC support +#endif + +/* Some platforms (FreeBSD, OpenBSD, Solaris) do not seem to define this */ + +#ifndef POLLRDHUP +# define POLLRDHUP (POLLIN | POLLHUP) +#endif + +/* Some platforms (Darwin) have to define a larger limit on groups membership */ + +#ifndef EXIM_GROUPLIST_SIZE +# define EXIM_GROUPLIST_SIZE NGROUPS_MAX +#endif + +/* Linux has TCP_CORK, FreeBSD has TCP_NOPUSH; they do pretty much the same */ + +#ifdef TCP_CORK +# define EXIM_TCP_CORK TCP_CORK +#elif defined(TCP_NOPUSH) +# define EXIM_TCP_CORK TCP_NOPUSH +#endif + +/* LibreSSL seems to not push out the SMTP response to QUIT with our usual +handling which is trying to get the client to FIN first so that the server does +not get the TIME_WAIT */ + +#if !defined(DISABLE_TLS) && defined(USE_OPENSSL) && defined(LIBRESSL_VERSION_NUMBER) +# define SERVERSIDE_CLOSE_NOWAIT +#endif + +#endif +/* End of exim.h */ |