summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2015-08-19 10:13:36 -0400
committerPatrick Uiterwijk <puiterwijk@redhat.com>2015-08-27 02:22:15 +0200
commitf1efb10af288c438fa034e7beb62e14b8417056f (patch)
treecb66bff2b8c02a48da906215eec087372528a16f
parentea3a3c63719961c66b7b45cd7cfee51cf4bd5f6d (diff)
downloadipsilon-master.tar.gz
ipsilon-master.tar.xz
ipsilon-master.zip
Validate options of the LDAP auth plugin on installationHEADmaster
Few of the LDAP options had any validation at all so it was easy to provide a bad DN template, basedn and server URL. These types of errors are now sufficient to kill the installer rather than letting it limp along and hope the user notices the failures in the output. https://fedorahosted.org/ipsilon/ticket/40 Signed-off-by: Rob Crittenden <rcritten@redhat.com> Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
-rwxr-xr-xipsilon/install/ipsilon-server-install20
-rw-r--r--ipsilon/login/authldap.py83
2 files changed, 72 insertions, 31 deletions
diff --git a/ipsilon/install/ipsilon-server-install b/ipsilon/install/ipsilon-server-install
index 2c16a03..378479d 100755
--- a/ipsilon/install/ipsilon-server-install
+++ b/ipsilon/install/ipsilon-server-install
@@ -30,14 +30,10 @@ STATICDIR = '/usr/share/ipsilon'
WSGI_SOCKET_PREFIX = None
-class ConfigurationError(Exception):
+class ConfigurationError(StandardError):
def __init__(self, message):
- super(ConfigurationError, self).__init__(message)
- self.message = message
-
- def __str__(self):
- return repr(self.message)
+ StandardError.__init__(self, message)
#Silence cherrypy logging to screen
@@ -181,7 +177,8 @@ def install(plugins, args):
plugin = plugins['Environment Helpers'][plugin_name]
plugin_changes = {}
if plugin.configure_server(args, plugin_changes) == False:
- logger.info('Configuration of environment helper %s failed' % plugin_name)
+ msg = 'Configuration of environment helper %s failed' % plugin_name
+ raise ConfigurationError(msg)
changes['env_helper'][plugin_name] = plugin_changes
logger.info('Configuring login managers')
@@ -192,7 +189,8 @@ def install(plugins, args):
sys.exit('Login provider %s not installed' % plugin_name)
plugin_changes = {}
if plugin.configure(args, plugin_changes) == False:
- logger.info('Configuration of login manager %s failed' % plugin_name)
+ msg = 'Configuration of login manager %s failed' % plugin_name
+ raise ConfigurationError(msg)
changes['login_manager'][plugin_name] = plugin_changes
logger.info('Configuring Info provider')
@@ -200,7 +198,8 @@ def install(plugins, args):
plugin = plugins['Info Provider'][plugin_name]
plugin_changes = {}
if plugin.configure(args, plugin_changes) == False:
- logger.info('Configuration of info provider %s failed' % plugin_name)
+ msg = 'Configuration of info provider %s failed' % plugin_name
+ raise ConfigurationError(msg)
changes['info_provider'][plugin_name] = plugin_changes
logger.info('Configuring Authentication Providers')
@@ -208,7 +207,8 @@ def install(plugins, args):
plugin = plugins['Auth Providers'][plugin_name]
plugin_changes = {}
if plugin.configure(args, plugin_changes) == False:
- logger.info('Configuration of auth provider %s failed' % plugin_name)
+ msg = 'Configuration of auth provider %s failed' % plugin_name
+ raise ConfigurationError(msg)
changes['auth_provider'][plugin_name] = plugin_changes
# Save any changes that were made
diff --git a/ipsilon/login/authldap.py b/ipsilon/login/authldap.py
index 321c461..1986490 100644
--- a/ipsilon/login/authldap.py
+++ b/ipsilon/login/authldap.py
@@ -8,6 +8,30 @@ from ipsilon.util import config as pconfig
from ipsilon.info.infoldap import InfoProvider as LDAPInfo
import ldap
import subprocess
+import logging
+
+
+def ldap_connect(server_url, tls):
+ tls = tls.lower()
+ tls_req_opt = None
+ if tls == "never":
+ tls_req_opt = ldap.OPT_X_TLS_NEVER
+ elif tls == "demand":
+ tls_req_opt = ldap.OPT_X_TLS_DEMAND
+ elif tls == "allow":
+ tls_req_opt = ldap.OPT_X_TLS_ALLOW
+ elif tls == "try":
+ tls_req_opt = ldap.OPT_X_TLS_TRY
+ if tls_req_opt is not None:
+ ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, tls_req_opt)
+
+ conn = ldap.initialize(server_url)
+
+ if tls != "notls":
+ if not server_url.startswith("ldaps"):
+ conn.start_tls_s()
+
+ return conn
class LDAP(LoginFormBase, Log):
@@ -17,26 +41,7 @@ class LDAP(LoginFormBase, Log):
self.ldap_info = None
def _ldap_connect(self):
-
- tls = self.lm.tls.lower()
- tls_req_opt = None
- if tls == "never":
- tls_req_opt = ldap.OPT_X_TLS_NEVER
- elif tls == "demand":
- tls_req_opt = ldap.OPT_X_TLS_DEMAND
- elif tls == "allow":
- tls_req_opt = ldap.OPT_X_TLS_ALLOW
- elif tls == "try":
- tls_req_opt = ldap.OPT_X_TLS_TRY
- if tls_req_opt is not None:
- ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, tls_req_opt)
-
- conn = ldap.initialize(self.lm.server_url)
-
- if tls != "notls":
- if not self.lm.server_url.startswith("ldaps"):
- conn.start_tls_s()
- return conn
+ return ldap_connect(self.lm.server_url, self.lm.tls)
def _authenticate(self, username, password):
@@ -200,7 +205,9 @@ class Installer(LoginManagerInstaller):
help='LDAP Server Url')
group.add_argument('--ldap-bind-dn-template', action='store',
help='LDAP Bind DN Template')
- group.add_argument('--ldap-tls-level', action='store', default=None,
+ group.add_argument('--ldap-tls-level', default='Demand',
+ choices=['Demand', 'Allow', 'Try', 'Never',
+ 'NoTLS'],
help='LDAP TLS level')
group.add_argument('--ldap-base-dn', action='store',
help='LDAP Base DN')
@@ -218,7 +225,17 @@ class Installer(LoginManagerInstaller):
config = dict()
if 'ldap_server_url' in opts:
config['server url'] = opts['ldap_server_url']
+ else:
+ logging.error('LDAP Server URL is required')
+ return False
if 'ldap_bind_dn_template' in opts:
+ try:
+ opts['ldap_bind_dn_template'] % {'username': 'test'}
+ except KeyError:
+ logging.error(
+ 'Bind DN template does not container %(username)s'
+ )
+ return False
config['bind dn template'] = opts['ldap_bind_dn_template']
if 'ldap_tls_level' in opts and opts['ldap_tls_level'] is not None:
config['tls'] = opts['ldap_tls_level']
@@ -226,6 +243,30 @@ class Installer(LoginManagerInstaller):
config['tls'] = 'Demand'
if 'ldap_base_dn' in opts and opts['ldap_base_dn'] is not None:
config['base dn'] = opts['ldap_base_dn']
+ test_dn = config['base dn']
+ else:
+ # default set in the config object
+ test_dn = 'dc=example,dc=com'
+
+ # Test the LDAP connection anonymously
+ try:
+ lh = ldap_connect(config['server url'], config['tls'])
+ lh.simple_bind_s('', '')
+ lh.search_s(test_dn, ldap.SCOPE_BASE,
+ attrlist=['objectclasses'])
+ except ldap.INSUFFICIENT_ACCESS:
+ logging.warn('Anonymous access not allowed, continuing')
+ except ldap.UNWILLING_TO_PERFORM: # probably minSSF issue
+ logging.warn('LDAP server unwilling to perform, expect issues')
+ except ldap.SERVER_DOWN:
+ logging.warn('LDAP server is down')
+ except ldap.NO_SUCH_OBJECT:
+ logging.error('Base DN not found')
+ return False
+ except ldap.LDAPError as e:
+ logging.error(e)
+ return False
+
po.save_plugin_config(config)
# Update global config to add login plugin