/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /** * @test * @author Vincent Ryan * @bug 4814522 * @summary Check that an LdapLoginModule can be initialized using various * JAAS configurations. * (LdapLoginModule replaces the JndiLoginModule for LDAP access) * * Run this test twice, once using the default security manager: * * @run main/othervm CheckConfigs * @run main/othervm/policy=CheckConfigs.policy CheckConfigs */ import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.HashMap; import javax.naming.CommunicationException; import javax.security.auth.*; import javax.security.auth.login.*; import javax.security.auth.callback.*; import com.sun.security.auth.module.LdapLoginModule; public class CheckConfigs { public static void main(String[] args) throws Exception { SecurityManager securityManager = System.getSecurityManager(); System.out.println(securityManager == null ? "[security manager is not running]" : "[security manager is running: " + securityManager.getClass().getName() + "]"); init(); checkConfigModes(); } private static void init() throws Exception { } private static void checkConfigModes() throws Exception { LoginContext ldapLogin; // search-first mode System.out.println("Testing search-first mode..."); try { ldapLogin = new LoginContext(LdapConfiguration.LOGIN_CONFIG_NAME, null, new TestCallbackHandler(), new SearchFirstMode()); ldapLogin.login(); throw new SecurityException("expected a LoginException"); } catch (LoginException le) { // expected behaviour (because no LDAP server is available) if (!(le.getCause() instanceof CommunicationException)) { throw le; } } // authentication-first mode System.out.println("\nTesting authentication-first mode..."); try { ldapLogin = new LoginContext(LdapConfiguration.LOGIN_CONFIG_NAME, null, new TestCallbackHandler(), new AuthFirstMode()); ldapLogin.login(); throw new SecurityException("expected a LoginException"); } catch (LoginException le) { // expected behaviour (because no LDAP server is available) if (!(le.getCause() instanceof CommunicationException)) { throw le; } } // authentication-only mode System.out.println("\nTesting authentication-only mode..."); try { ldapLogin = new LoginContext(LdapConfiguration.LOGIN_CONFIG_NAME, null, new TestCallbackHandler(), new AuthOnlyMode()); ldapLogin.login(); throw new SecurityException("expected a LoginException"); } catch (LoginException le) { // expected behaviour (because no LDAP server is available) if (!(le.getCause() instanceof CommunicationException)) { throw le; } } } private static class TestCallbackHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { ((NameCallback)callbacks[i]).setName("myname"); } else if (callbacks[i] instanceof PasswordCallback) { ((PasswordCallback)callbacks[i]) .setPassword("mypassword".toCharArray()); } else { throw new UnsupportedCallbackException (callbacks[i], "Unrecognized callback"); } } } } } class LdapConfiguration extends Configuration { // The JAAS configuration name for ldap-based authentication public static final String LOGIN_CONFIG_NAME = "TestAuth"; // The JAAS configuration for ldap-based authentication protected static AppConfigurationEntry[] entries; // The classname of the login module for ldap-based authentication protected static final String LDAP_LOGIN_MODULE = LdapLoginModule.class.getName(); /** * Gets the JAAS configuration for ldap-based authentication */ public AppConfigurationEntry[] getAppConfigurationEntry(String name) { return name.equals(LOGIN_CONFIG_NAME) ? entries : null; } /** * Refreshes the configuration. */ public void refresh() { // the configuration is fixed } } /** * This class defines the JAAS configuration for ldap-based authentication. * It is equivalent to the following textual configuration entry: * <pre> * TestAuth { * com.sun.security.auth.module.LdapLoginModule REQUIRED * userProvider="ldap://localhost:23456/dc=example,dc=com" * userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))" * authzIdentity="{EMPLOYEENUMBER}" * debug=true; * }; * </pre> */ class SearchFirstMode extends LdapConfiguration { public SearchFirstMode() { super(); Map<String, String> options = new HashMap<String, String>(4); options.put("userProvider", "ldap://localhost:23456/dc=example,dc=com"); options.put("userFilter", "(&(uid={USERNAME})(objectClass=inetOrgPerson))"); options.put("authzIdentity", "{EMPLOYEENUMBER}"); options.put("debug", "true"); entries = new AppConfigurationEntry[] { new AppConfigurationEntry(LDAP_LOGIN_MODULE, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; } } /** * This class defines the JAAS configuration for ldap-based authentication. * It is equivalent to the following textual configuration entry: * <pre> * TestAuth { * com.sun.security.auth.module.LdapLoginModule REQUIRED * userProvider="ldap://localhost:23456/dc=example,dc=com" * authIdentity="{USERNAME}" * userFilter="(&(|(samAccountName={USERNAME})(userPrincipalName={USERNAME})(cn={USERNAME}))(objectClass=user))" * useSSL=false * debug=true; * }; * </pre> */ class AuthFirstMode extends LdapConfiguration { public AuthFirstMode() { super(); Map<String, String> options = new HashMap<String, String>(5); options.put("userProvider", "ldap://localhost:23456/dc=example,dc=com"); options.put("authIdentity", "{USERNAME}"); options.put("userFilter", "(&(|(samAccountName={USERNAME})(userPrincipalName={USERNAME})" + "(cn={USERNAME}))(objectClass=user))"); options.put("useSSL", "false"); options.put("debug", "true"); entries = new AppConfigurationEntry[] { new AppConfigurationEntry(LDAP_LOGIN_MODULE, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; } } /** * This class defines the JAAS configuration for ldap-based authentication. * It is equivalent to the following textual configuration entry: * <pre> * TestAuth { * com.sun.security.auth.module.LdapLoginModule REQUIRED * userProvider="ldap://localhost:23456 ldap://localhost:23457" * authIdentity="cn={USERNAME},ou=people,dc=example,dc=com" * authzIdentity="staff" * debug=true; * }; * </pre> */ class AuthOnlyMode extends LdapConfiguration { public AuthOnlyMode() { super(); Map<String, String> options = new HashMap<String, String>(4); options.put("userProvider", "ldap://localhost:23456 ldap://localhost:23457"); options.put("authIdentity", "cn={USERNAME},ou=people,dc=example,dc=com"); options.put("authzIdentity", "staff"); options.put("debug", "true"); entries = new AppConfigurationEntry[] { new AppConfigurationEntry(LDAP_LOGIN_MODULE, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; } }