1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-06-26 16:45:52 +00:00

Merge pull request #1579 from petervarkoly/master

Implementing ssl connection for ldap auth
This commit is contained in:
Peter Bieringer 2024-09-23 19:42:08 +02:00 committed by GitHub
commit 499b37fd2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 73 additions and 4 deletions

View file

@ -834,10 +834,31 @@ Default: `(cn={0})`
##### ldap_load_groups
Load the ldap groups of the authenticated user. These groups can be used later on to define rights.
Load the ldap groups of the authenticated user. These groups can be used later on to define rights. This also gives you access to the group calendars, if they exist.
* The group calendar will be placed under collection_root_folder/GROUPS
* The name of the calendar directory is the base64 encoded group name.
* The group calneder folders will not be created automaticaly. This must be created manualy. [Here](https://github.com/Kozea/Radicale/wiki/LDAP-authentication) you can find a script to create group calneder folders https://github.com/Kozea/Radicale/wiki/LDAP-authentication
Default: False
##### ldap_use_ssl
Use ssl on the ldap connection
Default: False
##### ldap_ssl_verify_mode
The certifikat verification mode. NONE, OPTIONAL or REQUIRED
Default: REQUIRED
##### ldap_ssl_ca_file
The path to the CA file in pem format which is used to certificate the server certificate
Default:
##### lc_username
Сonvert username to lowercase, must be true for case-insensitive auth

11
config
View file

@ -72,7 +72,16 @@
#ldap_load_groups = True
# The filter to find the DN of the user. This filter must contain a python-style placeholder for the login
#ldap_filter = (&(objectClass=person)(cn={0}))
#ldap_filter = (&(objectClass=person)(uid={0}))
# Use ssl on the ldap connection
#ldap_use_ssl = False
# The certifikat verification mode. NONE, OPTIONAL, default is REQUIRED
#ldap_ssl_verify_mode = REQUIRED
# The path to the CA file in pem format which is used to certificate the server certificate
#ldap_ssl_ca_file =
# Htpasswd filename
#htpasswd_filename = /etc/radicale/users

View file

@ -15,14 +15,20 @@
# along with Radicale. If not, see <http://www.gnu.org/licenses/>.
"""
Authentication backend that checks credentials with a ldap server.
Following parameters are needed in the configuration
Following parameters are needed in the configuration:
ldap_uri The ldap url to the server like ldap://localhost
ldap_base The baseDN of the ldap server
ldap_reader_dn The DN of a ldap user with read access to get the user accounts
ldap_secret The password of the ldap_reader_dn
ldap_filter The search filter to find the user to authenticate by the username
ldap_load_groups If the groups of the authenticated users need to be loaded
Following parameters controls SSL connections:
ldap_use_ssl If the connection
ldap_ssl_verify_mode The certifikat verification mode. NONE, OPTIONAL, default is REQUIRED
ldap_ssl_ca_file
"""
import ssl
from radicale import auth, config
from radicale.log import logger
@ -36,6 +42,9 @@ class Auth(auth.BaseAuth):
_ldap_filter: str
_ldap_load_groups: bool
_ldap_version: int = 3
_ldap_use_ssl: bool = False
_ldap_ssl_verify_mode: int = ssl.CERT_REQUIRED
_ldap_ssl_ca_file: str = ""
def __init__(self, configuration: config.Configuration) -> None:
super().__init__(configuration)
@ -55,6 +64,15 @@ class Auth(auth.BaseAuth):
self._ldap_load_groups = configuration.get("auth", "ldap_load_groups")
self._ldap_secret = configuration.get("auth", "ldap_secret")
self._ldap_filter = configuration.get("auth", "ldap_filter")
if self._ldap_version == 3:
self._ldap_use_ssl = configuration.get("auth", "ldap_use_ssl")
if self._ldap_use_ssl:
self._ldap_ssl_ca_file = configuration.get("auth", "ldap_ssl_ca_file")
tmp = configuration.get("auth", "ldap_ssl_verify_mode")
if tmp == "NONE":
self._ldap_ssl_verify_mode = ssl.CERT_NONE
elif tmp == "OPTIONAL":
self._ldap_ssl_verify_mode = ssl.CERT_OPTIONAL
def _login2(self, login: str, password: str) -> str:
try:
@ -98,7 +116,16 @@ class Auth(auth.BaseAuth):
"""Connect the server"""
try:
logger.debug(f"_login3 {self._ldap_uri}, {self._ldap_reader_dn}")
server = self.ldap3.Server(self._ldap_uri)
if self._ldap_use_ssl:
tls = self.ldap3.Tls(validate=self._ldap_ssl_verify_mode)
if self._ldap_ssl_ca_file != "":
tls = self.ldap3.Tls(
validate=self._ldap_ssl_verify_mode,
ca_certs_file=self._ldap_ssl_ca_file
)
server = self.ldap3.Server(self._ldap_uri, use_ssl=True, tls=tls)
else:
server = self.ldap3.Server(self._ldap_uri)
conn = self.ldap3.Connection(server, self._ldap_reader_dn, password=self._ldap_secret)
except self.ldap3.core.exceptions.LDAPSocketOpenError:
raise RuntimeError("Unable to reach ldap server")

View file

@ -215,6 +215,18 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
"value": "False",
"help": "load the ldap groups of the authenticated user",
"type": bool}),
("ldap_use_ssl", {
"value": "False",
"help": "Use ssl on the ldap connection",
"type": bool}),
("ldap_ssl_verify_mode", {
"value": "REQUIRED",
"help": "The certifikat verification mode. NONE, OPTIONAL, default is REQUIRED",
"type": str}),
("ldap_ssl_ca_file", {
"value": "",
"help": "The path to the CA file in pem format which is used to certificate the server certificate",
"type": str}),
("strip_domain", {
"value": "False",
"help": "strip domain from username",