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:<steffen@kdc.localdomain> s-nail: >>> RCPT TO:<root@localhost> 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=<steffen@kdc.localdomain>, 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=<steffen@arch-2020.localdomain>, orig_to=<root@localhost>, 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 7 EXTERNAL service=smtp nologin lip=10.0.1.11 rip=10.0.0.1 secured valid-client-cert cert_username=steffen resp=<hidden> 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: FAIL 7 user=steffen original_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:<steffen@kdc.localdomain> s-nail: >>> RCPT TO:<root@localhost> s-nail: >>> DATA s-nail: >>> SERVER: 235 2.7.0 Authentication successful s-nail: >>> SERVER: 250 2.1.0 Ok s-nail: >>> SERVER: 250 2.1.5 Ok s-nail: >>> SERVER: 354 End data with <CR><LF>.<CR><LF> s-nail: >>> Date: Mon, 24 Aug 2020 21:02:36 +0200 s-nail: >>> From: steffen@kdc.localdomain s-nail: >>> To: root@localhost s-nail: >>> Subject: sa s-nail: >>> Message-ID: <20200824190236.FCYq7ZUM@kdc.localdomain> s-nail: >>> User-Agent: s-nail v14.9.19-119-g69d046f3 s-nail: >>> s-nail: >>> . s-nail: >>> QUIT s-nail: >>> SERVER: 250 2.0.0 Ok: queued as BB19B40551 s-nail: >>> SERVER: 221 2.0.0 Bye like so Aug 24 21:02:35 arch-2020 postfix/smtpd[11295]: connect from _gateway[10.0.0.1] Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: Module loaded: /usr/lib/dovecot/modules/auth/lib20_auth_var_expand_crypt.so Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: Read auth token secret from /run/dovecot/auth-token-secret.dat Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: passwd-file /etc/dovecot/pass-external.db: Read 1 users in 0 secs Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: passwd-file /etc/dovecot/pass.db: Read 1 users in 0 secs Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: auth client connected (pid=0) Aug 24 21:02:35 arch-2020 postfix/smtpd[11295]: 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 21:02:35 arch-2020 dovecot[11187]: auth: Debug: client in: AUTH 1 EXTERNAL service=smtp nologin lip=10.0.1.11 rip=10.0.0.1 secured valid-client-cert cert_username=steffen resp=<hidden> Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: passwd-file(steffen,10.0.0.1): Performing passdb lookup Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: passwd-file(steffen,10.0.0.1): lookup: user=steffen file=/etc/dovecot/pass-external.db Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: passwd-file(steffen,10.0.0.1): Finished passdb lookup Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: auth(steffen,10.0.0.1): Auth request finished Aug 24 21:02:35 arch-2020 dovecot[11187]: auth: Debug: client passdb out: OK 1 user=steffen original_user= Aug 24 21:02:38 arch-2020 postfix/smtpd[11295]: BB19B40551: client=_gateway[10.0.0.1], sasl_method=EXTERNAL, sasl_username=steffen Aug 24 21:02:38 arch-2020 postfix/cleanup[11299]: BB19B40551: message-id=<20200824190236.FCYq7ZUM@kdc.localdomain> Aug 24 21:02:38 arch-2020 postfix/qmgr[11163]: BB19B40551: from=<steffen@kdc.localdomain>, size=650, nrcpt=1 (queue active) Aug 24 21:02:38 arch-2020 postfix/smtpd[11295]: 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 21:02:38 arch-2020 postfix/local[11300]: BB19B40551: to=<steffen@arch-2020.localdomain>, orig_to=<root@localhost>, relay=local, delay=3, delays=3/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox) Aug 24 21:02:38 arch-2020 postfix/qmgr[11163]: BB19B40551: removed So even though the immediate response alone is not enough, it is used to verify that the commonName and the given name are identical. If it is that approach, i think it is ok. |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? It handles the SASL auth request. And i think this is great! However, i really would like to have the possibility to also allow a quick shot, as in permit_tls_clientcerts_now or something! I.e., skip the entire AUTH _if_ the client presented a valid client certificate, but otherwise simply go for SASL. Would be nice in a transition phase, or even regular, i think. |You're posting code, but that seems premature. Can you instead post a |description of the design? Perhaps moving the discussion to |postfix-devel... No i do not think it is premature in the sense of premature code. Maybe i did not get the context right, because postfix is a large base, but given the TLS extension that is already present for dovecot, that i have only extended so in that sense it is definetely not premature. For me it in fact "fixes a bug", since EXTERNAL authentification is announced by postfix, but just fails. And here, even though dovecot does provide the necessary hooks to make it succeed! And even if dovecot would extend the protocol to allow fingerprints to be passed in addition, so that certificate validation could be solely done by the auth server, this will not help postfix in particular, since you surely keep on providing the client certificate checks that you already have! No? 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: ? varshow tls-config-pairs set tls-config-pairs=MinProtocol=TLSv1.3,PrivateKey=/tmp/kdck.pem,Certificate=/tmp/kdcc.pem ? mail root@localhost ... s-nail: >>> AUTH OAUTHBEARER bixhPXN0ZWZmZW4sAWhvc3Q9a2RjLmxvY2FsZG9tYWluAXBvcnQ9NTg3AWF1dGg9QmVhcmVyIFN3YXkBAQ== s-nail: >>> MAIL FROM:<steffen@kdc.localdomain> s-nail: >>> RCPT TO:<root@localhost> s-nail: >>> DATA s-nail: >>> SERVER: 235 2.7.0 Authentication successful s-nail: >>> SERVER: 250 2.1.0 Ok s-nail: >>> SERVER: 250 2.1.5 Ok s-nail: >>> SERVER: 354 End data with <CR><LF>.<CR><LF> s-nail: >>> Date: Mon, 24 Aug 2020 20:16:27 +0200 s-nail: >>> From: steffen@kdc.localdomain s-nail: >>> To: root@localhost s-nail: >>> Subject: sas s-nail: >>> Message-ID: <20200824181627.8gV-pxzb@kdc.localdomain> s-nail: >>> User-Agent: s-nail v14.9.19-119-g69d046f3 s-nail: >>> s-nail: >>> . s-nail: >>> QUIT s-nail: >>> SERVER: 250 2.0.0 Ok: queued as A0D4C4054C s-nail: >>> SERVER: 221 2.0.0 Bye ... ? set tls-config-pairs=MinProtocol=TLSv1.3 ? mail root@localhost ... s-nail: >>> AUTH OAUTHBEARER bixhPXN0ZWZmZW4sAWhvc3Q9a2RjLmxvY2FsZG9tYWluAXBvcnQ9NTg3AWF1dGg9QmVhcmVyIFN3YXkBAQ== s-nail: >>> MAIL FROM:<steffen@kdc.localdomain> s-nail: >>> RCPT TO:<root@localhost> s-nail: >>> DATA s-nail: >>> SERVER: 235 2.7.0 Authentication successful s-nail: >>> SERVER: 250 2.1.0 Ok s-nail: >>> SERVER: 553 5.7.1 <steffen@kdc.localdomain>: Sender address rejected: not owned by user steffen s-nail: SMTP: unexpected status from server: 553 5.7.1 <steffen@kdc.localdomain>: Sender address rejected: not owned by user steffen What has the presence of the client certificate to do with this error?? 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)