/** * Copyright (c) Codice Foundation * <p/> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p/> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package ddf.ldap.ldaplogin; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.apache.karaf.jaas.config.JaasRealm; import org.apache.karaf.jaas.config.impl.Config; import org.apache.karaf.jaas.config.impl.Module; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Registers LDAP as a JAAS realm. * */ public class LdapLoginConfig { public static final String LDAP_BIND_USER_DN = "ldapBindUserDn"; public static final String LDAP_BIND_USER_PASS = "ldapBindUserPass"; public static final String LDAP_URL = "ldapUrl"; public static final String USER_BASE_DN = "userBaseDn"; public static final String GROUP_BASE_DN = "groupBaseDn"; public static final String KEY_ALIAS = "keyAlias"; public static final String START_TLS = "startTls"; private static final String CONFIG_NAME = "ldap"; private static final String SUFFICIENT_FLAG = "sufficient"; private static final Logger LOGGER = LoggerFactory.getLogger(LdapLoginConfig.class); private static final String LDAP_MODULE = ddf.ldap.ldaplogin.SslLdapLoginModule.class.getName(); private ServiceRegistration<JaasRealm> registration = null; private Map<String, String> ldapProperties = new HashMap<String, String>(); /** * Registers the passed-in modules under a new JaasRealm. * * @param modules * Modules to add to the JaasRealm. */ private void registerConfig(Module[] modules) { if (registration != null) { LOGGER.debug("Found previous registration, unregistering old service."); try { registration.unregister(); } catch (IllegalStateException ise) { LOGGER.debug( "Service was already unregistered, continuing on to register new service."); } } Config config = new Config(); BundleContext context = getContext(); config.setBundleContext(context); config.setName(CONFIG_NAME); config.setRank(2); config.setModules(modules); LOGGER.debug("Registering new service as a JaasRealm."); if (context != null) { registration = context.registerService(JaasRealm.class, config, null); } } protected BundleContext getContext() { Bundle cxfBundle = FrameworkUtil.getBundle(LdapLoginConfig.class); if (cxfBundle != null) { return cxfBundle.getBundleContext(); } return null; } /** * Update method that receives new properties. * * @param props * Map of properties. */ public void update(Map<String, ?> props) { LOGGER.debug("Received an updated set of configurations for the LDAP Login Config."); // create modules from the newly updated config Module ldapModule = createLdapModule(props); registerConfig(new Module[] {ldapModule}); } /** * Creates a new module with the given properties. * * @param properties * Map of properties. * @return newly created module. */ private Module createLdapModule(Map<String, ?> properties) { Module ldapModule = new Module(); ldapModule.setClassName(LDAP_MODULE); ldapModule.setFlags(SUFFICIENT_FLAG); ldapModule.setName("ldapModule"); Properties props = new Properties(); props.put("connection.username", properties.get(LDAP_BIND_USER_DN)); props.put("connection.password", properties.get(LDAP_BIND_USER_PASS)); props.put("connection.url", properties.get(LDAP_URL)); props.put("user.base.dn", properties.get(USER_BASE_DN)); props.put("user.filter", "(uid=%u)"); props.put("user.search.subtree", "true"); props.put("role.base.dn", properties.get(GROUP_BASE_DN)); props.put("role.filter", "(member=uid=%u," + properties.get(USER_BASE_DN) + ")"); props.put("role.name.attribute", "cn"); props.put("role.search.subtree", "true"); props.put("authentication", "simple"); props.put("ssl.protocol", "TLS"); props.put("ssl.truststore", "ts"); props.put("ssl.keystore", "ks"); props.put("ssl.keyalias", properties.get(KEY_ALIAS)); props.put("ssl.algorithm", "SunX509"); props.put("ssl.starttls", properties.get(START_TLS)); ldapModule.setOptions(props); return ldapModule; } public void setLdapBindUserDn(String ldapBindUserDn) { LOGGER.trace("setLdapBindUserDn called: {}", ldapBindUserDn); ldapProperties.put(LDAP_BIND_USER_DN, ldapBindUserDn); } public void setLdapBindUserPass(String bindUserPass) { LOGGER.trace("setLdapBindUserPass called: {}", bindUserPass); ldapProperties.put(LDAP_BIND_USER_PASS, bindUserPass); } public void setLdapUrl(String ldapUrl) { LOGGER.trace("setLdapUrl called: {}", ldapUrl); ldapProperties.put(LDAP_URL, ldapUrl); } public void setUserBaseDn(String userBaseDn) { LOGGER.trace("setUserBaseDn called: {}", userBaseDn); ldapProperties.put(USER_BASE_DN, userBaseDn); } public void setGroupBaseDn(String groupBaseDn) { LOGGER.trace("setGroupBaseDn called: {}", groupBaseDn); ldapProperties.put(GROUP_BASE_DN, groupBaseDn); } public void setKeyAlias(String keyAlias) { LOGGER.trace("setKeyAlias called: {}", keyAlias); ldapProperties.put(KEY_ALIAS, keyAlias); } public void setStartTls(boolean startTls) { LOGGER.trace("Setting startTls: {}", startTls); ldapProperties.put(START_TLS, String.valueOf(startTls)); } public void setStartTls(String startTls) { LOGGER.trace("Setting startTls: {}", startTls); ldapProperties.put(START_TLS, startTls); } public void configure() { LOGGER.trace("configure called - calling update"); update(ldapProperties); } }