1

Is it possible to verify the sender alias against the authenticated user, WITHOUT rewriting the From field? For example, given a (much simplified) alias file like:

a1@example.com:       user1@mydomain.com
a2@other.example.com: user1@mydomain.com
a3@example.com: a4@example.com
a4@example.com:       user1@mydomain.com

a5@example.com:       user2@mydomain.com

I want an authenticated user1 to be able to send as a1,a2,a3 or a4@example.com, but NOT a5@example.com, and I only want an authenticated user2 to be able to send as a5@example.com AND I want them to be able to use the aliases in the From: field of the emails they send (i.e. I don't want Exim to rewrite the From/Sender fields like for "control=submission").

Functionally, this would require Exim to reduce the sender alias to the final routable address, and then allow me access to that value in an acl to compare it against the authenticated user. I thought verify=sender would do that, but testing does not show that to be the case.

In my acl_check_rcpt I tried the following with no effect, as any authenticated user can still send as any valid alias or other local user, and the $sender_address is the alias and not the underlying real account:

  accept
    authenticated = *
    verify = sender
    logwrite = authenticated user '$authenticated_id' sending as '$sender_address' which \
        is '$sender_address_data' or '$address_data', if error: '$sender_verify_failure'

According to the Exim Documentation (Sec. 26), $sender_address_data should contain the result of the sender lookup after a verify=sender, but the logs show that variable as always empty:

authenticated user 'user1' sending as 'a5@example.com' which is '' or '', if error: ''

(Note that control=submission has little effect on this except to rewrite the From/Sender headers.)

Am I just going about this wrong? Is there a way to verify that the authenticated user can validly sent the alias they're sending from?

1

I got this working, and here is what I did.

First, in ALL the routers which handle local users, set the exim variable address_data to the ${local_part}:

real_local:
  driver              = accept
  domains             = +local_domains
  local_part_prefix   = real-
  check_local_user
  transport           = LOCAL_DELIVERY
  # Set this so acl can use it
  address_data        = ${local_part}

Then set up an acl to check the sender vs the authenticated user:

acl_smtp_mail = acl_check_sender_vs_auth

And have that new acl compare the authenticated user against the value of the address_data variable and ensure it is the same:

# Ensure that the MAIL FROM: address matches what the authenticated
# user is, if authentiation is used
acl_check_sender_vs_auth:
    accept
       authenticated = *
       # verify MUST be above condition to resolve $sender_address_data
       verify = sender
       condition = ${if eqi{$authenticated_id}{$sender_address_data}{yes}{no}}
       endpass
       logwrite = AUTH OK - authenticated user '$authenticated_id' sending email from '$sender_address', which belongs to '$sender_address_data'

    deny
       authenticated = *
       # verify MUST be above condition to resolve $sender_address_data
       verify = sender
       !condition = ${if eqi{$authenticated_id}{$sender_address_data}{yes}{no}}
       message = User '$authenticated_id' tried to send mail from '$sender_address', but that email address belongs to someone else
       logwrite = AUTH ERROR - authenticated user '$authenticated_id' tried sending from '$sender_address', but that address belongs to '$sender_address_data'

    accept
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.