| 1 22 package org.jboss.test.security.test; 23 24 import java.lang.reflect.Method ; 25 import java.io.Serializable ; 26 import java.io.IOException ; 27 import java.security.MessageDigest ; 28 import java.security.Principal ; 29 import java.security.KeyStore ; 30 import java.security.cert.X509Certificate ; 31 import java.security.acl.Group ; 32 import java.sql.Connection ; 33 import java.sql.DriverManager ; 34 import java.sql.SQLException ; 35 import java.sql.Statement ; 36 import java.util.Enumeration ; 37 import java.util.HashMap ; 38 import java.util.Iterator ; 39 import java.util.Map ; 40 import java.util.Set ; 41 import java.net.URL ; 42 import javax.naming.InitialContext ; 43 import javax.security.auth.Subject ; 44 import javax.security.auth.login.AppConfigurationEntry ; 45 import javax.security.auth.login.Configuration ; 46 import javax.security.auth.login.LoginContext ; 47 import javax.security.auth.login.LoginException ; 48 import javax.sql.DataSource ; 49 import javax.resource.spi.security.PasswordCredential ; 50 import javax.management.MBeanServerFactory ; 51 import javax.management.MBeanServer ; 52 import javax.management.ObjectName ; 53 import javax.net.ssl.KeyManagerFactory; 54 import javax.net.ssl.TrustManagerFactory; 55 56 import junit.framework.TestSuite; 57 58 import org.jboss.logging.Logger; 59 60 import org.jboss.logging.XLevel; 61 import org.jboss.security.SimpleGroup; 62 import org.jboss.security.SimplePrincipal; 63 import org.jboss.security.Util; 64 import org.jboss.security.SecurityAssociation; 65 import org.jboss.security.SecurityDomain; 66 import org.jboss.security.plugins.JaasSecurityDomain; 67 import org.jboss.security.auth.callback.UsernamePasswordHandler; 68 import org.jboss.security.auth.callback.SecurityAssociationHandler; 69 import org.jboss.security.auth.spi.UsernamePasswordLoginModule; 70 import org.jboss.test.JBossTestCase; 71 72 77 public class LoginModulesUnitTestCase extends JBossTestCase 78 { 79 80 83 static class TestConfig extends Configuration  84 { 85 public void refresh() 86 { 87 } 88 89 public AppConfigurationEntry [] getAppConfigurationEntry(String name) 90 { 91 AppConfigurationEntry [] entry = null; 92 try 93 { 94 Class [] parameterTypes = {}; 95 Method m = getClass().getDeclaredMethod(name, parameterTypes); 96 Object [] args = {}; 97 entry = (AppConfigurationEntry []) m.invoke(this, args); 98 } 99 catch(Exception e) 100 { 101 } 102 return entry; 103 } 104 105 AppConfigurationEntry [] testClientLogin() 106 { 107 String name = "org.jboss.security.ClientLoginModule"; 108 HashMap options = new HashMap (); 109 options.put("restore-login-identity", "true"); 110 AppConfigurationEntry ace = new AppConfigurationEntry (name, 111 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 112 AppConfigurationEntry [] entry = {ace}; 113 return entry; 114 } 115 AppConfigurationEntry [] testIdentity() 116 { 117 String name = "org.jboss.security.auth.spi.IdentityLoginModule"; 118 HashMap options = new HashMap (); 119 options.put("principal", "stark"); 120 options.put("roles", "Role3,Role4"); 121 AppConfigurationEntry ace = new AppConfigurationEntry (name, 122 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 123 AppConfigurationEntry [] entry = {ace}; 124 return entry; 125 } 126 AppConfigurationEntry [] testJdbc() 127 { 128 String name = "org.jboss.security.auth.spi.DatabaseServerLoginModule"; 129 HashMap options = new HashMap (); 130 options.put("dsJndiName", "testJdbc"); 131 options.put("principalsQuery", "select Password from Principals where PrincipalID=?"); 132 options.put("rolesQuery", "select Role, RoleGroup from Roles where PrincipalID=?"); 133 AppConfigurationEntry ace = new AppConfigurationEntry (name, 134 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 135 AppConfigurationEntry [] entry = {ace}; 136 return entry; 137 } 138 AppConfigurationEntry [] testSimple() 139 { 140 String name = "org.jboss.security.auth.spi.SimpleServerLoginModule"; 141 AppConfigurationEntry ace = new AppConfigurationEntry (name, 142 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap ()); 143 AppConfigurationEntry [] entry = {ace}; 144 return entry; 145 } 146 AppConfigurationEntry [] testUsernamePassword() 147 { 148 return other(); 149 } 150 AppConfigurationEntry [] testUsernamePasswordHash() 151 { 152 HashMap options = new HashMap (); 153 options.put("hashAlgorithm", "MD5"); 154 options.put("hashEncoding", "base64"); 155 AppConfigurationEntry ace = new AppConfigurationEntry (HashTestLoginModule.class.getName(), 156 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 157 AppConfigurationEntry [] entry = {ace}; 158 return entry; 159 } 160 AppConfigurationEntry [] testUsernamePasswordHashWithDigestCallback() 161 { 162 HashMap options = new HashMap (); 163 options.put("hashAlgorithm", "MD5"); 164 options.put("hashEncoding", "base64"); 165 options.put("hashCharset", "UTF-8"); 166 options.put("digestCallback", "org.jboss.test.security.test.TestDigestCallback"); 167 options.put("digest.preSalt", "pre"); 168 options.put("digest.postSalt", "post"); 169 AppConfigurationEntry ace = new AppConfigurationEntry (HashTestDigestCallbackLoginModule.class.getName(), 170 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 171 AppConfigurationEntry [] entry = {ace}; 172 return entry; 173 } 174 AppConfigurationEntry [] testAnon() 175 { 176 String name = "org.jboss.security.auth.spi.AnonLoginModule"; 177 HashMap options = new HashMap (); 178 options.put("unauthenticatedIdentity", "nobody"); 179 AppConfigurationEntry ace = new AppConfigurationEntry (name, 180 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 181 AppConfigurationEntry [] entry = {ace}; 182 return entry; 183 } 184 AppConfigurationEntry [] testNull() 185 { 186 String name = "org.jboss.security.auth.spi.AnonLoginModule"; 187 HashMap options = new HashMap (); 188 AppConfigurationEntry ace = new AppConfigurationEntry (name, 189 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 190 AppConfigurationEntry [] entry = {ace}; 191 return entry; 192 } 193 AppConfigurationEntry [] testUsersRoles() 194 { 195 String name = "org.jboss.security.auth.spi.UsersRolesLoginModule"; 196 AppConfigurationEntry ace = new AppConfigurationEntry (name, 197 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap ()); 198 AppConfigurationEntry [] entry = {ace}; 199 return entry; 200 } 201 AppConfigurationEntry [] testUsersRolesHash() 202 { 203 String name = "org.jboss.security.auth.spi.UsersRolesLoginModule"; 204 HashMap options = new HashMap (); 205 options.put("usersProperties", "usersb64.properties"); 206 options.put("hashAlgorithm", "MD5"); 207 options.put("hashEncoding", "base64"); 208 AppConfigurationEntry ace = new AppConfigurationEntry (name, 209 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 210 AppConfigurationEntry [] entry = {ace}; 211 return entry; 212 } 213 AppConfigurationEntry [] testAnonUsersRoles() 214 { 215 String name = "org.jboss.security.auth.spi.UsersRolesLoginModule"; 216 HashMap options = new HashMap (); 217 options.put("unauthenticatedIdentity", "nobody"); 218 AppConfigurationEntry ace = new AppConfigurationEntry (name, 219 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 220 AppConfigurationEntry [] entry = {ace}; 221 return entry; 222 } 223 AppConfigurationEntry [] testControlFlags() 224 { 225 String name1 = "org.jboss.security.auth.spi.UsersRolesLoginModule"; 226 AppConfigurationEntry ace1 = new AppConfigurationEntry (name1, 227 AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, new HashMap ()); 228 229 String name2 = "org.jboss.security.auth.spi.DatabaseServerLoginModule"; 230 HashMap options = new HashMap (); 231 options.put("dsJndiName", "testJdbc"); 232 options.put("principalsQuery", "select Password from Principals where PrincipalID=?"); 233 options.put("rolesQuery", "select Role, RoleGroup from Roles where PrincipalID=?"); 234 AppConfigurationEntry ace2 = new AppConfigurationEntry (name2, 235 AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options); 236 237 AppConfigurationEntry [] entry = {ace1, ace2}; 238 return entry; 239 } 240 AppConfigurationEntry [] testJCACallerIdentity() 241 { 242 String name = "org.jboss.resource.security.CallerIdentityLoginModule"; 243 HashMap options = new HashMap (); 244 options.put("userName", "jduke"); 245 options.put("password", "theduke"); 246 options.put("managedConnectionFactoryName", "jboss:name=fakeMCF"); 247 options.put("ignoreMissigingMCF", Boolean.TRUE); 248 AppConfigurationEntry ace = new AppConfigurationEntry (name, 249 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 250 AppConfigurationEntry [] entry = {ace}; 251 return entry; 252 } 253 AppConfigurationEntry [] testJaasSecurityDomainIdentityLoginModule() 254 { 255 String name = "org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule"; 256 HashMap options = new HashMap (); 257 options.put("userName", "sa"); 258 options.put("password", "E5gtGMKcXPP"); 259 options.put("managedConnectionFactoryName", "jboss.jca:service=LocalTxCM,name=DefaultDS"); 260 options.put("ignoreMissigingMCF", Boolean.TRUE); 261 options.put("jaasSecurityDomain", "jboss.test:service=JaasSecurityDomain,domain=testJaasSecurityDomainIdentityLoginModule"); 262 AppConfigurationEntry ace = new AppConfigurationEntry (name, 263 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 264 AppConfigurationEntry [] entry = {ace}; 265 return entry; 266 } 267 AppConfigurationEntry [] testCertLogin() 268 { 269 String name = "org.jboss.security.auth.spi.BaseCertLoginModule"; 270 HashMap options = new HashMap (); 271 options.put("securityDomain", "testCertLogin"); 272 AppConfigurationEntry ace = new AppConfigurationEntry (name, 273 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 274 AppConfigurationEntry [] entry = {ace}; 275 return entry; 276 } 277 AppConfigurationEntry [] testCertRoles() 278 { 279 String name = "org.jboss.security.auth.spi.CertRolesLoginModule"; 280 HashMap options = new HashMap (); 281 options.put("securityDomain", "testCertRoles"); 282 AppConfigurationEntry ace = new AppConfigurationEntry (name, 283 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); 284 AppConfigurationEntry [] entry = {ace}; 285 return entry; 286 } 287 AppConfigurationEntry [] other() 288 { 289 AppConfigurationEntry ace = new AppConfigurationEntry (TestLoginModule.class.getName(), 290 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap ()); 291 AppConfigurationEntry [] entry = {ace}; 292 return entry; 293 } 294 } 295 296 public static class TestLoginModule extends UsernamePasswordLoginModule 297 { 298 protected Group [] getRoleSets() 299 { 300 SimpleGroup roles = new SimpleGroup("Roles"); 301 Group [] roleSets = {roles}; 302 roles.addMember(new SimplePrincipal("TestRole")); 303 roles.addMember(new SimplePrincipal("Role2")); 304 return roleSets; 305 } 306 308 protected String getUsersPassword() 309 { 310 return "secret"; 311 } 312 } 313 public static class HashTestLoginModule extends TestLoginModule 314 { 315 317 protected String getUsersPassword() 318 { 319 MessageDigest md = null; 320 try 321 { 322 md = MessageDigest.getInstance("MD5"); 323 } 324 catch(Exception e) 325 { 326 e.printStackTrace(); 327 } 328 byte[] passwordBytes = "secret".getBytes(); 329 byte[] hash = md.digest(passwordBytes); 330 String passwordHash = Util.encodeBase64(hash); 331 return passwordHash; 332 } 333 } 334 public static class HashTestDigestCallbackLoginModule extends TestLoginModule 335 { 336 338 protected String getUsersPassword() 339 { 340 MessageDigest md = null; 341 try 342 { 343 md = MessageDigest.getInstance("MD5"); 344 } 345 catch(Exception e) 346 { 347 e.printStackTrace(); 348 } 349 byte[] passwordBytes = "secret".getBytes(); 350 md.update("pre".getBytes()); 351 md.update(passwordBytes); 352 md.update("post".getBytes()); 353 byte[] hash = md.digest(); 354 String passwordHash = Util.encodeBase64(hash); 355 return passwordHash; 356 } 357 } 358 359 362 static class TestDS implements DataSource , Serializable  363 { 364 private static final long serialVersionUID = 1; 365 public java.sql.Connection getConnection() throws java.sql.SQLException  366 { 367 return getConnection("sa", ""); 368 } 369 public java.sql.Connection getConnection(String user, String pass) throws java.sql.SQLException  370 { 371 java.sql.Connection con = null; 372 String jdbcURL = ""; 373 try 374 { 375 jdbcURL = "jdbc:hsqldb:hsql://" + System.getProperty("jbosstest.server.host", "localhost") + ":1701"; 376 con = DriverManager.getConnection(jdbcURL, user, pass); 377 } 378 catch(java.sql.SQLException sqle) 379 { 380 jdbcURL = "jdbc:hsqldb:."; con = DriverManager.getConnection(jdbcURL, user, pass); 382 } 383 return con; 384 } 385 public java.io.PrintWriter getLogWriter() throws java.sql.SQLException  386 { 387 return null; 388 } 389 public void setLogWriter(java.io.PrintWriter out) 390 throws java.sql.SQLException  391 { 392 } 393 public int getLoginTimeout() throws java.sql.SQLException  394 { 395 return 0; 396 } 397 public void setLoginTimeout(int seconds) throws java.sql.SQLException  398 { 399 } 400 } 401 402 static class TestSecurityDomain implements SecurityDomain, Serializable  403 { 404 private static final long serialVersionUID = 1; 405 406 private transient KeyStore store; 407 408 public KeyStore getKeyStore() throws SecurityException  409 { 410 return store; 411 } 412 413 public KeyManagerFactory getKeyManagerFactory() throws SecurityException  414 { 415 return null; 416 } 417 418 public KeyStore getTrustStore() throws SecurityException  419 { 420 return store; 421 } 422 423 public TrustManagerFactory getTrustManagerFactory() throws SecurityException  424 { 425 return null; 426 } 427 428 public String getSecurityDomain() 429 { 430 return null; 431 } 432 433 public Subject getActiveSubject() 434 { 435 return null; 436 } 437 438 public boolean isValid(Principal principal, Object credential, 439 Subject activeSubject) 440 { 441 return false; 442 } 443 444 public boolean isValid(Principal principal, Object credential) 445 { 446 return false; 447 } 448 449 public Principal getPrincipal(Principal principal) 450 { 451 return null; 452 } 453 454 public boolean doesUserHaveRole(Principal principal, Set roles) 455 { 456 return false; 457 } 458 459 public Set getUserRoles(Principal principal) 460 { 461 return null; 462 } 463 464 private void readObject(java.io.ObjectInputStream in) 465 throws IOException  466 { 467 try 468 { 469 store = KeyStore.getInstance("JKS"); 470 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 471 URL resURL = loader.getResource("security/tst.keystore"); 472 store.load(resURL.openStream(), "unit-tests".toCharArray()); 473 } 474 catch(Exception e) 475 { 476 throw new IOException (e.toString()); 477 } 478 } 479 480 483 public Principal getTargetPrincipal(Principal anotherDomainPrincipal, Map contextMap) 484 { 485 throw new RuntimeException ("Not implemented yet"); 486 } 487 } 488 489 public LoginModulesUnitTestCase(String testName) 490 { 491 super(testName); 492 } 493 494 protected void setUp() throws Exception  495 { 496 Configuration.setConfiguration(new TestConfig()); 498 } 499 500 public void testClientLogin() throws Exception  501 { 502 getLog().info("testClientLogin"); 503 UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "secret".toCharArray()); 504 LoginContext lc = new LoginContext ("testClientLogin", handler); 505 lc.login(); 506 Subject subject = lc.getSubject(); 507 Principal scott = new SimplePrincipal("scott"); 508 assertTrue("Principals contains scott", subject.getPrincipals().contains(scott)); 509 Principal saPrincipal = SecurityAssociation.getPrincipal(); 510 assertTrue("SecurityAssociation.getPrincipal == scott", saPrincipal.equals(scott)); 511 512 UsernamePasswordHandler handler2 = new UsernamePasswordHandler("scott2", "secret2".toCharArray()); 513 LoginContext lc2 = new LoginContext ("testClientLogin", handler2); 514 lc2.login(); 515 Principal scott2 = new SimplePrincipal("scott2"); 516 saPrincipal = SecurityAssociation.getPrincipal(); 517 assertTrue("SecurityAssociation.getPrincipal == scott2", saPrincipal.equals(scott2)); 518 lc2.logout(); 519 saPrincipal = SecurityAssociation.getPrincipal(); 520 assertTrue("SecurityAssociation.getPrincipal == scott", saPrincipal.equals(scott)); 521 522 lc.logout(); 523 } 524 525 public void testUsernamePassword() throws Exception  526 { 527 getLog().info("testUsernamePassword"); 528 UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "secret".toCharArray()); 529 LoginContext lc = new LoginContext ("testUsernamePassword", handler); 530 lc.login(); 531 Subject subject = lc.getSubject(); 532 Set groups = subject.getPrincipals(Group .class); 533 assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott"))); 534 assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles"))); 535 Group roles = (Group ) groups.iterator().next(); 536 assertTrue("TestRole is a role", roles.isMember(new SimplePrincipal("TestRole"))); 537 assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2"))); 538 539 lc.logout(); 540 } 541 public void testUsernamePasswordHash() throws Exception  542 { 543 getLog().info("testUsernamePasswordHash"); 544 UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "secret".toCharArray()); 545 LoginContext lc = new LoginContext ("testUsernamePasswordHash", handler); 546 lc.login(); 547 Subject subject = lc.getSubject(); 548 Set groups = subject.getPrincipals(Group .class); 549 assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott"))); 550 assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles"))); 551 Group roles = (Group ) groups.iterator().next(); 552 assertTrue("TestRole is a role", roles.isMember(new SimplePrincipal("TestRole"))); 553 assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2"))); 554 555 lc.logout(); 556 } 557 558 public void testUsernamePasswordHashWithDigestCallback() throws Exception  559 { 560 getLog().info("testUsernamePasswordHashWithDigestCallback"); 561 byte[] passBytes = {115, 101, 99, 114, 101, 116}; 563 String pass = new String (passBytes, "UTF-8"); 564 UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", pass.toCharArray()); 565 LoginContext lc = new LoginContext ("testUsernamePasswordHashWithDigestCallback", handler); 566 lc.login(); 567 Subject subject = lc.getSubject(); 568 Set groups = subject.getPrincipals(Group .class); 569 assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott"))); 570 assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles"))); 571 Group roles = (Group ) groups.iterator().next(); 572 assertTrue("TestRole is a role", roles.isMember(new SimplePrincipal("TestRole"))); 573 assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2"))); 574 575 lc.logout(); 576 } 577 578 public void testUsersRoles() throws Exception  579 { 580 getLog().info("testUsersRoles"); 581 UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "echoman".toCharArray()); 582 LoginContext lc = new LoginContext ("testUsersRoles", handler); 583 lc.login(); 584 Subject subject = lc.getSubject(); 585 Set groups = subject.getPrincipals(Group .class); 586 assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott"))); 587 assertTrue("Principals contains Roles", groups.contains(new |