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)

Reply via email to