diff --git a/radicale/auth/__init__.py b/radicale/auth/__init__.py index b30a3c79..8bc8ffad 100644 --- a/radicale/auth/__init__.py +++ b/radicale/auth/__init__.py @@ -43,6 +43,8 @@ "ldap", "dovecot") +AUTH_SOCKET_FAMILY: Sequence[str] = ("AF_UNIX", "AF_INET", "AF_INET6") + def load(configuration: "config.Configuration") -> "BaseAuth": """Load the authentication module chosen in configuration.""" diff --git a/radicale/auth/dovecot.py b/radicale/auth/dovecot.py index ce2353a0..340253c1 100644 --- a/radicale/auth/dovecot.py +++ b/radicale/auth/dovecot.py @@ -28,10 +28,21 @@ class Auth(auth.BaseAuth): def __init__(self, configuration): super().__init__(configuration) - self.socket = configuration.get("auth", "dovecot_socket") self.timeout = 5 self.request_id_gen = itertools.count(1) + config_family = configuration.get("auth", "dovecot_connection_type") + if config_family == "AF_UNIX": + self.family = socket.AF_UNIX + self.address = configuration.get("auth", "dovecot_socket") + return + + self.address = configuration.get("auth", "dovecot_host"), configuration.get("auth", "dovecot_port") + if config_family == "AF_INET": + self.family = socket.AF_INET + else: + self.family = socket.AF_INET6 + def _login(self, login, password): """Validate credentials. @@ -49,12 +60,12 @@ def _login(self, login, password): return "" with closing(socket.socket( - socket.AF_UNIX, + self.family, socket.SOCK_STREAM) ) as sock: try: sock.settimeout(self.timeout) - sock.connect(self.socket) + sock.connect(self.address) buf = bytes() supported_mechs = [] @@ -171,8 +182,8 @@ def _login(self, login, password): except socket.error as e: logger.fatal( - "Failed to communicate with Dovecot socket %r: %s" % - (self.socket, e) + "Failed to communicate with Dovecot: %s" % + (e) ) return "" diff --git a/radicale/config.py b/radicale/config.py index ed294812..743fe926 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -207,10 +207,23 @@ def json_str(value: Any) -> dict: "value": "False", "help": "enable caching of htpasswd file", "type": bool}), + ("dovecot_connection_type", { + "value": "AF_UNIX", + "help": "Connection type for dovecot authentication", + "type": str_or_callable, + "internal": auth.AUTH_SOCKET_FAMILY}), ("dovecot_socket", { "value": "/var/run/dovecot/auth-client", - "help": "dovecot auth socket", + "help": "dovecot auth AF_UNIX socket", + "type": str}), + ("dovecot_host", { + "value": "", + "help": "dovecot auth AF_INET or AF_INET6 host", "type": str}), + ("dovecot_port", { + "value": "12345", + "help": "dovecot auth port", + "type": int}), ("realm", { "value": "Radicale - Password Required", "help": "message displayed when a password is needed",