com.sun.enterprise.security.web.integration.WebPermissionUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project for IBM JDK
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.security.web.integration;
import java.util.*;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.WebResourcePermission;
import javax.security.jacc.WebRoleRefPermission;
import javax.security.jacc.WebUserDataPermission;
import java.util.logging.*;
import com.sun.logging.LogDomains;
import java.security.Permission;
import java.security.Permissions;
import com.sun.enterprise.deployment.*;
import com.sun.enterprise.deployment.web.*;
import org.glassfish.security.common.Role;
/**
* This class is used for generating Web permissions based on the
* deployment descriptor.
* @author Harpreet Singh
* @author Jean-Francois Arcand
* @author Ron Monzillo
*/
public class WebPermissionUtil {
static Logger logger = Logger.getLogger(LogDomains.SECURITY_LOGGER);
public WebPermissionUtil() {
}
/* changed to order default pattern / below extension */
private static final int PT_DEFAULT = 0;
private static final int PT_EXTENSION = 1;
private static final int PT_PREFIX = 2;
private static final int PT_EXACT = 3;
static int patternType(Object urlPattern) {
String pattern = urlPattern.toString();
if (pattern.startsWith("*.")) return PT_EXTENSION;
else if (pattern.startsWith("/") && pattern.endsWith("/*"))
return PT_PREFIX;
else if (pattern.equals("/")) return PT_DEFAULT;
else return PT_EXACT;
}
static boolean implies(String pattern, String path) {
// Check for exact match
if (pattern.equals(path))
return (true);
// Check for path prefix matching
if (pattern.startsWith("/") && pattern.endsWith("/*")) {
pattern = pattern.substring(0, pattern.length() - 2);
int length = pattern.length();
if (length == 0) return (true); // "/*" is the same as "/"
return (path.startsWith(pattern) &&
(path.length() == length ||
path.substring(length).startsWith("/")));
}
// Check for suffix matching
if (pattern.startsWith("*.")) {
int slash = path.lastIndexOf('/');
int period = path.lastIndexOf('.');
if ((slash >= 0) && (period > slash) &&
path.endsWith(pattern.substring(1))) {
return (true);
}
return (false);
}
// Check for universal mapping
if (pattern.equals("/"))
return (true);
return (false);
}
public static HashMap parseConstraints(WebBundleDescriptor wbd)
{
if (logger.isLoggable(Level.FINE)){
logger.entering("WebPermissionUtil", "parseConstraints");
}
Set roleSet = wbd.getRoles();
HashMap qpMap = new HashMap();
/*
* bootstrap the map with the default pattern; the default pattern will
* not be "committed", unless a constraint is defined on "\". This will
* ensure that a more restrictive constraint can be assigned to it
*/
qpMap.put("/", new MapValue("/"));
//Enumerate over security constraints
Enumeration esc = wbd.getSecurityConstraints();
while (esc.hasMoreElements()) {
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint translation: begin parsing security constraint");
}
SecurityConstraint sc = esc.nextElement();
AuthorizationConstraint ac = sc.getAuthorizationConstraint();
UserDataConstraint udc = sc.getUserDataConstraint();
// Enumerate over collections of URLPatterns within constraint
for (WebResourceCollection wrc: sc.getWebResourceCollections()) {
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint translation: begin parsing web resource collection");
}
// Enumerate over URLPatterns within collection
for (String url: wrc.getUrlPatterns()) {
if (url != null) {
// FIX TO BE CONFIRMED: encode all colons
url = url.replaceAll(":","%3A");
}
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint translation: process url: "+url);
}
// determine if pattern is already in map
MapValue mValue = qpMap.get(url);
// apply new patterns to map
if (mValue == null) {
mValue = new MapValue(url);
//Iterate over patterns in map
for(Map.Entry qpVal:qpMap.entrySet()) {
String otherUrl = qpVal.getKey();
int otherUrlType = patternType(otherUrl);
switch(patternType(url)) {
// if the new url/pattern is a path-prefix
// pattern, it must be qualified by every
// different (from it) path-prefix pattern
// (in the map) that is implied by the new
// pattern, and every exact pattern (in the map)
// that is implied by the new url.
// Also, the new pattern must be added as a
// qualifier of the default pattern, and every
// extension pattern (existing in the map), and
// of every different path-prefix pattern that
// implies the new pattern.
// Note that we know that the new pattern does
// not exist in the map, thus we know that the
// new pattern is different from any existing
// path prefix pattern.
case PT_PREFIX:
if ((otherUrlType == PT_PREFIX ||
otherUrlType == PT_EXACT) &&
implies(url,otherUrl))
mValue.addQualifier(otherUrl);
else if (otherUrlType == PT_PREFIX &&
implies(otherUrl,url))
qpVal.getValue().addQualifier(url);
else if (otherUrlType == PT_EXTENSION ||
otherUrlType == PT_DEFAULT)
qpVal.getValue().addQualifier(url);
break;
// if the new pattern is an extension pattern,
// it must be qualified by every path-prefix
// pattern (in the map), and every exact
// pattern (in the map) that is implied by
// the new pattern.
// Also, it must be added as a qualifier of
// the defualt pattern, if it exists in the
// map.
case PT_EXTENSION:
if (otherUrlType == PT_PREFIX ||
(otherUrlType == PT_EXACT &&
implies(url,otherUrl)))
mValue.addQualifier(otherUrl);
else if (otherUrlType == PT_DEFAULT)
qpVal.getValue().addQualifier(url);
break;
// if the new pattern is the default pattern
// it must be qualified by every other pattern
// in the map.
case PT_DEFAULT:
if (otherUrlType != PT_DEFAULT)
mValue.addQualifier(otherUrl);
break;
// if the new pattern is an exact pattern, it
// is not be qualified, but it must be added as
// as a qualifier to the default pattern, and to
// every path-prefix or extension pattern (in
// the map) that implies the new pattern.
case PT_EXACT:
if ((otherUrlType == PT_PREFIX ||
otherUrlType == PT_EXTENSION) &&
implies(otherUrl,url))
qpVal.getValue().addQualifier(url);
else if (otherUrlType == PT_DEFAULT)
qpVal.getValue().addQualifier(url);
break;
default : break;
}
}
// add the new pattern and its pattern spec to the map
qpMap.put(url, mValue);
}
String[] methodNames = wrc.getHttpMethodsAsArray();
BitSet methods = MethodValue.methodArrayToSet(methodNames);
BitSet omittedMethods = null;
if (methods.isEmpty()) {
String[] omittedNames =
wrc.getHttpMethodOmissionsAsArray();
omittedMethods =
MethodValue.methodArrayToSet(omittedNames);
}
// set and commit the method outcomes on the pattern
// note that an empty omitted method set is used to represent
// the set of all http methods
mValue.setMethodOutcomes(roleSet,ac,udc,methods,omittedMethods);
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint translation: end processing url: "+url);
}
}
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint translation: end parsing web resource collection");
}
}
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint translation: end parsing security constraint");
}
}
if (logger.isLoggable(Level.FINE)){
logger.exiting("WebPermissionUtil","parseConstraints");
}
return qpMap;
}
static void handleExcluded(Permissions collection, MapValue m, String name) {
String actions = null;
BitSet excludedMethods = m.getExcludedMethods();
if (m.otherConstraint.isExcluded()) {
BitSet methods = m.getMethodSet();
methods.andNot(excludedMethods);
if (!methods.isEmpty()) {
actions = "!" + MethodValue.getActions(methods);
}
} else if (!excludedMethods.isEmpty()) {
actions = MethodValue.getActions(excludedMethods);
} else {
return;
}
collection.add(new WebResourcePermission(name,actions));
collection.add(new WebUserDataPermission(name,actions));
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint capture: adding excluded methods: "+ actions);
}
}
static Permissions addToRoleMap(HashMap map,
String roleName, Permission p) {
Permissions collection = map.get(roleName);
if (collection == null) {
collection = new Permissions();
map.put(roleName,collection);
}
collection.add(p);
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint capture: adding methods to role: "+ roleName+" methods: " + p.getActions());
}
return collection;
}
static void handleRoles(HashMap map, MapValue m,
String name) {
HashMap rMap = m.getRoleMap();
List roleList = null;
// handle the roles for the omitted methods
if (!m.otherConstraint.isExcluded() && m.otherConstraint.isAuthConstrained()) {
roleList = m.otherConstraint.roleList;
for (String roleName : roleList) {
BitSet methods = m.getMethodSet();
//reduce ommissions for explicit methods granted to role
BitSet roleMethods = rMap.get(roleName);
if (roleMethods != null) {
methods.andNot(roleMethods);
}
String actions = null;
if (!methods.isEmpty()) {
actions = "!" + MethodValue.getActions(methods);
}
addToRoleMap(map,roleName,new WebResourcePermission(name,actions));
}
}
//handle explicit methods, skip roles that were handled above
BitSet methods = m.getMethodSet();
if (!methods.isEmpty()) {
for (Map.Entry rval:rMap.entrySet()) {
String roleName = rval.getKey();
if (roleList == null || !roleList.contains(roleName)) {
BitSet roleMethods = rval.getValue();
if (!roleMethods.isEmpty()) {
String actions = MethodValue.getActions(roleMethods);
addToRoleMap(map,roleName,new WebResourcePermission(name,actions));
}
}
}
}
}
static void handleNoAuth(Permissions collection, MapValue m,
String name) {
String actions = null;
BitSet noAuthMethods = m.getNoAuthMethods();
if (!m.otherConstraint.isAuthConstrained()) {
BitSet methods = m.getMethodSet();
methods.andNot(noAuthMethods);
if (!methods.isEmpty()) {
actions = "!" + MethodValue.getActions(methods);
}
} else if (!noAuthMethods.isEmpty()) {
actions = MethodValue.getActions(noAuthMethods);
} else {
return;
}
collection.add(new WebResourcePermission(name,actions));
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint capture: adding unchecked (for authorization) methods: "+ actions);
}
}
static void handleConnections(Permissions collection, MapValue m,
String name) {
BitSet allConnectMethods = null;
boolean allConnectAtOther = m.otherConstraint.isConnectAllowed
(ConstraintValue.connectTypeNone);
for (int i=0; i roleSet = wbd.getRoles();
for (Role r : roleSet) {
pc.removeRole(r.getName());
}
// 1st call will remove "*" role if present. 2nd will remove all roles (if supported).
pc.removeRole("*");
pc.removeRole("*");
}
public static void processConstraints(WebBundleDescriptor wbd,
PolicyConfiguration pc)
throws javax.security.jacc.PolicyContextException
{
if (logger.isLoggable(Level.FINE)){
logger.entering("WebPermissionUtil", "processConstraints");
logger.log(Level.FINE,"JACC: constraint translation: CODEBASE = "+
pc.getContextID());
}
HashMap qpMap = parseConstraints(wbd);
HashMap roleMap =
new HashMap();
Permissions excluded = new Permissions();
Permissions unchecked = new Permissions();
boolean deny = wbd.isDenyUncoveredHttpMethods();
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint capture: begin processing qualified url patterns"
+ " - uncovered http methods will be " + (deny ? "denied" : "permitted"));
}
// for each urlPatternSpec in the map
Iterator it = qpMap.values().iterator();
while (it.hasNext()) {
MapValue m = (MapValue) it.next();
if (!m.irrelevantByQualifier) {
String name = m.urlPatternSpec.toString();
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint capture: urlPattern: "+ name);
}
// handle Uncovered Methods
m.handleUncoveredMethods(deny);
// handle excluded methods
handleExcluded(excluded,m,name);
// handle methods requiring role
handleRoles(roleMap,m,name);
// handle methods that are not auth constrained
handleNoAuth(unchecked,m,name);
// handle transport constraints
handleConnections(unchecked,m,name);
}
}
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: constraint capture: end processing qualified url patterns");
Enumeration e = excluded.elements();
while (e.hasMoreElements()) {
Permission p = (Permission) e.nextElement();
String ptype = (p instanceof WebResourcePermission) ? "WRP " : "WUDP ";
logger.log(Level.FINE,"JACC: permission(excluded) type: "+ ptype + " name: "+ p.getName() + " actions: "+ p.getActions());
}
e = unchecked.elements();
while (e.hasMoreElements()) {
Permission p = (Permission) e.nextElement();
String ptype = (p instanceof WebResourcePermission) ? "WRP " : "WUDP ";
logger.log(Level.FINE,"JACC: permission(unchecked) type: "+ ptype + " name: "+ p.getName() + " actions: "+ p.getActions());
}
}
pc.addToExcludedPolicy(excluded);
pc.addToUncheckedPolicy(unchecked);
for (Map.Entry rVal : roleMap.entrySet()) {
String role = rVal.getKey();
Permissions pCollection = rVal.getValue();
pc.addToRole(role,pCollection);
if (logger.isLoggable(Level.FINE)){
Enumeration e = pCollection.elements();
while (e.hasMoreElements()) {
Permission p = (Permission) e.nextElement();
String ptype = (p instanceof WebResourcePermission) ? "WRP " : "WUDP ";
logger.log(Level.FINE,"JACC: permission("+ role + ") type: "+ ptype + " name: "+ p.getName() + " actions: "+ p.getActions());
}
}
}
if (logger.isLoggable(Level.FINE)){
logger.exiting("WebPermissionUtil", "processConstraints");
}
}
public static void createWebRoleRefPermission(WebBundleDescriptor wbd,
PolicyConfiguration pc)
throws javax.security.jacc.PolicyContextException
{
if (logger.isLoggable(Level.FINE)){
logger.entering("WebPermissionUtil", "createWebRoleRefPermission");
logger.log(Level.FINE,"JACC: role-reference translation: Processing WebRoleRefPermission : CODEBASE = "+ pc.getContextID());
}
List role = new ArrayList();
Set roleset = wbd.getRoles();
Role anyAuthUserRole = new Role("**");
boolean rolesetContainsAnyAuthUserRole = roleset.contains(anyAuthUserRole);
Set descs = wbd.getWebComponentDescriptors();
//V3 Commented for(Enumeration e = wbd.getWebComponentDescriptors(); e.hasMoreElements();){
for (WebComponentDescriptor comp : descs) {
//V3 Commented WebComponentDescriptor comp = (WebComponentDescriptor) e.nextElement();
String name = comp.getCanonicalName();
Enumeration esrr = comp.getSecurityRoleReferences();
for (; esrr.hasMoreElements();){
SecurityRoleReference srr = (SecurityRoleReference)esrr.nextElement();
if(srr != null){
String action = srr.getRoleName();
WebRoleRefPermission wrrp = new WebRoleRefPermission(name, action);
role.add(new Role(action));
pc.addToRole(srr.getSecurityRoleLink().getName(),wrrp);
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: role-reference translation: RoleRefPermission created with name(servlet-name) = "+ name +
" and action(Role-name tag) = " + action + " added to role(role-link tag) = "+ srr.getSecurityRoleLink().getName());
}
}
}
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: role-reference translation: Going through the list of roles not present in RoleRef elements and creating WebRoleRefPermissions ");
}
for(Iterator it = roleset.iterator(); it.hasNext();){
Role r = (Role)it.next();
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: role-reference translation: Looking at Role = "+r.getName());
}
if(!role.contains(r)){
String action = r.getName();
WebRoleRefPermission wrrp = new WebRoleRefPermission(name, action);
pc.addToRole(action ,wrrp);
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,"JACC: role-reference translation: RoleRef = "+ action +
" is added for servlet-resource = " + name);
logger.log(Level.FINE, "JACC: role-reference translation: Permission added for above role-ref ="
+ wrrp.getName() +" "+ wrrp.getActions());
}
}
}
/**
* JACC MR8 add WebRoleRefPermission for the any authenticated user role '**'
*/
if ((!role.contains(anyAuthUserRole)) && !rolesetContainsAnyAuthUserRole) {
addAnyAuthenticatedUserRoleRef(pc, name);
}
}
if (logger.isLoggable(Level.FINE)){
logger.exiting("WebPermissionUtil", "createWebRoleRefPermission");
}
// START S1AS8PE 4966609
/**
* For every security role in the web application add a
* WebRoleRefPermission to the corresponding role. The name of all such
* permissions shall be the empty string, and the actions of each
* permission shall be the corresponding role name. When checking a
* WebRoleRefPermission from a JSP not mapped to a servlet, use a
* permission with the empty string as its name
* and with the argument to isUserInRole as its actions
*/
for(Iterator it = roleset.iterator(); it.hasNext();){
Role r = (Role)it.next();
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,
"JACC: role-reference translation: Looking at Role = "
+ r.getName());
}
String action = r.getName();
WebRoleRefPermission wrrp = new WebRoleRefPermission("", action);
pc.addToRole(action ,wrrp);
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,
"JACC: role-reference translation: RoleRef = "
+ action
+ " is added for jsp's that can't be mapped to servlets");
logger.log(Level.FINE,
"JACC: role-reference translation: Permission added for above role-ref ="
+ wrrp.getName() +" "+ wrrp.getActions());
}
}
// END S1AS8PE 4966609
/**
* JACC MR8 add WebRoleRefPermission for the any authenticated user role '**'
*/
if (!rolesetContainsAnyAuthUserRole) {
addAnyAuthenticatedUserRoleRef(pc, "");
}
}
/**
* JACC MR8 add WebRoleRefPermission for the any authenticated user role '**'
*/
private static void addAnyAuthenticatedUserRoleRef(PolicyConfiguration pc, String name)
throws javax.security.jacc.PolicyContextException {
String action = "**";
WebRoleRefPermission wrrp = new WebRoleRefPermission(name, action);
pc.addToRole(action ,wrrp);
if (logger.isLoggable(Level.FINE)){
logger.log(Level.FINE,
"JACC: any authenticated user role-reference translation: Permission added for role-ref ="
+ wrrp.getName() +" "+ wrrp.getActions());
}
}
}
class ConstraintValue {
static String connectKeys[] =
{ "NONE",
"INTEGRAL",
"CONFIDENTIAL"
};
static int connectTypeNone = 1;
static HashMap connectHash = new HashMap();
static
{
for (int i=0; i roleList = new ArrayList();
int connectSet;
ConstraintValue() {
excluded = false;
ignoreRoleList = false;
//roleList = new ArrayList();
connectSet = 0;
}
static boolean bitIsSet(int map , int bit) {
return (map & bit) == bit ? true : false;
}
void setRole(String role) {
synchronized(roleList) {
if (!roleList.contains(role)) {
roleList.add(role);
}
}
}
void removeRole(String role) {
synchronized(roleList) {
if (roleList.contains(role)) {
roleList.remove(role);
}
}
}
void setPredefinedOutcome(boolean outcome) {
if (!outcome) {
excluded = true;
} else {
ignoreRoleList = true;
}
}
void addConnectType(String guarantee) {
int b = connectTypeNone;
if (guarantee != null) {
Integer bit = connectHash.get(guarantee);
if (bit == null)
throw new IllegalArgumentException
("constraint translation error-illegal trx guarantee");
b = bit.intValue();
}
connectSet |= b;
}
boolean isExcluded() {
return excluded;
}
/* ignoreRoleList is true if there was a security-constraint
* without an auth-constraint; such a constraint combines to
* allow access without authentication.
*/
boolean isAuthConstrained() {
if (excluded) {
return true;
} else if (ignoreRoleList || roleList.isEmpty()) {
return false;
}
return true;
}
boolean isTransportConstrained() {
if (excluded || (connectSet != 0 &&
!bitIsSet(connectSet,connectTypeNone))) {
return true;
}
return false;
}
boolean isConnectAllowed(int cType) {
if (!excluded && (connectSet == 0 ||
bitIsSet(connectSet,connectTypeNone) ||
bitIsSet(connectSet,cType))) {
return true;
}
return false;
}
void setOutcome(Set roleSet,
AuthorizationConstraint ac, UserDataConstraint udc) {
if (ac == null) {
setPredefinedOutcome(true);
} else {
boolean containsAllRoles = false;
Enumeration eroles = ac.getSecurityRoles();
if (!eroles.hasMoreElements()) {
setPredefinedOutcome(false);
}
else while (eroles.hasMoreElements()) {
SecurityRoleDescriptor srd =
(SecurityRoleDescriptor)eroles.nextElement();
String roleName = srd.getName();
if ("*".equals(roleName)) {
containsAllRoles = true;
} else {
setRole(roleName);
}
}
/**
* JACC MR8 When role '*' named, do not include any authenticated user
* role '**' unless an application defined a role named '**'
*/
if (containsAllRoles) {
removeRole("**");
Iterator it = roleSet.iterator();
while(it.hasNext()) {
setRole(((Role)it.next()).getName());
}
}
}
addConnectType(udc == null? null : udc.getTransportGuarantee());
if (WebPermissionUtil.logger.isLoggable(Level.FINE)){
WebPermissionUtil.logger.log
(Level.FINE,"JACC: setOutcome yields: " + toString());
}
}
void setValue(ConstraintValue constraint) {
excluded = constraint.excluded;
ignoreRoleList = constraint.ignoreRoleList;
roleList.clear();
Iterator rit = constraint.roleList.iterator();
while(rit.hasNext()) {
String role = (String) rit.next();
roleList.add(role);
}
connectSet = constraint.connectSet;
}
public String toString() {
StringBuilder roles =new StringBuilder(" roles: ");
Iterator rit = roleList.iterator();
while(rit.hasNext()) {
roles.append(" ").append((String) rit.next());
}
StringBuilder transports = new StringBuilder("transports: ");
for (int i=0; i methodNames = new ArrayList();
int index;
MethodValue (String methodName) {
index = getMethodIndex(methodName);
}
MethodValue (String methodName, ConstraintValue constraint) {
index = getMethodIndex(methodName);
setValue(constraint);
}
static String getMethodName(int index) {
synchronized(methodNames) {
return methodNames.get(index);
}
}
static int getMethodIndex(String name) {
synchronized(methodNames) {
int index = methodNames.indexOf(name);
if (index < 0) {
index = methodNames.size();
methodNames.add(index,name);
}
return index;
}
}
static String getActions (BitSet methodSet) {
if (methodSet == null || methodSet.isEmpty()) {
return null;
}
StringBuffer actions = null;
for (int i=methodSet.nextSetBit(0); i>=0; i=methodSet.nextSetBit(i+1)){
if (actions == null) {
actions = new StringBuffer();
} else {
actions.append(",");
}
actions.append(getMethodName(i));
}
return (actions == null ? null : actions.toString());
}
static String[] getMethodArray (BitSet methodSet) {
if (methodSet == null || methodSet.isEmpty()) {
return null;
}
int size = 0;
ArrayList methods = new ArrayList();
for (int i=methodSet.nextSetBit(0); i>=0; i=methodSet.nextSetBit(i+1)){
methods.add(getMethodName(i));
size += 1;
}
return (String[]) methods.toArray(new String[size]);
}
static BitSet methodArrayToSet(String[] methods) {
BitSet methodSet = new BitSet();
for (int i=0; methods != null && i methodValues =
new HashMap();
ConstraintValue otherConstraint;
MapValue (String urlPattern) {
this.committed = false;
this.patternType = WebPermissionUtil.patternType(urlPattern);
this.patternLength = urlPattern.length();
this.irrelevantByQualifier = false;
this.urlPatternSpec = new StringBuffer(urlPattern);
otherConstraint = new ConstraintValue();
}
void addQualifier(String urlPattern) {
if (WebPermissionUtil.implies(urlPattern,
this.urlPatternSpec.substring(0,this.patternLength)))
this.irrelevantByQualifier = true;
this.urlPatternSpec.append(":" + urlPattern);
}
MethodValue getMethodValue(int methodIndex) {
String methodName = MethodValue.getMethodName(methodIndex);
synchronized(methodValues) {
MethodValue methodValue = methodValues.get(methodName);
if (methodValue == null) {
methodValue = new MethodValue(methodName,otherConstraint);
methodValues.put(methodName,methodValue);
if (WebPermissionUtil.logger.isLoggable(Level.FINE)){
WebPermissionUtil.logger.log
(Level.FINE,"JACC: created MethodValue: " +
methodValue);
}
}
return methodValue;
}
}
BitSet getExcludedMethods() {
BitSet methodSet = new BitSet();
synchronized (methodValues) {
Collection values = methodValues.values();
for (MethodValue v : values) {
if (v.isExcluded()) {
methodSet.set(v.index);
}
}
}
return methodSet;
}
BitSet getNoAuthMethods() {
BitSet methodSet = new BitSet();
synchronized(methodValues) {
Collection values = methodValues.values();
for(MethodValue v : values){
if (!v.isAuthConstrained()) {
methodSet.set(v.index);
}
}
}
return methodSet;
}
BitSet getAuthConstrainedMethods() {
BitSet methodSet = new BitSet();
synchronized (methodValues) {
Collection values = methodValues.values();
for (MethodValue v : values) {
if (v.isAuthConstrained()) {
methodSet.set(v.index);
}
}
}
return methodSet;
}
BitSet getTransportConstrainedMethods() {
BitSet methodSet = new BitSet();
synchronized (methodValues) {
Collection values = methodValues.values();
for (MethodValue v : values) {
if (v.isTransportConstrained()) {
methodSet.set(v.index);
}
}
}
return methodSet;
}
/**
* Map of methods allowed per role
*/
HashMap getRoleMap() {
HashMap roleMap = new HashMap();
synchronized (methodValues) {
Collection values = methodValues.values();
for (MethodValue v : values) {
if (!v.isExcluded() && v.isAuthConstrained()) {
for (String role : v.roleList) {
BitSet methodSet = roleMap.get(role);
if (methodSet == null) {
methodSet = new BitSet();
roleMap.put(role, methodSet);
}
methodSet.set(v.index);
}
}
}
}
return roleMap;
}
BitSet getConnectMap(int cType) {
BitSet methodSet = new BitSet();
synchronized (methodValues) {
Collection values = methodValues.values();
for (MethodValue v : values) {
/*
* NOTE WELL: prior version of this method
* could not be called during constraint parsing
* because it finalized the connectSet when its
* value was 0 (indicating any connection, until
* some specific bit is set)
*
if (v.connectSet == 0) {
v.connectSet = MethodValue.connectTypeNone;
}
*/
if (v.isConnectAllowed(cType)) {
methodSet.set(v.index);
}
}
}
return methodSet;
}
BitSet getMethodSet() {
BitSet methodSet = new BitSet();
synchronized (methodValues) {
Collection values = methodValues.values();
for (MethodValue v : values) {
methodSet.set(v.index);
}
}
return methodSet;
}
void setMethodOutcomes(Set roleSet,
AuthorizationConstraint ac, UserDataConstraint udc,
BitSet methods,BitSet omittedMethods) {
committed = true;
if (omittedMethods != null) {
// get the ommitted methodSet
BitSet methodsInMap = getMethodSet();
BitSet saved = (BitSet) omittedMethods.clone();
// determine methods being newly omitted
omittedMethods.andNot(methodsInMap);
// create values for newly omitted, init from otherConstraint
for (int i = omittedMethods.nextSetBit(0); i >= 0;
i = omittedMethods.nextSetBit(i+1)) {
getMethodValue(i);
}
//combine this constraint into constraint on all other methods
otherConstraint.setOutcome(roleSet,ac,udc);
methodsInMap.andNot(saved);
// recursive call to combine constraint into prior omitted methods
setMethodOutcomes(roleSet,ac,udc,methodsInMap,null);
} else {
for (int i = methods.nextSetBit(0); i >= 0;
i = methods.nextSetBit(i+1)){
// create values (and init from otherConstraint) if not in map
// then combine with this constraint.
getMethodValue(i).setOutcome(roleSet,ac,udc);
}
}
}
void handleUncoveredMethods(boolean deny) {
/*
* bypass any uncommitted patterns (e.g. the default pattern) which were
* entered in the map, but that were not named in a security constraint
*/
if (!committed) {
return;
}
boolean otherIsUncovered = false;
synchronized (methodValues) {
BitSet uncoveredMethodSet = new BitSet();
// for all the methods in the mapValue
for (MethodValue v : methodValues.values()) {
// if the method is uncovered add its id to the uncovered set
if (v.isUncovered()) {
if (deny) {
v.setPredefinedOutcome(false);
}
uncoveredMethodSet.set(v.index);
}
}
// if the constraint on all other methods is uncovered
if (otherConstraint.isUncovered()) {
/*
* this is the case where the problem is most severe, since
* a non-enumerble set of http methods has been left uncovered.
* the set of method will be logged and denied.
*/
otherIsUncovered = true;
if (deny) {
otherConstraint.setPredefinedOutcome(false);
}
/*
* ensure that the methods that are reported as uncovered
* includes any enumerated methods that were found to be uncovered.
*/
BitSet otherMethodSet = getMethodSet();
if (!uncoveredMethodSet.isEmpty()) {
/*
* uncoveredMethodSet contains methods that otherConstraint
* pertains to, so remove them from otherMethodSet which
* is the set to which the otherConstraint does not apply
*/
otherMethodSet.andNot(uncoveredMethodSet);
}
/*
* when otherIsUncovered, uncoveredMethodSet contains methods to
* which otherConstraint does NOT apply
*/
uncoveredMethodSet = otherMethodSet;
}
if (otherIsUncovered || !uncoveredMethodSet.isEmpty()) {
String uncoveredMethods = MethodValue.getActions(uncoveredMethodSet);
Object[] args = new Object[] {urlPatternSpec, uncoveredMethods};
if (deny) {
if (otherIsUncovered) {
WebPermissionUtil.logger.log(Level.INFO,
"JACC: For the URL pattern {0}, all but the following methods have been excluded: {1}", args);
}
else {
WebPermissionUtil.logger.log(Level.INFO,
"JACC: For the URL pattern {0}, the following methods have been excluded: {1}", args);
}
}
else {
if (otherIsUncovered) {
WebPermissionUtil.logger.log(Level.WARNING,
"JACC: For the URL pattern {0}, all but the following methods were uncovered: {1}", args);
}
else {
WebPermissionUtil.logger.log(Level.WARNING,
"JACC: For the URL pattern {0}, the following methods were uncovered: {1}", args);
}
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy