I think I finally have a solution - thanks to Wietse and Viktor.  To
recap I am replacing Sendmail with Postfix in a legacy application and
I was struggling with these two requirements:

1. The server must authenticate clients differently depending on a
"client connection profile"; the profile can be defined in terms of
client IP address or host name; each connection profile defines
whether SMTP AUTH should be offered and the valid credentials; the
server must ensure clients can only authenticate using the credentials
from the appropriate profile.

Filtering out the SMTP AUTH option can be achieved using
smtpd_discard_ehlo_keyword_address_maps defined to call a custom
socketmap table that determines the matching connection profile and
returns "200 AUTH" if authentication is not required; it must lookup
the client's PTR record in DNS if any profiles are defined in terms of
host name.
The smtpd_sender_restrictions option can then be used to call out
(after the MAIL command) to a custom policy server that determines the
matching connection profile using the client_address and client_name
attributes (no need to use DNS here, presumably smtpd has already done
the lookup) and compares the sasl_username attribute against the
profile credentials.  If the client has not authenticated with the
correct username the policy server can reject the connection.

Note: The client will see an error in response to the MAIL command
instead of the AUTH command but I don't think that matters (the client
would see a similar effect if smtpd_sender_login_maps was used for
envelope sender address authorization).

2.  The server must offer and enforce TLS differently depending on a
"client connection profile"; the profile can be defined in terms of
client IP address or host name (as above); each profile defines
whether STARTTLS should be offered, whether TLS is mandatory, and
whether a valid client certificate is required.

Filtering out the STARTTLS option can be achieved using
smtpd_discard_ehlo_keyword_address_maps as described above.
The smtpd_tls_security_level parameter must be set to "may" rather
than "encrypt" if there are any profiles where TLS is not mandatory.
The smtpd_tls_ask_ccert must be set to "yes" if there are any
connection profiles that require certificate validation.
The enforcement can be achieved using smtpd_helo_restrictions to call
(after the EHLO command) a custom policy server that determines the
matching connection profile as described above, and uses the
encryption_protocol attribute to determine if TLS is in use and the
ccert_subject attribute to see if a trusted client certificate was
provided.  (Note: smtpd will validate the certificate if provided even
when  smtpd_tls_security_level is "may".)

Note: the smtpd_delay_reject option must be set to "no" to prevent the
client sending authentication credentials on a plain text connection
where TLS was defined as mandatory (otherwise the policy server is
called after the RCPT command not after the EHLO command).

Any reason why this won't work?

regards,
Rob

Reply via email to