/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. 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.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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.ericsson.ssa.container.auth;
import com.sun.enterprise.deployment.RoleReference;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jvnet.glassfish.comms.deployment.backend.ResourceCollection;
import org.jvnet.glassfish.comms.deployment.backend.SecurityConstraint;
import com.ericsson.ssa.dd.SecurityRole;
import com.ericsson.ssa.dd.SecurityRoleReference;
import org.jvnet.glassfish.comms.deployment.backend.Servlet;
import org.jvnet.glassfish.comms.deployment.backend.SipApplication;
import org.jvnet.glassfish.comms.security.authorize.SipResourcePermission;
import org.jvnet.glassfish.comms.security.authorize.SipRoleRefPermission;
import org.jvnet.glassfish.comms.security.authorize.SipRoleRefPermission;
import org.jvnet.glassfish.comms.security.authorize.SipUserDataPermission;
import org.jvnet.glassfish.comms.security.util.PolicyBuilder;
import java.security.Permissions;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Enumeration;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.PolicyConfigurationFactory;
import javax.security.jacc.PolicyContextException;
import org.jvnet.glassfish.comms.security.authorize.SipResourcePermission;
import org.jvnet.glassfish.comms.security.authorize.SipRoleRefPermission;
import org.jvnet.glassfish.comms.security.util.PolicyBuilder;
import org.jvnet.glassfish.comms.security.authorize.SipUserDataPermission;
/**
*
* @author K.Venugopal@sun.com
*/
public class DescriptorProcessor {
private PolicyConfiguration pc = null;
private static String[] sipMethods = new String[]{
"INVITE", "CANCEL", "REGISTER", "ACK", "OPTIONS", "INFO"
};
@SuppressWarnings(value = "unchecked")
public void process(String contextId, SipApplication sipConfig) {
Enumeration<SecurityConstraint> constraints = sipConfig.getSecurityConstraints();
PolicyBuilder util = new PolicyBuilder();
HashMap reslist = new HashMap();
HashMap roleList = new HashMap();
try {
pc = (PolicyConfiguration) util.getInstance(contextId);
} catch (PolicyContextException pce) {
pce.printStackTrace();
}
if (constraints == null || !(constraints.hasMoreElements())) {
addDefaultPermissions(sipConfig);
return;
}
//Iterator<SecurityConstraint> itr = constraints.iterator();
boolean noUDPerm = true;//no userdata permission
Key key = new Key();
Enumeration<SecurityRole> roleMap = sipConfig.getSecurityRoles();
Map<String, TransportConstraints> userDataConsTable = new HashMap<String, TransportConstraints>();
HashMap<String, Set> restrictedActionList = new HashMap<String, Set>();
while (constraints.hasMoreElements()) {
SecurityConstraint sc = constraints.nextElement();
Collection<ResourceCollection> resources = sc.getResourceCollections();
Collection<String> roles = sc.getAuthorizationConstraintRoleNames();
String transportType = sc.getUserDataTransportGuarantee();
Iterator resItr = resources.iterator();
while (resItr.hasNext()) {
ResourceCollection rc = (ResourceCollection) resItr.next();
Collection snColl = rc.getServletNames();
Collection smColl = rc.getSipMethods();
if(roles == null)continue;
Iterator roleItr = roles.iterator();
ServletActions servletRoles = null;
while (roleItr.hasNext()) {
Iterator snItr = snColl.iterator();
Iterator smItr = smColl.iterator();
String roleName = (String) roleItr.next();
if (roleMap != null) {
for (Enumeration e = roleMap; e.hasMoreElements();) {
if (e.nextElement().equals(roleName)) {
continue;
}
}
}
key.roleName = roleName;
while (snItr.hasNext()) {
String servletName = (String) snItr.next();
key.servletName = servletName;
if (!restrictedActionList.containsKey(servletName)) {
restrictedActionList.put(servletName,
new HashSet<String>());
}
ServletActions servletActions = null;
TransportConstraints tc = null;
if (transportType != null) {
if (userDataConsTable.containsKey(servletName)) {
tc = userDataConsTable.get(servletName);
} else {
tc = new TransportConstraints(servletName);
userDataConsTable.put(servletName, tc);
}
tc.setType(transportType);
}
if (reslist.containsKey(key)) {
servletActions = (ServletActions) reslist.get(key);
} else {
servletActions = new ServletActions(servletName);
reslist.put(new Key(key.servletName, key.roleName),
servletActions);
}
while (smItr.hasNext()) {
String smName = (String) smItr.next();
servletActions.setAction(smName);
Set<String> resActions = restrictedActionList.get(servletName);
resActions.add(smName);
if (tc != null) {
tc.setAction(smName);
}
}
}
}
}
}
Set resKeys = reslist.keySet();
Iterator keyItr = resKeys.iterator();
HashMap<String, Permissions> permCollection = new HashMap();
try {
while (keyItr.hasNext()) {
key = (Key) keyItr.next();
ServletActions sa = (DescriptorProcessor.ServletActions) reslist.get(key);
SipResourcePermission srp = new SipResourcePermission(key.servletName,
sa.actions);
Permissions p = null;
if (permCollection.containsKey(key.roleName)) {
p = permCollection.get(key.roleName);
} else {
p = new Permissions();
permCollection.put(key.roleName, p);
}
p.add(srp);
pc.addToRole(key.roleName,
new SipRoleRefPermission(key.servletName, key.roleName));
}
Iterator<String> permItr = permCollection.keySet().iterator();
while (permItr.hasNext()) {
String role = permItr.next();
Permissions perms = (Permissions) permCollection.get(role);
pc.addToRole(role, perms);
}
Map<String, Servlet> servlets = sipConfig.getServlets();
Iterator<Servlet> servletItr = servlets.values().iterator();
while (servletItr.hasNext()) {
Servlet servlet = servletItr.next();
String servletName = servlet.getServletName();
Enumeration<RoleReference> srRef = servlet.getSecurityRoleReferences();
if (srRef != null) {
// Iterator<SecurityRoleReference> srItr = srRef.iterator();
while (srRef.hasMoreElements()) {
RoleReference srr = srRef.nextElement();
String roleLink = srr.getSecurityRoleLink().getName();
String roleName = srr.getRolename();
SipRoleRefPermission srp = new SipRoleRefPermission(servletName,
roleName);
pc.addToRole(roleLink, srp);
}
}
}
Permissions udcPermList = new Permissions();
Iterator<TransportConstraints> tcItr = userDataConsTable.values().iterator();
while (tcItr.hasNext()) {
TransportConstraints tcValue = tcItr.next();
//String[] actions = tcValue.actions.toArray(new String[0]);
SipUserDataPermission wdp = new SipUserDataPermission(tcValue.servletName,
tcValue.actions, tcValue.getType());
noUDPerm = false;
//SipUserDataPermission(tcValue.servletName, actions, tcValue.getType());
udcPermList.add(wdp);
}
if (noUDPerm) {
addDefaultUserDataPermissions(sipConfig, udcPermList);
}
Map<String, Servlet> servletList = sipConfig.getServlets();
Iterator<String> sitr = servletList.keySet().iterator();
while (sitr.hasNext()) {
String sn = sitr.next();
// if (restrictedActionList.containsKey(sn)) {
// continue;
// }
Set<String> ral = restrictedActionList.get(sn);
Set<String> allowedActions = new HashSet<String>();
if (ral == null) {
SipResourcePermission srp = new SipResourcePermission(sn, allowedActions);
udcPermList.add(srp);
continue;
}
Iterator<String> ralItr = ral.iterator();
while (ralItr.hasNext()) {
allowedActions.add(ralItr.next());
}
SipResourcePermission srp = new SipResourcePermission(true, sn, allowedActions);
udcPermList.add(srp);
}
pc.addToUncheckedPolicy(udcPermList);
pc.commit();
} catch (PolicyContextException pce) {
pce.printStackTrace();
}
sipConfig.getSecurityRoles();
}
private void addDefaultPermissions(SipApplication sipConfig) {
try {
Map<String, Servlet> servletList = sipConfig.getServlets();
Iterator<String> sitr = servletList.keySet().iterator();
Permissions udcPermList = new Permissions();
Set<String> emptySet = new HashSet<String>();
String transport = null;
while (sitr.hasNext()) {
String sn = sitr.next();
udcPermList.add(new SipResourcePermission(sn, emptySet));
udcPermList.add(new SipUserDataPermission(sn, emptySet, transport));
}
pc.addToUncheckedPolicy(udcPermList);
pc.commit();
} catch (PolicyContextException pce) {
pce.printStackTrace();
}
}
private void addDefaultUserDataPermissions(SipApplication sipConfig, Permissions udcPermList) {
Map<String, Servlet> servletList = sipConfig.getServlets();
Iterator<String> sitr = servletList.keySet().iterator();
Set<String> emptySet = new HashSet<String>();
String transport = null;
while (sitr.hasNext()) {
String sn = sitr.next();
udcPermList.add(new SipUserDataPermission(sn, emptySet, transport));
}
}
class Key {
String servletName = null;
String roleName = null;
public Key() {
}
public Key(String servletName, String roleName) {
this.servletName = servletName;
this.roleName = roleName;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Key)) {
return false;
}
Key key = (Key) obj;
if (((servletName != null) && servletName.equals(key.servletName)) &&
((roleName != null) && roleName.equals(key.roleName))) {
return true;
}
return false;
}
@Override
public int hashCode() {
if ((servletName == null) && (roleName != null)) {
return roleName.hashCode();
}
if ((roleName == null) && (servletName != null)) {
return servletName.hashCode();
}
if ((servletName == null) && (roleName == null)) {
return 0;
}
return servletName.hashCode() + roleName.hashCode();
}
public void reset() {
servletName = null;
roleName = null;
}
}
class ServletActions {
String servletName = "";
Set<String> actions = new HashSet<String>();
Set<String> roles = new HashSet<String>();
public ServletActions(String servletName) {
this.servletName = servletName;
}
public void setServletName(String sn) {
this.servletName = sn;
}
@SuppressWarnings(value = "unchecked")
public void setAction(String action) {
actions.add(action);
}
public void setRole(String rn) {
this.roles.add(rn);
}
}
class TransportConstraints extends ServletActions {
String transportType = null;
public TransportConstraints(String servletName) {
super(servletName);
}
public void setType(String type) {
this.transportType = type;
}
public String getType() {
return transportType;
}
}
}