From 485a2b6cc52be6ea6b38baa968b5cbdb0bcab296 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Tue, 20 Nov 2018 21:22:40 +0000 Subject: [PATCH] Return mail_crypt_save_version=2 on responses --- README.md | 7 +++++++ dovecot/keyproxy.go | 34 ++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 63ef43fb..4416aa71 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,13 @@ private keys from LDAP, and serve the *unencrypted* keys to Dovecot using its [dict proxy protocol](https://wiki2.dovecot.org/AuthDatabase/Dict). +*NOTE* that passdb lookups using *dovecot-keylookupd* contain the +cleartext password as part of the key, which may be logged in case of +error! This is currently a huge limitation of this solution, but there +seems to be no workaround that does not involve switching to a +fork()-based solution (like the checkpassword script). That might be a +better solution long-term. + TODO: explain the lookup protocol. # Configuration diff --git a/dovecot/keyproxy.go b/dovecot/keyproxy.go index b831c4c1..8ef42139 100644 --- a/dovecot/keyproxy.go +++ b/dovecot/keyproxy.go @@ -42,19 +42,41 @@ func (c *Config) check() error { return c.LDAPConfig.Valid() } +// The response returned to userdb lookups. It contains the user's +// public key as a global key for the mail_crypt plugin, and it sets +// mail_crypt_save_version to 2. The idea is that you would then set +// mail_crypt_save_version = 0 in the global Dovecot configuration, +// which would then disable encryption for users without encryption +// keys. For details on what this means, see +// https://wiki2.dovecot.org/Plugins/MailCrypt. type userdbResponse struct { - PublicKey string `json:"mail_crypt_global_public_key"` + PublicKey string `json:"mail_crypt_global_public_key"` + SaveVersion int `json:"mail_crypt_save_version"` } +func newUserDBResponse(publicKey string) *userdbResponse { + return &userdbResponse{ + PublicKey: publicKey, + SaveVersion: 2, + } +} + +// The response returned to passdb lookups. We return the user's +// private key and the mail_crypt_save_version attribute as userdb +// parameters (hence the 'userdb_' prefix), and set the noauthenticate +// bit to inform Dovecot that this lookup is only meant to provide +// additional data, not authentication. type passdbResponse struct { - PrivateKey string `json:"userdb_mail_crypt_global_private_key"` - NoAuth bool `json:"noauthenticate"` + PrivateKey string `json:"userdb_mail_crypt_global_private_key"` + SaveVersion int `json:"userdb_mail_crypt_save_version"` + NoAuth bool `json:"noauthenticate"` } func newPassDBResponse(privateKey string) *passdbResponse { return &passdbResponse{ - PrivateKey: privateKey, - NoAuth: true, + PrivateKey: privateKey, + SaveVersion: 2, + NoAuth: true, } } @@ -123,7 +145,7 @@ func (s *KeyLookupProxy) lookupUserdb(ctx context.Context, username string) (int return nil, false, nil } log.Printf("userdb lookup for %s", username) - return &userdbResponse{PublicKey: s.b64encode(pub)}, true, nil + return newUserDBResponse(s.b64encode(pub)), true, nil } func (s *KeyLookupProxy) lookupPassdb(ctx context.Context, username, password string) (interface{}, bool, error) { -- GitLab