### -*-m4-*- ### ### Client authentication for distorted.org.uk Exim configuration ### ### (c) 2012 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software Foundation, ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ###-------------------------------------------------------------------------- ### Authenticators. m4_define(<:CHECK_PASSWD:>, <:${lookup {$1} lsearch {CONF_sysconf_dir/passwd} \ {${if crypteq {$2} {$value}}} \ {false}}:>) m4_define(<:ALLOW_PLAINTEXT_AUTH_P:>, <:or {{match_ip {$sender_host_address}{+localnet}} \ {and {{def:tls_cipher} {eq{$acl_c_mode}{submission}}}}}:>) SECTION(auth)m4_dnl plain: driver = plaintext public_name = PLAIN server_advertise_condition = ${if ALLOW_PLAINTEXT_AUTH_P} server_prompts = : server_condition = CHECK_PASSWD($auth2, $auth3) server_set_id = $auth2 login: driver = plaintext public_name = LOGIN server_advertise_condition = ${if ALLOW_PLAINTEXT_AUTH_P} server_prompts = <; Username: ; Password: server_condition = CHECK_PASSWD($auth1, $auth2) server_set_id = $auth1 DIVERT(null) ###-------------------------------------------------------------------------- ### Verification of sender address. SECTION(global, acl)m4_dnl acl_not_smtp_start = not_smtp_start SECTION(acl, misc)m4_dnl not_smtp_start: ## Record the user's name. warn set acl_c_user = $sender_ident ## Done. accept SECTION(acl, mail-hooks)m4_dnl ## Check that a submitted message's sender address is allowable. require acl = mail_check_auth SECTION(acl, misc)m4_dnl mail_check_auth: ## If this isn't a submission then it doesn't need checking. accept condition = ${if !eq{$acl_c_mode}{submission}} ## If the caller hasn't formally authenticated, but this is a ## loopback connection, then we can trust identd to tell us the right ## answer. So we should stash the right name somewhere consistent. warn set acl_c_user = $authenticated_id hosts = +localnet !authenticated = * set acl_c_user = $sender_ident ## User must be authenticated. deny message = Sender not authenticated !hosts = +localnet !authenticated = * ## Make sure that the local part is one that the authenticated sender ## is allowed to claim. deny message = Sender address forbidden to calling user !condition = ${LOOKUP_DOMAIN($sender_address_domain, {${if and {{match_local_part \ {$acl_c_user} \ {+dom_users}} \ {match_local_part \ {$sender_address_local_part} \ {+dom_locals}}}}}, {${if and {{match_local_part \ {$sender_address_local_part} \ {+user_extaddr}} \ {or {{eq {$sender_address_domain} \ {}} \ {match_domain \ {$sender_address_domain} \ {+public}}}}}}})} ## All done. accept DIVERT(null) ###-------------------------------------------------------------------------- ### Dealing with `AUTH' parameters and relaying. SECTION(global, acl)m4_dnl acl_smtp_mailauth = mailauth SECTION(acl, misc)m4_dnl ## Check the `AUTH=...' parameter to a `MAIL' command. mailauth: ## If the client has authenticated using TLS then we're OK. The ## sender was presumably checked upstream, and we can believe that ## the name has been transmitted honestly. accept condition = ${if def:tls_peerdn} ## If this is submission, and the client has authenticated, then we ## check that the name matches the user. accept condition = ${if eq {$authenticated_sender} \ {$authenticated_id@CONF_master_domain}} ## Otherwise we can't tell who really sent it. deny message = Authenticated user not authoritative for claimed sender. DIVERT(null) ###----- That's all, folks --------------------------------------------------