Re: TLS client certificates and auth external
Hey, i have withdrawn from Jaroslaw Rafa wrote in <20200826083557.ga15...@rafa.eu.org>: |Dnia 25.08.2020 o godz. 23:39:43 Steffen Nurpmeso pisze: |> Usually you be given a username and a password, and a server name |> and a port. That you enter into the MUA, and the rest you do not |> know. (Unless you use a real primitive MUA, where you have to be |> explicit.) | |I would say the opposite: it is a rather primitive MUA that does not \ |give you |more configuration settings. Well i have no idea. I only ever used pine, mutt, alpine and the thing i maintain. I once started into Apple Mail by 2010 (November 2009 i bought the one Apple i wanted to have once, so around that time), and also i unfortunately have to enter the GMail web interface sometimes because i have message size restrictions for the box they forward to, and especially if my mother sends me super-over-sized photos this does not work out ... and all that is a closed black box. The former even with icons for text attachments and such. I have read the bugzilla/forum thread that was referred to in this thread last year, and in that thread a very big graphical application was made configurable in respect to AUTH. |In most MUAs I used, besides a server name and a port, you can (and should) |configure whether a) you want to use AUTH or not b) you want to connect |unencrypted, encrypted via SMTP-over-TLS (as typically on port 465) or |encrypted via STARTTLS (as typically on port 587). Of course there are some |defaults for these parameters, but you can always change them. |If you configure in the MUA that you don't want to use AUTH, then you also |don't enter any username and password. And with this setting the MUA does |not try to use AUTH even if the server advertises it. You know, the nice thing about this thread is that i have reread the entire postfix TLS and ACCESS readme files, and i have a much better configuration now. I even started thinking whether i should support relay for authenticated clients, instead of going over ssh all the time. (Though the mux is practically always online if i am online, so ...) I would have no idea how to configure GMail or the Apple Mail i used (once, a decade ago) to achieve that. Having said that, one more thing comes to mind regarding postfix. Ciao, --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
Dnia 25.08.2020 o godz. 23:39:43 Steffen Nurpmeso pisze: > Usually you be given a username and a password, and a server name > and a port. That you enter into the MUA, and the rest you do not > know. (Unless you use a real primitive MUA, where you have to be > explicit.) I would say the opposite: it is a rather primitive MUA that does not give you more configuration settings. In most MUAs I used, besides a server name and a port, you can (and should) configure whether a) you want to use AUTH or not b) you want to connect unencrypted, encrypted via SMTP-over-TLS (as typically on port 465) or encrypted via STARTTLS (as typically on port 587). Of course there are some defaults for these parameters, but you can always change them. If you configure in the MUA that you don't want to use AUTH, then you also don't enter any username and password. And with this setting the MUA does not try to use AUTH even if the server advertises it. -- Regards, Jaroslaw Rafa r...@rafa.eu.org -- "In a million years, when kids go to school, they're gonna know: once there was a Hushpuppy, and she lived with her daddy in the Bathtub."
Re: TLS client certificates and auth external
Viktor Dukhovni wrote in <20200825182533.gw37...@straasha.imrryr.org>: |On Tue, Aug 25, 2020 at 07:06:29PM +0200, Steffen Nurpmeso wrote: | |>|because: |>| |>|1. The server indicated support for SASL in its EHLO response. |>|2. The client chose to perform SASL auth. |>| |>|If you want clients to skip SASL auth, configure them to not use |>|SASL auth (no passwords, no EXTERNAL, just a client cert). |> |> That does not work. Oh. Yes, it does! | |Naturally... Heh. |>|The protocol flow is: |> ... |>| 250 AUTH PLAIN GSSAPI ... |>|C: !!! chooses to perform or skip SASL !!! |>|--- possible SASL handshake here --- |> |> Yes, but, you know, _if_ the server announces AUTH then of course |> any automatic software will choose AUTH! Because, why would the |> server announce AUTH if it would not need it? | |Because it is advertising a *capability* not a mandate. Lots of |servers advertise AUTH even when only some clients need to or |choose to use AUTH. Of course you can always set up a dedicated |MSA on some IP:port combination which only accepts client certs, |and is configured to NOT offer AUTH. That's your choice. Usually you be given a username and a password, and a server name and a port. That you enter into the MUA, and the rest you do not know. (Unless you use a real primitive MUA, where you have to be explicit.) And for the basic MUA i maintain one could read already in the year 2004 (!) smtp-auth Sets the SMTP authentication method. If set to `login', or if unset and both smtp-auth-user and smtp-auth-password are set, AUTH LOGIN is used. If set to `cram-md5', AUTH CRAM-MD5 is used. Otherwise, no SMTP authentication is performed. smtp-auth-password Sets the global password for SMTP AUTH. Both user and password have to be given for AUTH LOGIN and AUTH CRAM-MD5. smtp-auth-user Sets the global user name for SMTP AUTH. Both user and password have to be given for AUTH LOGIN and AUTH CRAM-MD5. (plus omitted specializations). And in 2007 it had changed to smtp-auth Sets the SMTP authentication method. If set to `login', or if unset and smtp-auth-user is set, AUTH LOGIN is used. If set to `cram-md5', AUTH CRAM-MD5 is used; if set to `plain', AUTH PLAIN is used. Otherwise, no SMTP authentication is performed. I personally have _never_ send a mail via a smarthost without having authenticated myself. |And for a client to initiate SASL AUTH it has to be configured with |suitable credentials, and told to use them with the server in question. Yes. At least the former, the latter is then always automatic as of my experience. |Clients don't (implementation incompetence aside) just automatically |send their passwords to some random server that happens to include |"AUTH" in its EHLO response. I am only talking MUA here. So please replace the "client" as above with the word "mail user agent", or also simple MTAs like DMA or msmtp. You define a smarthost to contact, and if so (at least DMA can also send mail directly to a receiver instead), a login is performed. |> This does not make sense! | |It makes sense to me. You intuition is misleading you in various |non-productive directions. Try to set some preconceptions aside |and take in a new perspective. This is very tough. But maybe we have a notational problem only, where my "client" is a MUA, wheras your "client" is any SMTP aware software which transports a message to a SMTP server. |>|The relative order of the relay and recipient restrictions is somewhat |>|in flux at the moment, it changed in Postfix 3.3, but the docs have |> |> (Must be that, then.) | |No, that's just a pedantic side comment, not relevant to your situation, |needed only to avoid a small inaccuracy. So i withdraw politely in silence. Good Evening, --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
On Tue, Aug 25, 2020 at 07:06:29PM +0200, Steffen Nurpmeso wrote: > |because: > | > |1. The server indicated support for SASL in its EHLO response. > |2. The client chose to perform SASL auth. > | > |If you want clients to skip SASL auth, configure them to not use > |SASL auth (no passwords, no EXTERNAL, just a client cert). > > That does not work. Oh. Yes, it does! Naturally... > |The protocol flow is: > ... > | 250 AUTH PLAIN GSSAPI ... > |C: !!! chooses to perform or skip SASL !!! > |--- possible SASL handshake here --- > > Yes, but, you know, _if_ the server announces AUTH then of course > any automatic software will choose AUTH! Because, why would the > server announce AUTH if it would not need it? Because it is advertising a *capability* not a mandate. Lots of servers advertise AUTH even when only some clients need to or choose to use AUTH. Of course you can always set up a dedicated MSA on some IP:port combination which only accepts client certs, and is configured to NOT offer AUTH. That's your choice. And for a client to initiate SASL AUTH it has to be configured with suitable credentials, and told to use them with the server in question. Clients don't (implementation incompetence aside) just automatically send their passwords to some random server that happens to include "AUTH" in its EHLO response. > This does not make sense! It makes sense to me. You intuition is misleading you in various non-productive directions. Try to set some preconceptions aside and take in a new perspective. > |The relative order of the relay and recipient restrictions is somewhat > |in flux at the moment, it changed in Postfix 3.3, but the docs have > > (Must be that, then.) No, that's just a pedantic side comment, not relevant to your situation, needed only to avoid a small inaccuracy. -- Viktor.
Re: TLS client certificates and auth external
Viktor Dukhovni wrote in <20200825160538.gt37...@straasha.imrryr.org>: |On Tue, Aug 25, 2020 at 04:56:26PM +0200, Steffen Nurpmeso wrote: |> Emmanuel Fusté wrote in |> : |>|Le 24/08/2020 à 21:14, Steffen Nurpmeso a écrit : |>|> Something else, maybe. |>|> I do not understand why my (stupid) config |>|> |>|>smtpd_sender_restrictions = |>|>check_ccert_access hash:/etc/postfix/relay_clientcert, |>|>permit_tls_clientcerts, |>|>reject_unknown_sender_domain, |>|> #reject_sender_login_mismatch, |>|>permit_sasl_authenticated, |>|> reject |>|> |>|> succeeds only if reject_sender_login_mismatch is commented out |>|> _unless_ i pass a valid client certificate. I.e., even if |>|> anything is ok except for with/out client certificate: |> |>|Just for this part : what is your content of the map configured by |>|smtpd_sender_login_maps ? |> |> I am confused. That makes no sense. To reiterate, if i pass |> a valid client certificate check_ccert_access matches, the rest of |> the chain is skipped, but SASL authentication is still performed, |> permit_sasl_authenticated still matters! If i do not pass a valid |> client certificate, reject_sender_login_mismatch triggers because |> .. but the map is empty! Also for this test the order of the |> chain cannot matter, because SASL authentication happens later. |> Whatever. Note the error happens after authentication was |> reported as being successful. | |What you're actually confused about has little to do with client certs |and to some extent SASL. | |First and foremost you need to understand that a "permit" action in the |sender restrictions is NOT final, it just short-circuits the *sender* |restrictions, the rest of restrictions, and in particular the "relay" |and "recipient" restrictions are still processed. I have to think about that. These at least do not include SASL. |Therefore, the "check_ccert_access" you actually care about is the one |in "smtpd_relay_restrictions" and/or "smtpd_recipient_restrictions". That is only as above. :) |Your other point of confusion is that you're imagining that the |restriction processing determines the SMTP protocol control flow, such |that SASL authentication only happens when "permit_sasl_authenticated" |or similar is evaluated. | |In fact, by the time (especially smtpd_delay_reject=yes, the strongly |recommended default) that the restriction processing is happening, the Ah! |SASL authentication handshake is long in the past. It happens Indeed. |because: | |1. The server indicated support for SASL in its EHLO response. |2. The client chose to perform SASL auth. | |If you want clients to skip SASL auth, configure them to not use |SASL auth (no passwords, no EXTERNAL, just a client cert). That does not work. Oh. Yes, it does! ? set smtp-config=-auth ? mail root@localhost ... s-nail: >>> STARTTLS s-nail: >>> SERVER: 220 2.0.0 Ready to start TLS s-nail: TLS: applying config: MinProtocol = TLSv1.3 s-nail: TLS: applying config: Certificate = /tmp/kdcc.pem s-nail: TLS: applying config: PrivateKey = /tmp/kdck.pem ... s-nail: >>> EHLO kdc.localdomain ... s-nail: >>> SERVER: 250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 XOAUTH2 OAUTHBEARER EXTERNAL GSSAPI ... s-nail: *smtp-config*: using pipelining extension s-nail: >>> MAIL FROM: s-nail: >>> RCPT TO: s-nail: >>> DATA s-nail: >>> SERVER: 250 2.1.0 Ok s-nail: >>> SERVER: 250 2.1.5 Ok s-nail: >>> SERVER: 354 End data with . ... s-nail: >>> QUIT s-nail: >>> SERVER: 250 2.0.0 Ok: queued as E076C40547 |The protocol flow is: ... | 250 AUTH PLAIN GSSAPI ... |C: !!! chooses to perform or skip SASL !!! |--- possible SASL handshake here --- Yes, but, you know, _if_ the server announces AUTH then of course any automatic software will choose AUTH! Because, why would the server announce AUTH if it would not need it? This does not make sense! There are clients which do not even allow users to fine-tune the authentication mechanism which is used! In fact, last years thread on this ML caused that widely used MUA (i have forgotten) to actually implement that possibility!! (The lengthy bugzilla or whatever forum threads will show this. Thinkable also that the respective people are (still) on this list and read this even.) I would presume that the _sole_ reason why postfix have had no(t much bigger) problems with EXTERNAL SASL is that it is likely that EXTERNAL is not chosen automatically. This is what my MUA will do with the next minor release auth Authentication (RFC 4954) allows account credentials to be passed. This word disables all authentication mechanisms, but enables only those which can be managed automatically without external help; for example GSSAPI requires an exter‐ nally granted ticket to exist, and is therefore excluded by the default automatic selection,
Re: TLS client certificates and auth external
Viktor Dukhovni wrote in <20200825161847.gu37...@straasha.imrryr.org>: |On Tue, Aug 25, 2020 at 05:56:41PM +0200, Steffen Nurpmeso wrote: |You have still now answered Wietse's question. If you were to do |"EXTERNAL" auth, what determines whether a user presented a valid |credential, and what part of the certificate determines the associated |login name? Who is authorised to assert such login names. | |You need to be careful to not inadvertently authorise every CA on the |planet to assert login credentials on your server. Avoiding this takes |some care. But no, i have done so from the very start? Or i do not understand what you mean. Postfix is the one that validates the client certificate the same way it does now. And it passes the necessary information to the SASL auth server so that the announced EXTERNAL SASL mechanism can actually truly be used, and succeeds. At the moment, if check_ccert_access is used, and SASL is, too, two entirely distinct logins are thinkable, no? Isn't that a much bigger mess? Than just allowing EXTERNAL and let the commonName of the certificate be of any value. I do not understand. This is how it is done?? |As I said before, instead of sending patches, if you want to see |new functionality in Postfix, please post a clear set of written |requirements and a proposed design (if you want to propose one). And as i said before, all i could imagine is that the dovecot SASL auth is improved, so that a fingerprint digest is exchanged, and an actual fingerprint is passed. But for postfix this likely does not change the situation even then, because all the different sorts of client certificate checkings surely will not go away. And you do have at least check_ccert_access as well as permit_tls_clientcerts+relay_clientcerts possibilities, do you? What is actually wrong? I do not propose anything, it is you who have at least two different client certificate mechanisms _plus_ SASL, which is inspected _in addition_ for at least the check_ccert_access that i have configured correctly? Correct? If so, where is the problem of allowing dovecot to use the data of the verified client certificate? --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
On Tue, Aug 25, 2020 at 05:56:41PM +0200, Steffen Nurpmeso wrote: > Twenty years ago i was an angry young man because the new German > passports did not include S/MIME++ certificates and PGP keys, > signed by the German government. In the meantime the > "Bundesdruckerei" (which has become more or less private until > then, what a mess, in my opinion) actually acts as a certificate > authority. TL;DR, OAUTH is a complex mess. Its main effect is to discourage use of your own mail client, so you use WebMail, or some "app" on a mobile device. Its security is worse than passwords, especially for users who know how to manage passwords. But perhaps for sufficiently clueless users the password is less likely to be sent insecurely or to the wrong party. It is shoddy tech, optimised for the unwashed masses. > |as long as their certificate contains an email address that matches > |smtpd_sender_login_maps? > > Oh, sorry, i am not an administrator. I have read the postfix > documentation once in 2015, to setup my server VM. Until then > only externally managed accounts. And the server does not support > any login mechanism at all, the message enters the postfix there > via ssh and sendmail. That is enough for me. (It even drives > mailing lists, but that via aliases.) You have still now answered Wietse's question. If you were to do "EXTERNAL" auth, what determines whether a user presented a valid credential, and what part of the certificate determines the associated login name? Who is authorised to assert such login names. You need to be careful to not inadvertently authorise every CA on the planet to assert login credentials on your server. Avoiding this takes some care. As I said before, instead of sending patches, if you want to see new functionality in Postfix, please post a clear set of written requirements and a proposed design (if you want to propose one). -- Viktor.
Re: TLS client certificates and auth external
On Tue, Aug 25, 2020 at 04:56:26PM +0200, Steffen Nurpmeso wrote: > Emmanuel Fusté wrote in > : > |Le 24/08/2020 à 21:14, Steffen Nurpmeso a écrit : > |> Something else, maybe. > |> I do not understand why my (stupid) config > |> > |>smtpd_sender_restrictions = > |>check_ccert_access hash:/etc/postfix/relay_clientcert, > |>permit_tls_clientcerts, > |>reject_unknown_sender_domain, > |> #reject_sender_login_mismatch, > |>permit_sasl_authenticated, > |> reject > |> > |> succeeds only if reject_sender_login_mismatch is commented out > |> _unless_ i pass a valid client certificate. I.e., even if > |> anything is ok except for with/out client certificate: > > |Just for this part : what is your content of the map configured by > |smtpd_sender_login_maps ? > > I am confused. That makes no sense. To reiterate, if i pass > a valid client certificate check_ccert_access matches, the rest of > the chain is skipped, but SASL authentication is still performed, > permit_sasl_authenticated still matters! If i do not pass a valid > client certificate, reject_sender_login_mismatch triggers because > .. but the map is empty! Also for this test the order of the > chain cannot matter, because SASL authentication happens later. > Whatever. Note the error happens after authentication was > reported as being successful. What you're actually confused about has little to do with client certs and to some extent SASL. First and foremost you need to understand that a "permit" action in the sender restrictions is NOT final, it just short-circuits the *sender* restrictions, the rest of restrictions, and in particular the "relay" and "recipient" restrictions are still processed. Therefore, the "check_ccert_access" you actually care about is the one in "smtpd_relay_restrictions" and/or "smtpd_recipient_restrictions". Your other point of confusion is that you're imagining that the restriction processing determines the SMTP protocol control flow, such that SASL authentication only happens when "permit_sasl_authenticated" or similar is evaluated. In fact, by the time (especially smtpd_delay_reject=yes, the strongly recommended default) that the restriction processing is happening, the SASL authentication handshake is long in the past. It happens because: 1. The server indicated support for SASL in its EHLO response. 2. The client chose to perform SASL auth. If you want clients to skip SASL auth, configure them to not use SASL auth (no passwords, no EXTERNAL, just a client cert). The protocol flow is: C: SYN S: SYN-ACK C: ACK S: 220 greeting C: EHLO S: 250- ... 250 STARTTLS C: STARTTLS S: 250 make my day... C: TLS client hello S: TLS server hello : ... sound and fury of TLS handshake ... Channel is now TLS encrypted C: 250 EHLO S: 250- ... 250 AUTH PLAIN GSSAPI ... C: !!! chooses to perform or skip SASL !!! --- possible SASL handshake here --- C: MAIL FROM: BODY=8BITMIME SIZE=... S: 250-OK C: RCPT TO: ORCPT=... S: --- evaluates *ALL* restrictions here! --- client restrictions -- might look at cert or SASL login helo restrictions -- might look at cert or SASL login sender restrictions -- might look at cert or SASL login recipient restrictions -- might look at cert or SASL login relay restrictions -- might look at cert or SASL login S: 250 OK (or 5XX go spam someone else) C: DATA S: evaluates data restrictions here -- might look at cert or SASL login 354 Go ahead (or 5XX go spam someone else) C: . S: evaluates end of data restrictions here -- might look at cert or SASL login S: 250 OK (or 5XX go spam someone else) C: QUIT S: 221 Goodbye With this in mind, you'll have an easier time to understand where SASL and client certs fit into the picture. The relative order of the relay and recipient restrictions is somewhat in flux at the moment, it changed in Postfix 3.3, but the docs have not caught up, and I hope it will change again 3.6, provided you set the compatibility level high enough. But this is unlikely to matter terribly much in most cases. -- Viktor.
Re: TLS client certificates and auth external
Hello. Wietse Venema wrote in <4bbwrb5qbbzj...@spike.porcupine.org>: |What is the trust model: can anyone send email as long as they have |a valid certificate that is signed by one of hundreds of CAs, and I am a political person and can only response to this politically. Other than that i do not know, Wietse Venema. Twenty years ago i was an angry young man because the new German passports did not include S/MIME++ certificates and PGP keys, signed by the German government. In the meantime the "Bundesdruckerei" (which has become more or less private until then, what a mess, in my opinion) actually acts as a certificate authority. The IETF pushes per-DNS-zone authorities. DNS can now go over encrypted transport, and the content itself is also (though differently, unfortunately) cryptographically verifiable, if the zone does that. The Internet of Things produces devices which want to call home and take part in the internet. If you buy a light bulb today it may want to contact home when you use it first in five years from now on. The past has shown passports are important, i also say this in particular as a German (others could chime in of course), people even kill for passports eventually. I do not see a particular difference in between digital and paper passports. I know for sure however that with client certificates there is a little bit of security and affirmation where otherwise there is nothing. My MUA for example was treated as a lesser secure application by a big free mail provider, because it does not use OAuth. Even though my password is in an encrypted .netrc file, and that in turn exists on an encrypted partition on an unencrypted block device (and also that will change in the future). The partition is unmounted on lid close. The data transport is secured via TLS. Why is this lesser secure? Especially since XOAUTH2 / OAUTHBEARER is not lesser secure. But in how far is that different than just offering the possibility to specify per-application passwords, for example. I.e., diversify that, do not use the account master password for logins via SMTP / POP3 / IMAP? And then i have to go over HTTPS to refresh my temporary password. Why is that necessary, the XOAUTH2 / OAUTHBEARER JSON hashmasp used during login could very well be used to update refresh tokens on the fly, too. Maybe in the future there will be advertisements when updating the token, i do not know. I cannot time out this token, different to Kerberos/GSSAPI, where my local kdestroy(1) program can be used to disable the ticket. With client certificates people are, or could be, responsible themselves. We have programs like GPG agent and ssh-agent, there are USB sticks like yubikey and such, which help in storing their private counterparts securely (unless the scene is getting real tough, at least, but this cannot be helped anyhow, i would say). Their content is standardized, the algorithms are standardized and well-tested, and open for any mathematician / cryptographer who is dedicated enough to go for it. This is as good as it can get. |as long as their certificate contains an email address that matches |smtpd_sender_login_maps? Oh, sorry, i am not an administrator. I have read the postfix documentation once in 2015, to setup my server VM. Until then only externally managed accounts. And the server does not support any login mechanism at all, the message enters the postfix there via ssh and sendmail. That is enough for me. (It even drives mailing lists, but that via aliases.) But in the meantime i have become conscious that this login-test setup is totally broken, i am already reading the documentation anew in another window. Thank you! By the way, there is a little improvement in the patch: diff --git a/src/xsasl/xsasl_dovecot_server.c b/src/xsasl/xsasl_dovecot_server.c -index 601f787..9b849b4 100644 +index 601f787..780fd91 100644 --- a/src/xsasl/xsasl_dovecot_server.c +++ b/src/xsasl/xsasl_dovecot_server.c @@ -166,7 +166,8 @@ typedef struct { @@ -98,8 +97,8 @@ index 601f787..9b849b4 100644 server->mechanism_argv = 0; -server->tls_flag = args->tls_flag; +server->tls_flags = args->tls_flags; -+server->tls_cert_username = (args->tls_flags && args->tls_cert_username) -+ ? mystrdup(args->tls_cert_username) : 0; ++server->tls_cert_username = ((args->tls_flags & XSASL_TLS_CLIENT_CERT) ++ && args->tls_cert_username) ? mystrdup(args->tls_cert_username) : 0; It does not really fix a bug, but is more explicit. (I have not compiled this, i only recognized it would be more explicit like this.) I will attach this version, ok? | Wietse --End of <4bbwrb5qbbzj...@spike.porcupine.org> Ciao, Mr. Venema, --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) diff --git a/src/smtpd/smtpd_sasl_glue.c
Re: TLS client certificates and auth external
Emmanuel Fusté wrote in : |Le 24/08/2020 à 21:14, Steffen Nurpmeso a écrit : |> Something else, maybe. |> I do not understand why my (stupid) config |> |>smtpd_sender_restrictions = |>check_ccert_access hash:/etc/postfix/relay_clientcert, |>permit_tls_clientcerts, |>reject_unknown_sender_domain, |> #reject_sender_login_mismatch, |>permit_sasl_authenticated, |> reject |> |> succeeds only if reject_sender_login_mismatch is commented out |> _unless_ i pass a valid client certificate. I.e., even if |> anything is ok except for with/out client certificate: |Just for this part : what is your content of the map configured by |smtpd_sender_login_maps ? Nothing. ;) Hm. I think i have misread the documentation anyhow, this is totally false: i have also thought that check_ccert_access is used to enable permit_tls_clientcerts. Hm. I have to reread it all, i did so first and last in 2015, for my server VM, and that is simple, allows no logins at all! Thanks for pointing this out. I think i have real shortcomings understanding the syntax above, actually. I thought the above is worked sequentially, and some actions are "insertions", for example there is "sleep SECONDS", which is then performed when walking the chain of tests, at the very position of the chain, in place. I thought this check_ccert_access is like that, too, loading the according DB, to enable permit_tls_clientcerts. Obviously wrong. So the check_ccert_access check makes the test login succeed when there is a client certificate, the remains of the chain are not evaluated at all, but the SASL login is then performed as a totally different step because i have smtpd_sasl_auth_enable? This has nothing to do with the permit_sasl_authenticated in the chain above, thus. But no, here smtpd_sasl_auth_enable is used to enable permit_sasl_authenticated in chains, says the documentation. I am confused. That makes no sense. To reiterate, if i pass a valid client certificate check_ccert_access matches, the rest of the chain is skipped, but SASL authentication is still performed, permit_sasl_authenticated still matters! If i do not pass a valid client certificate, reject_sender_login_mismatch triggers because .. but the map is empty! Also for this test the order of the chain cannot matter, because SASL authentication happens later. Whatever. Note the error happens after authentication was reported as being successful. I better go now. :) I really have to try out reject_unauth_pipelining. Hm! |Emmanuel. Au revoir. --End of --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
What is the trust model: can anyone send email as long as they have a valid certificate that is signed by one of hundreds of CAs, and as long as their certificate contains an email address that matches smtpd_sender_login_maps? Wietse
Re: TLS client certificates and auth external
Le 24/08/2020 à 21:14, Steffen Nurpmeso a écrit : Something else, maybe. I do not understand why my (stupid) config smtpd_sender_restrictions = check_ccert_access hash:/etc/postfix/relay_clientcert, permit_tls_clientcerts, reject_unknown_sender_domain, #reject_sender_login_mismatch, permit_sasl_authenticated, reject succeeds only if reject_sender_login_mismatch is commented out _unless_ i pass a valid client certificate. I.e., even if anything is ok except for with/out client certificate: Just for this part : what is your content of the map configured by smtpd_sender_login_maps ? Emmanuel.
Re: TLS client certificates and auth external
Viktor Dukhovni wrote in <20200823024200.go37...@straasha.imrryr.org>: |On Sun, Aug 23, 2020 at 02:36:51AM +0200, Steffen Nurpmeso wrote: ... |I think that there's a major semantic problem here. The code validating |the certificate chain against some issuer(s) trusted to identify local |users should also be the code that's mapping certificates to user names. I agree that it sounds more sane if there is only one point of interest regarding TLS client certificate verification. On the dovecot list i asked (? i think yes) for extending the protocol, so that the auth server can announce a fingerprint digest, and the client would then create an according fingerprint over the entire certificate, and pass cert_username= plus the fingerprint to the authentication server. So then the SASL auth server would be the sole instance of client certificate verification. However, postfix already implements a lot of TLS and client certificate validation, and even as an outsider it seems unlikely that all that bunch of code is simply removed, in order to be replaced with SASL? So then this does not matter much. Except, of course, you say that dovecot should simply not offer EXTERNAL authentication because the auth client has to perform the validation. Yes. And no. SASL EXTERNAL is an old standard, and it should be pushed forward, imho. Because having client certificates is much better for users than anything else i can imagine. My opinion. Also postfix does not take care for permit_tls_clientcerts it seems, it continues working the list, in my case. I am not a postfix configuration professional _however_. I would have expected that this permit_ stops walking the list immediately, but it seems smtpd_sasl_auth_enable=yes causes the permit_sasl_authenticated=yes thereafter to be inspected anyway! So this is an either-or configuration it seems, all-client-certs and no SASL, or SASL plus client certs. And then, the need for just another authentication method is maybe just as bad! And also because, dovecot actually verifies that the user name in the immediate response is identical to the passed cert_username: ? set user=laber ? mail root@localhost ... s-nail: SMTP: authentication: selecting EXTERNAL s-nail: >>> AUTH EXTERNAL bGFiZXI= s-nail: >>> MAIL FROM: s-nail: >>> RCPT TO: s-nail: >>> DATA s-nail: >>> SERVER: 535 5.7.8 Error: authentication failed: s-nail: SMTP: unexpected status from server: 535 5.7.8 Error: authentication failed: gives this log (now i know how to handle journalctl less output) Aug 24 20:56:09 arch-2020 postfix/smtpd[11165]: 8165E4054C: client=_gateway[10.0.0.1], sasl_method=EXTERNAL, sasl_username=steffen Aug 24 20:56:09 arch-2020 postfix/cleanup[11199]: 8165E4054C: message-id=<20200824185607.jxkJIVnT@kdc.localdomain> Aug 24 20:56:09 arch-2020 postfix/qmgr[11163]: 8165E4054C: from=, size=653, nrcpt=1 (queue active) Aug 24 20:56:09 arch-2020 postfix/smtpd[11165]: disconnect from _gateway[10.0.0.1] ehlo=2 starttls=1 auth=1 mail=1 rcpt=1 data=1 quit=1 commands=8 Aug 24 20:56:09 arch-2020 postfix/local[11202]: 8165E4054C: to=, orig_to=, relay=local, delay=3.1, delays=3.1/0.02/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox) Aug 24 20:56:09 arch-2020 postfix/qmgr[11163]: 8165E4054C: removed Aug 24 20:56:45 arch-2020 postfix/smtpd[11165]: connect from _gateway[10.0.0.1] Aug 24 20:56:45 arch-2020 postfix/smtpd[11165]: Trusted TLS connection established from _gateway[10.0.0.1]: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (1024 bits) server-digest SHA256 client-signature RSA-PSS (1024 bits) client-digest SHA256 Aug 24 20:56:45 arch-2020 dovecot[11187]: auth: Debug: client in: AUTH 7EXTERNALservice=smtpnologinlip=10.0.1.11 rip=10.0.0.1securedvalid-client-cert cert_username=steffenresp= Aug 24 20:56:45 arch-2020 dovecot[11187]: auth: external(steffen,10.0.0.1): login user: Master user login attempted without master passdbs Aug 24 20:56:45 arch-2020 dovecot[11187]: auth: Debug: auth(steffen,10.0.0.1): Auth request finished Aug 24 20:56:47 arch-2020 dovecot[11187]: auth: Debug: client passdb out: FAIL7user=steffenoriginal_user= Aug 24 20:56:47 arch-2020 postfix/smtpd[11165]: warning: _gateway[10.0.0.1]: SASL EXTERNAL authentication failed: Aug 24 20:56:48 arch-2020 postfix/smtpd[11165]: too many errors after AUTH from _gateway[10.0.0.1] Aug 24 20:56:48 arch-2020 postfix/smtpd[11165]: disconnect from _gateway[10.0.0.1] ehlo=2 starttls=1 auth=0/1 commands=3/4 ? set user=steffen ? mail root@localhost ... s-nail: SMTP: authentication: selecting EXTERNAL s-nail: >>> AUTH EXTERNAL c3RlZmZlbg== s-nail: >>> MAIL FROM: s-nail: >>> RCPT TO: s-nail: >>> DATA s-nail: >>> SERVER: 235 2.7.0 Authentication successful s-nail: >>> SERVER: 250 2.1.0 Ok s-nail:
Re: TLS client certificates and auth external
Hello and good evening! Please excuse the late replay. Wietse Venema wrote in <4bzhbq2rngzj...@spike.porcupine.org>: |Viktor Dukhovni: |> On Sun, Aug 23, 2020 at 02:36:51AM +0200, Steffen Nurpmeso wrote: ... |Annd if you must pass additional information to the Dovecot auth |server, the proper way is to extend the xsasl_server_create() API, |not adding ad-hoc arguments here and there to poke data through the |abstraction layers. So i have rewritten the patch, and extended XSASL_SERVER_CREATE_ARGS instead, it makes things much easier! I also adjusted the documentation in xsasl_server.c accordingly, i had not seen that on Saturday. I can successfully authentificate with the EXTERNAL SASL mechanism. Ciao from Germany, --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) diff --git a/src/smtpd/smtpd_sasl_glue.c b/src/smtpd/smtpd_sasl_glue.c index 020c830..830d5c9 100644 --- a/src/smtpd/smtpd_sasl_glue.c +++ b/src/smtpd/smtpd_sasl_glue.c @@ -185,9 +185,9 @@ voidsmtpd_sasl_initialize(void) voidsmtpd_sasl_activate(SMTPD_STATE *state, const char *sasl_opts_name, const char *sasl_opts_val) { -const char *mechanism_list; +const char *tls_cert_username, *mechanism_list; XSASL_SERVER_CREATE_ARGS create_args; -int tls_flag; +int tls_flags; /* * Sanity check. @@ -207,10 +207,16 @@ voidsmtpd_sasl_activate(SMTPD_STATE *state, const char *sasl_opts_name, /* * Set up a new server context for this connection. */ +tls_cert_username = 0; #ifdef USE_TLS -tls_flag = state->tls_context != 0; +tls_flags = (state->tls_context != 0) ? XSASL_TLS_SECURED : 0; +if (tls_flags && TLS_CERT_IS_PRESENT(state->tls_context)) { + tls_flags |= XSASL_TLS_CLIENT_CERT; + tls_cert_username = state->tls_context->peer_CN; +} + #else -tls_flag = 0; +tls_flags = 0; #endif #define ADDR_OR_EMPTY(addr, unknown) (strcmp(addr, unknown) ? addr : "") #define REALM_OR_NULL(realm) (*(realm) ? (realm) : (char *) 0) @@ -228,9 +234,10 @@ voidsmtpd_sasl_activate(SMTPD_STATE *state, const char *sasl_opts_name, client_port = ADDR_OR_EMPTY(state->port, CLIENT_PORT_UNKNOWN), service = var_smtpd_sasl_service, - user_realm = REALM_OR_NULL(var_smtpd_sasl_realm), + user_realm = REALM_OR_NULL(var_smtpd_sasl_realm), security_options = sasl_opts_val, - tls_flag = tls_flag)) == 0) + tls_flags = tls_flags, + tls_cert_username = tls_cert_username)) == 0) msg_fatal("SASL per-connection initialization failed"); /* diff --git a/src/xsasl/xsasl.h b/src/xsasl/xsasl.h index b494d7e..2cbff64 100644 --- a/src/xsasl/xsasl.h +++ b/src/xsasl/xsasl.h @@ -54,7 +54,8 @@ typedef struct XSASL_SERVER_CREATE_ARGS { const char *service; const char *user_realm; const char *security_options; -int tls_flag; +int tls_flags; +const char *tls_cert_username; /* (Or 0; only used if tls_flags!=0!) */ } XSASL_SERVER_CREATE_ARGS; typedef struct XSASL_SERVER_IMPL { @@ -65,12 +66,15 @@ typedef struct XSASL_SERVER_IMPL { extern XSASL_SERVER_IMPL *xsasl_server_init(const char *, const char *); extern ARGV *xsasl_server_types(void); +#define XSASL_TLS_SECURED (1<<0) /* (In fact: .tls_flags not 0) */ +#define XSASL_TLS_CLIENT_CERT (1<<1) + #define xsasl_server_create(impl, args) \ (impl)->create((impl), (args)) -#define XSASL_SERVER_CREATE(impl, args, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ +#define XSASL_SERVER_CREATE(impl, args, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ xsasl_server_create((impl), (((args)->a1), ((args)->a2), ((args)->a3), \ ((args)->a4), ((args)->a5), ((args)->a6), ((args)->a7), ((args)->a8), \ - ((args)->a9), ((args)->a10), (args))) + ((args)->a9), ((args)->a10), ((args)->a11), (args))) #define xsasl_server_done(impl) (impl)->done((impl)); /* diff --git a/src/xsasl/xsasl_dovecot_server.c b/src/xsasl/xsasl_dovecot_server.c index 601f787..9b849b4 100644 --- a/src/xsasl/xsasl_dovecot_server.c +++ b/src/xsasl/xsasl_dovecot_server.c @@ -166,7 +166,8 @@ typedef struct { char *username; /* authenticated user */ VSTRING *sasl_line; unsigned int sec_props; /* Postfix mechanism filter */ -int tls_flag; /* TLS enabled in this session */ +int tls_flags; /* TLS flags of this session */ +char *tls_cert_username; /* If .tls_flags, maybe commonName */ char *mechanism_list; /* filtered mechanism list */ ARGV *mechanism_argv; /* ditto */ char *client_addr; /* remote IP address */ @@ -450,7 +451,9 @@ static XSASL_SERVER *xsasl_dovecot_server_create(XSASL_SERVER_IMPL *impl, server->last_request_id = 0; server->mechanism_list = 0; server->mechanism_argv = 0; -server->tls_flag = args->tls_flag; +
Re: TLS client certificates and auth external
Viktor Dukhovni: > On Sun, Aug 23, 2020 at 02:36:51AM +0200, Steffen Nurpmeso wrote: > > > However, short of time (it will be no sooner than six o'clock in > > the morning until i will get home, sorry! Just in case anyone is > > interested), i blindly added another cert_username=steffen to the > > stuff in src/xsasl/xsasl_dovecot_server.c, and with that we will > > get the job done! > > I think that there's a major semantic problem here. The code validating > the certificate chain against some issuer(s) trusted to identify local > users should also be the code that's mapping certificates to user names. > > It sounds like you have Postfix validating the certificate trust chain, > but then Dovecot, doing the user mapping. Or if not, what role exactly > is Dovecot playing in all this? > > You're posting code, but that seems premature. Can you instead post a > description of the design? Perhaps moving the discussion to > postfix-devel... Annd if you must pass additional information to the Dovecot auth server, the proper way is to extend the xsasl_server_create() API, not adding ad-hoc arguments here and there to poke data through the abstraction layers. Wietse
Re: TLS client certificates and auth external
On Sun, Aug 23, 2020 at 02:36:51AM +0200, Steffen Nurpmeso wrote: > However, short of time (it will be no sooner than six o'clock in > the morning until i will get home, sorry! Just in case anyone is > interested), i blindly added another cert_username=steffen to the > stuff in src/xsasl/xsasl_dovecot_server.c, and with that we will > get the job done! I think that there's a major semantic problem here. The code validating the certificate chain against some issuer(s) trusted to identify local users should also be the code that's mapping certificates to user names. It sounds like you have Postfix validating the certificate trust chain, but then Dovecot, doing the user mapping. Or if not, what role exactly is Dovecot playing in all this? You're posting code, but that seems premature. Can you instead post a description of the design? Perhaps moving the discussion to postfix-devel... -- Viktor.
Re: TLS client certificates and auth external
Hello! Steffen Nurpmeso wrote in <20200820232547.x0nbc%stef...@sdaoden.eu>: ... |Wietse Venema wrote in | <4bxstk189nzj...@spike.porcupine.org>: ||Steffen Nurpmeso: ||> Wietse Venema wrote in ||> <4bwxll093mzj...@spike.porcupine.org>: ||>|Steffen Nurpmeso: ... ||>|Short summary: Postfix does not implement a single iota of SASL ||>|AUTH support. Postfix simply propagates the names of mechanisms ||>|that the backend (Cyrus or Dovecot) claims to support, and Postfix | ... ||>|If Dovecot claims to support SASL EXTERNAL but does not handle it, ||>|that that is a bit of a WTF. ... ||> until SASL says it is done?!. How could EXTERNAL ever work like ||> that in a client/server->auth-server situation? || ||There's a chicken and egg question in there somewhere. || ||https://wiki1.dovecot.org/Authentication%20Protocol mentions ||two attributes that might be relevant, and that Postfix can send: || ||secured ||Remote user has secured transport to auth client] (eg. localhost, \ ||SSL, TLS) || ||valid-client-cert ||Remote user has presented a valid SSL certificate. || ||But these are booleans. What protocol attribute would Postfix use ||to pass certificate name information (and which name, as there ||can be any number of them)? ... |the dovecot SASL wiki entry. So it seems postfixs SASL support |can be improved a bit. And, well, i think for EXTERNAL there has |to be user name as an immediate response, so this would be that. | |I would like to look into this tomorrow or on Saturday, maybe |i can produce a patch that adds the above keywords to the postfix/ |dovecot SASL interaction? Well. I first wanted to pass the SMTPD_STATE through to the SASL support, but then i added a flag field, which avoided possibly undesired new header inclusions. (I never compiled that path.) Unfortunately that still does not help and bring EXTERNAL authentication support to postfix, because dovecot still complains about unknown user name, even if the user name comes with the initial response, even with Aug 23 01:39:29 arch-2020 dovecot[245]: auth: Debug: client in: AUTH1 EXTERNALservice=smtpnologinlip=10.0.1.11 rip=10.0.0.1securedvalid-client-cert Aug 23 01:39:29 arch-2020 dovecot[245]: auth: external(?,10.0.0.1): username not known Aug 23 01:39:29 arch-2020 dovecot[245]: auth: Debug: auth(?,10.0.0.1): Auth request finished Aug 23 01:39:31 arch-2020 postfix/smtpd[6433]: warning: _gateway[10.0.0.1]: SASL EXTERNAL authentication failed: Aug 23 01:39:31 arch-2020 dovecot[245]: auth: Debug: client passdb out: FAIL 1 Aug 23 01:39:32 arch-2020 postfix/smtpd[6433]: too many errors after AUTH from _gateway[10.0.0.1] However, short of time (it will be no sooner than six o'clock in the morning until i will get home, sorry! Just in case anyone is interested), i blindly added another cert_username=steffen to the stuff in src/xsasl/xsasl_dovecot_server.c, and with that we will get the job done! So i added another "const char *certuser" and with that i can successfully use EXTERNAL authentication with postfix! Yay. However, my MUA also supports a "externanon" authentication which uses EXTERNAL with an empty immediate response, and that does not work out for now, but my code is currently in chaos, so that could also be it. Please find the first non-working approach in -try1.patch, the latter in -try2.patch. This is against v3.5.6. Of course i have no idea of the codebase say, let alone style, i hope i somehow got that tab/space .. hm ... Good night and a nice Sunday i wish! Ciao from Germany! --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) diff --git a/src/smtpd/smtpd_sasl_glue.c b/src/smtpd/smtpd_sasl_glue.c index 020c830..e16f1dc 100644 --- a/src/smtpd/smtpd_sasl_glue.c +++ b/src/smtpd/smtpd_sasl_glue.c @@ -288,15 +288,24 @@ int smtpd_sasl_authenticate(SMTPD_STATE *state, const char *sasl_method, const char *init_response) { -int status; +int flags, status; const char *sasl_username; +flags = 0; +#ifdef USE_TLS +if(state->tls_context != NULL){ + flags = XSASL_FLAG_SECURED; + if(TLS_CERT_IS_PRESENT(state->tls_context)) + flags |= XSASL_FLAG_CLIENT_CERT; +} +#endif + /* * SASL authentication protocol start-up. Process any initial client * response that was sent along in the AUTH command. */ for (status = xsasl_server_first(state->sasl_server, sasl_method, - init_response, state->sasl_reply); + init_response, state->sasl_reply, flags); status == XSASL_AUTH_MORE; status = xsasl_server_next(state->sasl_server, STR(state->buffer), state->sasl_reply)) { diff --git a/src/xsasl/xsasl.h b/src/xsasl/xsasl.h index b494d7e..a3c6bc9 100644
Re: TLS client certificates and auth external
Viktor Dukhovni wrote in <20200820163012.gl86...@straasha.imrryr.org>: |On Thu, Aug 20, 2020 at 10:59:06AM -0400, Wietse Venema wrote: | |> There's a chicken and egg question in there somewhere. |> |> https://wiki1.dovecot.org/Authentication%20Protocol mentions |> two attributes that might be relevant, and that Postfix can send: |> |> secured |> Remote user has secured transport to auth client] (eg. localhost, \ |> SSL, TLS) |> |> valid-client-cert |> Remote user has presented a valid SSL certificate. |> |> But these are booleans. What protocol attribute would Postfix use |> to pass certificate name information (and which name, as there |> can be any number of them)? | |For "EXTERNAL" to be applicable, Postfix would need to have a table |mapping client certificate fingerprints (or X.509 subject DNs, or even |specific SANs from trusted client certificates) to appropriate login |names. Or just leave it. Even if there is a mismatch in the name of the certificate and the name passed in the immediate response. That is totally ugly. I think the real power of EXTERNAL would come into play if the client certificate would be verified by the dovecot auth server, too. I.e., if all the details of user authentication would be handled there. |Which really means doing "EXTERNAL" directly in Postfix. There isn't |a good way of delegating EXTERNAL to another entity (i.e. Dovecot). What i still do not understand is why in things like smtpd_client_restrictions = check_ccert_access hash:/etc/postfix/relay_clientcert, permit_tls_clientcerts, permit_sasl_authenticated, reject the permit_tls_clientcerts does not cause the AUTH to be suppressed. I think there should at least be an option to allow skipping AUTH via SASL if the client certificate is correct. (I would not expect that the postfix side handling of client certificates vanishes even if SASL EXTERNAL becomes extended as envisioned in the other mail.) Good night. --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
Good evening from Germany. Please excuse the late reply, it is midsummer here and i spend as much time as possible on the outside (mostly bicycling). (And just one more day, then the weather will change and it will be 10 degrees colder.) Wietse Venema wrote in <4bxstk189nzj...@spike.porcupine.org>: |Steffen Nurpmeso: |> Wietse Venema wrote in |> <4bwxll093mzj...@spike.porcupine.org>: |>|Steffen Nurpmeso: |>|> I have no idea of the inner sensitivities of postfix, but i do not |>|> understand where the problem lies. Why does postfix "wave |>|> through" the SASL offering of EXTERNAL when it does not support |>|> it? (I have no idea of SASL library interfaces.) |>| |>|Short summary: Postfix does not implement a single iota of SASL |>|AUTH support. Postfix simply propagates the names of mechanisms |>|that the backend (Cyrus or Dovecot) claims to support, and Postfix ... |>|If Dovecot claims to support SASL EXTERNAL but does not handle it, |>|that that is a bit of a WTF. |> |> I see. So postfix sees the AUTH and then switches to SASL |> inclusive the immediate response and henceforth yields everything |> until SASL says it is done?!. How could EXTERNAL ever work like |> that in a client/server->auth-server situation? | |There's a chicken and egg question in there somewhere. | |https://wiki1.dovecot.org/Authentication%20Protocol mentions |two attributes that might be relevant, and that Postfix can send: | |secured |Remote user has secured transport to auth client] (eg. localhost, \ |SSL, TLS) | |valid-client-cert |Remote user has presented a valid SSL certificate. | |But these are booleans. What protocol attribute would Postfix use |to pass certificate name information (and which name, as there |can be any number of them)? So in the meantime i had posted to dovecot. I have not looked at the dovecot SASL wiki entry. So it seems postfixs SASL support can be improved a bit. And, well, i think for EXTERNAL there has to be user name as an immediate response, so this would be that. I would like to look into this tomorrow or on Saturday, maybe i can produce a patch that adds the above keywords to the postfix/ dovecot SASL interaction? --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
On Thu, Aug 20, 2020 at 10:59:06AM -0400, Wietse Venema wrote: > There's a chicken and egg question in there somewhere. > > https://wiki1.dovecot.org/Authentication%20Protocol mentions > two attributes that might be relevant, and that Postfix can send: > > secured > Remote user has secured transport to auth client] (eg. localhost, SSL, > TLS) > > valid-client-cert > Remote user has presented a valid SSL certificate. > > But these are booleans. What protocol attribute would Postfix use > to pass certificate name information (and which name, as there > can be any number of them)? For "EXTERNAL" to be applicable, Postfix would need to have a table mapping client certificate fingerprints (or X.509 subject DNs, or even specific SANs from trusted client certificates) to appropriate login names. Which really means doing "EXTERNAL" directly in Postfix. There isn't a good way of delegating EXTERNAL to another entity (i.e. Dovecot). -- Viktor.
Re: TLS client certificates and auth external
Steffen Nurpmeso: > Hello. > > Wietse Venema wrote in > <4bwxll093mzj...@spike.porcupine.org>: > |Steffen Nurpmeso: > |> I have no idea of the inner sensitivities of postfix, but i do not > |> understand where the problem lies. Why does postfix "wave > |> through" the SASL offering of EXTERNAL when it does not support > |> it? (I have no idea of SASL library interfaces.) > | > |Short summary: Postfix does not implement a single iota of SASL > |AUTH support. Postfix simply propagates the names of mechanisms > |that the backend (Cyrus or Dovecot) claims to support, and Postfix > |proxies requests and responses between the remote SMTP client and > |the SASL backend. Postfix has no idea what SASL mechanisms are, > |including EXTERNAL. It just proxies stuff. > | > |If Dovecot claims to support SASL EXTERNAL but does not handle it, > |that that is a bit of a WTF. > > I see. So postfix sees the AUTH and then switches to SASL > inclusive the immediate response and henceforth yields everything > until SASL says it is done?!. How could EXTERNAL ever work like > that in a client/server->auth-server situation? There's a chicken and egg question in there somewhere. https://wiki1.dovecot.org/Authentication%20Protocol mentions two attributes that might be relevant, and that Postfix can send: secured Remote user has secured transport to auth client] (eg. localhost, SSL, TLS) valid-client-cert Remote user has presented a valid SSL certificate. But these are booleans. What protocol attribute would Postfix use to pass certificate name information (and which name, as there can be any number of them)? Wietse Wietse
Re: TLS client certificates and auth external
Hello. Wietse Venema wrote in <4bwxll093mzj...@spike.porcupine.org>: |Steffen Nurpmeso: |> I have no idea of the inner sensitivities of postfix, but i do not |> understand where the problem lies. Why does postfix "wave |> through" the SASL offering of EXTERNAL when it does not support |> it? (I have no idea of SASL library interfaces.) | |Short summary: Postfix does not implement a single iota of SASL |AUTH support. Postfix simply propagates the names of mechanisms |that the backend (Cyrus or Dovecot) claims to support, and Postfix |proxies requests and responses between the remote SMTP client and |the SASL backend. Postfix has no idea what SASL mechanisms are, |including EXTERNAL. It just proxies stuff. | |If Dovecot claims to support SASL EXTERNAL but does not handle it, |that that is a bit of a WTF. I see. So postfix sees the AUTH and then switches to SASL inclusive the immediate response and henceforth yields everything until SASL says it is done?!. How could EXTERNAL ever work like that in a client/server->auth-server situation? |> Ie postfix is configured to check client certificates, why does |> it not "simply" allow the same configuration setting that dovecot |> supports, something like auth_ssl_username_from_cert=yes, then |> requires that for case(EXTERNAL) nothing but an empty immediate |> response is passed, then passed the user given in the certificate |> to the dovecot process? Or do also allow a username, but ensure |> the given one is identical to that specified in the certificate? | |Are you suggesting that we create new SASL protocol support in |Postfix to handle the EXTERNAL protocol inside Postfix? There |currently is no code in Postfix for any SASL mechanism at all. I am sorry to have blamed postfix for this. Looking at this by searching for cert_user in the dovecot source it seems what would be needed would be at least two new strings in the dovecot interaction, valid_cert (or so, forgotten) and cert_username, so that the authentication server can act accordingly (blindly trusting the correspondent, so to say)! I think i will unsubscribe here and go there, they have broken GSSAPI authentication with v2.3.11.3 (the ML thread already exists, however)! Thank you! P.S.: but regarding the list of mechanisms, postfix _does_ do something about it even as smtpd, especially xsasl_dovecot_server_mech_filter() cought my eye now? P.P.S.: while i am here, i wonder how LMDB support could ever worked for postfix. In 2018 i had implemented LMDB support for bogofilter, by then on AlpineLinux with musl C library. I looked around also in postfix (my plan was to have an all-LMDB based email chain), and saw (and see still) if ((status = mdb_env_create()) != 0) ... if ((status = mdb_env_set_mapsize(env, slmdb->curr_limit)) != 0 || (status = mdb_env_open(env, path, lmdb_flags, 0644)) != 0 but this caused reproducable crashes. It forced me to write an alternative implementation which does not resize at all. However that is optional and the original, resizing based approach was implemented (but we do not jump, we use a nice little cache): /* TODO We may not do this unless going for a huge fixed size, because with * TODO v0.9.22 a further DB open will then crash in mdb_*_put() after * TODO a growing _mapsize call! ... */ #ifdef a_BFLM_FIXED_SIZE e = mdb_env_set_mapsize(rv->bflm_env, a_BFLM_FIXED_SIZE); if(e != MDB_SUCCESS){ emsg = "mdb_env_set_mapsize()"; goto jerr2; } #endif e = mdb_env_open(rv->bflm_env, rv->bflm_filepath, MDB_NOSUBDIR, 0660); I.e., initial spacing caused later crashes, at least on this specific AlpineLinux (gcc / musl C) combination. But since the postfix user base is so large and noone reported a problem, i did not by then, too. Ciao from Germany! | Wietse --End of <4bwxll093mzj...@spike.porcupine.org> --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
Steffen Nurpmeso: > I have no idea of the inner sensitivities of postfix, but i do not > understand where the problem lies. Why does postfix "wave > through" the SASL offering of EXTERNAL when it does not support > it? (I have no idea of SASL library interfaces.) Short summary: Postfix does not implement a single iota of SASL AUTH support. Postfix simply propagates the names of mechanisms that the backend (Cyrus or Dovecot) claims to support, and Postfix proxies requests and responses between the remote SMTP client and the SASL backend. Postfix has no idea what SASL mechanisms are, including EXTERNAL. It just proxies stuff. If Dovecot claims to support SASL EXTERNAL but does not handle it, that that is a bit of a WTF. > Ie postfix is configured to check client certificates, why does > it not "simply" allow the same configuration setting that dovecot > supports, something like auth_ssl_username_from_cert=yes, then > requires that for case(EXTERNAL) nothing but an empty immediate > response is passed, then passed the user given in the certificate > to the dovecot process? Or do also allow a username, but ensure > the given one is identical to that specified in the certificate? Are you suggesting that we create new SASL protocol support in Postfix to handle the EXTERNAL protocol inside Postfix? There currently is no code in Postfix for any SASL mechanism at all. Wietse
Re: TLS client certificates and auth external
Hello. I am new to this list, and only come here to continue on this old thread. I have restored it from X-MARC-Message: https://marc.info/?l=postfix-users=155674111415072 so message-id etc. may not truly be correct, i apologise for that. And also, first, thank you for postfix, i use it for quite some years for my small private use cases, and it is working just fine! I have problems to deal with EXTERNAL authentification in conjunction with postfix, too. And whereas i personally like EXTERNAL very much, because i think that "client certificates everywhere" would be a good thing also for the IoT, so to say, my personal interest for now lies solely in proper (testing) support of the small MUA i maintain, for the EXTERNAL authentification. I have no idea of the inner sensitivities of postfix, but i do not understand where the problem lies. Why does postfix "wave through" the SASL offering of EXTERNAL when it does not support it? (I have no idea of SASL library interfaces.) If postfix is configured to check client certificates, why does it not "simply" allow the same configuration setting that dovecot supports, something like auth_ssl_username_from_cert=yes, then requires that for case(EXTERNAL) nothing but an empty immediate response is passed, then passed the user given in the certificate to the dovecot process? Or do also allow a username, but ensure the given one is identical to that specified in the certificate? My explanation last year (when in implemented EXTERNAL authentification for my MUA) was that due to the many-process approach of postfix the relevant information is not available? But today, "running against this problem" again, i can hardly believe that the I/O is decoupled so extensively. Having said all that, i simply assume that SASL takes only a user name and a password, hm. Aug 19 18:36:11 arch-2020 postfix/smtpd[4684]: connect from _gateway[10.0.0.1] Aug 19 18:36:11 arch-2020 dovecot[3229]: auth: Debug: client in: AUTH 2EXTERNALservice=smtpnologinlip=10.0.1.11 rip=10.0.0.1securedresp= Aug 19 18:36:11 arch-2020 dovecot[3229]: auth: external(?,10.0.0.1): username not known Aug 19 18:36:11 arch-2020 dovecot[3229]: auth: Debug: auth(?,10.0.0.1): Auth request finished Aug 19 18:36:13 arch-2020 postfix/smtpd[4684]: warning: _gateway[10.0.0.1]: SASL EXTERNAL authentication failed: Aug 19 18:36:13 arch-2020 dovecot[3229]: auth: Debug: client passdb out: FAIL 2 Aug 19 18:36:13 arch-2020 postfix/smtpd[4684]: 0E5B240511: client=_gateway[10.0.0.1] When i use EXTERNAL for IMAP and POP3, directly via dovecot that is, then i see a cert_username= as well as valid-client-cert passing by in the log. Like i said, i have never looked behind these scenes of SASL, dovecot auth and postfix source code. Another thing i do not understand is that _when_ i do have permit_tls_clientcerts, and the client certificate matches, that AUTHs are still announced and required. (However, if i turn off smtpd_sasl_auth_enable=yes then not, ... of course.) Whereas it does not help me and my EXTERNAL support, i think it would be sensible to offer such a configuration possibility? Thanks in advance, and Ciao and good night from Germany, --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: TLS client certificates and auth external
On 01/05/2019 22:04, Viktor Dukhovni wrote: > On Wed, May 01, 2019 at 09:57:29PM +0200, John Fawcett wrote: > >>> virtual_alias_maps = { >>> hash:/etc/postfix/virtual, >>> { search = full, full-noext, localpart-if-local, at-domain } >>> } { >>> other table ... >>> } >>> >>> Ditto for canonical_maps and transport_maps. >>> >>> This would be a compatibility break, because with the above, all >>> virtual_alias_maps searches are done on the first table before >>> trying the next table. One could argue that current behavior is >>> non-intuitive. >> If virtual_alias_maps are the only place where postfix searches for a >> pattern across multiple tables before passing on to the next pattern >> then it should not be too much of a surprise to bring it in line with >> the rest of the lookup logic. > As mentioned above, it is not just virtual aliases, but the proposed > compatibility break is likely what most users actually expect, and > then have to learn the actual non-intuitive behaviour. Thanks for clarifying. I had missed that. I can only answer for myself, but still it would be no issue even if the search order is changed for all these because I tend to use single tables. I do use multiple tables in local_recipient_maps but for lists it does not make any difference to the result if the search order is changed. John
Re: TLS client certificates and auth external
On Wed, May 01, 2019 at 09:57:29PM +0200, John Fawcett wrote: > > virtual_alias_maps = { > > hash:/etc/postfix/virtual, > > { search = full, full-noext, localpart-if-local, at-domain } > > } { > > other table ... > > } > > > > Ditto for canonical_maps and transport_maps. > > > > This would be a compatibility break, because with the above, all > > virtual_alias_maps searches are done on the first table before > > trying the next table. One could argue that current behavior is > > non-intuitive. > If virtual_alias_maps are the only place where postfix searches for a > pattern across multiple tables before passing on to the next pattern > then it should not be too much of a surprise to bring it in line with > the rest of the lookup logic. As mentioned above, it is not just virtual aliases, but the proposed compatibility break is likely what most users actually expect, and then have to learn the actual non-intuitive behaviour. > Though personally I would vote for the incompatible change. I also would support the compatibility break. The proposed new behaviour is more intuitive, and I think more useful. When the first table has a matching "partial" key, and the second table has a matching "full" key. I would still expect the first table to win, with the second table consulted only when the first table would yield no result on its own. -- Viktor.
Re: TLS client certificates and auth external
On 28/04/2019 21:49, Wietse Venema wrote: > ... > > Once the above is implemented, the same approach could be used to > improve other parts of Postfix by making existing hard-coded behavior > configurable, for example how check_client_access looks up subnet > and partial address information, or how virtual_alias_maps looks > up full and partial address forms. The examples below show the > lookup order that is currently hard-coded. > > smtpd_mumble_restrictions = > ... > check_client_access { > maptype:mapname, > # instead of parent, maybe use dot-parent or no parent > { search = domain, parent, address, subnet } > } > ... > > virtual_alias_maps = { > hash:/etc/postfix/virtual, > { search = full, full-noext, localpart-if-local, at-domain } > } { > other table ... > } > > Ditto for canonical_maps and transport_maps. > > This would be a compatibility break, because with the above, all > virtual_alias_maps searches are done on the first table before > trying the next table. One could argue that current behavior is > non-intuitive. > > > > Wietse Sounds like a good idea which should make the code more robust by removing hard coded logic in multiple places. If virtual_alias_maps are the only place where postfix searches for a pattern across multiple tables before passing on to the next pattern then it should not be too much of a surprise to bring it in line with the rest of the lookup logic. I guess that virtual_alias_maps configurations with multiple tables are less common than those with a single table. However, if strong reasons come out against the change, the search order could be configurable either "horizontally" across multiple tables or "vertically" into single tables. It would just mean sorting the name_code vector a different way from the default. Though personally I would vote for the incompatible change. John
Re: TLS client certificates and auth external
Continuing the discussion of a strawman user interface, I see some opportunities to generalize this and to make some improvements elsewhere in Postfix. We start with Postfix access control based on client certificate feartures: smtpd_mumble_restrictions = ... check_tls_access { maptype:mapname, { search = rfc822name, subject_dn, smtputf8mailbox, ... } } ... where the 'search' attribute specifies a list with one or more of rfc822name, subject_dn, smtputf8mailbox, key_fingerprint, and so on. This requires new infrastructure that converts the 'search' list into a list of named constants (internally, a vector of NAME_CODE results). check_tls_access is then implemented as a loop over the internal form of the search list. So far, so good. Would this syntax also be useful for other Postfix features? It would be good if it does. Here's a strawman inside a strawman. Once the above is implemented, the same approach could be used to improve other parts of Postfix by making existing hard-coded behavior configurable, for example how check_client_access looks up subnet and partial address information, or how virtual_alias_maps looks up full and partial address forms. The examples below show the lookup order that is currently hard-coded. smtpd_mumble_restrictions = ... check_client_access { maptype:mapname, # instead of parent, maybe use dot-parent or no parent { search = domain, parent, address, subnet } } ... virtual_alias_maps = { hash:/etc/postfix/virtual, { search = full, full-noext, localpart-if-local, at-domain } } { other table ... } Ditto for canonical_maps and transport_maps. This would be a compatibility break, because with the above, all virtual_alias_maps searches are done on the first table before trying the next table. One could argue that current behavior is non-intuitive. Another possible benefit: this syntax may be useful to support substring queries with 'postmap -q'. To make the main.cf configuration easier to use, the config file parser could be modified to process '}' at the start of a line as the continuation of the preceding line. This would be a simple change. Wietse
Re: TLS client certificates and auth external
Zitat von Viktor Dukhovni : On Apr 19, 2019, at 1:10 PM, Wietse Venema wrote: Using a name instead of cert fingerprint also requires revocation checking. Cert revocation is not needed, as long as there is an an explicit mapping like: certificate identity -> permit/etc action certificate identity -> ersatz SASL login name By removing such a mapping, one can 'revoke' the privileges that were associated with the certificate.' My thoughts exactly! We should probably document this: Note: No revocation checks are performed. To revoke privileges, remove the table entry matching a given certificate or "subject". As for "CN" matching, I'm concerned that multiple certificates can have the same CN, which is not required unique, especially if the certificates have different "O" or "OU" values. What's more likely to be unique is an rfc822Name subjectAlternative name, or the full subject DN. More recently, we also have SmtpUTF8Mailbox: https://tools.ietf.org/html/rfc8398#section-3 So I think that more thought needs to go into what lookup key or keys are extract from the candidate certificates. This may need to be configurable, or we could try: 1. The full subject DN (in RFC2854 form, suitably quoted). 2. Each rfc822Name SAN. 3. Each SmtpUTF8Mailbox (note U-label domain part). The multiple certificates with one common CN would be a feature in my case. We need to relay O365 mail and don't want to open the whole IP space used by O365 which is changing anyway. So the plan was to use the common CN for the whole outgoing servers. One example is: Apr 17 17:03:45 mailin postfix/smtpd[6909]: mail-ve1eur02lp0207.outbound.protection.outlook.com[2a01:111:f400:7e06::207]: depth=0 verify=1 subject=/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=mail.protection.outlook.com There are many DNS names an the full subject is also different, but to my knowledge we always have "CN=mail.protection.outlook.com" The question is if the CAs check/validate the CN and protect it against misuse. Andreas
Re: TLS client certificates and auth external
Viktor Dukhovni: > > Cert revocation is not needed, as long as there is an an explicit > > mapping like: > > > >certificate identity -> permit/etc action > >certificate identity -> ersatz SASL login name > > > > By removing such a mapping, one can 'revoke' the privileges that > > were associated with the certificate.' > > My thoughts exactly! We should probably document this: > > Note: No revocation checks are performed. To revoke privileges, > remove the table entry matching a given certificate or "subject". > > As for "CN" matching, I'm concerned that multiple certificates can have > the same CN, which is not required unique, especially if the certificates > have different "O" or "OU" values. What's more likely to be unique is > an rfc822Name subjectAlternative name, or the full subject DN. More > recently, we also have SmtpUTF8Mailbox: > > https://tools.ietf.org/html/rfc8398#section-3 > > So I think that more thought needs to go into what lookup key or > keys are extract from the candidate certificates. This may need > to be configurable, or we could try: > > 1. The full subject DN (in RFC2854 form, suitably quoted). > 2. Each rfc822Name SAN. > 3. Each SmtpUTF8Mailbox (note U-label domain part). Here is a strawman user interface, similar to smtpd_milters: smtpd_mumble_restrictions = ... check_access { maptype:mapname, { search = rfc822name, cccert_dn } } ... where the 'search' attribute specifies a list with one or more of rfc822name, cccert_dn, ccert_key_fingerprint, and so on. The check_access 'search' attribute would not need to be specific to TLS at all; the search list could specify other things: check_access { maptype:mapname, search=client } which is equivalent to "check_client_access maptype:mapname". Or we could ignore the opportunity for generalization and call it check_tls_access. The only real work is to implement support for a set of named integers (internally, a vector of NAME_CODE results). The rest of the work would be writing trivial wrappers, and documenting this. Wietse
Re: TLS client certificates and auth external
On 4/20/19 1:09 AM, Viktor Dukhovni wrote: On Apr 19, 2019, at 6:42 PM, Michael Ströder wrote: If a cert's key get compromised (e.g. laptop lost/stolen) I expect the user's cert to be revoked and a new cert to be issued for the *same* subject name. How to deal with that without revocation check? > Delete the name match, and match by the key fingerprint until the old certificate is expired. Then go back to name checks. Sounds complicated to get that right. I think that people are asking for this feature because they just want to issue a new cert and *not* deal with any postfix map update. CRLs don't make for reliable infrastructure. My view is that, pretending otherwise would be disservice to the Postfix user community. It is much easier to update the Postfix tables than to provision a working CRL infrastructure. I have no plans to spend any time working on CRL support to Postfix. Fair enough. Personally I'd continue to use fingerprints anyway. I'm rather questioning whether it's worth the effort to implement something else. Ciao, Michael. smime.p7s Description: S/MIME Cryptographic Signature
Re: TLS client certificates and auth external
> On Apr 19, 2019, at 6:42 PM, Michael Ströder wrote: > > If a cert's key get compromised (e.g. laptop lost/stolen) I expect the user's > cert to be revoked and a new cert to be issued for the *same* subject name. > How to deal with that without revocation check? Delete the name match, and match by the key fingerprint until the old certificate is expired. Then go back to name checks. > I think that people are asking for this feature because they just want to > issue > a new cert and *not* deal with any postfix map update. CRLs don't make for reliable infrastructure. My view is that, pretending otherwise would be disservice to the Postfix user community. It is much easier to update the Postfix tables than to provision a working CRL infrastructure. I have no plans to spend any time working on CRL support to Postfix. -- -- Viktor.
Re: TLS client certificates and auth external
On 4/19/19 7:10 PM, Wietse Venema wrote: Michael Str?der: On 4/18/19 9:45 PM, Viktor Dukhovni wrote: On Apr 18, 2019, at 12:01 PM, Wietse Venema wrote: Eventually there will be a postfix--nonprod release that combines all the code (jay) and none of the guarantees (bleh). I am not convinced that stuffing arbitrary PKI identities into a SASL identity is necessarily a good idea. Maybe it is safer to solve this problem without PKI-to-SASL cross-talk. I would expect the mapping to be indirect. That is, a table lookup key of either the client public key fingerprint to a SASL name (roughly what we have now, but with an explicit RHS indicating the desired SASL identity), or else the client's subject name in a standard (likely RFC2254) form, again mapped to the desired identity, provided the client certificate is from a trusted PKI issuer. Using a name instead of cert fingerprint also requires revocation checking. Cert revocation is not needed, as long as there is an an explicit mapping like: certificate identity -> permit/etc action certificate identity -> ersatz SASL login name By removing such a mapping, one can 'revoke' the privileges that were associated with the certificate. If a cert's key get compromised (e.g. laptop lost/stolen) I expect the user's cert to be revoked and a new cert to be issued for the *same* subject name. How to deal with that without revocation check? I think that people are asking for this feature because they just want to issue a new cert and *not* deal with any postfix map update. Maybe I'm missing something though. Ciao, Michael. smime.p7s Description: S/MIME Cryptographic Signature
Re: TLS client certificates and auth external
> On Apr 19, 2019, at 1:10 PM, Wietse Venema wrote: > >> Using a name instead of cert fingerprint also requires revocation checking. > > Cert revocation is not needed, as long as there is an an explicit > mapping like: > >certificate identity -> permit/etc action >certificate identity -> ersatz SASL login name > > By removing such a mapping, one can 'revoke' the privileges that > were associated with the certificate.' My thoughts exactly! We should probably document this: Note: No revocation checks are performed. To revoke privileges, remove the table entry matching a given certificate or "subject". As for "CN" matching, I'm concerned that multiple certificates can have the same CN, which is not required unique, especially if the certificates have different "O" or "OU" values. What's more likely to be unique is an rfc822Name subjectAlternative name, or the full subject DN. More recently, we also have SmtpUTF8Mailbox: https://tools.ietf.org/html/rfc8398#section-3 So I think that more thought needs to go into what lookup key or keys are extract from the candidate certificates. This may need to be configurable, or we could try: 1. The full subject DN (in RFC2854 form, suitably quoted). 2. Each rfc822Name SAN. 3. Each SmtpUTF8Mailbox (note U-label domain part). -- Viktor.
Re: TLS client certificates and auth external
Michael Str?der: > On 4/18/19 9:45 PM, Viktor Dukhovni wrote: > >> On Apr 18, 2019, at 12:01 PM, Wietse Venema wrote: > >> > >> Eventually there will be a postfix--nonprod release that combines > >> all the code (jay) and none of the guarantees (bleh). > >> > >> I am not convinced that stuffing arbitrary PKI identities into a > >> SASL identity is necessarily a good idea. Maybe it is safer to solve > >> this problem without PKI-to-SASL cross-talk. > > > > I would expect the mapping to be indirect. That is, a table lookup > > key of either the client public key fingerprint to a SASL name (roughly > > what we have now, but with an explicit RHS indicating the desired SASL > > identity), or else the client's subject name in a standard (likely > > RFC2254) form, again mapped to the desired identity, provided the > > client certificate is from a trusted PKI issuer. > > Using a name instead of cert fingerprint also requires revocation checking. Cert revocation is not needed, as long as there is an an explicit mapping like: certificate identity -> permit/etc action certificate identity -> ersatz SASL login name By removing such a mapping, one can 'revoke' the privileges that were associated with the certificate. Wietse
Re: TLS client certificates and auth external
On 4/18/19 9:45 PM, Viktor Dukhovni wrote: On Apr 18, 2019, at 12:01 PM, Wietse Venema wrote: Eventually there will be a postfix--nonprod release that combines all the code (jay) and none of the guarantees (bleh). I am not convinced that stuffing arbitrary PKI identities into a SASL identity is necessarily a good idea. Maybe it is safer to solve this problem without PKI-to-SASL cross-talk. I would expect the mapping to be indirect. That is, a table lookup key of either the client public key fingerprint to a SASL name (roughly what we have now, but with an explicit RHS indicating the desired SASL identity), or else the client's subject name in a standard (likely RFC2254) form, again mapped to the desired identity, provided the client certificate is from a trusted PKI issuer. Using a name instead of cert fingerprint also requires revocation checking. Ciao, Michael. smime.p7s Description: S/MIME Cryptographic Signature
Re: TLS client certificates and auth external
lst_ho...@kwsoft.de: > > Zitat von Wietse Venema : > > > lst_ho...@kwsoft.de: > >> What is the way to go to take part of the feature development? I looks > >> like we need a slight modification of the auth external as described. > > > > Mailin glist discussions. > > > > Eventually there will be a postfix--nonprod release that combines > > all the code (jay) and none of the guarantees (bleh). > > > > I am not convinced that stuffing arbitrary PKI identities into a > > SASL identity is necessarily a good idea. Maybe it is safer to solve > > this problem without PKI-to-SASL cross-talk. > > At least in my case no SASL would be needed. For me a > relay_clientcerts able to list allowed validated CNs would be enough. > The SASL stuff will be handy for tie a "identity" to certificates and > assign additional rights/limits of course. One SASL-less option that I can think of is check_cname_access: map the CNAME to an action. Requires that the certificate is verified. Would that work? Thius approach avoids the mixing of PKI identities and SASL identities. Implementation note: this would require that check_cname_access looks up a quoted string if the CNAME contains spaces. The postnap command understands quoted strings as of Postfix 3.2. Wietse
Re: TLS client certificates and auth external
Le 18/04/2019 à 21:45, Viktor Dukhovni a écrit : On Apr 18, 2019, at 12:01 PM, Wietse Venema wrote: Eventually there will be a postfix--nonprod release that combines all the code (jay) and none of the guarantees (bleh). I am not convinced that stuffing arbitrary PKI identities into a SASL identity is necessarily a good idea. Maybe it is safer to solve this problem without PKI-to-SASL cross-talk. I would expect the mapping to be indirect. That is, a table lookup key of either the client public key fingerprint to a SASL name (roughly what we have now, but with an explicit RHS indicating the desired SASL identity), or else the client's subject name in a standard (likely RFC2254) form, again mapped to the desired identity, provided the client certificate is from a trusted PKI issuer. Yes I agree. The proposed sasl provider dance is for a quick hack to not have to implement the client subject name table lookup. Emmanuel.
Re: TLS client certificates and auth external
> On Apr 18, 2019, at 12:01 PM, Wietse Venema wrote: > > Eventually there will be a postfix--nonprod release that combines > all the code (jay) and none of the guarantees (bleh). > > I am not convinced that stuffing arbitrary PKI identities into a > SASL identity is necessarily a good idea. Maybe it is safer to solve > this problem without PKI-to-SASL cross-talk. I would expect the mapping to be indirect. That is, a table lookup key of either the client public key fingerprint to a SASL name (roughly what we have now, but with an explicit RHS indicating the desired SASL identity), or else the client's subject name in a standard (likely RFC2254) form, again mapped to the desired identity, provided the client certificate is from a trusted PKI issuer. -- Viktor.
Re: TLS client certificates and auth external
Zitat von Wietse Venema : lst_ho...@kwsoft.de: What is the way to go to take part of the feature development? I looks like we need a slight modification of the auth external as described. Mailin glist discussions. Eventually there will be a postfix--nonprod release that combines all the code (jay) and none of the guarantees (bleh). I am not convinced that stuffing arbitrary PKI identities into a SASL identity is necessarily a good idea. Maybe it is safer to solve this problem without PKI-to-SASL cross-talk. Wietse At least in my case no SASL would be needed. For me a relay_clientcerts able to list allowed validated CNs would be enough. The SASL stuff will be handy for tie a "identity" to certificates and assign additional rights/limits of course. Andreas
Re: TLS client certificates and auth external
lst_ho...@kwsoft.de: > What is the way to go to take part of the feature development? I looks > like we need a slight modification of the auth external as described. Mailin glist discussions. Eventually there will be a postfix--nonprod release that combines all the code (jay) and none of the guarantees (bleh). I am not convinced that stuffing arbitrary PKI identities into a SASL identity is necessarily a good idea. Maybe it is safer to solve this problem without PKI-to-SASL cross-talk. Wietse
Re: TLS client certificates and auth external
Zitat von Emmanuel Fusté : You need the relay_clientcerts map with relay_clientcerts_auto mode. Put the fingerprint or pkey_fingerprint and the mapped SASL identity in the file and it will work For example: 43:B6:FE:07:BB:2E:BF:86:8A:4D:2A:DD:78:07:09:C6 xxx.kwsoft.de Will try that, but for our final use case we have no way fix the fingerprint of the remote client, it can change any time. The only thing which should stay is the CN. smtpd_tls_loglevel = 2 smtpd_tls_ask_ccert = yes smtpd_sasl_auth_enable = yes smtpd_use_tls=yes smtpd_tls_CApath = /etc/ssl/certs But this leads to Apr 18 11:46:05 linux-test postfix/smtpd[4257]: kw-tools.hq.kwsoft.de[10.1.7.15]: subject_CN=xxx.kwsoft.de, issuer=SwissSign Server Silver CA 2014 - G22, fingerprint=B8:D9:ED:1F:33:FE:DB:36:11:A6:D9:3F:BA:B5:1D:44, pkey_fingerprint=43:B6:FE:07:BB:2E:BF:86:8A:4D:2A:DD:78:07:09:C6 Apr 18 11:46:05 linux-test postfix/smtpd[4257]: Trusted TLS connection established from kw-tools.hq.kwsoft.de[10.1.7.15]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) Apr 18 11:46:05 linux-test postfix/smtpd[4257]: NOQUEUE: reject: RCPT from kw-tools.hq.kwsoft.de[10.1.7.15]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo= Apr 18 11:46:05 linux-test postfix/smtpd[4257]: disconnect from kw-tools.hq.kwsoft.de[10.1.7.15] ehlo=2 starttls=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1 commands=6/8 What i actually need is relaying based on validated certificate CN without forcing the client to use some form of authentication, so this would basically mean relay_clientcerts with CN lookup key or a relay_clientcerts_auto_cn to always skip AUTH and use the CN as username i guess. Yes, if you don't want fingerprint to something maps, you need a "commonName_auto" mode which rely on SASL external provider to validate the user (provide the map of valid users) but auto triggered. For that, you need to invoke SASL external auth directly in the smtpd sasl glue code as it is in the processing of the AUTH verb (a simplified single step version). Will look at it if I have time, but I prefer to wait Viktor/Wietse comments before. Emmanuel. Thanks, so i will wait for comment if we can include our special case also. Andreas
Re: TLS client certificates and auth external
Le 18/04/2019 à 12:05, lst_ho...@kwsoft.de a écrit : Zitat von Emmanuel Fusté : Hello, Great piece of work ! It solve a big part of my problem, but sadly I need to go deeper. Le 18/03/2019 à 22:45, Bastian Schmidt a écrit : In the meantime I have completed a patch and sent it to Wietse and Victor, which adds an option smtpd_sasl_tls_ccert_username. As the patch is rather small, I also attached it to this message. This smtpd_sasl_tls_ccert_username option can be used in the following way: Using smtpd_sasl_tls_ccert_username = commonName After providing a verified client certificate, postfix advertises auth external and the user can authenticate with the username being the commonName of the certificate. This is for users having control over the CA issuing the certificates and resembles the way cyrus imap handles the situation. Using smtpd_sasl_tls_ccert_username = relay_clientcerts When a client presents a certificate, where the fingerprint matches in relay_clientcerts, the lookup value (previously unused) is used to get the username for sasl. The client can then perform an auth external with this username successfully. This is a solution for users, which cannot control the CAs or do not want to trust them or cope with crls, ... It fits in the way postfix currently handles client certificates. I have to deal with products that do not support SMTP AUTH (big email security appliance provider .) but are able to present a TLS certificate. On my platform, the use of the smtpd_sender_login_maps and associated restrictions (reject_sender_login_mismatch) is mandatory to achieve our goal. At first, I was thinking about using the lookup value of relay_clientcerts to map a sasl username. It is nicely done with your patch with smtpd_sasl_tls_ccert_username = relay_clientcerts, but I need to go one step further: I need to completely bypass the sasl provider call and act as if the mapped user successfully authenticate. It would be something like "smtpd_sasl_tls_ccert_username = relay_clientcerts_nosasl" or relay_clientcerts_saslbypass or other (I'm not good at finding good option naming ...) The goal is to be as transparent as possible : - if the client is not found in the relay_clientcerts, act as usual - if the client is found in the relay_clientcerts, no longer announce AUTH support, the auth and identity mapping is already done by the relay_clientcerts map I think it is not a big code complexity addition on top of your work, but before going further I would like to request for comments about this. Viktor, Wietse, would you accept such addition ? Emmanuel. I tested this with a patched postfix for my usage scenario (relaying based on validated CN) but i fail to get it work. Note that i don't need a sasl username at all, but also tested with sasl username and check_sasl_access. The config basically looks like this: smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, check_sasl_access hash://etc/postfix/check_sasl_access, defer_unauth_destination # tested both #smtpd_sasl_tls_ccert_username = commonName smtpd_sasl_tls_ccert_username = relay_clientcerts_auto #relay_clientcerts = hash://etc/postfix/relay_clientcerts You need the relay_clientcerts map with relay_clientcerts_auto mode. Put the fingerprint or pkey_fingerprint and the mapped SASL identity in the file and it will work For example: 43:B6:FE:07:BB:2E:BF:86:8A:4D:2A:DD:78:07:09:C6 xxx.kwsoft.de smtpd_tls_loglevel = 2 smtpd_tls_ask_ccert = yes smtpd_sasl_auth_enable = yes smtpd_use_tls=yes smtpd_tls_CApath = /etc/ssl/certs But this leads to Apr 18 11:46:05 linux-test postfix/smtpd[4257]: kw-tools.hq.kwsoft.de[10.1.7.15]: subject_CN=xxx.kwsoft.de, issuer=SwissSign Server Silver CA 2014 - G22, fingerprint=B8:D9:ED:1F:33:FE:DB:36:11:A6:D9:3F:BA:B5:1D:44, pkey_fingerprint=43:B6:FE:07:BB:2E:BF:86:8A:4D:2A:DD:78:07:09:C6 Apr 18 11:46:05 linux-test postfix/smtpd[4257]: Trusted TLS connection established from kw-tools.hq.kwsoft.de[10.1.7.15]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) Apr 18 11:46:05 linux-test postfix/smtpd[4257]: NOQUEUE: reject: RCPT from kw-tools.hq.kwsoft.de[10.1.7.15]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo= Apr 18 11:46:05 linux-test postfix/smtpd[4257]: disconnect from kw-tools.hq.kwsoft.de[10.1.7.15] ehlo=2 starttls=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1 commands=6/8 What i actually need is relaying based on validated certificate CN without forcing the client to use some form of authentication, so this would basically mean relay_clientcerts with CN lookup key or a relay_clientcerts_auto_cn to always skip AUTH and use the CN as username i guess. Yes, if you don't want fingerprint to something maps, you need a "commonName_auto" mode which rely on SASL external provider to validate the user (provide the map of valid users) but auto triggered. For that, you need to
Re: TLS client certificates and auth external
Zitat von Emmanuel Fusté : Hello, Great piece of work ! It solve a big part of my problem, but sadly I need to go deeper. Le 18/03/2019 à 22:45, Bastian Schmidt a écrit : In the meantime I have completed a patch and sent it to Wietse and Victor, which adds an option smtpd_sasl_tls_ccert_username. As the patch is rather small, I also attached it to this message. This smtpd_sasl_tls_ccert_username option can be used in the following way: Using smtpd_sasl_tls_ccert_username = commonName After providing a verified client certificate, postfix advertises auth external and the user can authenticate with the username being the commonName of the certificate. This is for users having control over the CA issuing the certificates and resembles the way cyrus imap handles the situation. Using smtpd_sasl_tls_ccert_username = relay_clientcerts When a client presents a certificate, where the fingerprint matches in relay_clientcerts, the lookup value (previously unused) is used to get the username for sasl. The client can then perform an auth external with this username successfully. This is a solution for users, which cannot control the CAs or do not want to trust them or cope with crls, ... It fits in the way postfix currently handles client certificates. I have to deal with products that do not support SMTP AUTH (big email security appliance provider .) but are able to present a TLS certificate. On my platform, the use of the smtpd_sender_login_maps and associated restrictions (reject_sender_login_mismatch) is mandatory to achieve our goal. At first, I was thinking about using the lookup value of relay_clientcerts to map a sasl username. It is nicely done with your patch with smtpd_sasl_tls_ccert_username = relay_clientcerts, but I need to go one step further: I need to completely bypass the sasl provider call and act as if the mapped user successfully authenticate. It would be something like "smtpd_sasl_tls_ccert_username = relay_clientcerts_nosasl" or relay_clientcerts_saslbypass or other (I'm not good at finding good option naming ...) The goal is to be as transparent as possible : - if the client is not found in the relay_clientcerts, act as usual - if the client is found in the relay_clientcerts, no longer announce AUTH support, the auth and identity mapping is already done by the relay_clientcerts map I think it is not a big code complexity addition on top of your work, but before going further I would like to request for comments about this. Viktor, Wietse, would you accept such addition ? Emmanuel. I tested this with a patched postfix for my usage scenario (relaying based on validated CN) but i fail to get it work. Note that i don't need a sasl username at all, but also tested with sasl username and check_sasl_access. The config basically looks like this: smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, check_sasl_access hash://etc/postfix/check_sasl_access, defer_unauth_destination # tested both #smtpd_sasl_tls_ccert_username = commonName smtpd_sasl_tls_ccert_username = relay_clientcerts_auto #relay_clientcerts = hash://etc/postfix/relay_clientcerts smtpd_tls_loglevel = 2 smtpd_tls_ask_ccert = yes smtpd_sasl_auth_enable = yes smtpd_use_tls=yes smtpd_tls_CApath = /etc/ssl/certs But this leads to Apr 18 11:46:05 linux-test postfix/smtpd[4257]: kw-tools.hq.kwsoft.de[10.1.7.15]: subject_CN=xxx.kwsoft.de, issuer=SwissSign Server Silver CA 2014 - G22, fingerprint=B8:D9:ED:1F:33:FE:DB:36:11:A6:D9:3F:BA:B5:1D:44, pkey_fingerprint=43:B6:FE:07:BB:2E:BF:86:8A:4D:2A:DD:78:07:09:C6 Apr 18 11:46:05 linux-test postfix/smtpd[4257]: Trusted TLS connection established from kw-tools.hq.kwsoft.de[10.1.7.15]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) Apr 18 11:46:05 linux-test postfix/smtpd[4257]: NOQUEUE: reject: RCPT from kw-tools.hq.kwsoft.de[10.1.7.15]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo= Apr 18 11:46:05 linux-test postfix/smtpd[4257]: disconnect from kw-tools.hq.kwsoft.de[10.1.7.15] ehlo=2 starttls=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1 commands=6/8 What i actually need is relaying based on validated certificate CN without forcing the client to use some form of authentication, so this would basically mean relay_clientcerts with CN lookup key or a relay_clientcerts_auto_cn to always skip AUTH and use the CN as username i guess. Any other idea? Thanks Andreas Any othe idea
Re: TLS client certificates and auth external
Zitat von Wietse Venema : lst_ho...@kwsoft.de: This sounds like the feature we will need. I doubt the client would be able to do real AUTH, but we have to trust/relay based on the CN of a validated certificate. Is there any progress merging this in the 3.5 line or do i have to poke around with patches some longer? Yes and yes. It is ready when it is ready. Wietser What is the way to go to take part of the feature development? I looks like we need a slight modification of the auth external as described. Thanks Andreas
Re: TLS client certificates and auth external
lst_ho...@kwsoft.de: > This sounds like the feature we will need. I doubt the client would be > able to do real AUTH, but we have to trust/relay based on the CN of a > validated certificate. Is there any progress merging this in the 3.5 > line or do i have to poke around with patches some longer? Yes and yes. It is ready when it is ready. Wietser
Re: TLS client certificates and auth external
Zitat von Emmanuel Fusté : Le 27/03/2019 à 18:10, Emmanuel Fusté a écrit : Le 27/03/2019 à 17:14, Viktor Dukhovni a écrit : On Wed, Mar 27, 2019 at 04:31:33PM +0100, Emmanuel Fusté wrote: The goal is to be as transparent as possible : - if the client is not found in the relay_clientcerts, act as usual - if the client is found in the relay_clientcerts, no longer announce AUTH support, the auth and identity mapping is already done by the relay_clientcerts map I believe you're asking Postfix to (when configured to do that) simulate "AUTH EXTERNAL" when the client has presented a client certificate, but proceeds from "EHLO" to "MAIL FROM" with no intevening explicit "AUTH". Yes exactly, if a hash to sasl id/username mapping is found in the relay_clientcerts The simulated "AUTH EXTERNAL" would never "fail" (5XX), it either yields an authenticated user or proceeds with the user unauthenticated, and acts accordingly. Does that sound right? Yes, in case of unauthenticated (not present in relay_clientcerts), the simulated "AUTH EXTERNAL" must ideally not be performed and AUTH support be announced as usual as this is perhaps a client with proper AUTH support (otherwise it would be listed with a mapping in relay_clientcerts). Ok, patch attached. Need to be applied on top of Bastian one. Work well here, thanks to the hard part done by Bastian ! Please comment. Emmanuel. This sounds like the feature we will need. I doubt the client would be able to do real AUTH, but we have to trust/relay based on the CN of a validated certificate. Is there any progress merging this in the 3.5 line or do i have to poke around with patches some longer? Thanks Andreas
Re: TLS client certificates and auth external
Le 27/03/2019 à 18:10, Emmanuel Fusté a écrit : Le 27/03/2019 à 17:14, Viktor Dukhovni a écrit : On Wed, Mar 27, 2019 at 04:31:33PM +0100, Emmanuel Fusté wrote: The goal is to be as transparent as possible : - if the client is not found in the relay_clientcerts, act as usual - if the client is found in the relay_clientcerts, no longer announce AUTH support, the auth and identity mapping is already done by the relay_clientcerts map I believe you're asking Postfix to (when configured to do that) simulate "AUTH EXTERNAL" when the client has presented a client certificate, but proceeds from "EHLO" to "MAIL FROM" with no intevening explicit "AUTH". Yes exactly, if a hash to sasl id/username mapping is found in the relay_clientcerts The simulated "AUTH EXTERNAL" would never "fail" (5XX), it either yields an authenticated user or proceeds with the user unauthenticated, and acts accordingly. Does that sound right? Yes, in case of unauthenticated (not present in relay_clientcerts), the simulated "AUTH EXTERNAL" must ideally not be performed and AUTH support be announced as usual as this is perhaps a client with proper AUTH support (otherwise it would be listed with a mapping in relay_clientcerts). Ok, patch attached. Need to be applied on top of Bastian one. Work well here, thanks to the hard part done by Bastian ! Please comment. Emmanuel. --- postfix-3.4.5/src/smtpd/smtpd_sasl_glue.c 2019-04-10 12:26:39.571554576 +0200 +++ postfix-3.4.5-cert-auto/src/smtpd/smtpd_sasl_glue.c 2019-04-10 12:35:26.189153746 +0200 @@ -201,6 +201,7 @@ static const NAME_CODE sasl_tls_user[] = { SASL_TLS_USER_NAME_COMMON_NAME, SASL_TLS_USER_COMMON_NAME, SASL_TLS_USER_NAME_RELAY_CLIENTCERTS, SASL_TLS_USER_RELAY_CLIENTCERTS, + SASL_TLS_USER_NAME_RELAY_CLIENTCERTS_AUTO, SASL_TLS_USER_RELAY_CLIENTCERTS_AUTO, 0, SASL_TLS_USER_NONE }; #endif @@ -236,6 +237,7 @@ verified_user = TLS_CERT_IS_TRUSTED(state->tls_context) ? state->tls_context->peer_CN : 0; break; case SASL_TLS_USER_RELAY_CLIENTCERTS: + case SASL_TLS_USER_RELAY_CLIENTCERTS_AUTO: if ( TLS_CERT_IS_PRESENT(state->tls_context) ) { int i; char *prints[2]; @@ -262,6 +264,15 @@ #endif #define ADDR_OR_EMPTY(addr, unknown) (strcmp(addr, unknown) ? addr : "") #define REALM_OR_NULL(realm) (*(realm) ? (realm) : (char *) 0) + +if ((name_code(sasl_tls_user, NAME_CODE_FLAG_NONE, + var_smtpd_sasl_tls_ccert_username) == SASL_TLS_USER_RELAY_CLIENTCERTS_AUTO) +&& verified_user) { + + smtpd_sasl_login(state, verified_user, "RELAY_CLIENTCERTS_AUTO"); + state->sasl_mechanism_list = mystrdup(""); + return; +} if ((state->sasl_server = XSASL_SERVER_CREATE(smtpd_sasl_impl, _args, --- postfix-3.4.5/src/smtpd/smtpd_sasl_glue.h 2019-04-10 12:26:39.571554576 +0200 +++ postfix-3.4.5-cert-auto/src/smtpd/smtpd_sasl_glue.h 2019-04-10 11:10:49.054873903 +0200 @@ -26,10 +26,12 @@ /* for SASL external auth */ #define SASL_TLS_USER_NAME_COMMON_NAME "commonName" #define SASL_TLS_USER_NAME_RELAY_CLIENTCERTS "relay_clientcerts" +#define SASL_TLS_USER_NAME_RELAY_CLIENTCERTS_AUTO "relay_clientcerts_auto" #define SASL_TLS_USER_NONE 0 #define SASL_TLS_USER_COMMON_NAME 1 #define SASL_TLS_USER_RELAY_CLIENTCERTS 2 +#define SASL_TLS_USER_RELAY_CLIENTCERTS_AUTO 3 /* LICENSE /* .ad
Re: TLS client certificates and auth external
Le 27/03/2019 à 17:14, Viktor Dukhovni a écrit : On Wed, Mar 27, 2019 at 04:31:33PM +0100, Emmanuel Fusté wrote: The goal is to be as transparent as possible : - if the client is not found in the relay_clientcerts, act as usual - if the client is found in the relay_clientcerts, no longer announce AUTH support, the auth and identity mapping is already done by the relay_clientcerts map I believe you're asking Postfix to (when configured to do that) simulate "AUTH EXTERNAL" when the client has presented a client certificate, but proceeds from "EHLO" to "MAIL FROM" with no intevening explicit "AUTH". Yes exactly, if a hash to sasl id/username mapping is found in the relay_clientcerts The simulated "AUTH EXTERNAL" would never "fail" (5XX), it either yields an authenticated user or proceeds with the user unauthenticated, and acts accordingly. Does that sound right? Yes, in case of unauthenticated (not present in relay_clientcerts), the simulated "AUTH EXTERNAL" must ideally not be performed and AUTH support be announced as usual as this is perhaps a client with proper AUTH support (otherwise it would be listed with a mapping in relay_clientcerts). But I could live with an unconditional simulated "AUTH EXTERNAL" mode as clients not normally present a certificate. I did not already dig in the code to see if it is doable in a "clean" manner or if the unconditional simulated "AUTH EXTERNAL" mode is the only way to go without too intrusive changes. Emmanuel.
Re: TLS client certificates and auth external
On Wed, Mar 27, 2019 at 04:31:33PM +0100, Emmanuel Fusté wrote: > The goal is to be as transparent as possible : > - if the client is not found in the relay_clientcerts, act as usual > - if the client is found in the relay_clientcerts, no longer announce > AUTH support, the auth and identity mapping is already done by the > relay_clientcerts map I believe you're asking Postfix to (when configured to do that) simulate "AUTH EXTERNAL" when the client has presented a client certificate, but proceeds from "EHLO" to "MAIL FROM" with no intevening explicit "AUTH". The simulated "AUTH EXTERNAL" would never "fail" (5XX), it either yields an authenticated user or proceeds with the user unauthenticated, and acts accordingly. Does that sound right? -- Viktor.
Re: TLS client certificates and auth external
Hello, Great piece of work ! It solve a big part of my problem, but sadly I need to go deeper. Le 18/03/2019 à 22:45, Bastian Schmidt a écrit : In the meantime I have completed a patch and sent it to Wietse and Victor, which adds an option smtpd_sasl_tls_ccert_username. As the patch is rather small, I also attached it to this message. This smtpd_sasl_tls_ccert_username option can be used in the following way: Using smtpd_sasl_tls_ccert_username = commonName After providing a verified client certificate, postfix advertises auth external and the user can authenticate with the username being the commonName of the certificate. This is for users having control over the CA issuing the certificates and resembles the way cyrus imap handles the situation. Using smtpd_sasl_tls_ccert_username = relay_clientcerts When a client presents a certificate, where the fingerprint matches in relay_clientcerts, the lookup value (previously unused) is used to get the username for sasl. The client can then perform an auth external with this username successfully. This is a solution for users, which cannot control the CAs or do not want to trust them or cope with crls, ... It fits in the way postfix currently handles client certificates. I have to deal with products that do not support SMTP AUTH (big email security appliance provider .) but are able to present a TLS certificate. On my platform, the use of the smtpd_sender_login_maps and associated restrictions (reject_sender_login_mismatch) is mandatory to achieve our goal. At first, I was thinking about using the lookup value of relay_clientcerts to map a sasl username. It is nicely done with your patch with smtpd_sasl_tls_ccert_username = relay_clientcerts, but I need to go one step further: I need to completely bypass the sasl provider call and act as if the mapped user successfully authenticate. It would be something like "smtpd_sasl_tls_ccert_username = relay_clientcerts_nosasl" or relay_clientcerts_saslbypass or other (I'm not good at finding good option naming ...) The goal is to be as transparent as possible : - if the client is not found in the relay_clientcerts, act as usual - if the client is found in the relay_clientcerts, no longer announce AUTH support, the auth and identity mapping is already done by the relay_clientcerts map I think it is not a big code complexity addition on top of your work, but before going further I would like to request for comments about this. Viktor, Wietse, would you accept such addition ? Emmanuel.
Re: TLS client certificates and auth external
In the meantime I have completed a patch and sent it to Wietse and Victor, which adds an option smtpd_sasl_tls_ccert_username. As the patch is rather small, I also attached it to this message. This smtpd_sasl_tls_ccert_username option can be used in the following way: Using smtpd_sasl_tls_ccert_username = commonName After providing a verified client certificate, postfix advertises auth external and the user can authenticate with the username being the commonName of the certificate. This is for users having control over the CA issuing the certificates and resembles the way cyrus imap handles the situation. Using smtpd_sasl_tls_ccert_username = relay_clientcerts When a client presents a certificate, where the fingerprint matches in relay_clientcerts, the lookup value (previously unused) is used to get the username for sasl. The client can then perform an auth external with this username successfully. This is a solution for users, which cannot control the CAs or do not want to trust them or cope with crls, ... It fits in the way postfix currently handles client certificates. Both solutions then cause permit_sasl_authenticated to succeed and the sasl username to be set correctly. The default for smtpd_sasl_tls_ccert_username (the empty value) or any other value cause auth external to not be advertised and neither succeed; the same situation as without the patch. I have the first version running successfully in a small local installation using cyrus sasl, where K-9 and Thunderbird are both able to use client certificates (and simple username/password login). With cyrus sasl the setup is more or less straight forward. I also setup a virtual machine to test a dovecot sasl setup. Here the setup is more complicated, as dovecot has to be setup to allow an empty password, when using external auth (and only, when using external auth). This is only possible since version dovecot version 2.2.28. Here I have tested my patch using the s_client only. Best regards, Bastian On 11.03.19 03:47, Matthew Horan wrote: > On Jan 8, 2019, at 5:17 PM, Bastian Schmidt <[hidden email]> wrote: I have an email client (K-9 on Android), which, when using TLS client certificates insists on sending an auth external. However, postfix/SASL does not advertise external auth, which causes the client to not being able to use client certificates with postfix. As I see it, postfix is missing the external mechanism as specified in RFC (SASL) completely. Thus, I have implemented this feature (for TLS CA client certs) and I am currently successfully running this on a local installation using cyrus sasl. I would be willing to provide a patch and would really like to see this integrated in future versions of postfix. I'm quite excited about seeing this feature added to Postfix. I have a similar configuration, and have been putting off making the proposed changes myself. I had previously posted on the Dovecot mailing list [1] to no avail. I'm happy to know that there are at least two of us out there who would benefit from this feature! Thanks, Matt [1] https://www.dovecot.org/list/dovecot/2017-February/106884.html -- Sent from: http://postfix.1071664.n5.nabble.com/Postfix-Users-f2.html --- a/mantools/postlink 2018-01-14 17:48:00.0 +0100 +++ b/mantools/postlink 2019-01-16 17:34:24.202943858 +0100 @@ -692,6 +692,7 @@ s;\bsmtp_balance_inet_protocols\b;$&;g; s;\bsmtpd_enforce_tls\b;$&;g; s;\bsmtpd_sasl_tls_security_options\b;$&;g; +s;\bsmtpd_sasl_tls_ccert_username\b;$&;g; s;\bsmtpd_sasl_type\b;$&;g; s;\bsmtpd_start[-]*\n* *[]*tls_timeout\b;$&;g; s;\bsmtpd_tls_CAfile\b;$&;g; --- a/proto/postconf.proto 2018-11-11 01:40:29.0 +0100 +++ b/proto/postconf.proto 2019-01-16 17:34:24.206943858 +0100 @@ -9671,9 +9671,12 @@ Postfix version 2.5). Postfix lookup tables are in the form of (key, value) pairs. -Since we only need the key, the value can be chosen freely, e.g. -the name of the user or host: -D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home +When doing SASL external authentication using client certificates +and using relay_clientcerts to derive the username +(smtpd_sasl_tls_ccert_username = relay_clientcerts), the lookup result +will determine the SASL username. In other cases, +the value can be chosen freely: +D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 user1 Example: @@ -10284,6 +10287,37 @@ This feature is available in Postfix 2.2 and later. +%PARAM smtpd_sasl_tls_ccert_username + + Use a client certificate to perform SASL external authentication +and specify how the SASL username is derived from the certificate. + + To allow passwordless authentication for client certificates specify +one of the following: + + + +commonName + +Use the commonName of the certificate as a SASL username. +The certificate had to be verified successfully. + +relay_clientcerts + +Use the fingerprint of the client certificate and
Re: TLS client certificates and auth external
> On Jan 8, 2019, at 5:17 PM, Bastian Schmidt <[hidden email]> wrote: > > I have an email client (K-9 on Android), which, when using TLS client > certificates insists on sending an auth external. However, postfix/SASL > does not advertise external auth, which causes the client to not being > able to use client certificates with postfix. > > As I see it, postfix is missing the external mechanism as specified in RFC > (SASL) completely. Thus, I have implemented this feature (for TLS CA > client certs) and I am currently successfully running this on a local > installation using cyrus sasl. > > I would be willing to provide a patch and would really like to see this > integrated in future versions of postfix. I'm quite excited about seeing this feature added to Postfix. I have a similar configuration, and have been putting off making the proposed changes myself. I had previously posted on the Dovecot mailing list [1] to no avail. I'm happy to know that there are at least two of us out there who would benefit from this feature! Thanks, Matt [1] https://www.dovecot.org/list/dovecot/2017-February/106884.html -- Sent from: http://postfix.1071664.n5.nabble.com/Postfix-Users-f2.html
Re: TLS client certificates and auth external
Bastian Schmidt: > Shall I remove the check again? After all, it's just a simple if and > won't hurt. In case later someone makes initialization conditional it > would prevent the segfault. Removing this initialization would be a bad idea. The way the code works is that all table variables are initialized, so that the consumers of those tables do not have to worry about it. Wietse > > On 17.01.19 20:46, Wietse Venema wrote: > > Bastian Schmidt: > >> No, it would not segfault (permit_tls_clientcerts does not do any check > >> as well.). > > I see, because the relay_ccerts initialization is unconditional: > > > > relay_ccerts = maps_create(VAR_RELAY_CCERTS, var_smtpd_relay_ccerts, > >DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); > > > > Therefore it is safe to acces the information. > > > >> However, I like the idea and added some checks to improve the patch. > > In this specific case there is no need to validate relay_ccerts. > > > > Wietse > > > >> Also, I was finally able to get dovecot installed for testing and have > >> fixed some issues for dovecot-sasl. > >> > >> Bastian > >> > >> > >> On 16.01.19 01:08, Wietse Venema wrote: > >>> Will this code segfault if relay_clientcerts is not specified? You > >>> may want to add some checks that information exists before using it. > >>> > >>> Wietse > >> > > [ Attachment, skipping... ] > > >
Re: TLS client certificates and auth external
> On Jan 8, 2019, at 5:17 PM, Bastian Schmidt wrote: > > I have an email client (K-9 on Android), which, when using TLS client > certificates insists on sending an auth external. However, postfix/SASL does > not advertise external auth, which causes the client to not being able to use > client certificates with postfix. > > As I see it, postfix is missing the external mechanism as specified in RFC > (SASL) completely. Thus, I have implemented this feature (for TLS CA > client certs) and I am currently successfully running this on a local > installation using cyrus sasl. > > I would be willing to provide a patch and would really like to see this > integrated in future versions of postfix. > > I hope this is the right postfix mailing list for this request. Well perhaps postfix-devel is equally or more appropriate. There is a key design issue here: * In typical Postfix configurations we see relay restrictions of the form: smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination which is fine, when the user has enrolled for a login account on the receiving system. But with client certs, anyone can get a client certificate from some CA, or even mint their own. So what does "SASL authenticated" mean with client certs? Is there a particular issuing CA that's the only one trusted to issue client certs? Or does the client certificate fingerprint need to match a lookup table for it to be considered authenticated? My advice is that a trusted CA, and likely often accidentally every CA on the planet from one of the usual CA bundles, is much too risky in this context, and would drag in revocation lists, OCSP, and that whole dumpster-fire of PKI issues. Therefore, the meaning of SASL authenticated for EXTERNAL should be that the client certificate fingerprint matches a lookup table that maps the client certificate to something resembling a SASL user name. You would then either "permit_sasl_authenticated" without distinguishing between one user and another, or else use "check_sasl_access" based on username obtained from the fingerprint->username map. You could also then use the "sender login mismatch" features by matching the username with valid sender addresses, ... Otherwise, "EXTERNAL" should be fairly straight-forward. Feel free to move the discussion to postfix-devel, or continue here to the extent the discussion stays high level, rather than dives into the implementation. -- Viktor.