diff options
author | Nils Schwabe | 2014-04-30 15:54:59 +0200 |
---|---|---|
committer | Nils Schwabe | 2014-04-30 15:54:59 +0200 |
commit | 0ee8c7190cb020101f7807a2f12b26a3f62a89b0 (patch) | |
tree | d8f98466325c4d21cbad960b65b2e70b5e047da5 /src/main/java/org/openslx/imagemaster/db | |
parent | Add some new exceptions for problems with image's data (diff) | |
download | masterserver-0ee8c7190cb020101f7807a2f12b26a3f62a89b0.tar.gz masterserver-0ee8c7190cb020101f7807a2f12b26a3f62a89b0.tar.xz masterserver-0ee8c7190cb020101f7807a2f12b26a3f62a89b0.zip |
Add connecting to LDAP with cert (JKS in globals.config)
Connecting to BW LDAP works now (finally!!)
Diffstat (limited to 'src/main/java/org/openslx/imagemaster/db')
-rw-r--r-- | src/main/java/org/openslx/imagemaster/db/LdapUser.java | 172 |
1 files changed, 83 insertions, 89 deletions
diff --git a/src/main/java/org/openslx/imagemaster/db/LdapUser.java b/src/main/java/org/openslx/imagemaster/db/LdapUser.java index deb30f3..a38b805 100644 --- a/src/main/java/org/openslx/imagemaster/db/LdapUser.java +++ b/src/main/java/org/openslx/imagemaster/db/LdapUser.java @@ -1,9 +1,18 @@ package org.openslx.imagemaster.db; +import java.io.File; import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.apache.directory.api.ldap.model.cursor.CursorException; @@ -11,11 +20,14 @@ import org.apache.directory.api.ldap.model.cursor.EntryCursor; import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.exception.LdapException; import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.ldap.client.api.LdapConnection; import org.apache.directory.ldap.client.api.LdapConnectionConfig; import org.apache.directory.ldap.client.api.LdapNetworkConnection; import org.apache.log4j.Logger; +import org.apache.mina.filter.ssl.KeyStoreFactory; import org.openslx.imagemaster.Globals; import org.openslx.imagemaster.Globals.PropBool; +import org.openslx.imagemaster.Globals.PropInt; import org.openslx.imagemaster.Globals.PropString; import org.openslx.imagemaster.session.User; import org.openslx.imagemaster.thrift.iface.AuthenticationError; @@ -23,35 +35,6 @@ import org.openslx.imagemaster.thrift.iface.AuthenticationException; import org.openslx.imagemaster.util.Sha512Crypt; /** - * This TrustManager is used to accept custom certificates. - * TODO: Once we are talking to the real server(s), we should - * actually verify the cert, or we could just stop using ssl - * altogether. - */ -class MyTrustManager implements X509TrustManager -{ - - @Override - public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) - throws CertificateException - { - } - - @Override - public void checkServerTrusted( X509Certificate[] arg0, String arg1 ) - throws CertificateException - { - } - - @Override - public X509Certificate[] getAcceptedIssuers() - { - return new X509Certificate[ 0 ]; - } - -} - -/** * Represents a user instance that was queries (primarily) from LDAP. * Additional information that is not provided by the LDAP server might * be fetched from other sources, like the local database. @@ -71,91 +54,102 @@ public class LdapUser extends User * Query LDAP for user with given login * * @param login Login of user in the form "user@organization.com" - * @return instance of LDAPUser for matching entry from LDAP, or null if not found + * @return instance of LDAPUser for matching entry from LDAP */ public static LdapUser forLogin( final String login, final String password ) throws AuthenticationException { String username, organization, firstName, lastName, eMail, satelliteAddress; - String[] temp = login.split( "@" ); - if ( temp.length != 2 ) - throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Login must be in form user@organization.com" ); - - LdapConnectionConfig ldapConfig = new LdapConnectionConfig(); - ldapConfig.setTrustManagers( new MyTrustManager() ); - ldapConfig.setLdapPort( Globals.getPropertyInt( Globals.PropInt.LDAPPORT ) ); - ldapConfig.setLdapHost( Globals.getPropertyString( Globals.PropString.LDAPHOST ) ); - ldapConfig.setUseSsl( Globals.getPropertyBool( PropBool.LDAPSSL ) ); - - LdapNetworkConnection connection = new LdapNetworkConnection( ldapConfig ); - - // bind connection - try { - if ( connection.connect() ) { - String name = Globals.getPropertyString( PropString.LDAPBINDQUERY ).replace( "%", login ).replace( "@", "\\40" ); - log.info( "Bind with: " + name ); - connection.bind( name, password ); - } - } catch ( LdapException e1 ) { - log.warn( "Connection to LDAP failed: " + e1.getMessage() ); - } - - if ( !connection.isConnected() ) { - try { - connection.unBind(); - connection.close(); - } catch ( LdapException | IOException e ) { - // Not doing anything here, as ldap already failed... - } - throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Could not connect to LDAP server." ); - } - - // test authorization - if ( !connection.isAuthenticated() ) { - try { - connection.unBind(); - connection.close(); - } catch ( LdapException | IOException e ) { - // Failing disconnect... Can't do much about it, just go on - } - throw new AuthenticationException( AuthenticationError.INVALID_CREDENTIALS, "Could not authenticate to LDAP server. Invalid credentials?" ); - } - - // make search query +// String[] temp = login.split( "@" ); +// if ( temp.length != 2 ) +// throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Login must be in form user@organization.com" ); + + LdapConnection connection = null; try { + LdapConnectionConfig config = new LdapConnectionConfig(); + + // TODO: Load from configuration file + + String ldapHost = Globals.getPropertyString( PropString.LDAPHOST ); + log.info( "Setting host... " + ldapHost ); + config.setLdapHost( ldapHost ); + + boolean useSsl = Globals.getPropertyBool( PropBool.LDAPSSL ); + log.info( "Setting use ssl... " + useSsl); + config.setUseSsl( useSsl ); + + int ldapPort = Globals.getPropertyInt( PropInt.LDAPPORT ); + log.info( "Setting port... " + ldapPort ); + config.setLdapPort( ldapPort ); + + // load keystore ... + KeyStoreFactory ksf = new KeyStoreFactory(); + ksf.setDataFile( new File(Globals.getPropertyString( PropString.LDAPKEYSTOREPATH )) ); + ksf.setPassword( Globals.getPropertyString( PropString.LDAPKEYSTOREPASSWORD ) ); + ksf.setType( "jks" ); + + // ... and set TrustManager + TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); + tmf.init( ksf.newInstance() ); + + config.setTrustManagers( tmf.getTrustManagers() ); + + connection = new LdapNetworkConnection( config ); + + log.info( "Trying to bind..." ); + String bind = Globals.getPropertyString( PropString.LDAPBINDQUERY ).replace( "%", login ); + connection.bind( bind, password ); + //connection.bind(); + log.info( "Bind successful" ); + + + // make search query EntryCursor cursor = connection.search( Globals.getPropertyString( Globals.PropString.LDAPSEARCHBASEDN ), Globals.getPropertyString( Globals.PropString.LDAPSEARCHFILTER ).replace( "%", login ), SearchScope.SUBTREE ); // only use the first result cursor.next(); Entry entry = cursor.get(); - username = entry.get( "cn" ).getString(); - organization = "Test Organization"; // will be filled with bwIDM LDAP server + username = entry.get( "cn" ).toString().split( " " )[1].split( "@" )[0]; + organization = entry.get( "cn" ).toString().split( "@" )[1]; firstName = entry.get( "givenName" ).getString(); lastName = entry.get( "sn" ).getString(); - eMail = entry.get( "rufPreferredMail" ).getString(); + eMail = entry.get( "mail" ).getString(); + // get the satellite address from db DbSatellite dbSatellite = DbSatellite.fromOrganization( organization ); if ( dbSatellite != null ) { satelliteAddress = dbSatellite.getAddress(); } else { - // TODO: Organization is not known.. Handle this - satelliteAddress = "addressNotKown"; + // Organization is not known. This should not happen because the login would have failed then. + throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Your Organization is not known by the server. Please contact your administrator." ); } - } catch ( LdapException | CursorException e1 ) { - return null; + // everything went fine + return new LdapUser( 0, username, Sha512Crypt.Sha512_crypt( password, null, 0 ), organization, firstName, lastName, eMail, satelliteAddress ); + } catch ( LdapException e) { + e.printStackTrace(); + throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Something went wrong." ); + } catch ( CursorException e ) { + e.printStackTrace(); + throw new AuthenticationException( AuthenticationError.INVALID_CREDENTIALS, "Could not find user entry." ); + } catch ( IOException e ) { + // could not load keyfile + e.printStackTrace(); + } catch ( NoSuchAlgorithmException e ) { + // could not load algorithm + e.printStackTrace(); + } catch ( KeyStoreException | NoSuchProviderException | CertificateException e ) { + // some problem with the key + e.printStackTrace(); } finally { // close connection try { connection.unBind(); - } catch ( LdapException e ) { - return null; - } - try { connection.close(); - } catch ( IOException e ) { - return null; + } catch ( IOException | LdapException e ) { + e.printStackTrace(); + throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Something went very wrong." ); } } - return new LdapUser( 0, username, Sha512Crypt.Sha512_crypt( password, null, 0 ), organization, firstName, lastName, eMail, satelliteAddress ); + return null; } } |