/* * Copyright 2011 Future Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.ldap.msgbus; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Requires; import org.krakenapps.api.PrimitiveConverter; import org.krakenapps.codec.Base64; import org.krakenapps.ldap.LdapServerType; import org.krakenapps.ldap.LdapUser; import org.krakenapps.ldap.LdapProfile; import org.krakenapps.ldap.LdapProfile.CertificateType; import org.krakenapps.ldap.LdapService; import org.krakenapps.ldap.LdapSyncService; import org.krakenapps.msgbus.MsgbusException; import org.krakenapps.msgbus.Request; import org.krakenapps.msgbus.Response; import org.krakenapps.msgbus.handler.MsgbusMethod; import org.krakenapps.msgbus.handler.MsgbusPlugin; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.novell.ldap.LDAPConnection; @Component(name = "ldap-plugin") @MsgbusPlugin public class LdapPlugin { private final Logger logger = LoggerFactory.getLogger(LdapPlugin.class.getName()); private BundleContext bc; @Requires private LdapService ldap; public LdapPlugin(BundleContext bc) { this.bc = bc; } @MsgbusMethod public void getProfiles(Request req, Response resp) { List<Object> profiles = new ArrayList<Object>(); try { for (LdapProfile profile : ldap.getProfiles()) profiles.add(profile.serialize()); resp.put("profiles", PrimitiveConverter.serialize(profiles)); } catch (Exception e) { logger.error("kraken ldap: cannot obtain trust store", e); throw new MsgbusException("ldap", "cannot obtain trust store"); } } @MsgbusMethod public void getProfile(Request req, Response resp) { try { String name = req.getString("name"); LdapProfile profile = ldap.getProfile(name); if (profile == null) throw new MsgbusException("ldap", "profile not found"); resp.put("profile", profile.serialize()); } catch (Exception e) { logger.error("kraken ldap: cannot obtain trust store", e); throw new MsgbusException("ldap", "cannot obtain trust store"); } } @MsgbusMethod public void getTrustStore(Request req, Response resp) { String name = req.getString("name"); if (name == null) throw new MsgbusException("ldap", "name not found"); LdapProfile profile = ldap.getProfile(name); try { X509Certificate cert = profile.getX509Certificate(); if (cert == null) throw new MsgbusException("ldap", "trust store not found"); resp.put("trust_store", new String(Base64.encode(cert.getEncoded()))); } catch (Exception e) { logger.error("kraken ldap: cannot obtain trust store, name [{}]", name, e); throw new MsgbusException("ldap", "cannot obtain trust store"); } } @MsgbusMethod public void createProfile(Request req, Response resp) { try { LdapProfile profile = toProfile(new LdapProfile(), req.getParams()); if (req.has("cert_type") && req.has("cert_base64")) { String base64 = req.getString("cert_base64"); profile.setX509Certificate(Base64.decode(base64)); } ldap.createProfile(profile); } catch (Exception e) { throw new MsgbusException("ldap", "invalid cert"); } } @MsgbusMethod public void updateProfile(Request req, Response resp) { try { String name = req.getString("name"); LdapProfile profile = toProfile(ldap.getProfile(name), req.getParams()); byte[] cert = null; if (req.has("cert_base64")) { String base64 = req.getString("cert_base64"); cert = Base64.decode(base64); } profile.setX509Certificate(cert); ldap.updateProfile(profile); } catch (Exception e) { throw new MsgbusException("ldap", "invalid cert"); } } public LdapProfile toProfile(LdapProfile profile, Map<String, Object> m) throws CertificateException { profile.setName((String) m.get("name")); profile.setDc((String) m.get("dc")); profile.setAccount((String) m.get("account")); profile.setPort((Integer) m.get("port")); profile.setPassword((String) m.get("password")); profile.setBaseDn((String) m.get("base_dn")); profile.setServerType(LdapServerType.valueOf((String) m.get("server_type"))); if (m.containsKey("sync_interval")) profile.setSyncInterval((Integer) m.get("sync_interval")); if (m.containsKey("cert_type") && m.containsKey("trust_store")) { profile.setType(CertificateType.valueOf((String) m.get("cert_type"))); profile.setX509Certificate(Base64.decode((String) m.get("trust_store"))); } return profile; } @MsgbusMethod public void removeProfiles(Request req, Response resp) { @SuppressWarnings("unchecked") List<String> names = (List<String>) req.get("names"); for (String name : names) ldap.removeProfile(name); } @MsgbusMethod public void removeProfile(Request req, Response resp) { String name = req.getString("name"); ldap.removeProfile(name); } @Deprecated @MsgbusMethod public void getDomainUserAccounts(Request req, Response resp) { getUsers(req, resp); } @SuppressWarnings("unchecked") @MsgbusMethod public void getUsers(Request req, Response resp) { List<Object> users = new ArrayList<Object>(); Set<String> fields = null; if (req.has("fields")) fields = new HashSet<String>((List<String>) req.get("fields")); String name = req.getString("name"); LdapProfile profile = ldap.getProfile(name); if (profile == null) throw new MsgbusException("ldap", "profile not found"); for (LdapUser account : ldap.getUsers(profile)) users.add(filt((Map<String, Object>) PrimitiveConverter.serialize(account), fields)); resp.put("users", users); } private Map<String, Object> filt(Map<String, Object> m, Set<String> fields) { if (fields == null) return m; Map<String, Object> filtered = new HashMap<String, Object>(); for (String field : fields) filtered.put(field, m.get(field)); return filtered; } @MsgbusMethod public void verifyPassword(Request req, Response resp) { String name = req.getString("name"); String account = req.getString("account"); String testPassword = req.getString("test_password"); LdapProfile profile = ldap.getProfile(name); if (profile == null) throw new MsgbusException("ldap", "profile not found"); boolean validity = ldap.verifyPassword(profile, account, testPassword); resp.put("result", validity); } @MsgbusMethod public void testConnection(Request req, Response resp) { String dc = req.getString("dc"); Integer port = req.getInteger("port"); String account = req.getString("account"); String password = req.getString("password"); String baseDn = req.getString("base_dn"); LdapProfile profile = new LdapProfile(); profile.setName("test_connection"); profile.setDc(dc); profile.setPort(port); profile.setAccount(account); profile.setPassword(password); profile.setBaseDn(baseDn); try { if (req.has("cert_type") && req.has("cert_base64")) { String type = req.getString("cert_type"); String base64 = req.getString("cert_base64"); logger.debug("kraken-ldap: user certificate type [{}], base64 [{}]", type, base64); profile.setX509Certificate(Base64.decode(base64)); if (port == null) profile.setPort(LDAPConnection.DEFAULT_SSL_PORT); } else { if (port == null) profile.setPort(LDAPConnection.DEFAULT_PORT); } } catch (Exception e) { logger.error("kraken ldap: cannot set trust store", e); throw new MsgbusException("ldap", "invalid cert"); } logger.trace("kraken ldap: create test ldap profile [{}]", profile.toString()); ldap.testLdapConnection(profile, req.getInteger("timeout")); } @MsgbusMethod public void sync(Request req, Response resp) { ServiceReference ref = bc.getServiceReference(LdapSyncService.class.getName()); if (ref == null) throw new MsgbusException("ldap", "kraken-dom not found"); String name = req.getString("name"); LdapProfile profile = ldap.getProfile(name); if (profile == null) throw new MsgbusException("ldap", "profile not found"); LdapSyncService ldapSync = (LdapSyncService) bc.getService(ref); ldapSync.sync(profile); } }