/* */ package org.jboss.security.plugins.auth;
/* */
/* */ import java.lang.reflect.Method;
/* */ import java.lang.reflect.UndeclaredThrowableException;
/* */ import java.security.Principal;
/* */ import java.security.acl.Group;
/* */ import java.util.Arrays;
/* */ import java.util.Enumeration;
/* */ import java.util.HashMap;
/* */ import java.util.Iterator;
/* */ import java.util.Map;
/* */ import java.util.Set;
/* */ import javax.security.auth.Subject;
/* */ import javax.security.auth.callback.CallbackHandler;
/* */ import javax.security.auth.login.LoginContext;
/* */ import javax.security.auth.login.LoginException;
/* */ import javax.security.auth.message.AuthException;
/* */ import javax.security.auth.message.AuthStatus;
/* */ import javax.security.auth.message.MessageInfo;
/* */ import javax.security.auth.message.config.AuthConfigFactory;
/* */ import javax.security.auth.message.config.AuthConfigProvider;
/* */ import javax.security.auth.message.config.ServerAuthConfig;
/* */ import javax.security.auth.message.config.ServerAuthContext;
/* */ import javax.security.jacc.PolicyContext;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.security.AuthorizationManager;
/* */ import org.jboss.security.RealmMapping;
/* */ import org.jboss.security.SecurityContext;
/* */ import org.jboss.security.SecurityContextUtil;
/* */ import org.jboss.security.SecurityUtil;
/* */ import org.jboss.security.SubjectSecurityManager;
/* */ import org.jboss.security.auth.callback.AppCallbackHandler;
/* */ import org.jboss.security.auth.callback.SecurityAssociationHandler;
/* */ import org.jboss.security.plugins.SecurityContextAssociation;
/* */ import org.jboss.util.CachePolicy;
/* */ import org.jboss.util.TimedCachePolicy;
/* */ import org.jboss.util.TimedCachePolicy.TimedEntry;
/* */
/* */ public class JaasSecurityManagerBase
/* */ implements SubjectSecurityManager, RealmMapping
/* */ {
/* */ private String securityDomain;
/* */ private CachePolicy domainCache;
/* */ private CallbackHandler handler;
/* */ private transient Method setSecurityInfo;
/* 222 */ private boolean deepCopySubjectOption = false;
/* */ protected Logger log;
/* */ protected boolean trace;
/* */
/* */ public JaasSecurityManagerBase()
/* */ {
/* 234 */ this("other", new SecurityAssociationHandler());
/* */ }
/* */
/* */ public JaasSecurityManagerBase(String securityDomain, CallbackHandler handler)
/* */ {
/* 245 */ this.securityDomain = securityDomain;
/* 246 */ this.handler = handler;
/* 247 */ String categoryName = getClass().getName() + '.' + securityDomain;
/* 248 */ this.log = Logger.getLogger(categoryName);
/* 249 */ this.trace = this.log.isTraceEnabled();
/* */
/* 252 */ Class[] sig = { Principal.class, Object.class };
/* */ try
/* */ {
/* 255 */ this.setSecurityInfo = handler.getClass().getMethod("setSecurityInfo", sig);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 259 */ String msg = "Failed to find setSecurityInfo(Princpal, Object) method in handler";
/* 260 */ throw new UndeclaredThrowableException(e, msg);
/* */ }
/* 262 */ this.log.debug("CallbackHandler: " + handler);
/* */ }
/* */
/* */ public void setCachePolicy(CachePolicy domainCache)
/* */ {
/* 272 */ this.domainCache = domainCache;
/* 273 */ this.log.debug("CachePolicy set to: " + domainCache);
/* */ }
/* */
/* */ public void setDeepCopySubjectOption(Boolean flag)
/* */ {
/* 284 */ this.log.debug("setDeepCopySubjectOption=" + flag);
/* 285 */ this.deepCopySubjectOption = (flag == Boolean.TRUE);
/* */ }
/* */
/* */ public void flushCache()
/* */ {
/* 293 */ if (this.domainCache != null)
/* 294 */ this.domainCache.flush();
/* */ }
/* */
/* */ public String getSecurityDomain()
/* */ {
/* 302 */ return this.securityDomain;
/* */ }
/* */
/* */ public Subject getActiveSubject()
/* */ {
/* 317 */ Subject subj = null;
/* 318 */ SecurityContext sc = SecurityContextAssociation.getSecurityContext();
/* 319 */ if (sc != null)
/* */ {
/* 321 */ subj = sc.getUtil().getSubject();
/* */ }
/* 323 */ return subj;
/* */ }
/* */
/* */ public boolean isValid(Principal principal, Object credential)
/* */ {
/* 334 */ return isValid(principal, credential, null);
/* */ }
/* */
/* */ public boolean isValid(Principal principal, Object credential, Subject activeSubject)
/* */ {
/* 353 */ DomainInfo cacheInfo = getCacheInfo(principal, true);
/* 354 */ if (this.trace) {
/* 355 */ this.log.trace("Begin isValid, principal:" + principal + ", cache info: " + cacheInfo);
/* */ }
/* 357 */ boolean isValid = false;
/* 358 */ if (cacheInfo != null)
/* */ {
/* 360 */ isValid = validateCache(cacheInfo, credential, activeSubject);
/* 361 */ if (cacheInfo != null)
/* 362 */ cacheInfo.release();
/* */ }
/* 364 */ if (!isValid)
/* 365 */ isValid = authenticate(principal, credential, activeSubject);
/* 366 */ if (this.trace)
/* 367 */ this.log.trace("End isValid, " + isValid);
/* 368 */ return isValid;
/* */ }
/* */
/* */ public boolean isValid(MessageInfo requestMessage, Subject clientSubject, String layer)
/* */ {
/* 376 */ AuthStatus status = AuthStatus.FAILURE;
/* */ try
/* */ {
/* 380 */ String contextID = PolicyContext.getContextID();
/* 381 */ AuthConfigFactory factory = AuthConfigFactory.getFactory();
/* 382 */ AuthConfigProvider provider = factory.getConfigProvider(layer, contextID, null);
/* 383 */ ServerAuthConfig serverConfig = provider.getServerAuthConfig(layer, contextID, new AppCallbackHandler("DUMMY", "DUMMY".toCharArray()));
/* */
/* 385 */ ServerAuthContext sctx = serverConfig.getAuthContext(contextID, new Subject(), new HashMap());
/* */
/* 387 */ if (clientSubject == null)
/* 388 */ clientSubject = new Subject();
/* 389 */ Subject serviceSubject = new Subject();
/* 390 */ status = sctx.validateRequest(requestMessage, clientSubject, serviceSubject);
/* */ }
/* */ catch (AuthException ae)
/* */ {
/* 395 */ this.log.trace("AuthException:", ae);
/* */ }
/* 397 */ return AuthStatus.SUCCESS == status;
/* */ }
/* */
/* */ public Principal getPrincipal(Principal principal)
/* */ {
/* 410 */ if (this.domainCache == null)
/* 411 */ return principal;
/* 412 */ Principal result = principal;
/* */
/* 414 */ synchronized (this.domainCache)
/* */ {
/* 416 */ DomainInfo info = getCacheInfo(principal, false);
/* 417 */ if (this.trace)
/* 418 */ this.log.trace("getPrincipal, cache info: " + info);
/* 419 */ if (info != null)
/* */ {
/* 421 */ result = info.callerPrincipal;
/* */
/* 423 */ if (result == null)
/* 424 */ result = principal;
/* 425 */ info.release();
/* */ }
/* */ }
/* */
/* 429 */ return result;
/* */ }
/* */
/* */ public boolean doesUserHaveRole(Principal principal, Set<Principal> rolePrincipals)
/* */ {
/* 451 */ AuthorizationManager am = SecurityUtil.getAuthorizationManager(this.securityDomain, "java:/jaas");
/* */
/* 453 */ return am.doesUserHaveRole(principal, rolePrincipals);
/* */ }
/* */
/* */ public Set<Principal> getUserRoles(Principal principal)
/* */ {
/* 466 */ AuthorizationManager am = SecurityUtil.getAuthorizationManager(this.securityDomain, "java:/jaas");
/* */
/* 468 */ return am.getUserRoles(principal);
/* */ }
/* */
/* */ public Principal getTargetPrincipal(Principal anotherDomainPrincipal, Map<String, Object> contextMap)
/* */ {
/* 477 */ throw new RuntimeException("Not implemented yet");
/* */ }
/* */
/* */ private boolean authenticate(Principal principal, Object credential, Subject theSubject)
/* */ {
/* 490 */ Subject subject = null;
/* 491 */ boolean authenticated = false;
/* 492 */ LoginException authException = null;
/* */ try
/* */ {
/* 497 */ LoginContext lc = defaultLogin(principal, credential);
/* 498 */ subject = lc.getSubject();
/* */
/* 501 */ if (subject != null)
/* */ {
/* 504 */ if (theSubject != null)
/* */ {
/* 506 */ SubjectActions.copySubject(subject, theSubject, false, this.deepCopySubjectOption);
/* */ }
/* */ else
/* */ {
/* 510 */ theSubject = subject;
/* */ }
/* */
/* 513 */ authenticated = true;
/* */
/* 515 */ updateCache(lc, subject, principal, credential);
/* */ }
/* */
/* */ }
/* */ catch (LoginException e)
/* */ {
/* 521 */ if (((principal != null) && (principal.getName() != null)) || (this.trace))
/* 522 */ this.log.trace("Login failure", e);
/* 523 */ authException = e;
/* */ }
/* */
/* 526 */ SubjectActions.setContextInfo("org.jboss.security.exception", authException);
/* */
/* 528 */ return authenticated;
/* */ }
/* */
/* */ private LoginContext defaultLogin(Principal principal, Object credential)
/* */ throws LoginException
/* */ {
/* 543 */ Object[] securityInfo = { principal, credential };
/* 544 */ CallbackHandler theHandler = null;
/* */ try
/* */ {
/* 547 */ theHandler = (CallbackHandler)this.handler.getClass().newInstance();
/* 548 */ this.setSecurityInfo.invoke(theHandler, securityInfo);
/* */ }
/* */ catch (Throwable e)
/* */ {
/* 552 */ if (this.trace)
/* 553 */ this.log.trace("Failed to create/setSecurityInfo on handler", e);
/* 554 */ LoginException le = new LoginException("Failed to setSecurityInfo on handler");
/* 555 */ le.initCause(e);
/* 556 */ throw le;
/* */ }
/* 558 */ Subject subject = new Subject();
/* 559 */ LoginContext lc = null;
/* 560 */ if (this.trace)
/* 561 */ this.log.trace("defaultLogin, principal=" + principal);
/* 562 */ lc = SubjectActions.createLoginContext(this.securityDomain, subject, theHandler);
/* 563 */ lc.login();
/* 564 */ if (this.trace)
/* 565 */ this.log.trace("defaultLogin, lc=" + lc + ", subject=" + SubjectActions.toString(subject));
/* 566 */ return lc;
/* */ }
/* */
/* */ private boolean validateCache(DomainInfo info, Object credential, Subject theSubject)
/* */ {
/* 574 */ if (this.trace)
/* */ {
/* 576 */ StringBuffer tmp = new StringBuffer("Begin validateCache, info=");
/* 577 */ tmp.append(info.toString());
/* 578 */ tmp.append(";credential.class=");
/* 579 */ if (credential != null)
/* */ {
/* 581 */ Class c = credential.getClass();
/* 582 */ tmp.append(c.getName());
/* 583 */ tmp.append('@');
/* 584 */ tmp.append(System.identityHashCode(c));
/* */ }
/* */ else
/* */ {
/* 588 */ tmp.append("null");
/* */ }
/* 590 */ this.log.trace(tmp.toString());
/* */ }
/* */
/* 593 */ Object subjectCredential = info.credential;
/* 594 */ boolean isValid = false;
/* */
/* 596 */ if ((credential == null) || (subjectCredential == null))
/* */ {
/* 599 */ isValid = (credential == null) && (subjectCredential == null);
/* */ }
/* 602 */ else if (subjectCredential.getClass().isAssignableFrom(credential.getClass()))
/* */ {
/* 607 */ if ((subjectCredential instanceof Comparable))
/* */ {
/* 609 */ Comparable c = (Comparable)subjectCredential;
/* 610 */ isValid = c.compareTo(credential) == 0;
/* */ }
/* 612 */ else if ((subjectCredential instanceof char[]))
/* */ {
/* 614 */ char[] a1 = (char[])(char[])subjectCredential;
/* 615 */ char[] a2 = (char[])(char[])credential;
/* 616 */ isValid = Arrays.equals(a1, a2);
/* */ }
/* 618 */ else if ((subjectCredential instanceof byte[]))
/* */ {
/* 620 */ byte[] a1 = (byte[])(byte[])subjectCredential;
/* 621 */ byte[] a2 = (byte[])(byte[])credential;
/* 622 */ isValid = Arrays.equals(a1, a2);
/* */ }
/* 624 */ else if (subjectCredential.getClass().isArray())
/* */ {
/* 626 */ Object[] a1 = (Object[])(Object[])subjectCredential;
/* 627 */ Object[] a2 = (Object[])(Object[])credential;
/* 628 */ isValid = Arrays.equals(a1, a2);
/* */ }
/* */ else
/* */ {
/* 632 */ isValid = subjectCredential.equals(credential);
/* */ }
/* */ }
/* 635 */ else if (((subjectCredential instanceof char[])) && ((credential instanceof String)))
/* */ {
/* 637 */ char[] a1 = (char[])(char[])subjectCredential;
/* 638 */ char[] a2 = ((String)credential).toCharArray();
/* 639 */ isValid = Arrays.equals(a1, a2);
/* */ }
/* 641 */ else if (((subjectCredential instanceof String)) && ((credential instanceof char[])))
/* */ {
/* 643 */ char[] a1 = ((String)subjectCredential).toCharArray();
/* 644 */ char[] a2 = (char[])(char[])credential;
/* 645 */ isValid = Arrays.equals(a1, a2);
/* */ }
/* */
/* 649 */ if (isValid)
/* */ {
/* 652 */ if (theSubject != null)
/* */ {
/* 654 */ SubjectActions.copySubject(info.subject, theSubject, false, this.deepCopySubjectOption);
/* */ }
/* */ }
/* 657 */ if (this.trace) {
/* 658 */ this.log.trace("End validateCache, isValid=" + isValid);
/* */ }
/* 660 */ return isValid;
/* */ }
/* */
/* */ private DomainInfo getCacheInfo(Principal principal, boolean allowRefresh)
/* */ {
/* 677 */ if (this.domainCache == null) {
/* 678 */ return null;
/* */ }
/* 680 */ DomainInfo cacheInfo = null;
/* 681 */ synchronized (this.domainCache)
/* */ {
/* 683 */ if (allowRefresh == true)
/* 684 */ cacheInfo = (DomainInfo)this.domainCache.get(principal);
/* */ else
/* 686 */ cacheInfo = (DomainInfo)this.domainCache.peek(principal);
/* 687 */ if (cacheInfo != null)
/* 688 */ cacheInfo.acquire();
/* */ }
/* 690 */ return cacheInfo;
/* */ }
/* */
/* */ private Subject updateCache(LoginContext lc, Subject subject, Principal principal, Object credential)
/* */ {
/* 697 */ if (this.domainCache == null) {
/* 698 */ return subject;
/* */ }
/* 700 */ long lifetime = 0L;
/* 701 */ if ((this.domainCache instanceof TimedCachePolicy))
/* */ {
/* 703 */ TimedCachePolicy cache = (TimedCachePolicy)this.domainCache;
/* 704 */ lifetime = cache.getDefaultLifetime();
/* */ }
/* 706 */ DomainInfo info = new DomainInfo(lifetime);
/* 707 */ DomainInfo.access$302(info, lc);
/* 708 */ DomainInfo.access$202(info, new Subject());
/* 709 */ SubjectActions.copySubject(subject, info.subject, true, this.deepCopySubjectOption);
/* 710 */ DomainInfo.access$102(info, credential);
/* */
/* 712 */ if (this.trace)
/* */ {
/* 714 */ this.log.trace("updateCache, inputSubject=" + SubjectActions.toString(subject) + ", cacheSubject=" + SubjectActions.toString(info.subject));
/* */ }
/* */
/* 721 */ Set subjectGroups = subject.getPrincipals(Group.class);
/* 722 */ Iterator iter = subjectGroups.iterator();
/* 723 */ while (iter.hasNext())
/* */ {
/* 725 */ Group grp = (Group)iter.next();
/* 726 */ String name = grp.getName();
/* 727 */ if (name.equals("CallerPrincipal"))
/* */ {
/* 729 */ Enumeration members = grp.members();
/* 730 */ if (members.hasMoreElements()) {
/* 731 */ DomainInfo.access$002(info, (Principal)members.nextElement());
/* */ }
/* */
/* */ }
/* */
/* */ }
/* */
/* 740 */ if ((principal == null) && (info.callerPrincipal == null))
/* */ {
/* 742 */ Set subjectPrincipals = subject.getPrincipals(Principal.class);
/* 743 */ iter = subjectPrincipals.iterator();
/* 744 */ while (iter.hasNext())
/* */ {
/* 746 */ Principal p = (Principal)iter.next();
/* 747 */ if (!(p instanceof Group)) {
/* 748 */ DomainInfo.access$002(info, p);
/* */ }
/* */
/* */ }
/* */
/* */ }
/* */
/* 757 */ synchronized (this.domainCache)
/* */ {
/* 759 */ if (this.domainCache.peek(principal) != null)
/* 760 */ this.domainCache.remove(principal);
/* 761 */ this.domainCache.insert(principal, info);
/* 762 */ if (this.trace)
/* 763 */ this.log.trace("Inserted cache info: " + info);
/* */ }
/* 765 */ return info.subject;
/* */ }
/* */
/* */ public static class DomainInfo
/* */ implements TimedCachePolicy.TimedEntry
/* */ {
/* 84 */ private static Logger log = Logger.getLogger(DomainInfo.class);
/* 85 */ private static boolean trace = log.isTraceEnabled();
/* */ private LoginContext loginCtx;
/* */ private Subject subject;
/* */ private Object credential;
/* */ private Principal callerPrincipal;
/* */ private long expirationTime;
/* */ private boolean needsDestroy;
/* */ private int activeUsers;
/* */
/* */ public DomainInfo(long lifetime)
/* */ {
/* 106 */ this.expirationTime = lifetime;
/* 107 */ if (this.expirationTime != -1L)
/* 108 */ this.expirationTime *= 1000L;
/* */ }
/* */
/* */ synchronized int acquire()
/* */ {
/* 113 */ return this.activeUsers++;
/* */ }
/* */
/* */ synchronized int release() {
/* 117 */ int users = this.activeUsers--;
/* 118 */ if ((this.needsDestroy == true) && (users == 0))
/* */ {
/* 120 */ if (trace)
/* 121 */ log.trace("needsDestroy is true, doing logout");
/* 122 */ logout();
/* */ }
/* 124 */ return users;
/* */ }
/* */
/* */ synchronized void logout() {
/* 128 */ if (trace)
/* 129 */ log.trace("logout, subject=" + this.subject + ", this=" + this);
/* */ try
/* */ {
/* 132 */ if (this.loginCtx != null)
/* 133 */ this.loginCtx.logout();
/* */ }
/* */ catch (Throwable e)
/* */ {
/* 137 */ if (trace)
/* 138 */ log.trace("Cache entry logout failed", e);
/* */ }
/* */ }
/* */
/* */ public void init(long now)
/* */ {
/* 144 */ this.expirationTime += now;
/* */ }
/* */
/* */ public boolean isCurrent(long now) {
/* 148 */ boolean isCurrent = this.expirationTime == -1L;
/* 149 */ if (!isCurrent)
/* 150 */ isCurrent = this.expirationTime > now;
/* 151 */ return isCurrent;
/* */ }
/* */
/* */ public boolean refresh() {
/* 155 */ return false;
/* */ }
/* */
/* */ public void destroy()
/* */ {
/* 162 */ if (trace)
/* */ {
/* 164 */ log.trace("destroy, subject=" + this.subject + ", this=" + this + ", activeUsers=" + this.activeUsers);
/* */ }
/* */
/* 168 */ synchronized (this)
/* */ {
/* 170 */ if (this.activeUsers == 0) {
/* 171 */ logout();
/* */ }
/* */ else {
/* 174 */ if (trace)
/* 175 */ log.trace("destroy saw activeUsers=" + this.activeUsers);
/* 176 */ this.needsDestroy = true;
/* */ }
/* */ }
/* */ }
/* */
/* */ public Object getValue() {
/* 182 */ return this;
/* */ }
/* */
/* */ public String toString() {
/* 186 */ StringBuffer tmp = new StringBuffer(super.toString());
/* 187 */ tmp.append('[');
/* 188 */ tmp.append(SubjectActions.toString(this.subject));
/* 189 */ tmp.append(",credential.class=");
/* 190 */ if (this.credential != null)
/* */ {
/* 192 */ Class c = this.credential.getClass();
/* 193 */ tmp.append(c.getName());
/* 194 */ tmp.append('@');
/* 195 */ tmp.append(System.identityHashCode(c));
/* */ }
/* */ else
/* */ {
/* 199 */ tmp.append("null");
/* */ }
/* 201 */ tmp.append(",expirationTime=");
/* 202 */ tmp.append(this.expirationTime);
/* 203 */ tmp.append(']');
/* */
/* 205 */ return tmp.toString();
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.security.plugins.auth.JaasSecurityManagerBase
* JD-Core Version: 0.6.0
*/