Am Dienstag, den 17.08.2010, 14:31 +0000 schrieb Igor Galić:
> > Either use the LdapTlsContextFactory, or the patched tomcat. Not both.
> > I
> > would advise to use the factory, since you can use a supported
> > tomcat.
> 
> ACK. Done that. In a vanilla Tomcat, I've put your LdapTlsContextFactory in
> jar in lib/ with a config such as this:
> 
> 
>                 <Realm className="org.apache.catalina.realm.JNDIRealm"
>                         connectionURL="ldap://mail.brainsware.org:389";
>                         alternateURL="ldap://mail.esotericsystems.at:389";
>                         commonRole="admin" connectionName="uid=whatever" 
> connectionPassword="securityisgreat."
>                         userBase="ou=people,dc=brainsware,dc=org" 
> userPattern="(uid={0})(postOfficeBox=internal_projects)"
>                         contextFactory="tc.startTLS.LdapTlsContextFactory"
>                         userSearch="uid={0}" />
That looks right. I believe I have found one issue with my code. It will
get a InitialDirContext with your admin user and password, before it is
negotiating TLS. I have attached another ContextFactory, which will
remove admin user, password and authentication method prior to TLS
negotiation. After (hopefully) establishing TLS it adds those parameters
back in. As with the last factory, you should select a package name of
your liking. 
> 
> On startup I see this:
> 
> INFO: Starting Servlet Engine: Apache Tomcat/6.0.29
> Aug 17, 2010 9:33:47 AM org.apache.catalina.realm.JNDIRealm open
> WARNING: Exception performing authentication
> javax.naming.AuthenticationNotSupportedException: [LDAP: error code 13 - 
> confidentiality required]
>         at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3032)
>         at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2987)
>         at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2789)
>         at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2703)
>         at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:293)
>         at 
> com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
>         at 
> com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
>         at 
> com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
>         at 
> com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
>         at 
> javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
>         at 
> javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
>         at javax.naming.InitialContext.init(InitialContext.java:223)
>         at 
> javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:134)
>         at 
> tc.startTLS.LdapTlsContextFactory$ProxyLdapContext.<init>(LdapTlsContextFactory.java:31)
this is just one line apart from startTLS :(

>         at 
> tc.startTLS.LdapTlsContextFactory$ProxyLdapContext.<init>(LdapTlsContextFactory.java:25)
>         at 
> tc.startTLS.LdapTlsContextFactory.getInitialContext(LdapTlsContextFactory.java:96)
>         at 
> javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
...
> 
> But the interesting thing is, that I see this here on login attempt (it's 
> actually the
> first time I've tried that in a long time now... so I don't know what the 
> other cases would
> have brought us):

> 
> SEVERE: An exception or error occurred in the container during the request 
> processing
> java.lang.reflect.UndeclaredThrowableException
>         at $Proxy0.getAttributes(Unknown Source)
>         at 
> javax.naming.directory.InitialDirContext.getAttributes(InitialDirContext.java:123)
I think this error is a result of the above stacktrace. The factory has
given us an object (proxy), which is not really useful. At least I hope
so.
>  
> > I had attached a second java class to my last mail, which you can use
> > to
> > test the connection to your ldap server without tomcat. You may have
> > to
> > specify a java keystore with your trusted certs. You can do this by
> > specifying the java env variable
> > -Djavax.net.ssl.trustStore=PATH_TO_MY/truststore.jks. If you want to
> > learn
> > more about the tls steps, you can specify  -Djavax.net.debug=ssl.
> 
> I haven't managed to get the TlsTest.java to compile.
Why? 

Bye
 Felix
>  
> > > The wireshark trace still looks the same.
> Yep, still does.
> 
> i

package dummy;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.StartTlsRequest;
import javax.naming.ldap.StartTlsResponse;
import javax.naming.spi.InitialContextFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import com.sun.jndi.ldap.LdapCtxFactory;

public class LdapTlsContextFactory implements InitialContextFactory {

	private static final class ProxyLdapContext implements InvocationHandler {
		private final LdapContext delegate;
		private final StartTlsResponse tls;

		@SuppressWarnings("unchecked")
		private ProxyLdapContext(Hashtable env) throws NamingException {
			Map<String, Object> savedEnv = new HashMap<String, Object>();
			for (String key : Arrays.asList(Context.SECURITY_AUTHENTICATION,
					Context.SECURITY_CREDENTIALS, Context.SECURITY_PRINCIPAL,
					Context.SECURITY_PROTOCOL)) {
				Object entry = env.remove(key);
				if (entry != null) {
					savedEnv.put(key, entry);
				}
			}
			delegate = new InitialLdapContext(env, null);
			tls = (StartTlsResponse) delegate
					.extendedOperation(new StartTlsRequest());
			tls.setHostnameVerifier(new HostnameVerifier() {

				@Override
				public boolean verify(String hostname, SSLSession session) {
					return true;
				}
			});
			try {
				SSLSession negotiate = tls.negotiate();
				Logger.getLogger(this.getClass().getCanonicalName()).fine(
						"LDAP is now using " + negotiate.getProtocol());
			} catch (IOException e) {
				throw new NamingException(e.getMessage());
			}
			for (Map.Entry<String, Object> savedEntry : savedEnv.entrySet()) {
				delegate.addToEnvironment(savedEntry.getKey(), savedEntry
						.getValue());
			}
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if ("close".equals(method.getName())) {
				return doClose(delegate);
			}
			return method.invoke(delegate, args);
		}

		private Object doClose(LdapContext delegate) throws IOException,
				IllegalAccessException, InvocationTargetException {
			try {
				if (tls != null) {
					try {
						tls.close();
					} catch (IOException e) {
						throw new InvocationTargetException(e);
					}
				}
			} finally {
				try {
					if (delegate != null) {
						delegate.close();
					}
				} catch (NamingException e) {
					throw new InvocationTargetException(e);
				}
			}
			return null;
		}
	}

	public static final String REAL_INITIAL_CONTEXT_FACTORY = "REAL_INITIAL_CONTEXT_FACTORY";

	@SuppressWarnings("unchecked")
	@Override
	public Context getInitialContext(final Hashtable environment)
			throws NamingException {
		final Hashtable proxyEnv = new Hashtable(environment);
		Object realFactory;
		if (environment.contains(REAL_INITIAL_CONTEXT_FACTORY)) {
			realFactory = environment.get(REAL_INITIAL_CONTEXT_FACTORY);
		} else {
			realFactory = LdapCtxFactory.class.getCanonicalName();
		}
		proxyEnv.put(Context.INITIAL_CONTEXT_FACTORY, realFactory);
		proxyEnv.put("com.sun.jndi.ldap.connect.pool", "false");
		return (Context) Proxy.newProxyInstance(this.getClass()
				.getClassLoader(), new Class<?>[] { DirContext.class },
				new ProxyLdapContext(proxyEnv));
	}

}

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to