#
# $Id$
#
# Master configuration file for *.infradead.org Exim hosts.
#

# Let anyone run 'exim -bp'.
queue_list_requires_admin = false

# ACLs.
acl_smtp_rcpt = check_recipient
acl_smtp_data = check_content
#acl_smtp_etrn = check_etrn
acl_smtp_vrfy = check_vrfy
acl_smtp_expn = check_expn

# SA-Exim.
# local_scan_path = /usr/libexec/exim/sa-exim.so

# Get these from per-site include:
## hostlist relay_hosts
## domainlist extra_local_domains
### These have sane defaults anyway
## qualify_recipient
## primary_hostname

#.include $primary_hostname.base.conf

qualify_domain = infradead.org

domainlist local_domains = @ : @[] : +extra_local_domains

domainlist virtual_domains = dsearch;/etc/exim/virtual
domainlist relay_domains = partial1-lsearch;/etc/exim/relay-domains

hostlist trust_hosts = pentafluge.infradead.org : \
		       baythorne.infradead.org : \
		       canuck.infradead.org : \
		       phoenix.infradead.org : \
		       vger.kernel.org

trusted_users = mail
never_users = root

gecos_pattern = ^([^,:]*)
gecos_name = $1

log_selector =  \
              +address_rewrite \
              +smtp_confirmation \
              +tls_cipher \
              +tls_peerdn

# Global system filter to check reply/references and add warnings.
system_filter = /etc/exim/reply_filter

# Allow SMTP AUTH only if encrypted.
auth_advertise_hosts = ${if eq{$tls_cipher}{}{localhost}{*}}

# Do reverse DNS for logging purposes on all connecting machines
host_lookup = *

rfc1413_hosts = *
rfc1413_query_timeout = 20s

smtp_accept_queue_per_connection = 100
smtp_load_reserve = 20
deliver_queue_load_max = 15
queue_only_load = 15
accept_8bitmime

tls_advertise_hosts = *
tls_certificate = /usr/share/ssl/certs/exim.pem
tls_privatekey = /usr/share/ssl/certs/exim.pem

received_header_text = "Received: \
         ${if def:sender_rcvhost {from ${sender_rcvhost}\n\t}\
         {${if def:sender_ident {from ${sender_ident} }}\
         ${if def:sender_helo_name {(helo=${sender_helo_name})\n\t}}}}\
         by ${primary_hostname} \
         ${if def:received_protocol {with ${received_protocol}}} \
         (Exim ${version_number} #${compile_number} (Red Hat Linux))\n\t\
         id ${message_id}\
         ${if def:received_for {\n\tfor <$received_for>}}"

freeze_tell = postmaster@pentafluge.infradead.org
allow_domain_literals
# av_scanner = sophie:/var/run/sophie
# spamd_address = 127.0.0.1 783


# When Exim can neither deliver a message nor return it to sender, it "freezes"
# the delivery error message (aka "bounce message"). There are also other
# circumstances in which messages get frozen. They will stay on the queue for
# ever unless one of the following options is set.

# This option unfreezes frozen bounce messages after two days, tries
# once more to deliver them, and ignores any delivery failures.

ignore_bounce_errors_after = 3d

# This option cancels (removes) frozen messages that are older than a week.

timeout_frozen_after = 14d

######################################################################
#                        ACCESS CONTROL LISTS                        #
######################################################################

begin acl

#!!# ACL that is used after the RCPT command

check_recipient:

  # Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by
  # testing for an empty sending host field.

  accept  hosts = :

  #############################################################################
  # The following section of the ACL is concerned with local parts that contain
  # @ or % or ! or / or | or dots in unusual places.
  #
  # The characters other than dots are rarely found in genuine local parts, but
  # are often tried by people looking to circumvent relaying restrictions.
  # Therefore, although they are valid in local parts, these rules lock them
  # out, as a precaution.
  #
  # Empty components (two dots in a row) are not valid in RFC 2822, but Exim
  # allows them because they have been encountered. (Consider local parts
  # constructed as "firstinitial.secondinitial.familyname" when applied to
  # someone like me, who has no second initial.) However, a local part starting
  # with a dot or containing /../ can cause trouble if it is used as part of a
  # file name (e.g. for a mailing list). This is also true for local parts that
  # contain slashes. A pipe symbol can also be troublesome if the local part is
  # incorporated unthinkingly into a shell command line.
  #
  # Two different rules are used. The first one is stricter, and is applied to
  # messages that are addressed to one of the local domains handled by this
  # host. It blocks local parts that begin with a dot or contain @ % ! / or |.
  # If you have local accounts that include these characters, you will have to
  # modify this rule.

  deny    domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]

  # The second rule applies to all other domains, and is less strict. This
  # allows your own users to send outgoing messages to sites that use slashes
  # and vertical bars in their local parts. It blocks local parts that begin
  # with a dot, slash, or vertical bar, but allows these characters within the
  # local part. However, the sequence /../ is barred. The use of @ % and ! is
  # blocked, as before. The motivation here is to prevent your users (or
  # your users' viruses) from mounting certain kinds of attack on remote sites.

  deny    domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
  #############################################################################

  # Accept mail to postmaster in any local domain, regardless of the source,
  # and without verifying the sender.

  accept  local_parts	= postmaster
          domains	= +local_domains : +relay_domains : +virtual_domains

  # Accept mail sent with authentication.
  accept authenticated	= *

  # Deny obviously bogus sender (don't try callout yet)
  require  verify	= sender

  # Do RBL checks but not for trusted hosts, or spam-loving recipients.
  deny    hosts		= !+trust_hosts
	  !recipients   = @@lsearch;/etc/exim/rbl-except-recipients
          message	= host is listed in $dnslist_domain blacklist\nMail postmaster@infradead.org if you think this is in error
          dnslists	= list.dsbl.org : relays.ordb.org

  # Deny unknown recipient at local or virtual domain
  deny	   domains	= +local_domains : +virtual_domains
	   !verify	= recipient
	   message	= Unknown recipient

  # Deny unknown recipient at relay domain, with callout but accepting
  # temporary failures (else backup MX is pointless anyway).
  deny	   domains	= +relay_domains
	   !verify	= recipient/defer_ok/callout=20s,random,defer_ok
	   message	= Unknown recipient at target domain

  # Trivial sender sanity check
  require  verify	= sender

  # Accept from trusted hosts and relay_hosts without further verification
  accept   hosts	= +relay_hosts : +trust_hosts

  # Now do a callout to verify the sender more thoroughly
  require  hosts	= !+trust_hosts
           verify	= sender/callout=70s,random,postmaster

  accept  domains	= +local_domains : +virtual_domains : +relay_domains
  deny	  message	= Relay not permitted.
  accept


# This access control list is used for content scanning with the exiscan-acl
# patch. You must also uncomment the entry for acl_smtp_data (scroll up),
# otherwise the ACL will not be used. IMPORTANT: the default entries here
# should be treated as EXAMPLES. You MUST read the file doc/exiscan-acl-spec.txt
# to fully understand what you are doing ...

check_content:
  # No content checking for hosts we trust.
  accept  hosts		= +trust_hosts

  # Require a little standards compliance.
  require verify	= header_syntax
          message	= Invalid address in message header. Consult RFC2822.

  # Deny messages without Message-ID.
  deny    hosts		= <; !127.0.0.1 ; !::1
          condition	= ${if eq {$h_message-id:}{<E$message_id@$primary_hostname>} {1}}
          message	= Absent Message-ID.

  # First unpack MIME containers and reject serious errors.
  deny  message = This message contains a MIME error ($demime_reason)
        demime = *
        condition = ${if >{$demime_errorlevel}{2}{1}{0}}

  warn  message = X-MIME-Error: $demime_reason
        demime = *
        condition = ${if >{$demime_errorlevel}{0}{1}{0}}
      
  # Reject typically wormish file extensions. There is almost no
  # sense in sending such files by email.
  deny  message = This message contains an unwanted file extension ($found_extension)
        demime = scr:vbs:bat:lnk:pif:exe
  
#  # Reject virus infested messages.
#  deny  message = This message contains malware ($malware_name)
#        malware = *

#  # Reject messages containing "viagra" in all kinds of whitespace/case combinations
#  # WARNING: this is an example !
#  deny  message = This message matches a blacklisted regular expression ($regex_match_string)
#        regex = [Vv] *[Ii] *[Aa] *[Gg] *[Rr] *[Aa]

  # Always add X-Spam-Score and X-Spam-Report headers, using SA system-wide settings
  # (user "nobody"), no matter if over threshold or not.
  warn  message = X-Spam-Score: $spam_score ($spam_bar)
        spam = nobody:true
  # Add X-Spam-Report header only if the score isn't zero.
  warn  message = X-Spam-Report: $spam_report
        spam = nobody:true
	condition = ${if >{$spam_score_int}{1}{1}{0}}

  # Add X-Spam-Flag if spam is over system-wide threshold
  warn message = X-Spam-Flag: YES
       spam = nobody

  # Reject spam messages with score over 10, using an extra condition.
  deny  message = This message scored $spam_score points. Congratulations!
        spam = nobody:true
        condition = ${if >{$spam_score_int}{100}{1}{0}}

  # finally accept all the rest
  accept
  
check_vrfy:
  accept

check_expn:
  accept

######################################################################
#                      REWRITE CONFIGURATION                         #
######################################################################

#begin rewrite

#.include $primary_hostname.rewrites.conf

######################################################################
#                      ROUTERS CONFIGURATION                         #
######################################################################

begin routers

# For the virtual domains, if a user isn't present in the
# alias list, reject it by having no_more set.

virtual_postmaster:
  driver = redirect
  domains = dsearch;/etc/exim/virtual
  local_parts = postmaster:root:abuse:mailer-daemon
  data = postmaster@pentafluge.infradead.org

virtual_domains:
  driver = redirect
  domains = dsearch;/etc/exim/virtual
  data = ${lookup{$local_part}lsearch{/etc/exim/virtual/$domain}}
  headers_add = X-Infradead-Aliases: $original_local_part@$original_domain rewritten to ${lookup{$local_part}lsearch{/etc/exim/virtual/$domain}} by $primary_hostname
  allow_defer
  allow_fail
  forbid_file
  forbid_pipe
  retry_use_local_part
  no_more

# For the real infradead domains, use aliases if they're present 
# else continue normally. This is just an optimisation.
infradead_aliases:
  driver = redirect
  domains = dsearch;/etc/exim/aliases
  data = ${lookup{$local_part}lsearch{/etc/exim/aliases/$domain}}
  headers_add = X-Infradead-Aliases: $original_local_part@$original_domain rewritten to ${lookup{$local_part}lsearch{/etc/exim/aliases/$domain}} by $primary_hostname
  allow_defer
  allow_fail
  forbid_file
  forbid_pipe
  retry_use_local_part

# Normal remote SMTP delivery 
lookuphost:
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8

literal:
  driver = ipliteral
  domains = ! +local_domains
  transport = remote_smtp
  no_more

real_localuser:
  driver = accept
  check_local_user
  local_part_prefix = real-
  transport = local_delivery

system_aliases:
  driver = redirect
  allow_defer
  allow_fail
  data = ${lookup{$local_part}lsearch{/etc/aliases}}
  file_transport = address_file
  pipe_transport = address_pipe
  retry_use_local_part
  user = mail

.ifdef MAILMAN_HOME
# Don't accept bounces to the lists themselves.
mailman_bogus_bounces:
  driver = redirect
  domains = +mailman_domains
  require_files = MAILMAN_HOME/lists/$local_part/config.pck
  allow_fail
  data = :fail: Lists do not send messages and should not receive bounces
  
mailman_router:
  driver = accept
  domains = +mailman_domains
  require_files = MAILMAN_HOME/lists/$local_part/config.pck
  local_part_suffix_optional
  local_part_suffix = -bounces : -bounces+* : \
                      -confirm+* : -join : -leave : \
                      -owner : -request : -admin
  transport = mailman_transport
.endif

userforward:
  driver = redirect
  allow_filter
  check_ancestor
  check_local_user
  no_expn
  file = $home/.forward
  file_transport = address_file
  initgroups
  modemask = 002
  pipe_transport = address_pipe
  reply_transport = address_reply
  skip_syntax_errors
  syntax_errors_text = "\
    This is an automatically generated message. An error has been \
    found\nin your .forward file. Details of the error are reported \
    below. While\nthis error persists, messages addressed to you will \
    get delivered into\nyour normal mailbox and you will receive a \
    copy of this message for\neach one."
  syntax_errors_to = real-$local_part@$domain
  no_verify

procmail:
  driver = accept
  check_local_user
  require_files = ${local_part}:${home}/.procmailrc
  transport = procmail
  no_verify

localuser:
  driver = accept
  check_local_user
  transport = local_delivery


######################################################################
#                    AUTHENTICATORS CONFIGURATION                    #
######################################################################


begin authenticators

outlook:
  driver = plaintext
  public_name = LOGIN
  server_prompts = "Username:: : Password::"
  server_condition = ${if eq{${lookup{$1}lsearch{/etc/exim/authusers}{$value}fail}}{$2}{yes}{no}}
  server_set_id = $1

plain:
  driver = plaintext
  public_name = PLAIN
  server_prompts = :
  server_condition = ${if eq{${lookup{$2}lsearch{/etc/exim/authusers}{$value}fail}}{$3}{yes}{no}}
  server_set_id = $2

cram:
  driver = cram_md5
  public_name = CRAM-MD5
  server_secret = ${lookup{$1}lsearch{/etc/exim/authusers}{$value}fail}
  server_set_id = $1


######################################################################
#                      TRANSPORTS CONFIGURATION                      #
######################################################################

begin transports

remote_smtp:
  driver = smtp

procmail:
  driver = pipe
  delivery_date_add
  envelope_to_add
  return_path_add
  command = "/usr/bin/procmail -d ${local_part}"
  user = $local_part
  initgroups
  check_string = "From "
  escape_string = ">From "
# group = mail

local_delivery:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add
  file = /var/spool/mail/${local_part}
  group = mail
  mode = 0660
  no_mode_fail_narrower

address_pipe:
  driver = pipe
  return_output

address_file:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add
  no_mode_fail_narrower

address_directory:
  driver = appendfile
  check_string = 
  delivery_date_add
  envelope_to_add
  return_path_add
  message_prefix = ""
  message_suffix = ""
  maildir_format
  no_mode_fail_narrower

address_reply:
  driver = autoreply

.ifdef MAILMAN_HOME
mailman_transport:
  driver = pipe
  command = MAILMAN_WRAP \
            '${if def:local_part_suffix \
                  {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
                  {post}}' \
            $local_part
  current_directory = MAILMAN_HOME
  home_directory = MAILMAN_HOME
  user = MAILMAN_UID
  group = MAILMAN_GID
.endif

######################################################################
#                      RETRY CONFIGURATION                           #
######################################################################


begin retry

*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,8h
