diff --git a/modoboa_installer/config_dict_template.py b/modoboa_installer/config_dict_template.py index 32af0e55..2436e3b5 100644 --- a/modoboa_installer/config_dict_template.py +++ b/modoboa_installer/config_dict_template.py @@ -189,7 +189,6 @@ def is_email(user_input): "option": "extensions", "default": ( "modoboa-amavis " - "modoboa-postfix-autoreply modoboa-sievefilters " "modoboa-webmail modoboa-contacts " "modoboa-radicale" ), diff --git a/modoboa_installer/scripts/dovecot.py b/modoboa_installer/scripts/dovecot.py index b4520e13..30fb1800 100644 --- a/modoboa_installer/scripts/dovecot.py +++ b/modoboa_installer/scripts/dovecot.py @@ -4,6 +4,7 @@ import os import pwd import shutil +import uuid from .. import database from .. import package @@ -14,7 +15,6 @@ class Dovecot(base.Installer): - """Dovecot installer.""" appname = "dovecot" @@ -27,7 +27,9 @@ class Dovecot(base.Installer): } config_files = [ "dovecot.conf", "dovecot-dict-sql.conf.ext", "conf.d/10-ssl.conf", - "conf.d/10-master.conf", "conf.d/20-lmtp.conf", "conf.d/10-ssl-keys.try"] + "conf.d/10-master.conf", "conf.d/20-lmtp.conf", "conf.d/10-ssl-keys.try", + "conf.d/dovecot-oauth2.conf.ext" + ] with_user = True def setup_user(self): @@ -53,17 +55,35 @@ def get_packages(self): if package.backend.FORMAT == "deb": if "pop3" in self.config.get("dovecot", "extra_protocols"): packages += ["dovecot-pop3d"] - return super(Dovecot, self).get_packages() + packages + return super().get_packages() + packages def install_packages(self): """Preconfigure Dovecot if needed.""" package.backend.preconfigure( "dovecot-core", "create-ssl-cert", "boolean", "false") - super(Dovecot, self).install_packages() + super().install_packages() + + def create_oauth2_app(self): + """Create a application for Oauth2 authentication.""" + # FIXME: how can we check that application already exists ? + venv_path = self.config.get("modoboa", "venv_path") + python_path = os.path.join(venv_path, "bin", "python") + instance_path = self.config.get("modoboa", "instance_path") + script_path = os.path.join(instance_path, "manage.py") + client_id = "dovecot" + client_secret = str(uuid.uuid4()) + cmd = ( + f"{python_path} {script_path} createapplication " + f"--name=Dovecot --skip-authorization " + f"--client-id={client_id} --client-secret={client_secret} " + f"confidential client-credentials" + ) + utils.exec_cmd(cmd) + return client_id, client_secret def get_template_context(self): """Additional variables.""" - context = super(Dovecot, self).get_template_context() + context = super().get_template_context() pw_mailbox = pwd.getpwnam(self.mailboxes_owner) dovecot_package = {"deb": "dovecot-core", "rpm": "dovecot"} ssl_protocol_parameter = "ssl_protocols" @@ -84,6 +104,13 @@ def get_template_context(self): # Protocols are automatically guessed on debian/ubuntu protocols = "" + oauth2_client_id, oauth2_client_secret = self.create_oauth2_app() + hostname = self.config.get("general", "hostname") + oauth2_introspection_url = ( + f"https://{oauth2_client_id}:{oauth2_client_secret}" + f"@{hostname}/api/o/introspect/" + ) + context.update({ "db_driver": self.db_driver, "mailboxes_owner_uid": pw_mailbox[2], @@ -100,7 +127,8 @@ def get_template_context(self): "radicale_auth_socket_path": os.path.basename( self.config.get("dovecot", "radicale_auth_socket_path")), "modoboa_2_2_or_greater": "" if self.modoboa_2_2_or_greater else "#", - "not_modoboa_2_2_or_greater": "" if not self.modoboa_2_2_or_greater else "#" + "not_modoboa_2_2_or_greater": "" if not self.modoboa_2_2_or_greater else "#", + "oauth2_introspection_url": oauth2_introspection_url }) return context diff --git a/modoboa_installer/scripts/files/dovecot/conf.d/10-auth.conf b/modoboa_installer/scripts/files/dovecot/conf.d/10-auth.conf index d991a507..cd55c173 100644 --- a/modoboa_installer/scripts/files/dovecot/conf.d/10-auth.conf +++ b/modoboa_installer/scripts/files/dovecot/conf.d/10-auth.conf @@ -96,7 +96,7 @@ auth_master_user_separator = * # plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey # gss-spnego # NOTE: See also disable_plaintext_auth setting. -auth_mechanisms = plain login +auth_mechanisms = plain login oauthbearer xoauth2 ## ## Password and user databases @@ -120,6 +120,7 @@ auth_mechanisms = plain login #!include auth-system.conf.ext !include auth-sql.conf.ext +!include auth-oauth2.conf.ext #!include auth-ldap.conf.ext #!include auth-passwdfile.conf.ext #!include auth-checkpassword.conf.ext diff --git a/modoboa_installer/scripts/files/dovecot/conf.d/auth-oauth2.conf.ext b/modoboa_installer/scripts/files/dovecot/conf.d/auth-oauth2.conf.ext new file mode 100644 index 00000000..d0628723 --- /dev/null +++ b/modoboa_installer/scripts/files/dovecot/conf.d/auth-oauth2.conf.ext @@ -0,0 +1,5 @@ +passdb { + driver = oauth2 + mechanisms = xoauth2 oauthbearer + args = /etc/dovecot/conf.d/dovecot-oauth2.conf.ext +} diff --git a/modoboa_installer/scripts/files/dovecot/conf.d/dovecot-oauth2.conf.ext.tpl b/modoboa_installer/scripts/files/dovecot/conf.d/dovecot-oauth2.conf.ext.tpl new file mode 100644 index 00000000..9c7cbc88 --- /dev/null +++ b/modoboa_installer/scripts/files/dovecot/conf.d/dovecot-oauth2.conf.ext.tpl @@ -0,0 +1,6 @@ +introspection_mode = post +introspection_url = %{oauth2_introspection_url} +username_attribute = username +tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt +active_attribute = active +active_value = true diff --git a/modoboa_installer/scripts/files/uwsgi/modoboa.ini.tpl b/modoboa_installer/scripts/files/uwsgi/modoboa.ini.tpl index cd76f33c..9d27e21f 100644 --- a/modoboa_installer/scripts/files/uwsgi/modoboa.ini.tpl +++ b/modoboa_installer/scripts/files/uwsgi/modoboa.ini.tpl @@ -13,3 +13,4 @@ socket = %uwsgi_socket_path chmod-socket = 660 vacuum = true single-interpreter = True +buffer-size = 8192