For my sins, I built and continue to operate a website for a local adult football association. Email services are provided via Exim and Dovecot for a few positions, but most email is sent by the website itself.

To regularise access to email, I recently decided to move the users to vmail and dispense with having home directories, etc. Only one internal administrative user remains as a true local user. The necessary information for the others resides in a MySQL database which is also used by Dovecot.

In the process of making the transition, I have run afoul of the need to sanitise $local_part and $domain. The result is that it is no longer possible to send or receive emails involving those accounts. Users can log in and read mail.

The exim configuration is monolithic: /etc/exim4/exim4.conf. I've been using exim for the best part of 30 years, and cribbed the existing file from one of my other sites. It has worked fine until now.

Here are the router, transport, and authenticator settings. Included at the top is a set of macros that I found on a website during my frantic Google searches. The actual display of $local_part and $domain varies because I have been trying everything: this is just the current mess. There are no error messages on starting exim.

Macros:

 DETAINTFILE = /etc/exim4/detaint
 BADCHARS = \N[^A-Za-z0-9_.-]+\N
 SAFELOCALPART = ${lookup{${sg{$local_part}{BADCHARS}{_}}} lsearch*,ret=key{DETAINTFILE}}  SAFEDOMAIN = ${lookup{${sg{$domain}{BADCHARS}{_}}} lsearch*,ret=key{DETAINTFILE}}

begin routers

dnslookup:
 driver = dnslookup
 domains = ! +local_domains
 transport = remote_smtp
 ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
 no_more

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

vmail_aliases:
 driver = redirect
 allow_fail
 allow_defer
 data = ${lookup mysql{SELECT username FROM mailaliases WHERE alias='SAFELOCALPART'}}
 file_transport = address_file
 pipe_transport = address_pipe

localuser:
 driver = accept
 check_local_user = yes
 domains = +local_domains

 transport = local_delivery

vmail_user:
 driver = accept
 domains = +local_domains
 condition = ${lookup mysql{SELECT email_username FROM league WHERE email_username='$local_part_data' AND domain='scasl.ca'}{$value}fail}
 transport = dovecot_virtual_delivery

vmail_nonuser:
 driver = redirect
 allow_fail = true
 data = :fail: Unknown user
 more = false

begin transports

remote_smtp:
  driver = smtp
    authenticated_sender = $local_part_data
    dkim_domain = scasl.ca
    dkim_selector = 20230601
    dkim_private_key = /etc/dkimkeys/20230601.private
    dkim_canon = relaxed
  message_linelength_limit = 1G

local_delivery:
    debug_print = "T: local_delivery for $local_part_data@$domain_data"
    driver = appendfile
    file = /var/mail/${lookup{$local_part_data}lsearch,ret=key{/etc/passwd}}

    delivery_date_add = true
    envelope_to_add = true
    return_path_add = true
    group = mail

dovecot_virtual_delivery:
   driver = pipe
   command = /usr/lib/dovecot/deliver -d $local_part_data@$domain_data -f $sender_address
   delivery_date_add = true
   envelope_to_add = true
   return_path_add = true
   user = vmail
   temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78

address_pipe:
  driver = pipe
  return_output

address_file:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add

address_reply:
  driver = autoreply

begin authenticators

plain_saslauthd_server:
driver = plaintext
server_condition = ${if saslauthd{{$auth2}{$auth3}}{1}{0}}
server_set_id = $auth2
server_prompts = :
server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}

dovecot_login:
  driver = dovecot
  public_name = LOGIN
  server_socket = /var/run/dovecot/auth-client
  server_condition = ${if and {{eq{$auth1}{${lookup mysql{select email_username FROM league WHERE email_username='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}'}}}} \         {eq{$auth2}{${lookup mysql{select email_password FROM league WHERE email_username='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}'}}}}}}   server_set_id = ${lookup mysql{SELECT email_username FROM league WHERE email_username='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}' AND status!='ARCHIVE'}}

dovecot_plain:
  driver = dovecot
  public_name = PLAIN
  server_socket = /var/run/dovecot/auth-client
  server_condition = ${if and {{eq{$auth2}{${lookup mysql{select email_username FROM league WHERE email_username='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}'}}}} \         {eq{$auth3}{${lookup mysql{select email_password FROM league WHERE email_username='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}'}}}}}}   server_set_id = ${lookup mysql{SELECT email_username FROM league WHERE email_username='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}' AND status!='ARCHIVE'}}


I will greatly appreciate any insights.

Cam


--
## subscription configuration (requires account):
##   https://lists.exim.org/mailman3/postorius/lists/exim-users.lists.exim.org/
## unsubscribe (doesn't require an account):
##   exim-users-unsubscr...@lists.exim.org
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Reply via email to