diff -r e8e63152f320 -r 2a9601315dfc javacommons/security/javasrc/com/nokia/mj/impl/security/midp/authorization/PermissionResolver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javacommons/security/javasrc/com/nokia/mj/impl/security/midp/authorization/PermissionResolver.java Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,724 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.mj.impl.security.midp.authorization; + +import java.util.Vector; +import java.util.Hashtable; +import java.security.Permission; +import com.nokia.mj.impl.utils.Uid; +import com.nokia.mj.impl.utils.Tokenizer; +import com.nokia.mj.impl.utils.exception.InvalidAttributeException; +import com.nokia.mj.impl.utils.InstallerDetailedErrorMessage; +import com.nokia.mj.impl.utils.InstallerErrorMessage; +import com.nokia.mj.impl.utils.OtaStatusCode; +import com.nokia.mj.impl.security.midp.common.PermissionAttribute; +import com.nokia.mj.impl.security.midp.common.PolicyBasedPermission; +import com.nokia.mj.impl.security.midp.common.PolicyBasedPermissionImpl; +import com.nokia.mj.impl.security.midp.common.UserSecuritySettings; +import com.nokia.mj.impl.security.common.PermissionBase; +import com.nokia.mj.impl.security.midp.storage.*; +import com.nokia.mj.impl.storage.StorageSession; +import com.nokia.mj.impl.security.utils.Logger; + + +/** + * Permission resolver: it resolves a list of permissions against another list + * of permissions, returning the list of permissions which resolved the + * permissions. Resolving means callint the implies method of Permission + * objects + */ +public final class PermissionResolver +{ + /* + * Cache for Permission objects + */ + // Add synchronization for access to these hashtables + private static Hashtable policyPermissionInstances = new Hashtable(); + private static Hashtable grantedPermissionInstances = new Hashtable(); + + public static Vector resolvePermissions( + Uid msUID, + PermissionAttribute[] requestedPermissions, + PolicyBasedPermission[] policyPermissions) + { + if (requestedPermissions == null) + { + return null; + } + + Vector resolvedPermissions = new Vector(); + for (int i=0; i 0) + { + for (int j=0; j 0) + { + for (int i=0; i 0) + { + UserSecuritySettings settings2 = + permission2.getUserSecuritySettings(); + // group resolve permissions by name and settings + if (permission1.getClass().getName().equals(permission2.getClass().getName()) + && ((permission1.getName() != null && permission2.getName() != null + && permission1.getName().equals(permission2.getName())) + || (permission1.getName() == null && permission2.getName() == null)) + && ((settings1 != null && settings2 != null && settings1.equals(settings2)) + || (settings1 == null && settings2 == null))) + { + // replace element at position k with another one having + // the combined actions + resolvedPermissions.setElementAt(getResolvedPermission( + permission1.getPromptDetails(), + p.getSettings(), + requestedPermission.getClass().getName(), + requestedPermission.getName(), + permission2.getActionList() + "," + permission1.getActionList()), + k); + found = true; + break; + } + } + } + if (!found) + { + resolvedPermissions.addElement(permission1); + } + break; + } + } + } + catch (InstantiationException e) + { + // ignore it + } + if (!permissionResolved) + { + resolvedPermissions.removeAllElements(); + break; + } + } + if (resolvedPermissions.size() > 0) + { + return resolvedPermissions; + } + } + // stage 3: try the granted complex permissions (complex permission = permission with multiple actions) + // - step 1: group permissions having same name, target and settings + // into a list of complex permissions (= permissions with + // same name, target and settings but with the composite + // action (comma separated list of individual actions) + // - step 2: try to resolve the requested permission against the + // list of complet permissions + Vector tmp = new Vector(); + for (int i=0; i 0) + { + PermisionInstanceAndSettings instance1 = + (PermisionInstanceAndSettings)tmp.elementAt(0); + tmp.removeElementAt(0); + Permission permission1 = (Permission)instance1.getPermissionInstance(); + UserSecuritySettings settings1 = instance1.getSettings(); + String compositeAction = ""; + // put the individual actions into a vector so that the composite + // action is made only by unique actions (duplicates are discarded) + Vector uniqueActions = new Vector(); + int i=0; + while (i 0) + { + if (!uniqueActions.contains(permission1.getActions())) + { + if (compositeAction.length() > 0) + { + compositeAction += ","; + } + compositeAction += permission1.getActions(); + uniqueActions.addElement(permission1.getActions()); + } + } + if (permission2.getActions() != null && permission2.getActions().length() > 0) + { + if (!uniqueActions.contains(permission2.getActions())) + { + if (compositeAction.length() > 0) + { + compositeAction += ","; + } + compositeAction += permission2.getActions(); + uniqueActions.addElement(permission2.getActions()); + } + } + } + else + { + i++; + } + } + if (compositeAction.length() > 0 && compositeAction.indexOf(',') != -1) + { + try + { + Permission perm = (Permission)ClassInstantiator.newInstance( + permission1.getClass().getName(), + permission1.getName(), + compositeAction); + if (perm.getClass().isInstance(requestedPermission) + && perm.implies(requestedPermission)) + { + resolvedPermissions.addElement( + getResolvedPermission( + requestedPermission, + permission1, + settings1, + requestedPermission.getClass().getName(), + requestedPermission.getName(), + requestedPermission.getActions())); + return resolvedPermissions; + } + } + catch (InstantiationException ex) {} + } + } + if (resolvedPermissions.size() == 0) + { + return null; + } + return resolvedPermissions; + } + + private static Vector resolvePermission( + Uid msUID, + Permission requestedPermission, + PolicyBasedPermission[] policyPermissions) + { + Vector permissionInstances = getPolicyPermissionInstances( + msUID, policyPermissions); + return resolvePermission(requestedPermission, permissionInstances); + } + + private static PolicyBasedPermissionImpl getResolvedPermission( + PermissionBase securityPromptDetails, + UserSecuritySettings userSettings, + String permissionName, + String targetName, + String actionList) + { + PermissionBase securityPromptDetails2 = securityPromptDetails; + if (securityPromptDetails != null + && (!PermissionBase.matchActions(securityPromptDetails.getActions(),actionList) + || !PermissionBase.matchActions(actionList, securityPromptDetails.getActions()))) + { + // the new instance is created only if the actions are different + try + { + securityPromptDetails2 = (PermissionBase)ClassInstantiator + .newInstance(securityPromptDetails.getClass().getName(), + securityPromptDetails.getName(), + actionList); + } + catch (InstantiationException e2) + { + // ignore it (no details) + } + } + return new PolicyBasedPermissionImpl( + permissionName, + targetName, + actionList, + userSettings, + securityPromptDetails2); + } + + private static PolicyBasedPermissionImpl getResolvedPermission( + Permission requestedPermission, + Object policyPermission, + UserSecuritySettings userSettings, + String permissionName, + String targetName, + String actionList) + { + PermissionBase securityPromptDetails = null; + if (requestedPermission instanceof PermissionBase) + { + securityPromptDetails = (PermissionBase)requestedPermission; + } + else if (policyPermission instanceof PermissionBase) + { + try + { + securityPromptDetails = (PermissionBase)ClassInstantiator + .newInstance(policyPermission.getClass().getName(), + requestedPermission.getName(), + requestedPermission.getActions()); + } + catch (InstantiationException e2) + { + // ignore it (no details) + } + } + return new PolicyBasedPermissionImpl( + permissionName, + targetName, + actionList, + userSettings, + securityPromptDetails); + } + + private static Vector getPolicyPermissionInstances(Uid msUID, PolicyBasedPermission[] policyPermissions) + { + // try retrieving the policy permissions from cache + Vector policyPermissionInstancesAndSettings = + (Vector)policyPermissionInstances.get(msUID); + if (policyPermissionInstancesAndSettings != null) + { + return policyPermissionInstancesAndSettings; + } + + // if the policy permissions are not in cache, then build it + // from policy permissions + policyPermissionInstancesAndSettings = new Vector(); + if (policyPermissions == null) + { + return null; + } + for (int i=0; i grant all the permissions from the policy + // - if name is not null -> then grant the permissions from policy with the same name + // - if target is null -> take the target from the policy permission, otherwise take the target of the requested permission + // - if actionList is null -> take the actionList from the policy permission, otherwise take the actionList of the requested + // permission if it matches the actionList from the policy + private static Vector resolveLegacyPermission(PermissionAttribute legacyPermission, PolicyBasedPermission[] policyPermissions) + { + if (policyPermissions == null) + { + return null; + } + + Vector resolvedPermissions = new Vector(); + if (legacyPermission.getName() == null) + { + if (policyPermissions == null) + { + return null; + } + resolvedPermissions = new Vector(); + for (int i=0; i