From c55127f7a26a401b220ec6831a00e2de057ba2bc Mon Sep 17 00:00:00 2001 From: felixvarghese Date: Fri, 6 Jul 2018 11:58:27 +0530 Subject: [PATCH] Connect to LDAP Server using StartTLS (#5784) * Connect to LDAP Server using StartTLS Connect to LDAP server using StartTLS for security. An option to require trusted certificates is also included. * fix try * remove trailing whitespace --- .../doctype/ldap_settings/ldap_settings.json | 86 +++++++++++++++++++ .../doctype/ldap_settings/ldap_settings.py | 19 ++++ 2 files changed, 105 insertions(+) diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.json b/frappe/integrations/doctype/ldap_settings/ldap_settings.json index 76c39a774a..f317f43070 100644 --- a/frappe/integrations/doctype/ldap_settings/ldap_settings.json +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.json @@ -299,6 +299,92 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "ldap_security", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "LDAP Security", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Off", + "description": "", + "fieldname": "ssl_tls_mode", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "SSL/TLS Mode", + "length": 0, + "no_copy": 0, + "options": "Off\nStartTLS", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "No", + "fieldname": "require_trusted_certificate", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Require Trusted Certificate", + "length": 0, + "no_copy": 0, + "options": "No\nYes", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "has_web_view": 0, diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.py b/frappe/integrations/doctype/ldap_settings/ldap_settings.py index b2f305c1a2..dba20afae5 100644 --- a/frappe/integrations/doctype/ldap_settings/ldap_settings.py +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.py @@ -17,6 +17,15 @@ class LDAPSettings(Document): try: import ldap conn = ldap.initialize(self.ldap_server_url) + try: + if self.ssl_tls_mode == 'StartTLS': + conn.set_option(ldap.OPT_X_TLS_DEMAND, True) + if self.require_trusted_certificate == 'Yes': + conn.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND) + conn.start_tls_s() + except: + frappe.throw(_("StartTLS is not supported")) + conn.simple_bind_s(self.base_dn, self.get_password(raise_exception=False)) except ImportError: msg = """ @@ -75,6 +84,16 @@ def authenticate_ldap_user(user=None, password=None): conn = ldap.initialize(settings.ldap_server_url) try: + try: + # set TLS settings for secure connection + if self.ssl_tls_mode == 'StartTLS': + conn.set_option(ldap.OPT_X_TLS_DEMAND, True) + if self.require_trusted_certificate == 'Yes': + conn.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND) + conn.start_tls_s() + except: + frappe.throw(_("StartTLS is not supported")) + # simple_bind_s is synchronous binding to server, it takes two param DN and password conn.simple_bind_s(settings.base_dn, settings.get_password(raise_exception=False))