1 /* 2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @author Vincent Ryan 27 * @bug 4814522 28 * @summary Check that an LdapLoginModule can be initialized using various 29 * JAAS configurations. 30 * (LdapLoginModule replaces the JndiLoginModule for LDAP access) 31 * 32 * Run this test twice, once using the default security manager: 33 * 34 * @run main/othervm CheckConfigs 35 * @run main/othervm/policy=CheckConfigs.policy CheckConfigs 36 */ 37 38 import java.io.IOException; 39 import java.util.Collections; 40 import java.util.Map; 41 import java.util.HashMap; 42 43 import javax.naming.CommunicationException; 44 import javax.security.auth.*; 45 import javax.security.auth.login.*; 46 import javax.security.auth.callback.*; 47 import com.sun.security.auth.module.LdapLoginModule; 48 49 public class CheckConfigs { 50 51 public static void main(String[] args) throws Exception { 52 SecurityManager securityManager = System.getSecurityManager(); 53 System.out.println(securityManager == null 54 ? "[security manager is not running]" 55 : "[security manager is running: " + 56 securityManager.getClass().getName() + "]"); 57 init(); 58 checkConfigModes(); 59 } 60 61 private static void init() throws Exception { 62 } 63 64 private static void checkConfigModes() throws Exception { 65 66 LoginContext ldapLogin; 67 68 // search-first mode 69 System.out.println("Testing search-first mode..."); 70 try { 71 ldapLogin = new LoginContext(LdapConfiguration.LOGIN_CONFIG_NAME, 72 null, new TestCallbackHandler(), new SearchFirstMode()); 73 ldapLogin.login(); 74 throw new SecurityException("expected a LoginException"); 75 76 } catch (LoginException le) { 77 // expected behaviour (because no LDAP server is available) 78 if (!(le.getCause() instanceof CommunicationException)) { 79 throw le; 80 } 81 } 82 83 // authentication-first mode 84 System.out.println("\nTesting authentication-first mode..."); 85 try { 86 ldapLogin = new LoginContext(LdapConfiguration.LOGIN_CONFIG_NAME, 87 null, new TestCallbackHandler(), new AuthFirstMode()); 88 ldapLogin.login(); 89 throw new SecurityException("expected a LoginException"); 90 91 } catch (LoginException le) { 92 // expected behaviour (because no LDAP server is available) 93 if (!(le.getCause() instanceof CommunicationException)) { 94 throw le; 95 } 96 } 97 98 // authentication-only mode 99 System.out.println("\nTesting authentication-only mode..."); 100 try { 101 ldapLogin = new LoginContext(LdapConfiguration.LOGIN_CONFIG_NAME, 102 null, new TestCallbackHandler(), new AuthOnlyMode()); 103 ldapLogin.login(); 104 throw new SecurityException("expected a LoginException"); 105 106 } catch (LoginException le) { 107 // expected behaviour (because no LDAP server is available) 108 if (!(le.getCause() instanceof CommunicationException)) { 109 throw le; 110 } 111 } 112 } 113 114 private static class TestCallbackHandler implements CallbackHandler { 115 116 public void handle(Callback[] callbacks) 117 throws IOException, UnsupportedCallbackException { 118 119 for (int i = 0; i < callbacks.length; i++) { 120 if (callbacks[i] instanceof NameCallback) { 121 ((NameCallback)callbacks[i]).setName("myname"); 122 123 } else if (callbacks[i] instanceof PasswordCallback) { 124 ((PasswordCallback)callbacks[i]) 125 .setPassword("mypassword".toCharArray()); 126 127 } else { 128 throw new UnsupportedCallbackException 129 (callbacks[i], "Unrecognized callback"); 130 } 131 } 132 } 133 } 134 } 135 136 class LdapConfiguration extends Configuration { 137 138 // The JAAS configuration name for ldap-based authentication 139 public static final String LOGIN_CONFIG_NAME = "TestAuth"; 140 141 // The JAAS configuration for ldap-based authentication 142 protected static AppConfigurationEntry[] entries; 143 144 // The classname of the login module for ldap-based authentication 145 protected static final String LDAP_LOGIN_MODULE = 146 LdapLoginModule.class.getName(); 147 148 /** 149 * Gets the JAAS configuration for ldap-based authentication 150 */ 151 public AppConfigurationEntry[] getAppConfigurationEntry(String name) { 152 return name.equals(LOGIN_CONFIG_NAME) ? entries : null; 153 } 154 155 /** 156 * Refreshes the configuration. 157 */ 158 public void refresh() { 159 // the configuration is fixed 160 } 161 } 162 163 /** 164 * This class defines the JAAS configuration for ldap-based authentication. 165 * It is equivalent to the following textual configuration entry: 166 * <pre> 167 * TestAuth { 168 * com.sun.security.auth.module.LdapLoginModule REQUIRED 169 * userProvider="ldap://localhost:23456/dc=example,dc=com" 170 * userFilter="(&(uid={USERNAME})(objectClass=inetOrgPerson))" 171 * authzIdentity="{EMPLOYEENUMBER}" 172 * debug=true; 173 * }; 174 * </pre> 175 */ 176 class SearchFirstMode extends LdapConfiguration { 177 178 public SearchFirstMode() { 179 super(); 180 181 Map<String, String> options = new HashMap<>(4); 182 options.put("userProvider", "ldap://localhost:23456/dc=example,dc=com"); 183 options.put("userFilter", 184 "(&(uid={USERNAME})(objectClass=inetOrgPerson))"); 185 options.put("authzIdentity", "{EMPLOYEENUMBER}"); 186 options.put("debug", "true"); 187 188 entries = new AppConfigurationEntry[] { 189 new AppConfigurationEntry(LDAP_LOGIN_MODULE, 190 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, 191 options) 192 }; 193 } 194 195 } 196 197 /** 198 * This class defines the JAAS configuration for ldap-based authentication. 199 * It is equivalent to the following textual configuration entry: 200 * <pre> 201 * TestAuth { 202 * com.sun.security.auth.module.LdapLoginModule REQUIRED 203 * userProvider="ldap://localhost:23456/dc=example,dc=com" 204 * authIdentity="{USERNAME}" 205 * userFilter="(&(|(samAccountName={USERNAME})(userPrincipalName={USERNAME})(cn={USERNAME}))(objectClass=user))" 206 * useSSL=false 207 * debug=true; 208 * }; 209 * </pre> 210 */ 211 class AuthFirstMode extends LdapConfiguration { 212 213 public AuthFirstMode() { 214 super(); 215 216 Map<String, String> options = new HashMap<>(5); 217 options.put("userProvider", "ldap://localhost:23456/dc=example,dc=com"); 218 options.put("authIdentity", "{USERNAME}"); 219 options.put("userFilter", 220 "(&(|(samAccountName={USERNAME})(userPrincipalName={USERNAME})" + 221 "(cn={USERNAME}))(objectClass=user))"); 222 options.put("useSSL", "false"); 223 options.put("debug", "true"); 224 225 entries = new AppConfigurationEntry[] { 226 new AppConfigurationEntry(LDAP_LOGIN_MODULE, 227 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, 228 options) 229 }; 230 } 231 } 232 233 /** 234 * This class defines the JAAS configuration for ldap-based authentication. 235 * It is equivalent to the following textual configuration entry: 236 * <pre> 237 * TestAuth { 238 * com.sun.security.auth.module.LdapLoginModule REQUIRED 239 * userProvider="ldap://localhost:23456 ldap://localhost:23457" 240 * authIdentity="cn={USERNAME},ou=people,dc=example,dc=com" 241 * authzIdentity="staff" 242 * debug=true; 243 * }; 244 * </pre> 245 */ 246 class AuthOnlyMode extends LdapConfiguration { 247 248 public AuthOnlyMode() { 249 super(); 250 251 Map<String, String> options = new HashMap<>(4); 252 options.put("userProvider", 253 "ldap://localhost:23456 ldap://localhost:23457"); 254 options.put("authIdentity", 255 "cn={USERNAME},ou=people,dc=example,dc=com"); 256 options.put("authzIdentity", "staff"); 257 options.put("debug", "true"); 258 259 entries = new AppConfigurationEntry[] { 260 new AppConfigurationEntry(LDAP_LOGIN_MODULE, 261 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, 262 options) 263 }; 264 } 265 266 }