1 23 24 package com.sun.web.security; 25 26 import java.io.File ; 27 import java.security.*; 28 import java.util.Set ; 29 import java.util.HashSet ; 30 import java.util.List ; 31 import java.util.ArrayList ; 32 import java.util.Iterator ; 33 import java.util.Map ; 34 import java.util.WeakHashMap ; 35 import java.util.Collections ; 36 import java.lang.*; 37 import java.net.URL ; 38 import java.net.URLEncoder ; 39 import java.net.URI ; 40 41 import javax.servlet.http.HttpServletRequest ; 42 import javax.security.jacc.*; 43 44 import java.util.logging.*; 45 import java.util.HashMap ; 46 import java.util.Map ; 47 import com.sun.logging.LogDomains; 48 import com.sun.web.security.WebPermissionUtil; 49 import com.sun.enterprise.deployment.WebBundleDescriptor; 50 import com.sun.enterprise.security.authorize.*; 51 import com.sun.enterprise.security.CachedPermission; 52 import com.sun.enterprise.security.CachedPermissionImpl; 53 import com.sun.enterprise.security.PermissionCache; 54 import com.sun.enterprise.security.PermissionCacheFactory; 55 import com.sun.enterprise.security.SecurityContext; 56 import com.sun.enterprise.security.audit.AuditManager; 57 import com.sun.enterprise.security.audit.AuditManagerFactory; 58 import com.sun.enterprise.security.authorize.PolicyContextHandlerImpl; 59 import com.sun.enterprise.web.WebContainer; 60 import com.sun.enterprise.deployment.runtime.common.SecurityRoleMapping; 61 import com.sun.enterprise.deployment.PrincipalImpl; 62 import com.sun.enterprise.deployment.Group; 63 import com.sun.enterprise.config.serverbeans.*; 64 import com.sun.enterprise.config.*; 65 import com.sun.enterprise.server.ApplicationServer; 66 import com.sun.enterprise.deployment.web.LoginConfiguration; 67 import com.sun.enterprise.deployment.runtime.web.SunWebApp; 68 import com.sun.enterprise.deployment.interfaces.SecurityRoleMapper; 69 import com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactory; 70 import com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactoryMgr; 71 import org.apache.catalina.HttpRequest; 72 73 86 public class WebSecurityManager { 87 private static Logger logger = 88 Logger.getLogger(LogDomains.SECURITY_LOGGER); 89 90 private static AuditManager auditManager = 91 AuditManagerFactory.getAuditManagerInstance(); 92 private static final String RESOURCE = "hasResourcePermission"; 93 private static final String USERDATA = "hasUserDataPermission"; 94 private static final String ROLEREF = "hasRoleRefPermission"; 95 96 private static final String DEFAULT_PATTERN = "/"; 97 private static final String EMPTY_STRING = ""; 98 99 private static final PolicyContextHandlerImpl pcHandlerImpl = 100 (PolicyContextHandlerImpl)PolicyContextHandlerImpl.getInstance(); 101 102 private static final Map ADMIN_PRINCIPAL = new HashMap (); 103 private static final Map ADMIN_GROUP = new HashMap (); 104 105 private String CONTEXT_ID = null; 108 private String CODEBASE = null; 109 110 protected Policy policy = Policy.getPolicy(); 112 113 protected PolicyConfiguration policyConfiguration = null; 114 protected PolicyConfigurationFactory policyConfigurationFactory = null; 115 protected CodeSource codesource = null; 116 117 private Map protectionDomainCache = 119 Collections.synchronizedMap(new WeakHashMap ()); 120 121 private static WebResourcePermission allResources = 122 new WebResourcePermission("/*",(String ) null); 123 124 private static WebUserDataPermission allConnections = 125 new WebUserDataPermission("/*",null); 126 127 private static Permission[] protoPerms = { 128 allResources, 129 allConnections 130 }; 131 132 private CachedPermission allResourcesCP = null; 136 137 private CachedPermission allConnectionsCP = null; 138 139 private PermissionCache uncheckedPermissionCache = null; 141 142 private static Set defaultPrincipalSet = 143 SecurityContext.getDefaultSecurityContext().getPrincipalSet(); 144 145 private static SecurityRoleMapperFactory factory = 146 SecurityRoleMapperFactoryMgr.getFactory(); 147 148 private WebBundleDescriptor wbd = null; 150 public WebSecurityManager(WebBundleDescriptor wbd) throws PolicyContextException { 152 this.wbd = wbd; 153 this.CONTEXT_ID = getContextID(wbd); 154 String appname = getAppId(); 155 factory.setAppNameForContext(appname, CONTEXT_ID); 156 initialise(); 157 } 158 159 private String removeSpaces(String withSpaces){ 160 return withSpaces.replace(' ', '_'); 161 } 162 public static String getContextID(WebBundleDescriptor wbd) { 165 String cid = null; 166 if (wbd != null ) { 167 String moduleId = wbd.getUniqueFriendlyId(); 168 cid = wbd.getApplication().getRegistrationName() + 169 '/' + wbd.getUniqueFriendlyId(); 170 } 171 return cid; 172 } 173 174 private void initialise() throws PolicyContextException { 175 String appName = wbd.getApplication().getRegistrationName(); 176 CODEBASE = removeSpaces(CONTEXT_ID) ; 177 if(WebContainer.ADMIN_VS.equals(getVirtualServers(appName))){ 178 LoginConfiguration lgConf = wbd.getLoginConfiguration(); 179 if (lgConf != null){ 180 String realmName = lgConf.getRealmName(); 181 SunWebApp sunDes = wbd.getSunDescriptor(); 182 if(sunDes != null){ 183 SecurityRoleMapping[] sr = sunDes.getSecurityRoleMapping(); 184 if(sr != null){ 185 for(int i=0; i<sr.length; i++){ 186 String [] principal = sr[i].getPrincipalName(); 187 if(principal != null){ 188 for(int plen=0;plen<principal.length; plen++ ){ 189 ADMIN_PRINCIPAL.put(realmName+principal[plen], new PrincipalImpl(principal[plen])); 190 } 191 } 192 List <String > groups = sr[i].getGroupNames(); 193 for(int glen = 0; glen < groups.size(); glen++ ){ 194 ADMIN_GROUP.put(realmName+groups.get(glen), new Group(groups.get(glen))) ; 195 } 196 } 197 } 198 } 199 } 200 } 201 202 try{ 204 java.net.URI uri = null; 205 try{ 206 if(logger.isLoggable(Level.FINE)) 207 logger.log(Level.FINE, "[Web-Security] Creating a Codebase URI with = "+CODEBASE); 208 uri = new java.net.URI ("file:///"+ CODEBASE); 209 if(uri != null){ 210 codesource = new CodeSource(new URL (uri.toString()), 211 (java.security.cert.Certificate []) null); 212 } 213 214 } catch(java.net.URISyntaxException use){ 215 logger.log(Level.FINE, "[Web-Security] Error Creating URI ", use); 217 throw new RuntimeException (use); 218 } 219 220 } catch(java.net.MalformedURLException mue){ 221 logger.log(Level.SEVERE, "ejbsm.codesourceerror", mue); 222 throw new RuntimeException (mue); 223 } 224 225 if(logger.isLoggable(Level.FINE)){ 226 logger.fine("[Web-Security] Context id (id under which WEB component in application will be created) = "+ CONTEXT_ID); 227 logger.fine("[Web-Security] Codebase (module id for web component) "+ CODEBASE); 228 } 229 230 boolean inService = getFactory().inService(CONTEXT_ID); 231 232 240 if (!inService) { 241 policyConfiguration = getFactory().getPolicyConfiguration(CONTEXT_ID,false); 242 generatePermissions(); 243 } 244 245 if (uncheckedPermissionCache == null) { 246 uncheckedPermissionCache = 247 PermissionCacheFactory.createPermissionCache 248 (this.CONTEXT_ID, codesource, protoPerms, null); 249 250 if (uncheckedPermissionCache != null) { 251 252 allResourcesCP = 253 new CachedPermissionImpl(uncheckedPermissionCache, 254 allResources); 255 allConnectionsCP = 256 new CachedPermissionImpl(uncheckedPermissionCache, 257 allConnections); 258 } 259 260 } else { 261 uncheckedPermissionCache.reset(); 262 } 263 264 } 265 private String getAppId() { 267 return wbd.getApplication().getRegistrationName(); 268 } 269 270 277 protected boolean checkPermission(Permission perm, Set principalSet) { 278 279 try{ 280 281 286 setPolicyContext(CONTEXT_ID); 287 288 } catch(Throwable t){ 289 logger.log(Level.FINE, "[Web-Security] Web Permission Access Denied.",t); 290 return false; 291 } 292 293 boolean ret = false; 294 295 if (uncheckedPermissionCache != null) { 296 ret = uncheckedPermissionCache.checkPermission(perm); 297 } 298 299 if (!ret) { 300 301 ProtectionDomain prdm = 302 (ProtectionDomain)protectionDomainCache.get(principalSet); 303 304 if (prdm == null) { 305 306 Principal[] principals = null; 307 principals = (principalSet == null ? null : 308 (Principal []) principalSet.toArray(new Principal[0])); 309 310 if(logger.isLoggable(Level.FINE)){ 311 logger.log(Level.FINE,"[Web-Security] Generating a protection domain for Permission check."); 312 313 for (int i=0; i<principals.length; i++){ 314 logger.log(Level.FINE, "[Web-Security] Checking with Principal : "+ principals[i].toString()); 315 } 316 } 317 318 prdm = new ProtectionDomain(codesource, null, null,principals); 319 protectionDomainCache.put(principalSet,prdm); 320 } 321 322 if(logger.isLoggable(Level.FINE)){ 323 logger.log(Level.FINE, "[Web-Security] Codesource with Web URL: " + codesource.getLocation().toString()); 324 logger.log(Level.FINE, "[Web-Security] Checking Web Permission with Principals : "+ principalSetToString(principalSet)); 325 logger.log(Level.FINE, "[Web-Security] Web Permission = " +perm.toString()); 326 } 327 328 ret = policy.implies(prdm, perm); 329 } 330 331 return ret; 332 } 333 334 protected PolicyConfigurationFactory getFactory() throws PolicyContextException{ 335 if (policyConfigurationFactory == null){ 336 try{ 337 policyConfigurationFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory(); 338 } catch(java.lang.ClassNotFoundException ex){ 339 throw new PolicyContextException(ex); 341 } 342 } 343 return policyConfigurationFactory; 344 } 345 346 private WebResourcePermission createWebResourcePermission( 347 HttpServletRequest httpsr) { 348 String originalUri = httpsr.getRequestURI(); 349 String mappedUri = (((HttpRequest) httpsr).getRequestPathMB() != null) ? 350 ((HttpRequest) httpsr).getRequestPathMB().toString() : null; 351 if (mappedUri == null) { 352 if (logger.isLoggable(Level.FINE)){ 353 logger.log(Level.FINE,"[Web-Security] mappedUri is null"); 354 } 355 throw new RuntimeException ("Fatal Error in creating WebResourcePermission"); 356 } 357 if(mappedUri.equals("/")) { 358 mappedUri = EMPTY_STRING; 359 } 360 WebResourcePermission perm = new WebResourcePermission( 361 mappedUri, httpsr.getMethod()); 362 return perm; 363 } 364 365 371 public boolean hasResourcePermission(HttpServletRequest httpsr){ 372 SecurityContext sc = getSecurityContext(httpsr.getUserPrincipal()); 373 WebResourcePermission perm = createWebResourcePermission(httpsr); 374 setSecurityInfo(httpsr); 375 boolean isGranted = checkPermission(perm,sc.getPrincipalSet()); 376 SecurityContext.setCurrent(sc); 377 if(logger.isLoggable(Level.FINE)){ 378 logger.log(Level.FINE,"[Web-Security] hasResource isGranted: " + isGranted); 379 logger.log(Level.FINE,"[Web-Security] hasResource perm: " + perm); 380 } 381 if(auditManager.isAuditOn()){ 382 Principal prin = httpsr.getUserPrincipal(); 383 String user = (prin != null) ? prin.getName(): null; 384 auditManager.webInvocation(user, httpsr, RESOURCE, isGranted); 385 } 386 return isGranted; 387 } 388 389 390 401 public boolean hasRoleRefPermission(String servletName, String role, Principal p) { 402 Set principalSet = getSecurityContext(p).getPrincipalSet(); 403 WebRoleRefPermission perm = new WebRoleRefPermission(servletName, role); 404 boolean isGranted = checkPermission(perm,principalSet); 405 if(logger.isLoggable(Level.FINE)){ 406 logger.log(Level.FINE,"[Web-Security] hasRoleRef perm: " + perm); 407 logger.log(Level.FINE,"[Web-Security] hasRoleRef isGranted: " + isGranted); 408 } 409 return isGranted; 410 } 411 412 413 421 public int hasUserDataPermission(HttpServletRequest httpsr){ 422 setSecurityInfo(httpsr); 423 WebUserDataPermission perm = new WebUserDataPermission(httpsr); 424 boolean isGranted = checkPermission(perm, defaultPrincipalSet); 425 int result = 0; 426 427 if ( isGranted ) { 428 result = 1; 429 } 430 431 if(logger.isLoggable(Level.FINE)){ 432 logger.log(Level.FINE,"[Web-Security] hasUserDataPermission perm: " + perm); 433 logger.log(Level.FINE,"[Web-Security] hasUserDataPermission isGranted: " + isGranted); 434 } 435 436 if(auditManager.isAuditOn()){ 437 Principal prin = httpsr.getUserPrincipal(); 438 String user = (prin != null) ? prin.getName(): null; 439 auditManager.webInvocation(user, httpsr, USERDATA, isGranted); 440 } 441 442 if ( !isGranted ) { 443 444 perm = new WebUserDataPermission 445 ( perm.getName(), 446 new String [] { httpsr.getMethod() }, 447 "CONFIDENTIAL" ); 448 449 isGranted = checkPermission(perm, defaultPrincipalSet); 450 451 if (isGranted) 452 result = -1; 453 } 454 455 return result; 456 } 457 458 private void generatePermissions(){ 459 try{ 460 WebPermissionUtil.processConstraints(wbd, policyConfiguration); 461 WebPermissionUtil.createWebRoleRefPermission(wbd, policyConfiguration); 462 } catch (PolicyContextException pce){ 463 logger.log(Level.FINE,"[Web-Security] FATAL Permission Generation: " + pce.getMessage()); 464 throw new RuntimeException ("Fatal error creating web permissions", pce); 465 } 466 } 467 468 public void destroy() throws PolicyContextException { 469 boolean wasInService = getFactory().inService(CONTEXT_ID); 470 if (policyConfiguration == null) { 471 policyConfiguration = getFactory(). 472 getPolicyConfiguration(CONTEXT_ID,false); 473 } 474 if (wasInService) { 475 policy.refresh(); 476 PermissionCacheFactory.removePermissionCache 477 (uncheckedPermissionCache); 478 uncheckedPermissionCache = null; 479 } 480 factory.removeAppNameForContext(CONTEXT_ID); 481 } 484 485 private static String setPolicyContext(final String ctxID) throws Throwable { 486 String old = PolicyContext.getContextID(); 487 if (old != ctxID && 488 (old == null || ctxID == null || !old.equals(ctxID))) { 489 490 if(logger.isLoggable(Level.FINE)){ 491 logger.fine("[Web-Security] Setting Policy Context ID: old = " + old + 492 " ctxID = " + ctxID); 493 } 494 495 try { 496 AccessController.doPrivileged(new PrivilegedExceptionAction(){ 497 public java.lang.Object run() throws Exception { 498 PolicyContext.setContextID(ctxID); 499 return null; 500 } 501 }); 502 } catch (java.security.PrivilegedActionException pae) { 503 Throwable cause = pae.getCause(); 504 if( cause instanceof java.security.AccessControlException ) { 505 logger.log(Level.SEVERE,"[Web-Security] setPolicy SecurityPermission required to call PolicyContext.setContextID",cause); 506 } else { 507 logger.log(Level.SEVERE,"[Web-Security] Unexpected Exception while setting policy context",cause); 508 } 509 throw cause; 510 } 511 } else if(logger.isLoggable(Level.FINE)){ 512 logger.fine("[Web-Security] Policy Context ID was: " + old); 513 } 514 return old; 515 } 516 517 522 private SecurityContext getSecurityContext(Principal principal) { 523 SecurityContext secContext = null; 524 if (principal != null) { 525 if (principal instanceof WebPrincipal){ 526 WebPrincipal wp = (WebPrincipal)principal; 527 secContext = wp.getSecurityContext(); 528 }else { 529 secContext = new SecurityContext(principal.getName(),null); 530 } 531 } 532 if (secContext == null) { 533 secContext = SecurityContext.getDefaultSecurityContext(); 534 } 535 return secContext; 536 } 537 538 542 private void setSecurityInfo(HttpServletRequest httpRequest) { 543 if (httpRequest != null) { 544 pcHandlerImpl.getHandlerData().setHttpServletRequest(httpRequest); 545 } 546 } 547 548 private String principalSetToString(Set principalSet) { 549 String result = null; 550 if (principalSet != null) { 551 Principal[] principals = 552 (Principal []) principalSet.toArray(new Principal[0]); 553 for (int i =0; i<principals.length; i++) { 554 if (i == 0) { 555 result = principals[i].toString(); 556 } else { 557 result = result + ", "+ new String (principals[i].toString()); 558 } 559 } 560 } 561 return result; 562 } 563 564 private String getVirtualServers(String appName) { 565 String ret = null; 566 try { 567 ConfigContext ctx = 568 ApplicationServer.getServerContext().getConfigContext(); 569 ret = ServerBeansFactory 570 .getVirtualServersByAppName(ctx, appName); 571 } catch (ConfigException ce) { 572 logger.log(Level.FINE, "Cannot get virtual server for " + appName, ce); 573 } 574 return ret; 575 } 576 577 public static Principal getAdminPrincipal(String username, String realmName){ 578 return (Principal)ADMIN_PRINCIPAL.get(realmName+username); 579 } 580 public static Principal getAdminGroup(String group, String realmName){ 581 return (Principal)ADMIN_GROUP.get(realmName+group); 582 } 583 584 public boolean hasNoConstrainedResources() { 585 if (allResourcesCP != null && allConnectionsCP != null) { 586 boolean x = allResourcesCP.checkPermission(); 587 boolean y = allConnectionsCP.checkPermission(); 588 return x && y; 589 } 590 return false; 591 } 592 } 593 | Popular Tags |