summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--clamd.exim.service11
-rw-r--r--exim-4.94-libdir.patch15
-rw-r--r--exim-4.96-pic.patch13
-rw-r--r--exim-4.98.2-config.patch816
-rw-r--r--exim-4.98.2-dlopen-localscan.patch270
-rw-r--r--exim-4.98.2-no-gsasl.patch15
-rw-r--r--exim-clamav-tmpfiles.conf1
-rw-r--r--exim-gen-cert45
-rw-r--r--exim-greylist.conf.inc167
-rw-r--r--exim-tidydb.sh10
-rw-r--r--exim.logrotate7
-rw-r--r--exim.pam3
-rw-r--r--exim.service14
-rw-r--r--exim.spec505
-rw-r--r--exim.sysconfig4
-rw-r--r--greylist-tidy.sh8
-rw-r--r--mk-greylist-db.sql13
-rw-r--r--sources1
-rw-r--r--trusted-configs6
20 files changed, 1925 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..446b424 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/exim-4.98.2.tar.xz
diff --git a/clamd.exim.service b/clamd.exim.service
new file mode 100644
index 0000000..2f60a66
--- /dev/null
+++ b/clamd.exim.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Clamd Exim An Interface Between MTA And Content Checkers
+After=network.target
+
+[Service]
+Type=forking
+PIDFile=/run/clamd.exim/clamd.pid
+ExecStart=/usr/sbin/clamd -c /etc/clamd.d/exim.conf
+
+[Install]
+WantedBy=multi-user.target
diff --git a/exim-4.94-libdir.patch b/exim-4.94-libdir.patch
new file mode 100644
index 0000000..34a1fa1
--- /dev/null
+++ b/exim-4.94-libdir.patch
@@ -0,0 +1,15 @@
+diff --git a/OS/Makefile-Linux b/OS/Makefile-Linux
+index dfb2fa8..58c30f7 100644
+--- a/OS/Makefile-Linux
++++ b/OS/Makefile-Linux
+@@ -27,8 +27,8 @@ LIBRESOLV = -lresolv
+
+ X11=/usr/X11R6
+ XINCLUDE=-I$(X11)/include
+-XLFLAGS=-L$(X11)/lib
+-X11_LD_LIB=$(X11)/lib
++XLFLAGS=-L$(X11)/$(_lib)
++X11_LD_LIB=$(X11)/$(_lib)
+
+ EXIWHAT_PS_ARG=ax
+ EXIWHAT_EGREP_ARG='/exim( |$$)'
diff --git a/exim-4.96-pic.patch b/exim-4.96-pic.patch
new file mode 100644
index 0000000..0d15a95
--- /dev/null
+++ b/exim-4.96-pic.patch
@@ -0,0 +1,13 @@
+diff --git a/src/lookups/Makefile b/src/lookups/Makefile
+index 19585bf..a0d355f 100644
+--- a/src/lookups/Makefile
++++ b/src/lookups/Makefile
+@@ -24,7 +24,7 @@ lookups.a: $(OBJ)
+ $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c
+
+ .c.so:; @echo "$(CC) -shared $*.c"
+- $(FE)$(CC) $(LOOKUP_$*_INCLUDE) $(LOOKUP_$*_LIBS) -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) $(DLFLAGS) $*.c -o $@
++ $(FE)$(CC) $(LOOKUP_$*_INCLUDE) $(LOOKUP_$*_LIBS) -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) $(DLFLAGS) $(PIC) $*.c -o $@
+
+ lf_check_file.o: $(HDRS) lf_check_file.c lf_functions.h
+ lf_quote.o: $(HDRS) lf_quote.c lf_functions.h
diff --git a/exim-4.98.2-config.patch b/exim-4.98.2-config.patch
new file mode 100644
index 0000000..12996b1
--- /dev/null
+++ b/exim-4.98.2-config.patch
@@ -0,0 +1,816 @@
+diff --git a/scripts/Configure-Makefile b/scripts/Configure-Makefile
+index dc5015f..07f8c23 100755
+--- a/scripts/Configure-Makefile
++++ b/scripts/Configure-Makefile
+@@ -319,7 +319,7 @@ if [ "${EXIM_PERL}" != "" ] ; then
+
+ mv $mft $mftt
+ echo "PERL_CC=`$PERL_COMMAND -MConfig -e 'print $Config{cc}'`" >>$mft
+- echo "PERL_CCOPTS=`$PERL_COMMAND -MExtUtils::Embed -e ccopts`" >>$mft
++ echo "PERL_CCOPTS=`$PERL_COMMAND -MExtUtils::Embed -e ccopts` \$(CFLAGS)" >>$mft
+ echo "PERL_LIBS=`$PERL_COMMAND -MExtUtils::Embed -e ldopts`" >>$mft
+ echo "" >>$mft
+ cat $mftt >> $mft
+diff --git a/src/EDITME b/src/EDITME
+index ebfaf64..9e4e818 100644
+--- a/src/EDITME
++++ b/src/EDITME
+@@ -103,7 +103,7 @@
+ # /usr/local/sbin. The installation script will try to create this directory,
+ # and any superior directories, if they do not exist.
+
+-BIN_DIRECTORY=/usr/exim/bin
++BIN_DIRECTORY=/usr/sbin
+
+
+ #------------------------------------------------------------------------------
+@@ -119,7 +119,7 @@ BIN_DIRECTORY=/usr/exim/bin
+ # don't exist. It will also install a default runtime configuration if this
+ # file does not exist.
+
+-CONFIGURE_FILE=/usr/exim/configure
++CONFIGURE_FILE=/etc/exim/exim.conf
+
+ # It is possible to specify a colon-separated list of files for CONFIGURE_FILE.
+ # In this case, Exim will use the first of them that exists when it is run.
+@@ -136,7 +136,7 @@ CONFIGURE_FILE=/usr/exim/configure
+ # deliveries. (Local deliveries run as various non-root users, typically as the
+ # owner of a local mailbox.) Specifying these values as root is not supported.
+
+-EXIM_USER=
++EXIM_USER=93
+
+ # If you specify EXIM_USER as a name, this is looked up at build time, and the
+ # uid number is built into the binary. However, you can specify that this
+@@ -157,7 +157,7 @@ EXIM_USER=
+ # for EXIM_USER (e.g. EXIM_USER=exim), you don't need to set EXIM_GROUP unless
+ # you want to use a group other than the default group for the given user.
+
+-# EXIM_GROUP=
++EXIM_GROUP=93
+
+ # Many sites define a user called "exim", with an appropriate default group,
+ # and use
+@@ -214,10 +214,10 @@ SPOOL_DIRECTORY=/var/spool/exim
+ # If you are building with TLS, the library configuration must be done:
+
+ # Uncomment this if you are using OpenSSL
+-# USE_OPENSSL=yes
++USE_OPENSSL=yes
+ # Uncomment one of these settings if you are using OpenSSL; pkg-config vs not
+ # and an optional location.
+-# USE_OPENSSL_PC=openssl
++USE_OPENSSL_PC=openssl
+ # TLS_LIBS=-lssl -lcrypto
+ # TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto
+
+@@ -344,7 +344,7 @@ TRANSPORT_SMTP=yes
+ # This one is special-purpose, and commonly not required, so it is not
+ # included by default.
+
+-# TRANSPORT_LMTP=yes
++TRANSPORT_LMTP=yes
+
+
+ #------------------------------------------------------------------------------
+@@ -353,9 +353,9 @@ TRANSPORT_SMTP=yes
+ # MBX, is included only when requested. If you do not know what this is about,
+ # leave these settings commented out.
+
+-# SUPPORT_MAILDIR=yes
+-# SUPPORT_MAILSTORE=yes
+-# SUPPORT_MBX=yes
++SUPPORT_MAILDIR=yes
++SUPPORT_MAILSTORE=yes
++SUPPORT_MBX=yes
+
+
+ #------------------------------------------------------------------------------
+@@ -413,22 +413,28 @@ LOOKUP_DBM=yes
+ LOOKUP_LSEARCH=yes
+ LOOKUP_DNSDB=yes
+
+-# LOOKUP_CDB=yes
+-# LOOKUP_DSEARCH=yes
++LOOKUP_CDB=yes
++LOOKUP_DSEARCH=yes
+ # LOOKUP_IBASE=yes
+ # LOOKUP_JSON=yes
+-# LOOKUP_LDAP=yes
++LOOKUP_LDAP=yes
++LDAP_LIB_TYPE=OPENLDAP2
++LOOKUP_LIBS=-lldap -llber -lsqlite3
+ # LOOKUP_LMDB=yes
+
+-# LOOKUP_MYSQL=yes
+-# LOOKUP_MYSQL_PC=mariadb
+-# LOOKUP_NIS=yes
+-# LOOKUP_NISPLUS=yes
++LOOKUP_MYSQL=2
++LOOKUP_MYSQL_PC=mariadb
++# LOOKUP_NIS=yes
++# LOOKUP_NISPLUS=yes
++CFLAGS+=-I/usr/include/nsl -I/usr/include/tirpc
++LIBS+=-L/usr/$(_lib)/nsl
++
+ # LOOKUP_ORACLE=yes
+-# LOOKUP_PASSWD=yes
+-# LOOKUP_PGSQL=yes
++LOOKUP_PASSWD=yes
++LOOKUP_PGSQL=2
++LOOKUP_PGSQL_LIBS=-lpq
+ # LOOKUP_REDIS=yes
+-# LOOKUP_SQLITE=yes
++LOOKUP_SQLITE=yes
+ # LOOKUP_SQLITE_PC=sqlite3
+ # LOOKUP_WHOSON=yes
+
+@@ -441,7 +447,7 @@ LOOKUP_DNSDB=yes
+
+
+ # Some platforms may need this for LOOKUP_NIS:
+-# LIBS += -lnsl
++LIBS += -lnsl
+
+ #------------------------------------------------------------------------------
+ # If you have set LOOKUP_LDAP=yes, you should set LDAP_LIB_TYPE to indicate
+@@ -515,7 +521,7 @@ SUPPORT_DANE=yes
+ # files are defaulted in the OS/Makefile-Default file, but can be overridden in
+ # local OS-specific make files.
+
+-# EXIM_MONITOR=eximon.bin
++EXIM_MONITOR=eximon.bin
+
+
+ #------------------------------------------------------------------------------
+@@ -525,7 +531,7 @@ SUPPORT_DANE=yes
+ # and the MIME ACL. Please read the documentation to learn more about these
+ # features.
+
+-# WITH_CONTENT_SCAN=yes
++WITH_CONTENT_SCAN=yes
+
+ # If you have content scanning you may wish to only include some of the scanner
+ # interfaces. Uncomment any of these lines to remove that code.
+@@ -609,12 +615,12 @@ DISABLE_MAL_MKS=yes
+
+ # Uncomment the following line to add DMARC checking capability, implemented
+ # using libopendmarc libraries. You must have SPF and DKIM support enabled also.
+-# SUPPORT_DMARC=yes
++SUPPORT_DMARC=yes
+ # CFLAGS += -I/usr/local/include
+-# LDFLAGS += -lopendmarc
++LDFLAGS += -lopendmarc
+ # Uncomment the following if you need to change the default. You can
+ # override it at runtime (main config option dmarc_tld_file)
+-# DMARC_TLD_FILE=/etc/exim/opendmarc.tlds
++DMARC_TLD_FILE=/usr/share/publicsuffix/public_suffix_list.dat
+ #
+ # Library version libopendmarc-1.4.1-1.fc33.x86_64 (on Fedora 33) is known broken;
+ # 1.3.2-3 works. It seems that the OpenDMARC project broke their API.
+@@ -749,7 +755,7 @@ FIXED_NEVER_USERS=root
+ # CONFIGURE_OWNER setting, to specify a configuration file which is listed in
+ # the TRUSTED_CONFIG_LIST file, then root privileges are not dropped by Exim.
+
+-# TRUSTED_CONFIG_LIST=/usr/exim/trusted_configs
++TRUSTED_CONFIG_LIST=/etc/exim/trusted-configs
+
+
+ #------------------------------------------------------------------------------
+@@ -794,18 +800,18 @@ FIXED_NEVER_USERS=root
+ # included in the Exim binary. You will then need to set up the run time
+ # configuration to make use of the mechanism(s) selected.
+
+-# AUTH_CRAM_MD5=yes
+-# AUTH_CYRUS_SASL=yes
+-# AUTH_DOVECOT=yes
++AUTH_CRAM_MD5=yes
++AUTH_CYRUS_SASL=yes
++AUTH_DOVECOT=yes
+ # AUTH_EXTERNAL=yes
+-# AUTH_GSASL=yes
+-# AUTH_GSASL_PC=libgsasl
++AUTH_GSASL=yes
++AUTH_GSASL_PC=libgsasl
+ # AUTH_HEIMDAL_GSSAPI=yes
+ # AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi
+ # AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi heimdal-krb5
+-# AUTH_PLAINTEXT=yes
+-# AUTH_SPA=yes
+-# AUTH_TLS=yes
++AUTH_PLAINTEXT=yes
++AUTH_SPA=yes
++AUTH_TLS=yes
+
+ # Heimdal through 1.5 required pkg-config 'heimdal-gssapi'; Heimdal 7.1
+ # requires multiple pkg-config files to work with Exim, so the second example
+@@ -832,7 +838,7 @@ FIXED_NEVER_USERS=root
+ # one that is set in the headers_charset option. The default setting is
+ # defined by this setting:
+
+-HEADERS_CHARSET="ISO-8859-1"
++HEADERS_CHARSET="UTF-8"
+
+ # If you are going to make use of $header_xxx expansions in your configuration
+ # file, or if your users are going to use them in filter files, and the normal
+@@ -852,7 +858,7 @@ HEADERS_CHARSET="ISO-8859-1"
+ # the Sieve filter support. For those OS where iconv() is known to be installed
+ # as standard, the file in OS/Makefile-xxxx contains
+ #
+-# HAVE_ICONV=yes
++HAVE_ICONV=yes
+ #
+ # If you are not using one of those systems, but have installed iconv(), you
+ # need to uncomment that line above. In some cases, you may find that iconv()
+@@ -928,7 +934,7 @@ HEADERS_CHARSET="ISO-8859-1"
+ # Once you have done this, "make install" will build the info files and
+ # install them in the directory you have defined.
+
+-# INFO_DIRECTORY=/usr/share/info
++INFO_DIRECTORY=/usr/share/info
+
+
+ #------------------------------------------------------------------------------
+@@ -941,7 +947,7 @@ HEADERS_CHARSET="ISO-8859-1"
+ # %s. This will be replaced by one of the strings "main", "panic", or "reject"
+ # to form the final file names. Some installations may want something like this:
+
+-# LOG_FILE_PATH=/var/log/exim_%slog
++LOG_FILE_PATH=/var/log/exim/%s.log
+
+ # which results in files with names /var/log/exim_mainlog, etc. The directory
+ # in which the log files are placed must exist; Exim does not try to create
+@@ -1013,7 +1019,7 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # (version 5.004 or later) installed, set EXIM_PERL to perl.o. Using embedded
+ # Perl costs quite a lot of resources. Only do this if you really need it.
+
+-# EXIM_PERL=perl.o
++EXIM_PERL=perl.o
+
+
+ #------------------------------------------------------------------------------
+@@ -1023,7 +1029,7 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # that the local_scan API is made available by the linker. You may also need
+ # to add -ldl to EXTRALIBS so that dlopen() is available to Exim.
+
+-# EXPAND_DLFUNC=yes
++EXPAND_DLFUNC=yes
+
+
+ #------------------------------------------------------------------------------
+@@ -1033,7 +1039,7 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # support, which is intended for use in conjunction with the SMTP AUTH
+ # facilities, is included only when requested by the following setting:
+
+-# SUPPORT_PAM=yes
++SUPPORT_PAM=yes
+
+ # You probably need to add -lpam to EXTRALIBS, and in some releases of
+ # GNU/Linux -ldl is also needed.
+@@ -1045,12 +1051,12 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # If you may want to use outbound (client-side) proxying, using Socks5,
+ # uncomment the line below.
+
+-# SUPPORT_SOCKS=yes
++SUPPORT_SOCKS=yes
+
+ # If you may want to use inbound (server-side) proxying, using Proxy Protocol,
+ # uncomment the line below.
+
+-# SUPPORT_PROXY=yes
++SUPPORT_PROXY=yes
+
+
+ #------------------------------------------------------------------------------
+@@ -1074,9 +1080,9 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # installed on your system (www.libspf2.org). Depending on where it is installed
+ # you may have to edit the CFLAGS and LDFLAGS lines.
+
+-# SUPPORT_SPF=yes
++SUPPORT_SPF=yes
+ # CFLAGS += -I/usr/local/include
+-# LDFLAGS += -lspf2
++LDFLAGS += -lspf2
+
+
+ #------------------------------------------------------------------------------
+@@ -1141,7 +1147,7 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # group. Once you have installed saslauthd, you should arrange for it to be
+ # started by root at boot time.
+
+-# CYRUS_SASLAUTHD_SOCKET=/var/state/saslauthd/mux
++CYRUS_SASLAUTHD_SOCKET=/var/run/saslauthd/mux
+
+
+ #------------------------------------------------------------------------------
+@@ -1155,8 +1161,8 @@ ZCAT_COMMAND=/usr/bin/zcat
+ # library for TCP wrappers, so you probably need something like this:
+ #
+ # USE_TCP_WRAPPERS=yes
+-# CFLAGS=-O -I/usr/local/include
+-# EXTRALIBS_EXIM=-L/usr/local/lib -lwrap
++CFLAGS+=$(RPM_OPT_FLAGS) $(PIE)
++EXTRALIBS_EXIM=-lpam -ldl -export-dynamic -rdynamic
+ #
+ # but of course there may need to be other things in CFLAGS and EXTRALIBS_EXIM
+ # as well.
+@@ -1208,7 +1214,7 @@ SYSTEM_ALIASES_FILE=/etc/aliases
+ # is "yes", as well as supporting line editing, a history of input lines in the
+ # current run is maintained.
+
+-# USE_READLINE=yes
++USE_READLINE=yes
+
+ # You may need to add -ldl to EXTRALIBS when you set USE_READLINE=yes.
+ # Note that this option adds to the size of the Exim binary, because the
+@@ -1225,7 +1231,7 @@ SYSTEM_ALIASES_FILE=/etc/aliases
+ #------------------------------------------------------------------------------
+ # Uncomment this setting to include IPv6 support.
+
+-# HAVE_IPV6=yes
++HAVE_IPV6=yes
+
+ ###############################################################################
+ # THINGS YOU ALMOST NEVER NEED TO MENTION #
+@@ -1246,13 +1252,13 @@ SYSTEM_ALIASES_FILE=/etc/aliases
+ # haven't got Perl, Exim will still build and run; you just won't be able to
+ # use those utilities.
+
+-# CHOWN_COMMAND=/usr/bin/chown
+-# CHGRP_COMMAND=/usr/bin/chgrp
+-# CHMOD_COMMAND=/usr/bin/chmod
+-# MV_COMMAND=/bin/mv
+-# RM_COMMAND=/bin/rm
+-# TOUCH_COMMAND=/usr/bin/touch
+-# PERL_COMMAND=/usr/bin/perl
++CHOWN_COMMAND=/usr/bin/chown
++CHGRP_COMMAND=/usr/bin/chgrp
++CHMOD_COMMAND=/usr/bin/chmod
++MV_COMMAND=/usr/bin/mv
++RM_COMMAND=/usr/bin/rm
++TOUCH_COMMAND=/usr/bin/touch
++PERL_COMMAND=/usr/bin/perl
+
+
+ #------------------------------------------------------------------------------
+@@ -1454,7 +1460,7 @@ EXIM_TMPDIR="/tmp"
+ # (process id) to a file so that it can easily be identified. The path of the
+ # file can be specified here. Some installations may want something like this:
+
+-# PID_FILE_PATH=/var/lock/exim.pid
++PID_FILE_PATH=/var/run/exim.pid
+
+ # If PID_FILE_PATH is not defined, Exim writes a file in its spool directory
+ # using the name "exim-daemon.pid".
+diff --git a/src/configure.default b/src/configure.default
+index 633c653..6379927 100644
+--- a/src/configure.default
++++ b/src/configure.default
+@@ -67,7 +67,7 @@
+ # +local_domains, +relay_to_domains, and +relay_from_hosts, respectively. They
+ # are all colon-separated lists:
+
+-domainlist local_domains = @
++domainlist local_domains = @ : localhost : localhost.localdomain
+ domainlist relay_to_domains =
+ hostlist relay_from_hosts = localhost
+ # (We rely upon hostname resolution working for localhost, because the default
+@@ -119,11 +119,13 @@ hostlist relay_from_hosts = localhost
+ # manual for details. The lists above are used in the access control lists for
+ # checking incoming messages. The names of these ACLs are defined here:
+
++acl_smtp_mail = acl_check_mail
+ acl_smtp_rcpt = acl_check_rcpt
+ .ifdef _HAVE_PRDR
+ acl_smtp_data_prdr = acl_check_prdr
+ .endif
+ acl_smtp_data = acl_check_data
++acl_smtp_mime = acl_check_mime
+
+ # You should not change those settings until you understand how ACLs work.
+
+@@ -136,7 +138,7 @@ acl_smtp_data = acl_check_data
+ # of what to set for other virus scanners. The second modification is in the
+ # acl_check_data access control list (see below).
+
+-# av_scanner = clamd:/tmp/clamd
++av_scanner = clamd:/var/run/clamd.exim/clamd.sock
+
+
+ # For spam scanning, there is a similar option that defines the interface to
+@@ -147,6 +149,12 @@ acl_smtp_data = acl_check_data
+ # spamd_address = 127.0.0.1 783
+
+
++# Set the default sqlite database file for greylisting. Uncomment this
++# if you use the greylisting ACLs defined below.
++
++# sqlite_dbfile = /var/spool/exim/db/greylist.db
++
++
+ # If Exim is compiled with support for TLS, you may want to change the
+ # following option so that Exim disallows certain clients from makeing encrypted
+ # connections. The default is to allow all.
+@@ -157,7 +165,7 @@ acl_smtp_data = acl_check_data
+
+ # This is equivalent to the default.
+
+-# tls_advertise_hosts = *
++tls_advertise_hosts = *
+
+ # Specify the location of the Exim server's TLS certificate and private key.
+ # The private key must not be encrypted (password protected). You can put
+@@ -165,8 +173,8 @@ acl_smtp_data = acl_check_data
+ # need the first setting, or in separate files, in which case you need both
+ # options.
+
+-# tls_certificate = /etc/ssl/exim.crt
+-# tls_privatekey = /etc/ssl/exim.pem
++tls_certificate = /etc/pki/tls/certs/exim.pem
++tls_privatekey = /etc/pki/tls/private/exim.pem
+
+ # For OpenSSL, prefer EC- over RSA-authenticated ciphers
+ .ifdef _HAVE_OPENSSL
+@@ -193,8 +201,8 @@ tls_resumption_hosts = ${if inlist {$received_port}{587:465} {:}{*}}
+ # them you should also allow TLS-on-connect on the traditional (and now
+ # standard) port 465.
+
+-# daemon_smtp_ports = 25 : 465 : 587
+-# tls_on_connect_ports = 465
++daemon_smtp_ports = 25 : 465 : 587
++tls_on_connect_ports = 465
+
+
+ # Specify the domain you want to be added to all unqualified addresses
+@@ -252,6 +260,24 @@ never_users = root
+
+ host_lookup = *
+
++# This setting, if uncommented, allows users to authenticate using
++# their system passwords against saslauthd if they connect over a
++# secure connection. If you have network logins such as NIS or
++# Kerberos rather than only local users, then you possibly also want
++# to configure /etc/sysconfig/saslauthd to use the 'pam' mechanism
++# too. Once a user is authenticated, the acl_check_rcpt ACL then
++# allows them to relay through the system.
++#
++# auth_advertise_hosts = ${if eq {$tls_cipher}{}{}{*}}
++#
++# By default, we set this option to allow SMTP AUTH from nowhere
++# (Exim's default would be to allow it from anywhere, even on an
++# unencrypted connection).
++#
++# Comment this one out if you uncomment the above. Did you make sure
++# saslauthd is actually running first?
++#
++auth_advertise_hosts =
+
+ # The setting below causes Exim to try to initialize the system resolver
+ # library with DNSSEC support. It has no effect if your library lacks
+@@ -382,8 +408,8 @@ timeout_frozen_after = 7d
+ # Note that TZ is handled separately by the timezone runtime option
+ # and TIMEZONE_DEFAULT buildtime option.
+
+-# keep_environment = ^LDAP
+-# add_environment = PATH=/usr/bin::/bin
++keep_environment = ^LDAP
++add_environment = PATH=/usr/bin::/bin
+
+
+
+@@ -394,6 +420,29 @@ timeout_frozen_after = 7d
+
+ begin acl
+
++
++# This access control list is used for the MAIL command in an incoming
++# SMTP message.
++
++acl_check_mail:
++
++ # Hosts are required to say HELO (or EHLO) before sending mail.
++ # So don't allow them to use the MAIL command if they haven't
++ # done so.
++
++ deny condition = ${if eq{$sender_helo_name}{} {1}}
++ message = Nice boys say HELO first
++
++ # Use the lack of reverse DNS to trigger greylisting. Some people
++ # even reject for it but that would be a little excessive.
++
++ warn condition = ${if eq{$sender_host_name}{} {1}}
++ set acl_m_greylistreasons = Host $sender_host_address lacks reverse DNS\n$acl_m_greylistreasons
++
++ accept
++
++
++
+ # This access control list is used for every RCPT command in an incoming
+ # SMTP message. The tests are run in order until the address is either
+ # accepted or denied.
+@@ -405,6 +454,7 @@ acl_check_rcpt:
+
+ accept hosts = :
+ control = dkim_disable_verify
++ control = dmarc_disable_verify
+
+ #############################################################################
+ # The following section of the ACL is concerned with local parts that contain
+@@ -458,7 +508,8 @@ acl_check_rcpt:
+ accept local_parts = postmaster
+ domains = +local_domains
+
+- # Deny unless the sender address can be verified.
++ # Deny unless the sender address can be routed. For proper verification of the
++ # address, read the documentation on callouts and add the /callout modifier.
+
+ require verify = sender
+
+@@ -498,6 +549,7 @@ acl_check_rcpt:
+ accept hosts = +relay_from_hosts
+ control = submission
+ control = dkim_disable_verify
++ control = dmarc_disable_verify
+
+ # Accept if the message arrived over an authenticated connection, from
+ # any host. Again, these messages are usually from MUAs, so recipient
+@@ -507,6 +559,7 @@ acl_check_rcpt:
+ accept authenticated = *
+ control = submission
+ control = dkim_disable_verify
++ control = dmarc_disable_verify
+
+ # Insist that any other recipient address that we accept is either in one of
+ # our local domains, or is in a domain for which we explicitly allow
+@@ -527,7 +580,8 @@ acl_check_rcpt:
+ # There are no default checks on DNS black lists because the domains that
+ # contain these lists are changing all the time. However, here are two
+ # examples of how you can get Exim to perform a DNS black list lookup at this
+- # point. The first one denies, whereas the second just warns.
++ # point. The first one denies, whereas the second just warns. The third
++ # triggers greylisting for any host in the blacklist.
+ #
+ # deny dnslists = black.list.example
+ # message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
+@@ -535,6 +589,10 @@ acl_check_rcpt:
+ # warn dnslists = black.list.example
+ # add_header = X-Warning: $sender_host_address is in a black list at $dnslist_domain
+ # log_message = found in $dnslist_domain
++ #
++ # warn dnslists = black.list.example
++ # set acl_m_greylistreasons = Host found in $dnslist_domain\n$acl_m_greylistreasons
++ #
+ #############################################################################
+
+ #############################################################################
+@@ -561,6 +619,10 @@ acl_check_rcpt:
+ # set acl_m_content_filter = ${lookup PER_RCPT_CONTENT_FILTER}
+ #############################################################################
+
++ # Alternatively, greylist for it:
++ # warn !verify = csa
++ # set acl_m_greylistreasons = Host failed CSA check\n$acl_m_greylistreasons
++
+ # At this point, the address has passed all the checks that have been
+ # configured, so we accept it unconditionally.
+
+@@ -610,21 +672,32 @@ acl_check_data:
+ message = header syntax
+ log_message = header syntax ($acl_verify_message)
+
++ # Put simple tests first. A good one is to check for the presence of a
++ # Message-Id: header, which RFC2822 says SHOULD be present. Some broken
++ # or misconfigured mailer software occasionally omits this from genuine
++ # messages too, though -- although it's not hard for the offender to fix
++ # after they receive a bounce because of it.
++ #
++ # deny condition = ${if !def:h_Message-ID: {1}}
++ # message = RFC2822 says that all mail SHOULD have a Message-ID header.\n\
++ # Most messages without it are spam, so your mail has been rejected.
++ #
++ # Alternatively if we're feeling more lenient we could just use it to
++ # trigger greylisting instead:
++
++ warn condition = ${if !def:h_Message-ID: {1}}
++ set acl_m_greylistreasons = Message lacks Message-Id: header. Consult RFC2822.\n$acl_m_greylistreasons
++
+ # Deny if the message contains a virus. Before enabling this check, you
+ # must install a virus scanner and set the av_scanner option above.
+ #
+ # deny malware = *
+ # message = This message contains a virus ($malware_name).
+
+- # Add headers to a message if it is judged to be spam. Before enabling this,
+- # you must install SpamAssassin. You may also need to set the spamd_address
+- # option above.
++ # Bypass SpamAssassin checks if the message is too large.
+ #
+- # warn spam = nobody
+- # add_header = X-Spam_score: $spam_score\n\
+- # X-Spam_score_int: $spam_score_int\n\
+- # X-Spam_bar: $spam_bar\n\
+- # X-Spam_report: $spam_report
++ # accept condition = ${if >={$message_size}{100000} {1}}
++ # add_header = X-Spam-Note: SpamAssassin run bypassed due to message size
+
+ #############################################################################
+ # No more tests if PRDR was actively used.
+@@ -638,11 +711,63 @@ acl_check_data:
+ # condition = ...
+ #############################################################################
+
++ # Run SpamAssassin, but allow for it to fail or time out. Add a warning message
++ # and accept the mail if that happens. Add an X-Spam-Flag: header if the SA
++ # score exceeds the SA system threshold.
++ #
++ # warn spam = nobody/defer_ok
++ # add_header = X-Spam-Flag: YES
++ #
++ # accept condition = ${if !def:spam_score_int {1}}
++ # add_header = X-Spam-Note: SpamAssassin invocation failed
++ #
++
++ # Unconditionally add score and report headers
++ #
++ # warn add_header = X-Spam-Score: $spam_score ($spam_bar)\n\
++ # X-Spam-Report: $spam_report
++
++ # And reject if the SpamAssassin score is greater than ten
++ #
++ # deny condition = ${if >{$spam_score_int}{100} {1}}
++ # message = Your message scored $spam_score SpamAssassin point. Report follows:\n\
++ # $spam_report
++
++ # Trigger greylisting (if enabled) if the SpamAssassin score is greater than 0.5
++ #
++ # warn condition = ${if >{$spam_score_int}{5} {1}}
++ # set acl_m_greylistreasons = Message has $spam_score SpamAssassin points\n$acl_m_greylistreasons
++
+
+- # Accept the message.
++ # If you want to greylist _all_ mail rather than only mail which looks like there
++ # might be something wrong with it, then you can do this...
++ #
++ # warn set acl_m_greylistreasons = We greylist all mail\n$acl_m_greylistreasons
++
++ # Now, invoke the greylisting. For this you need to have installed the exim-greylist
++ # package which contains this subroutine, and you need to uncomment the bit below
++ # which includes it too. Whenever the $acl_m_greylistreasons variable is non-empty,
++ # greylisting will kick in and will defer the mail to check if the sender is a
++ # proper mail which which retries, or whether it's a zombie. For more details, see
++ # the exim-greylist.conf.inc file itself.
++ #
++ # require acl = greylist_mail
+
+ accept
+
++# To enable the greylisting, also uncomment this line:
++# .include /etc/exim/exim-greylist.conf.inc
++
++acl_check_mime:
++
++ # File extension filtering.
++ deny message = Blacklisted file extension detected
++ condition = ${if match \
++ {${lc:$mime_filename}} \
++ {\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} \
++ {1}{0}}
++
++ accept
+
+
+ ######################################################################
+@@ -744,7 +869,7 @@ system_aliases:
+ driver = redirect
+ allow_fail
+ allow_defer
+- data = ${lookup{$local_part}lsearch{SYSTEM_ALIASES_FILE}}
++ data = ${lookup{$local_part}lsearch{/etc/aliases}}
+ # user = exim
+ file_transport = address_file
+ pipe_transport = address_pipe
+@@ -782,7 +907,7 @@ userforward:
+ # local_part_suffix = +* : -*
+ # local_part_suffix_optional
+ file = $home/.forward
+-# allow_filter
++ allow_filter
+ no_verify
+ no_expn
+ check_ancestor
+@@ -790,6 +915,12 @@ userforward:
+ pipe_transport = address_pipe
+ reply_transport = address_reply
+
++procmail:
++ driver = accept
++ check_local_user
++ require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
++ transport = procmail
++ no_verify
+
+ # This router matches local user mailboxes. If the router fails, the error
+ # message is "Unknown user".
+@@ -830,6 +961,25 @@ remote_smtp:
+ tls_resumption_hosts = *
+ .endif
+
++# This transport is used for delivering messages over SMTP using the
++# "message submission" port (RFC4409).
++
++remote_msa:
++ driver = smtp
++ port = 587
++ hosts_require_auth = *
++
++
++# This transport invokes procmail to deliver mail
++procmail:
++ driver = pipe
++ command = "/usr/bin/procmail -d $local_part"
++ return_path_add
++ delivery_date_add
++ envelope_to_add
++ user = $local_part
++ initgroups
++ return_output
+
+ # This transport is used for delivering messages to a smarthost, if the
+ # smarthost router is enabled. This starts from the same basis as
+@@ -884,8 +1034,8 @@ local_delivery:
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+-# group = mail
+-# mode = 0660
++ group = mail
++ mode = 0660
+
+
+ # This transport is used for handling pipe deliveries generated by alias or
+@@ -918,6 +1068,16 @@ address_reply:
+ driver = autoreply
+
+
++# This transport is used to deliver local mail to cyrus IMAP server via UNIX
++# socket. You'll need to configure the 'localuser' router above to use it.
++#
++#lmtp_delivery:
++# home_directory = /var/spool/imap
++# driver = lmtp
++# command = "/usr/lib/cyrus-imapd/deliver -l"
++# batch_max = 20
++# user = cyrus
++
+
+ ######################################################################
+ # RETRY CONFIGURATION #
+@@ -958,6 +1118,21 @@ begin rewrite
+ # AUTHENTICATION CONFIGURATION #
+ ######################################################################
+
++begin authenticators
++
++# This authenticator supports CRAM-MD5 username/password authentication
++# with Exim acting as a _client_, as it might when sending its outgoing
++# mail to a smarthost rather than directly to the final recipient.
++# Replace SMTPAUTH_USERNAME and SMTPAUTH_PASSWORD as appropriate.
++
++#client_auth:
++# driver = cram_md5
++# public_name = CRAM-MD5
++# client_name = SMTPAUTH_USERNAME
++# client_secret = SMTPAUTH_PASSWORD
++
++#
++
+ # The following authenticators support plaintext username/password
+ # authentication using the standard PLAIN mechanism and the traditional
+ # but non-standard LOGIN mechanism, with Exim acting as the server.
+@@ -973,7 +1148,7 @@ begin rewrite
+ # The default RCPT ACL checks for successful authentication, and will accept
+ # messages from authenticated users from anywhere on the Internet.
+
+-begin authenticators
++#
+
+ # PLAIN authentication has no server prompts. The client sends its
+ # credentials in one lump, containing an authorization ID (which we do not
+@@ -987,7 +1162,7 @@ begin authenticators
+ # driver = plaintext
+ # server_set_id = $auth2
+ # server_prompts = :
+-# server_condition = Authentication is not yet configured
++# server_condition = ${if saslauthd{{$2}{$3}{smtp}} {1}}
+ # server_advertise_condition = ${if def:tls_in_cipher }
+
+ # LOGIN authentication has traditional prompts and responses. There is no
+@@ -999,7 +1174,7 @@ begin authenticators
+ # driver = plaintext
+ # server_set_id = $auth1
+ # server_prompts = <| Username: | Password:
+-# server_condition = Authentication is not yet configured
++# server_condition = ${if saslauthd{{$1}{$2}{smtp}} {1}}
+ # server_advertise_condition = ${if def:tls_in_cipher }
+
+
diff --git a/exim-4.98.2-dlopen-localscan.patch b/exim-4.98.2-dlopen-localscan.patch
new file mode 100644
index 0000000..21ca340
--- /dev/null
+++ b/exim-4.98.2-dlopen-localscan.patch
@@ -0,0 +1,270 @@
+diff --git a/src/EDITME b/src/EDITME
+index 9e4e818..473010b 100644
+--- a/src/EDITME
++++ b/src/EDITME
+@@ -918,6 +918,21 @@ HAVE_ICONV=yes
+ # *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
+
+
++#------------------------------------------------------------------------------
++# On systems which support dynamic loading of shared libraries, Exim can
++# load a local_scan function specified in its config file instead of having
++# to be recompiled with the desired local_scan function. For a full
++# description of the API to this function, see the Exim specification.
++
++DLOPEN_LOCAL_SCAN=yes
++HAVE_LOCAL_SCAN=yes
++
++# If you set DLOPEN_LOCAL_SCAN, then you need to include -rdynamic in the
++# linker flags. Without it, the loaded .so won't be able to access any
++# functions from exim.
++
++LFLAGS=-rdynamic -ldl -pie
++
+ #------------------------------------------------------------------------------
+ # The default distribution of Exim contains only the plain text form of the
+ # documentation. Other forms are available separately. If you want to install
+diff --git a/src/config.h.defaults b/src/config.h.defaults
+index 13b203e..70be51d 100644
+--- a/src/config.h.defaults
++++ b/src/config.h.defaults
+@@ -33,6 +33,8 @@ Do not put spaces between # and the 'define'.
+
+ #define AUTH_VARS 4
+
++#define DLOPEN_LOCAL_SCAN
++
+ #define BIN_DIRECTORY
+
+ #define CONFIGURE_FILE
+diff --git a/src/globals.c b/src/globals.c
+index c50b7a4..50d1d13 100644
+--- a/src/globals.c
++++ b/src/globals.c
+@@ -152,6 +152,10 @@ time_t tls_watch_trigger_time = (time_t)0;
+ uschar *tls_advertise_hosts = NULL;
+ #endif
+
++#ifdef DLOPEN_LOCAL_SCAN
++uschar *local_scan_path = NULL;
++#endif
++
+ #ifndef DISABLE_PRDR
+ /* Per Recipient Data Response variables */
+ BOOL prdr_enable = FALSE;
+diff --git a/src/globals.h b/src/globals.h
+index dc9d384..d4eba50 100644
+--- a/src/globals.h
++++ b/src/globals.h
+@@ -150,6 +150,11 @@ extern uschar *tls_verify_hosts; /* Mandatory client verification */
+ extern int tls_watch_fd; /* for inotify of creds files */
+ extern time_t tls_watch_trigger_time; /* non-0: triggered */
+ #endif
++
++#ifdef DLOPEN_LOCAL_SCAN
++extern uschar *local_scan_path; /* Path to local_scan() library */
++#endif
++
+ extern uschar *tls_advertise_hosts; /* host for which TLS is advertised */
+
+ extern uschar *dsn_envid; /* DSN envid string */
+diff --git a/src/local_scan.c b/src/local_scan.c
+index da44cb7..5af46c6 100644
+--- a/src/local_scan.c
++++ b/src/local_scan.c
+@@ -7,59 +7,134 @@
+ /* See the file NOTICE for conditions of use and distribution. */
+ /* SPDX-License-Identifier: GPL-2.0-or-later */
+
++#include <local_scan.h>
+
+-/******************************************************************************
+-This file contains a template local_scan() function that just returns ACCEPT.
+-If you want to implement your own version, you should copy this file to, say
+-Local/local_scan.c, and edit the copy. To use your version instead of the
+-default, you must set
++#ifdef DLOPEN_LOCAL_SCAN
++extern uschar *local_scan_path; /* Path to local_scan() library */
++#endif
+
+-HAVE_LOCAL_SCAN=yes
+-LOCAL_SCAN_SOURCE=Local/local_scan.c
+-
+-in your Local/Makefile. This makes it easy to copy your version for use with
+-subsequent Exim releases.
+-
+-For a full description of the API to this function, see the Exim specification.
+-******************************************************************************/
+-
+-
+-/* This is the only Exim header that you should include. The effect of
+-including any other Exim header is not defined, and may change from release to
+-release. Use only the documented interface! */
+-
+-#include "local_scan.h"
+-
+-
+-/* This is a "do-nothing" version of a local_scan() function. The arguments
+-are:
+-
+- fd The file descriptor of the open -D file, which contains the
+- body of the message. The file is open for reading and
+- writing, but modifying it is dangerous and not recommended.
+-
+- return_text A pointer to an unsigned char* variable which you can set in
+- order to return a text string. It is initialized to NULL.
+-
+-The return values of this function are:
+-
+- LOCAL_SCAN_ACCEPT
+- The message is to be accepted. The return_text argument is
+- saved in $local_scan_data.
+-
+- LOCAL_SCAN_REJECT
+- The message is to be rejected. The returned text is used
+- in the rejection message.
+-
+- LOCAL_SCAN_TEMPREJECT
+- This specifies a temporary rejection. The returned text
+- is used in the rejection message.
+-*/
++#ifdef DLOPEN_LOCAL_SCAN
++#include <dlfcn.h>
++#include <stdlib.h>
++static int (*local_scan_fn)(int fd, uschar **return_text) = NULL;
++static int load_local_scan_library(void);
++#endif
+
+ int
+ local_scan(int fd, uschar **return_text)
+ {
+-return LOCAL_SCAN_ACCEPT;
++#ifdef DLOPEN_LOCAL_SCAN
++/* local_scan_path is defined AND not the empty string */
++if (local_scan_path && *local_scan_path)
++ {
++ if (!local_scan_fn)
++ {
++ if (!load_local_scan_library())
++ {
++ char *base_msg , *error_msg , *final_msg ;
++ int final_length = -1 ;
++
++ base_msg=US"Local configuration error - local_scan() library failure\n";
++ error_msg = dlerror() ;
++
++ final_length = strlen(base_msg) + strlen(error_msg) + 1 ;
++ final_msg = (char*)malloc( final_length*sizeof(char) ) ;
++ *final_msg = '\0' ;
++
++ strcat( final_msg , base_msg ) ;
++ strcat( final_msg , error_msg ) ;
++
++ *return_text = final_msg ;
++ return LOCAL_SCAN_TEMPREJECT;
++ }
++ }
++ return local_scan_fn(fd, return_text);
++ }
++else
++#endif
++ return LOCAL_SCAN_ACCEPT;
++ }
++
++#ifdef DLOPEN_LOCAL_SCAN
++
++static int load_local_scan_library(void)
++{
++/* No point in keeping local_scan_lib since we'll never dlclose() anyway */
++void *local_scan_lib = NULL;
++int (*local_scan_version_fn)(void);
++int vers_maj;
++int vers_min;
++
++local_scan_lib = dlopen(local_scan_path, RTLD_NOW);
++if (!local_scan_lib)
++ {
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library open failed - "
++ "message temporarily rejected");
++ return FALSE;
++ }
++
++local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_major");
++if (!local_scan_version_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan_version_major() function - message temporarily rejected");
++ return FALSE;
++ }
++
++/* The major number is increased when the ABI is changed in a non
++ backward compatible way. */
++vers_maj = local_scan_version_fn();
++
++local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_minor");
++if (!local_scan_version_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan_version_minor() function - message temporarily rejected");
++ return FALSE;
++ }
++
++/* The minor number is increased each time a new feature is added (in a
++ way that doesn't break backward compatibility) -- Marc */
++vers_min = local_scan_version_fn();
++
++
++if (vers_maj != LOCAL_SCAN_ABI_VERSION_MAJOR)
++ {
++ dlclose(local_scan_lib);
++ local_scan_lib = NULL;
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible major"
++ "version number, you need to recompile your module for this version"
++ "of exim (The module was compiled for version %d.%d and this exim provides"
++ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
++ LOCAL_SCAN_ABI_VERSION_MINOR);
++ return FALSE;
++ }
++else if (vers_min > LOCAL_SCAN_ABI_VERSION_MINOR)
++ {
++ dlclose(local_scan_lib);
++ local_scan_lib = NULL;
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible minor"
++ "version number, you need to recompile your module for this version"
++ "of exim (The module was compiled for version %d.%d and this exim provides"
++ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
++ LOCAL_SCAN_ABI_VERSION_MINOR);
++ return FALSE;
++ }
++
++local_scan_fn = dlsym(local_scan_lib, "local_scan");
++if (!local_scan_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan() function - message temporarily rejected");
++ return FALSE;
++ }
++
++return TRUE;
+ }
+
++#endif /* DLOPEN_LOCAL_SCAN */
++
+ /* End of local_scan.c */
+diff --git a/src/readconf.c b/src/readconf.c
+index 940c5d4..c2ddcf2 100644
+--- a/src/readconf.c
++++ b/src/readconf.c
+@@ -219,6 +219,9 @@ static optionlist optionlist_config[] = {
+ { "local_from_prefix", opt_stringptr, {&local_from_prefix} },
+ { "local_from_suffix", opt_stringptr, {&local_from_suffix} },
+ { "local_interfaces", opt_stringptr, {&local_interfaces} },
++#ifdef DLOPEN_LOCAL_SCAN
++ { "local_scan_path", opt_stringptr, &local_scan_path },
++#endif
+ #ifdef HAVE_LOCAL_SCAN
+ { "local_scan_timeout", opt_time, {&local_scan_timeout} },
+ #endif
diff --git a/exim-4.98.2-no-gsasl.patch b/exim-4.98.2-no-gsasl.patch
new file mode 100644
index 0000000..8ba9e1e
--- /dev/null
+++ b/exim-4.98.2-no-gsasl.patch
@@ -0,0 +1,15 @@
+diff --git a/src/EDITME b/src/EDITME
+index 473010b..1976437 100644
+--- a/src/EDITME
++++ b/src/EDITME
+@@ -804,8 +804,8 @@ AUTH_CRAM_MD5=yes
+ AUTH_CYRUS_SASL=yes
+ AUTH_DOVECOT=yes
+ # AUTH_EXTERNAL=yes
+-AUTH_GSASL=yes
+-AUTH_GSASL_PC=libgsasl
++# AUTH_GSASL=yes
++# AUTH_GSASL_PC=libgsasl
+ # AUTH_HEIMDAL_GSSAPI=yes
+ # AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi
+ # AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi heimdal-krb5
diff --git a/exim-clamav-tmpfiles.conf b/exim-clamav-tmpfiles.conf
new file mode 100644
index 0000000..df45687
--- /dev/null
+++ b/exim-clamav-tmpfiles.conf
@@ -0,0 +1 @@
+D /var/run/clamd.exim 0750 exim exim -
diff --git a/exim-gen-cert b/exim-gen-cert
new file mode 100644
index 0000000..27e8448
--- /dev/null
+++ b/exim-gen-cert
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+. /etc/sysconfig/network
+
+# Source exim configureation.
+if [ -f /etc/sysconfig/exim ] ; then
+ . /etc/sysconfig/exim
+fi
+
+USER=${USER:=exim}
+GROUP=${GROUP:=exim}
+
+gen_cert() {
+ if [ ! -f /etc/pki/tls/certs/exim.pem ] ; then
+ umask 077
+ FQDN=`hostname`
+ if [ "x${FQDN}" = "x" ]; then
+ FQDN=localhost.localdomain
+ fi
+ echo -n $"Generating exim certificate: "
+ cat << EOF | openssl req -new -x509 -days 365 -nodes \
+ -out /etc/pki/tls/certs/exim.pem \
+ -keyout /etc/pki/tls/private/exim.pem &>/dev/null
+--
+SomeState
+SomeCity
+SomeOrganization
+SomeOrganizationalUnit
+${FQDN}
+root@${FQDN}
+EOF
+ if [ $? -eq 0 ]; then
+ echo success
+ chown $USER:$GROUP /etc/pki/tls/{private,certs}/exim.pem
+ chmod 600 /etc/pki/tls/{private,certs}/exim.pem
+ else
+ echo failure
+ fi
+ echo
+ fi
+}
+
+gen_cert
+
+exit 0
diff --git a/exim-greylist.conf.inc b/exim-greylist.conf.inc
new file mode 100644
index 0000000..15ca61f
--- /dev/null
+++ b/exim-greylist.conf.inc
@@ -0,0 +1,167 @@
+#
+# Exim ACL for greylisting. David Woodhouse <dwmw2@infradead.org>
+#
+# For full background on the logic behind greylisting and how this
+# ACL works, see https://github.com/Exim/exim/wiki/SimpleGreylisting
+#
+
+# UPDATING TO EXIM 4.94+
+# ======================
+#
+# Previous versions of this ACL specified the sqlite database filename
+# in the sqlite lookup strings directly, but since Exim 4.94 is it no
+# longer permitted to mix "tainted" text which comes from the message
+# itself, with the filename. Thus, you now have to set
+#
+# sqlite_dbfile = /var/spool/exim/db/greylist.db
+#
+# ... in the main configuration because it can't be specified within
+# the ACL in this file any more.
+
+# USING THIS ACL
+# ==============
+#
+# First set sqlite_dbfile in the main configuration file to point to
+# the greylist sqlite database, as described above.
+#
+# In your main ACLs, gather reason(s) for greylisting into a variable
+# named $acl_m_greylistreasons before invoking this ACL with
+# 'require acl = greylist_mail'. The reasons should be separate lines
+# of text, and will be reported in the SMTP rejection message as well
+# as the log message. Anything "suspicious" about the email can be
+# used as criteria here — being HTML, having even a few SpamAssassin
+# points, even lacking SPF authorisation (which is OK for greylisting
+# although you should never reject outright for an SPF "failure"
+# because of the flaws in SPF).
+#
+# Obviously you need to .include this file too in order to be able
+# to invoke this greylist_mail ACL.
+
+# HOW IT WORKS
+# ============
+#
+# When a suspicious mail is seen, we temporarily reject it and wait to see
+# if the sender tries again. Most spam robots won't bother. Real mail hosts
+# _will_ retry, and we'll accept it the second time. For hosts which are
+# observed to retry, we don't bother greylisting again in the future --
+# it's obviously pointless. We remember such hosts, or 'known resenders',
+# by a tuple of their IP address and the name they used in HELO.
+#
+# We also include the time of listing for 'known resenders', just in case
+# someone wants to expire them after a certain amount of time. So the
+# database table for these 'known resenders' looks like this:
+#
+# CREATE TABLE resenders (
+# host TEXT,
+# helo TEXT,
+# time INTEGER,
+# PRIMARY KEY (host, helo) );
+#
+# To remember mail we've rejected, we create an 'identity' from its sender
+# and recipient addresses and its Message-ID: header. We don't include the
+# sending IP address in the identity, because sometimes the second and
+# subsequent attempts may come from a different IP address to the original.
+#
+# We do record the original IP address and HELO name though, because if
+# the message _is_ retried from another machine, it's the _first_ one we
+# want to record as a 'known resender'; not just its backup path.
+#
+# Obviously we record the time too, so the main table of greylisted mail
+# looks like this:
+#
+# CREATE TABLE greylist (
+# id TEXT,
+# expire INTEGER,
+# host TEXT,
+# helo TEXT);
+#
+
+greylist_mail:
+ # Firstly, accept if it was generated locally or by authenticated clients.
+ accept hosts = :
+ accept authenticated = *
+
+ # Secondly, there's _absolutely_ no point in greylisting mail from
+ # hosts which are known to resend their mail. Just accept it.
+ accept condition = ${lookup sqlite {SELECT host from resenders \
+ WHERE helo='${quote_sqlite:$sender_helo_name}' \
+ AND host='$sender_host_address';} {1}}
+
+ # Generate a hashed 'identity' for the mail, as described above.
+ warn set acl_m_greyident = ${hash{20}{62}{$sender_address$recipients$h_message-id:}}
+
+ # Attempt to look up this mail in the greylist database. If it's there,
+ # remember the expiry time for it; we need to make sure they've waited
+ # long enough.
+ warn set acl_m_greyexpiry = ${lookup sqlite {SELECT expire FROM greylist \
+ WHERE id='${quote_sqlite:$acl_m_greyident}';}{$value}}
+
+
+ # If there's absolutely nothing suspicious about the email, accept it. BUT...
+ accept condition = ${if eq {$acl_m_greylistreasons}{} {1}}
+ condition = ${if eq {$acl_m_greyexpiry}{} {1}}
+
+ # ..if this same mail was greylisted before (perhaps because it came from a
+ # host which *was* suspicious), then we still want to mark that original host
+ # as a "known resender". If we don't, then hosts which attempt to deliver from
+ # a dodgy Legacy IP address but then fall back to using IPv6 after greylisting
+ # will *never* see their Legacy IP address added to the 'known resenders' list.
+ accept condition = ${if eq {$acl_m_greylistreasons}{} {1}}
+ acl = write_known_resenders
+
+ # If the mail isn't already the database -- i.e. if the $acl_m_greyexpiry
+ # variable we just looked up is empty -- then try to add it now. This is
+ # where the 5 minute timeout is set ($tod_epoch + 300), should you wish
+ # to change it.
+ warn condition = ${if eq {$acl_m_greyexpiry}{} {1}}
+ set acl_m_dontcare = ${lookup sqlite {INSERT INTO greylist \
+ VALUES ( '${quote_sqlite:$acl_m_greyident}', \
+ '${eval10:$tod_epoch+300}', \
+ '$sender_host_address', \
+ '${quote_sqlite:$sender_helo_name}' );}}
+
+ # Be paranoid, and check if the insertion succeeded (by doing another lookup).
+ # Otherwise, if there's a database error we might end up deferring for ever.
+ defer condition = ${if eq {$acl_m_greyexpiry}{} {1}}
+ condition = ${lookup sqlite {SELECT expire FROM greylist \
+ WHERE id='${quote_sqlite:$acl_m_greyident}';} {1}}
+ message = Your mail was considered suspicious for the following reason(s):\n$acl_m_greylistreasons \
+ The mail has been greylisted for 5 minutes, after which it should be accepted. \
+ We apologise for the inconvenience. Your mail system should keep the mail on \
+ its queue and retry. When that happens, your system will be added to the list \
+ genuine mail systems, and mail from it should not be greylisted any more. \
+ In the event of problems, please contact postmaster@$qualify_domain
+ log_message = Greylisted <$h_message-id:> from <$sender_address> for offences: ${sg {$acl_m_greylistreasons}{\n}{,}}
+
+ # Handle the error case (which should never happen, but would be bad if it did).
+ # First by whining about it in the logs, so the admin can deal with it...
+ warn condition = ${if eq {$acl_m_greyexpiry}{} {1}}
+ log_message = Greylist insertion failed. Bypassing greylist.
+ # ... and then by just accepting the message.
+ accept condition = ${if eq {$acl_m_greyexpiry}{} {1}}
+
+ # OK, we've dealt with the "new" messages. Now we deal with messages which
+ # _were_ already in the database...
+
+ # If the message was already listed but its time hasn't yet expired, keep rejecting it
+ defer condition = ${if > {$acl_m_greyexpiry}{$tod_epoch}}
+ message = Your mail was previously greylisted and the time has not yet expired.\n\
+ You should wait another ${eval10:$acl_m_greyexpiry-$tod_epoch} seconds.\n\
+ Reason(s) for greylisting: \n$acl_m_greylistreasons
+
+ accept acl = write_known_resenders
+
+write_known_resenders:
+ # The message was listed but it's been more than five minutes. Accept it now and whitelist
+ # the _original_ sending host by its { IP, HELO } so that we don't delay its mail again.
+ warn set acl_m_orighost = ${lookup sqlite {SELECT host FROM greylist \
+ WHERE id='${quote_sqlite:$acl_m_greyident}';}{$value}}
+ set acl_m_orighelo = ${lookup sqlite {SELECT helo FROM greylist \
+ WHERE id='${quote_sqlite:$acl_m_greyident}';}{$value}}
+ set acl_m_dontcare = ${lookup sqlite {INSERT INTO resenders \
+ VALUES ( '$acl_m_orighost', \
+ '${quote_sqlite:$acl_m_orighelo}', \
+ '$tod_epoch' ); }}
+ logwrite = Added host $acl_m_orighost with HELO '$acl_m_orighelo' to known resenders
+
+ accept
diff --git a/exim-tidydb.sh b/exim-tidydb.sh
new file mode 100644
index 0000000..1b3dddc
--- /dev/null
+++ b/exim-tidydb.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+SPOOLDIR=/var/spool/exim
+
+cd $SPOOLDIR/db
+for a in retry misc wait-* callout ratelimit; do
+ [ -r "$a" ] || continue
+ [ "${a%%.lockfile}" = "$a" ] || continue
+ /usr/sbin/exim_tidydb $SPOOLDIR $a >/dev/null
+done
diff --git a/exim.logrotate b/exim.logrotate
new file mode 100644
index 0000000..05f13b9
--- /dev/null
+++ b/exim.logrotate
@@ -0,0 +1,7 @@
+# daemon does not need restarting after log rotate
+# so we do not prod it any more
+/var/log/exim/*log {
+ missingok
+ notifempty
+ delaycompress
+}
diff --git a/exim.pam b/exim.pam
new file mode 100644
index 0000000..1d78594
--- /dev/null
+++ b/exim.pam
@@ -0,0 +1,3 @@
+#%PAM-1.0
+auth include password-auth
+account include password-auth
diff --git a/exim.service b/exim.service
new file mode 100644
index 0000000..e6a82ba
--- /dev/null
+++ b/exim.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Exim Mail Transport Agent
+After=network.target
+Conflicts=sendmail.service postfix.service
+
+[Service]
+PrivateTmp=true
+Environment=QUEUE=1h
+EnvironmentFile=-/etc/sysconfig/exim
+ExecStartPre=-/usr/libexec/exim-gen-cert
+ExecStart=/usr/sbin/exim -bd -q${QUEUE}
+
+[Install]
+WantedBy=multi-user.target
diff --git a/exim.spec b/exim.spec
new file mode 100644
index 0000000..b8398d6
--- /dev/null
+++ b/exim.spec
@@ -0,0 +1,505 @@
+%bcond_without clamav
+%{!?_hardened_build:%global _hardened_build 1}
+
+Summary: The exim mail transfer agent
+Name: exim
+Version: 4.98.2
+Release: 1
+License: GPLv2+
+Url: https://www.exim.org/
+
+Provides: MTA smtpd smtpdaemon server(smtp)
+Requires(post): /sbin/restorecon %{_sbindir}/alternatives systemd
+Requires(preun): %{_sbindir}/alternatives systemd
+Requires(postun): %{_sbindir}/alternatives systemd
+Requires(pre): %{_sbindir}/groupadd, %{_sbindir}/useradd
+
+%if %{with clamav}
+BuildRequires: clamd
+%endif
+
+Source0: https://ftp.exim.org/pub/exim/exim4/%{name}-%{version}.tar.xz
+Source1: exim.sysconfig
+Source2: exim.logrotate
+# The exim-tidydb.sh is used to tidy up the contents of a hints database.
+Source3: exim-tidydb.sh
+Source4: exim.pam
+Source5: exim-clamav-tmpfiles.conf
+Source6: exim-greylist.conf.inc
+Source7: mk-greylist-db.sql
+# The greylist-tidy.sh is used to delete expired data in greylist
+Source8: greylist-tidy.sh
+Source9: trusted-configs
+Source10: exim.service
+# The exim-gen-cert is used to generate the certificate
+Source11: exim-gen-cert
+Source12: clamd.exim.service
+
+Patch0: exim-4.98.2-config.patch
+Patch1: exim-4.94-libdir.patch
+Patch2: exim-4.98.2-dlopen-localscan.patch
+Patch3: exim-4.96-pic.patch
+Patch4: exim-4.98.2-no-gsasl.patch
+
+
+Requires: /etc/pki/tls/certs /etc/pki/tls/private
+Requires: setup
+Requires: perl
+Recommends: publicsuffix-list
+BuildRequires: gcc
+BuildRequires: libdb-devel
+BuildRequires: openssl-devel
+BuildRequires: zlib-devel
+BuildRequires: openldap-devel
+BuildRequires: pam-devel
+BuildRequires: pcre2-devel
+BuildRequires: sqlite-devel
+BuildRequires: cyrus-sasl-devel
+BuildRequires: libspf2-devel
+BuildRequires: libopendmarc-devel
+BuildRequires: mariadb-connector-c-devel
+BuildRequires: libpq-devel
+BuildRequires: libXaw-devel
+BuildRequires: libXmu-devel
+BuildRequires: libXext-devel
+BuildRequires: libX11-devel
+BuildRequires: libSM-devel
+BuildRequires: perl-devel
+BuildRequires: perl-generators
+BuildRequires: perl-File-FcntlLock
+BuildRequires: libICE-devel
+BuildRequires: libXpm-devel
+BuildRequires: libXt-devel
+BuildRequires: perl(ExtUtils::Embed)
+BuildRequires: systemd-units
+BuildRequires: libgsasl-devel
+BuildRequires: mariadb-devel
+BuildRequires: libnsl2-devel
+BuildRequires: libtirpc-devel
+BuildRequires: gnupg2
+BuildRequires: grep
+BuildRequires: make
+
+%description
+Exim is a message transfer agent (MTA) developed at the University of
+Cambridge for use on Unix systems connected to the Internet. It is
+freely available under the terms of the GNU General Public Licence. In
+style it is similar to Smail 3, but its facilities are more
+general. There is a great deal of flexibility in the way mail can be
+routed, and there are extensive facilities for checking incoming
+mail. Exim can be installed in place of sendmail, although the
+configuration of exim is quite different to that of sendmail.
+
+%package mysql
+Summary: MySQL lookup support for Exim
+Requires: exim = %{version}-%{release}
+
+%description mysql
+This package contains the MySQL lookup module for Exim
+
+%package pgsql
+Summary: PostgreSQL lookup support for Exim
+Requires: exim = %{version}-%{release}
+
+%description pgsql
+This package contains the PostgreSQL lookup module for Exim
+
+%package mon
+Summary: X11 monitor application for Exim
+
+%description mon
+The Exim Monitor is an optional supplement to the Exim package. It
+displays information about Exim's processing in an X window, and an
+administrator can perform a number of control actions from the window
+interface.
+
+%if %{with clamav}
+%package clamav
+Summary: Clam Antivirus scanner dæmon configuration for use with Exim
+Requires: clamd exim
+Obsoletes: clamav-exim <= 0.86.2
+
+%description clamav
+This package contains configuration files which invoke a copy of the
+clamav dæmon for use with Exim. It can be activated by adding (or
+uncommenting)
+
+ av_scanner = clamd:%{_var}/run/clamd.exim/clamd.sock
+
+in your exim.conf, and using the 'malware' condition in the DATA ACL,
+as follows:
+
+ deny message = This message contains malware ($malware_name)
+ malware = *
+
+For further details of Exim content scanning, see chapter 41 of the Exim
+specification:
+http://www.exim.org/exim-html-%{version}/doc/html/spec_html/ch41.html
+
+%endif
+
+%package greylist
+Summary: Example configuration for greylisting using Exim
+Requires: sqlite exim
+Requires: crontabs
+
+%description greylist
+This package contains a simple example of how to do greylisting in Exim's
+ACL configuration. It contains a cron job to remove old entries from the
+greylisting database, and an ACL subroutine which needs to be included
+from the main exim.conf file.
+
+To enable greylisting, install this package and then uncomment the lines
+in Exim's configuration /etc/exim.conf which enable it. You need to
+uncomment at least two lines -- the '.include' directive which includes
+the new ACL subroutine, and the line which invokes the new subroutine.
+
+By default, this implementation only greylists mails which appears
+'suspicious' in some way. During normal processing of the ACLs we collect
+a list of 'offended' which it's committed, which may include having
+SpamAssassin points, lacking a Message-ID: header, coming from a blacklisted
+host, etc. There are examples of these in the default configuration file,
+mostly commented out. These should be sufficient for you to you trigger
+greylisting for whatever 'offences' you can dream of, or even to make
+greylisting unconditional.
+
+%prep
+%autosetup -p1
+
+cp src/EDITME Local/Makefile
+sed -i 's@^# LOOKUP_MODULE_DIR=.*@LOOKUP_MODULE_DIR=%{_libdir}/exim/%{version}-%{release}/lookups@' Local/Makefile
+sed -i 's@^# AUTH_LIBS=-lsasl2@AUTH_LIBS=-lsasl2@' Local/Makefile
+cp exim_monitor/EDITME Local/eximon.conf
+
+# Workaround for rhbz#1791878
+pushd doc
+for f in $(ls -dp cve-* | grep -v '/\|\(\.txt\)$'); do
+ mv "$f" "$f.txt"
+done
+popd
+
+%build
+%ifnarch s390 s390x sparc sparcv9 sparcv9v sparc64 sparc64v
+ export PIE=-fpie
+ export PIC=-fpic
+%else
+ export PIE=-fPIE
+ export PIC=-fPIC
+%endif
+
+export LDFLAGS="%{?__global_ldflags} %{?_hardened_build:-pie -Wl,-z,relro,-z,now}"
+make _lib=%{_lib} FULLECHO=
+
+%install
+mkdir -p $RPM_BUILD_ROOT%{_sbindir}
+mkdir -p $RPM_BUILD_ROOT%{_bindir}
+mkdir -p $RPM_BUILD_ROOT%{_libdir}
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/exim
+
+cd build-`scripts/os-type`-`scripts/arch-type`
+install -m 4775 exim $RPM_BUILD_ROOT%{_sbindir}
+
+for i in eximon eximon.bin exim_dumpdb exim_fixdb exim_tidydb \
+ exinext exiwhat exim_dbmbuild exicyclog exim_lock \
+ exigrep eximstats exipick exiqgrep exiqsumm \
+ exim_checkaccess convert4r4
+do
+ install -m 0755 $i $RPM_BUILD_ROOT%{_sbindir}
+done
+
+mkdir -p $RPM_BUILD_ROOT%{_libdir}/exim/%{version}-%{release}/lookups
+for i in mysql.so pgsql.so
+do
+ install -m755 lookups/$i \
+ $RPM_BUILD_ROOT%{_libdir}/exim/%{version}-%{release}/lookups
+done
+
+cd ..
+
+install -m 0644 src/configure.default $RPM_BUILD_ROOT%{_sysconfdir}/exim/exim.conf
+install -m 0644 %SOURCE4 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/exim
+
+mkdir -p $RPM_BUILD_ROOT/usr/lib
+pushd $RPM_BUILD_ROOT/usr/lib
+ln -sf ../sbin/exim sendmail.exim
+popd
+
+pushd $RPM_BUILD_ROOT%{_sbindir}/
+ln -sf exim sendmail.exim
+popd
+
+pushd $RPM_BUILD_ROOT%{_bindir}/
+ln -sf ../sbin/exim mailq.exim
+ln -sf ../sbin/exim runq.exim
+ln -sf ../sbin/exim rsmtp.exim
+ln -sf ../sbin/exim rmail.exim
+ln -sf ../sbin/exim newaliases.exim
+popd
+
+install -d -m 0750 $RPM_BUILD_ROOT%{_var}/spool/exim
+install -d -m 0750 $RPM_BUILD_ROOT%{_var}/spool/exim/db
+install -d -m 0750 $RPM_BUILD_ROOT%{_var}/spool/exim/input
+install -d -m 0750 $RPM_BUILD_ROOT%{_var}/spool/exim/msglog
+install -d -m 0750 $RPM_BUILD_ROOT%{_var}/log/exim
+
+mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8
+install -m644 doc/exim.8 $RPM_BUILD_ROOT%{_mandir}/man8/exim.8
+pod2man --center=EXIM --section=8 \
+ $RPM_BUILD_ROOT/usr/sbin/eximstats \
+ $RPM_BUILD_ROOT%{_mandir}/man8/eximstats.8
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig
+install -m 644 %SOURCE1 $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/exim
+
+# Systemd
+mkdir -p %{buildroot}%{_unitdir}
+mkdir -p $RPM_BUILD_ROOT%{_libexecdir}
+install -m644 %{SOURCE10} %{buildroot}%{_unitdir}
+install -m755 %{SOURCE11} %{buildroot}%{_libexecdir}
+
+%if %{with clamav}
+install -m644 %{SOURCE12} %{buildroot}%{_unitdir}
+%endif
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d
+install -m 0644 %SOURCE2 $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/exim
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily
+install -m 0755 %SOURCE3 $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily/exim-tidydb
+
+# generate ghost .pem file
+mkdir -p $RPM_BUILD_ROOT/etc/pki/tls/{certs,private}
+touch $RPM_BUILD_ROOT/etc/pki/tls/{certs,private}/exim.pem
+chmod 600 $RPM_BUILD_ROOT/etc/pki/tls/{certs,private}/exim.pem
+
+# generate alternatives ghosts
+mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1
+for i in %{_sbindir}/sendmail %{_bindir}/{mailq,runq,rsmtp,rmail,newaliases} \
+ /usr/lib/sendmail %{_sysconfdir}/pam.d/smtp
+do
+ touch $RPM_BUILD_ROOT$i
+done
+gzip < /dev/null > $RPM_BUILD_ROOT%{_mandir}/man1/mailq.1.gz
+
+%if %{with clamav}
+# Munge the clamav init and config files from clamav-devel. This really ought
+# to be a subpackage of clamav, but this hack will have to do for now.
+function clamsubst() {
+ sed -e "s!<SERVICE>!$3!g;s!<USER>!$4!g;""$5" %{_docdir}/clamd/"$1" >"$RPM_BUILD_ROOT$2"
+}
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/clamd.d
+clamsubst clamd.conf %{_sysconfdir}/clamd.d/exim.conf exim exim \
+ 's!^##*\(\(LogFile\|LocalSocket\|PidFile\|User\)\s\|\(StreamSaveToDisk\|ScanMail\|LogTime\|ScanArchive\)$\)!\1!;s!^Example!#Example!;'
+
+clamsubst clamd.logrotate %{_sysconfdir}/logrotate.d/clamd.exim exim exim ''
+cat <<EOF > $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/clamd.exim
+CLAMD_CONFIG='%_sysconfdir/clamd.d/exim.conf'
+CLAMD_SOCKET=%{_var}/run/clamd.exim/clamd.sock
+EOF
+ln -sf clamd $RPM_BUILD_ROOT/usr/sbin/clamd.exim
+
+mkdir -p %{buildroot}%{_tmpfilesdir}
+install -m 0644 %{SOURCE5} %{buildroot}%{_tmpfilesdir}/exim-clamav.conf
+mkdir -p $RPM_BUILD_ROOT%{_var}/run/clamd.exim
+mkdir -p $RPM_BUILD_ROOT%{_var}/log
+touch $RPM_BUILD_ROOT%{_var}/log/clamd.exim
+
+%endif
+
+# Set up the greylist subpackage
+install -m644 %{SOURCE6} $RPM_BUILD_ROOT/%_sysconfdir/exim/exim-greylist.conf.inc
+install -m644 %{SOURCE7} $RPM_BUILD_ROOT/%_sysconfdir/exim/mk-greylist-db.sql
+mkdir -p $RPM_BUILD_ROOT/%_sysconfdir/cron.daily
+install -m755 %{SOURCE8} $RPM_BUILD_ROOT/%_sysconfdir/cron.daily/greylist-tidy.sh
+install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%_sysconfdir/exim/trusted-configs
+touch $RPM_BUILD_ROOT/%_var/spool/exim/db/greylist.db
+
+%check
+build-`scripts/os-type`-`scripts/arch-type`/exim -C src/configure.default -bV
+
+%pre
+%{_sbindir}/groupadd -g 93 exim 2>/dev/null
+%{_sbindir}/useradd -d %{_var}/spool/exim -s /sbin/nologin -G mail -M -r -u 93 -g exim exim 2>/dev/null
+# Copy TLS certs from old location to new -- don't move them, because the
+# config file may be modified and may be pointing to the old location.
+if [ ! -f /etc/pki/tls/certs/exim.pem -a -f %{_datadir}/ssl/certs/exim.pem ] ; then
+ cp %{_datadir}/ssl/certs/exim.pem /etc/pki/tls/certs/exim.pem
+ cp %{_datadir}/ssl/private/exim.pem /etc/pki/tls/private/exim.pem
+fi
+
+exit 0
+
+%post
+%systemd_post %{name}.service
+
+%{_sbindir}/alternatives --install %{_sbindir}/sendmail mta %{_sbindir}/sendmail.exim 10 \
+ --slave %{_bindir}/mailq mta-mailq %{_bindir}/mailq.exim \
+ --slave %{_bindir}/runq mta-runq %{_bindir}/runq.exim \
+ --slave %{_bindir}/rsmtp mta-rsmtp %{_bindir}/rsmtp.exim \
+ --slave %{_bindir}/rmail mta-rmail %{_bindir}/rmail.exim \
+ --slave /etc/pam.d/smtp mta-pam /etc/pam.d/exim \
+ --slave %{_bindir}/newaliases mta-newaliases %{_bindir}/newaliases.exim \
+ --slave /usr/lib/sendmail mta-sendmail /usr/lib/sendmail.exim \
+ --slave %{_mandir}/man1/mailq.1.gz mta-mailqman %{_mandir}/man8/exim.8.gz \
+ --initscript exim
+
+%preun
+%systemd_preun %{name}.service
+if [ $1 = 0 ]; then
+ %{_sbindir}/alternatives --remove mta %{_sbindir}/sendmail.exim
+fi
+
+%postun
+%systemd_postun_with_restart %{name}.service
+if [ $1 -ge 1 ]; then
+ mta=`readlink /etc/alternatives/mta`
+ if [ "$mta" == "%{_sbindir}/sendmail.exim" ]; then
+ /usr/sbin/alternatives --set mta %{_sbindir}/sendmail.exim
+ fi
+fi
+
+%post greylist
+if [ ! -r %{_var}/spool/exim/db/greylist.db ]; then
+ sqlite3 %{_var}/spool/exim/db/greylist.db < %{_sysconfdir}/exim/mk-greylist-db.sql
+ chown exim:exim %{_var}/spool/exim/db/greylist.db
+ chmod 0660 %{_var}/spool/exim/db/greylist.db
+fi
+
+%files
+%attr(4755,root,root) %{_sbindir}/exim
+%{_sbindir}/exim_dumpdb
+%{_sbindir}/exim_fixdb
+%{_sbindir}/exim_tidydb
+%{_sbindir}/exinext
+%{_sbindir}/exiwhat
+%{_sbindir}/exim_dbmbuild
+%{_sbindir}/exicyclog
+%{_sbindir}/exigrep
+%{_sbindir}/eximstats
+%{_sbindir}/exipick
+%{_sbindir}/exiqgrep
+%{_sbindir}/exiqsumm
+%{_sbindir}/exim_lock
+%{_sbindir}/exim_checkaccess
+%{_sbindir}/convert4r4
+%{_sbindir}/sendmail.exim
+%{_bindir}/mailq.exim
+%{_bindir}/runq.exim
+%{_bindir}/rsmtp.exim
+%{_bindir}/rmail.exim
+%{_bindir}/newaliases.exim
+/usr/lib/sendmail.exim
+%{_mandir}/man8/*
+%dir %{_libdir}/exim
+%dir %{_libdir}/exim/%{version}-%{release}
+%dir %{_libdir}/exim/%{version}-%{release}/lookups
+
+%defattr(-,exim,exim)
+%dir %{_var}/spool/exim
+%dir %{_var}/spool/exim/db
+%dir %{_var}/spool/exim/input
+%dir %{_var}/spool/exim/msglog
+%dir %{_var}/log/exim
+
+%defattr(-,root,root)
+%dir %{_sysconfdir}/exim
+%config(noreplace) %{_sysconfdir}/exim/exim.conf
+%config(noreplace) %{_sysconfdir}/exim/trusted-configs
+%config(noreplace) %{_sysconfdir}/sysconfig/exim
+%{_unitdir}/exim.service
+%{_libexecdir}/exim-gen-cert
+%config(noreplace) %{_sysconfdir}/logrotate.d/exim
+%config(noreplace) %{_sysconfdir}/pam.d/exim
+%{_sysconfdir}/cron.daily/exim-tidydb
+
+%license LICENCE NOTICE
+%doc ACKNOWLEDGMENTS README.UPDATING README
+%doc doc util/unknownuser.sh
+%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) /etc/pki/tls/certs/exim.pem
+%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) /etc/pki/tls/private/exim.pem
+%attr(0755,root,root) %ghost %{_sbindir}/sendmail
+%attr(0755,root,root) %ghost %{_bindir}/mailq
+%attr(0755,root,root) %ghost %{_bindir}/runq
+%attr(0755,root,root) %ghost %{_bindir}/rsmtp
+%attr(0755,root,root) %ghost %{_bindir}/rmail
+%attr(0755,root,root) %ghost %{_bindir}/newaliases
+%attr(0755,root,root) %ghost /usr/lib/sendmail
+%ghost %{_sysconfdir}/pam.d/smtp
+%ghost %{_mandir}/man1/mailq.1.gz
+
+%files mysql
+%{_libdir}/exim/%{version}-%{release}/lookups/mysql.so
+
+%files pgsql
+%{_libdir}/exim/%{version}-%{release}/lookups/pgsql.so
+
+%files mon
+%{_sbindir}/eximon
+%{_sbindir}/eximon.bin
+
+%if %{with clamav}
+%post clamav
+/bin/mkdir -pm 0750 %{_var}/run/clamd.exim
+/bin/chown exim:exim %{_var}/run/clamd.exim
+/bin/touch %{_var}/log/clamd.exim
+/bin/chown exim:exim %{_var}/log/clamd.exim
+/sbin/restorecon %{_var}/log/clamd.exim
+if [ $1 -eq 1 ] ; then
+ /bin/systemctl daemon-reload >/dev/null 2>&1 || :
+fi
+
+%preun clamav
+if [ $1 = 0 ]; then
+ /bin/systemctl --no-reload clamd.exim.service > /dev/null 2>&1 || :
+ /bin/systemctl stop clamd.exim.service > /dev/null 2>&1 || :
+fi
+
+%postun clamav
+/bin/systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 1 ] ; then
+ /bin/systemctl try-restart clamd.exim.service >/dev/null 2>&1 || :
+fi
+
+%files clamav
+%{_sbindir}/clamd.exim
+%{_unitdir}/clamd.exim.service
+%config(noreplace) %verify(not mtime) %{_sysconfdir}/clamd.d/exim.conf
+%config(noreplace) %verify(not mtime) %{_sysconfdir}/sysconfig/clamd.exim
+%config(noreplace) %verify(not mtime) %{_sysconfdir}/logrotate.d/clamd.exim
+%{_tmpfilesdir}/exim-clamav.conf
+%ghost %attr(0750,exim,exim) %dir %{_var}/run/clamd.exim
+%ghost %attr(0644,exim,exim) %{_var}/log/clamd.exim
+%endif
+
+%files greylist
+%config %{_sysconfdir}/exim/exim-greylist.conf.inc
+%ghost %{_var}/spool/exim/db/greylist.db
+%{_sysconfdir}/exim/mk-greylist-db.sql
+%{_sysconfdir}/cron.daily/greylist-tidy.sh
+
+%changelog
+* Sun May 25 2025 zhuchao <tom_toworld@163.com> - 4.98.2-1
+- DESC: upgrade to 4.98.2 to resolve the to CVE-2025-26794 to CVE-2025-30232
+
+* Tue Jul 9 2024 zhangxianting <zhangxianting@uniontech.com> - 4.97.1-3
+- fix CVE-2024-39929
+
+* Tue Jul 9 2024 technology208 <technology@208suo.com> - 4.97-2
+- Fix CVE-2023-51766
+
+* Sun Feb 4 2024 zhuchao <tom_toworld@163.com> - 4.97.1-1
+- DESC:upgrade to 4.97.1 to resolve the CVE-2023-51766
+
+* Sat Dec 16 2023 zhuchao <tom_toworld@163.com> - 4.97-1
+- DESC:upgrade to 4.97 to resolve the CVE-2023-42114 to CVE-2023-42119
+
+* Tue Aug 29 2023 zhuchao <tom_toworld@163.com> - 4.96-3
+- DESC:fix bug about print error message in install exim-clamav and exim-greylist
+
+* Thu Feb 16 2023 zhuchao <tom_toworld@163.com> - 4.96-2
+- DESC:add build requirement init
+
+* Tue Oct 18 2022 zhuchao <tom_toworld@163.com> - 4.96-1
+- DESC:Package init
diff --git a/exim.sysconfig b/exim.sysconfig
new file mode 100644
index 0000000..69e525d
--- /dev/null
+++ b/exim.sysconfig
@@ -0,0 +1,4 @@
+DAEMON=yes
+QUEUE=1h
+USER=exim
+GROUP=exim
diff --git a/greylist-tidy.sh b/greylist-tidy.sh
new file mode 100644
index 0000000..20251f4
--- /dev/null
+++ b/greylist-tidy.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [ -s /var/spool/exim/db/greylist.db ]; then
+ sqlite3 /var/spool/exim/db/greylist.db <<EOF
+.timeout 5000
+DELETE FROM greylist WHERE expire < $((`date +%s` - 604800));
+EOF
+fi
diff --git a/mk-greylist-db.sql b/mk-greylist-db.sql
new file mode 100644
index 0000000..dff48c9
--- /dev/null
+++ b/mk-greylist-db.sql
@@ -0,0 +1,13 @@
+CREATE TABLE resenders (
+ host TEXT,
+ helo TEXT,
+ time INTEGER,
+ PRIMARY KEY (host, helo)
+);
+
+CREATE TABLE greylist (
+ id TEXT PRIMARY KEY,
+ expire INTEGER,
+ host TEXT,
+ helo TEXT
+);
diff --git a/sources b/sources
new file mode 100644
index 0000000..2d0b336
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+7ed3e24c1eef44824b79b4c442f99f0b exim-4.98.2.tar.xz
diff --git a/trusted-configs b/trusted-configs
new file mode 100644
index 0000000..135206b
--- /dev/null
+++ b/trusted-configs
@@ -0,0 +1,6 @@
+# This file contains a list, one per line, of the files which are permitted
+# to be used as Exim configuration files with root privileges. If you want
+# to be able to run Exim with the -C option, and have it re-execute itself
+# for local delivery, then you'll need to add your configuration file here.
+/etc/exim/exim4.conf
+/etc/exim/exim.conf