/** * Copyright (c) 2012 - Reinaldo de Carvalho <reinaldoc@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * */ package br.gov.frameworkdemoiselle.ldap.internal; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import javax.annotation.PostConstruct; import javax.enterprise.context.SessionScoped; import javax.inject.Inject; import org.slf4j.Logger; import br.gov.frameworkdemoiselle.internal.producer.LoggerProducer; import br.gov.frameworkdemoiselle.ldap.configuration.EntryManagerConfig; import br.gov.frameworkdemoiselle.ldap.core.EntryQueryMap; import com.novell.ldap.LDAPConnection; import com.novell.ldap.LDAPConstraints; import com.novell.ldap.LDAPException; import com.novell.ldap.LDAPJSSESecureSocketFactory; import com.novell.ldap.LDAPJSSEStartTLSFactory; @SessionScoped public class ConnectionManager implements Serializable { private static final long serialVersionUID = 1L; private Logger logger = LoggerProducer.create(ConnectionManager.class); @Inject private EntryManagerConfig entryManagerConfig; @Inject private EntryQueryMap queryMap; private LDAPConnection lc; private ConnectionURI connURI; private String binddn; private byte[] bindpw; private boolean referrals; private int protocol; private String authenticateFilter; private String authenticateDnResults; private boolean verbose = false; @PostConstruct private void init() throws URISyntaxException { if (entryManagerConfig.isVerbose()) verbose = true; connURI = new ConnectionURI(entryManagerConfig.getServer(), entryManagerConfig.isStarttls()); binddn = entryManagerConfig.getBinddn(); bindpw = entryManagerConfig.getBindpwInBytes(); referrals = entryManagerConfig.isReferrals(); protocol = entryManagerConfig.getProtocol(); authenticateFilter = entryManagerConfig.getAuthenticateFilter(); } /** * Make a LDAP Connection with configuration values; * * @throws LDAPException * @throws URISyntaxException */ private void connect() throws LDAPException, URISyntaxException { if (connURI.getTls() == ConnectionURI.TlsEnum.SSL) { LDAPJSSESecureSocketFactory connFactory = new LDAPJSSESecureSocketFactory(); lc = new LDAPConnection(connFactory); } else if (connURI.getTls() == ConnectionURI.TlsEnum.TLS) { LDAPJSSEStartTLSFactory connFactory = new LDAPJSSEStartTLSFactory(); lc = new LDAPConnection(connFactory); } else { lc = new LDAPConnection(); } lc.connect(connURI.getHost(), connURI.getPort()); if (connURI.getTls() == ConnectionURI.TlsEnum.TLS) { lc.startTLS(); } LDAPConstraints ldapConstraints = new LDAPConstraints(); ldapConstraints.setReferralFollowing(referrals); lc.setConstraints(ldapConstraints); } /** * Make a LDAP Connection with user values; Don't use this method unless * necessary, make resource configuration; * * @throws LDAPException */ public boolean connect(String serverURI, boolean useTLS) { try { connURI = new ConnectionURI(serverURI, useTLS); connect(); return true; } catch (LDAPException e) { loggerInfo("LDAPException raised at connect()"); return false; } catch (URISyntaxException e) { loggerInfo("URISyntaxException raised at connect()"); return false; } } /** * Disconnect from server; * * @throws LDAPException */ private void disconnect() throws LDAPException { lc.disconnect(); } /** * Make and Return a LDAP Connection if not connected; * * @return LDAPConnection * @throws LDAPException * @throws URISyntaxException */ private LDAPConnection getConnection() throws LDAPException, URISyntaxException { if (lc == null || !lc.isConnected()) { connect(); } return lc; } /** * Try get a authenticated connection, bind fails silently; * * @return LDAPConnection instance */ public LDAPConnection initialized() { bind(binddn, bindpw, protocol); return lc; } /** * Authenticate by user information; if already connected then reconnect and * authenticate; Don't use this method unless necessary, make resource * configuration; * * @param binddn * @param bindpw */ public boolean bind(String binddn, String bindpw, int protocol) { byte[] bindpwutf; try { bindpwutf = bindpw.getBytes("UTF8"); } catch (Exception e) { loggerInfo("Exception raised at bind()"); e.printStackTrace(); return false; } return bind(binddn, bindpwutf, protocol); } /** * Authenticate by user information; if already connected then reconnect and * authenticate; Don't use this method unless necessary, make resource * configuration; * * @param binddn * @param bindpw */ public boolean bind(String binddn, byte[] bindpw, int protocol) { this.binddn = binddn; this.bindpw = bindpw; this.protocol = protocol; try { bind(); return true; } catch (Exception e) { loggerInfo("Bind failed for dn: " + binddn); return false; } } /** * Get a Connection and do Authentication; if already connected then * reconnect and authenticate; * * @throws LDAPException * @throws URISyntaxException * @throws UnsupportedEncodingException */ private void bind() throws LDAPException, URISyntaxException { if (getConnection().isBound()) { if (!binddn.equals(getConnection().getAuthenticationDN())) { disconnect(); getConnection().bind(protocol, binddn, bindpw); } } else getConnection().bind(protocol, binddn, bindpw); } /** * Get DN used on bind operation or null * * @return A DN used on bind operation or null */ public String getBindDn() { try { if (getConnection().isBound()) return getConnection().getAuthenticationDN(); } catch (Exception e) { // Ignore } return null; } /** * This is a isolated method that use a alternative connection to validate a * dn or user and a password. This method don't touch current connection. * * @param binddn * @param bindpw * @return authentication results */ public boolean authenticate(String binddn, String bindpw, int protocol) { authenticateDnResults = null; if (binddn != null && !binddn.contains("=")) { queryMap.setSearchFilter(authenticateFilter .replaceAll("%u", binddn)); binddn = queryMap.getSingleDn(); } if (binddn != null) { ConnectionManager cm = new ConnectionManager(); cm.connect(connURI.getServerURI(), connURI.isStarttls()); boolean auth = cm.bind(binddn, bindpw, protocol); if (auth) authenticateDnResults = cm.getBindDn(); return auth; } return false; } /** * Get DN used on authenticate operation or null * * @return A DN used on authenticate operation or null */ public String getAuthenticateDn() { return authenticateDnResults; } private void loggerInfo(String msg) { if (verbose) this.logger.info(msg); } public boolean isVerbose() { return verbose; } public void setVerbose(boolean verbose) { this.verbose = verbose; } }