Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PermissionAdmin.java')
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PermissionAdmin.java723
1 files changed, 723 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PermissionAdmin.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PermissionAdmin.java
new file mode 100644
index 000000000..348303416
--- /dev/null
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PermissionAdmin.java
@@ -0,0 +1,723 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.framework.internal.core;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.ProtectionDomain;
+import java.util.Vector;
+
+import org.eclipse.osgi.framework.adaptor.PermissionStorage;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+/**
+ * Permission Admin service for the OSGi specification.
+ *
+ * The Permission Admin service allows operators to
+ * manage the permissions of bundles. There is at most one Permission Admin
+ * service present in the Framework.
+ * <p>
+ * Access to the Permission Admin service is protected by
+ * corresponding
+ * <tt>ServicePermission</tt>. In addition the <tt>AdminPermission</tt>
+ * is required to actually set permissions.
+ *
+ * <p>Bundle permissions are managed using a permission table. A bundle's location
+ * serves as the key into this permission table. The value of a table entry is
+ * the set of permissions (of type <tt>PermissionInfo</tt>) granted to the
+ * bundle with the given location.
+ * A bundle may have an entry in the permission table prior to being installed
+ * in the Framework.
+ *
+ * <p>The permissions specified in <tt>setDefaultPermissions</tt> are used as the
+ * default
+ * permissions which are granted to all bundles that do not have an entry in
+ * the permission table.
+ *
+ * <p>Any changes to a bundle's permissions in the permission table will take
+ * effect no later than when bundle's <tt>java.security.ProtectionDomain</tt>
+ * is involved in a permission check, and will be made persistent.
+ *
+ * <p>Only permission classes on the system classpath or from an exported
+ * package are considered during a permission check.
+ * Additionally, only permission classes that are subclasses of
+ * <tt>java.security.Permission</tt> and define a 2-argument constructor
+ * that takes a <i>name</i> string and an <i>actions</i> string can be used.
+ * <p>
+ * Permissions implicitly granted by the Framework (for example, a bundle's
+ * permission to access its persistent storage area) cannot be changed, and
+ * are not reflected in the permissions returned by <tt>getPermissions</tt>
+ * and <tt>getDefaultPermissions</tt>.
+ */
+public class PermissionAdmin implements org.osgi.service.permissionadmin.PermissionAdmin
+{
+ /** framework object */
+ protected Framework framework;
+
+ /** permission storage object */
+ protected PermissionStorage storage;
+
+ /** The permissions to use if no other permissions can be determined */
+ protected PermissionInfo[] defaultDefaultPermissionInfos;
+
+ /** The basic implied permissions for a bundle */
+ protected PermissionInfo[] baseImpliedPermissionInfos;
+
+ /** The permission collection containing the default assigned permissions */
+ protected BundleCombinedPermissions defaultAssignedPermissions;
+
+ /**
+ * Construstor.
+ *
+ * @param framework Framework object.
+ */
+ protected PermissionAdmin(Framework framework, PermissionStorage storage)
+ {
+ this.framework = framework;
+ this.storage = storage;
+
+ defaultDefaultPermissionInfos = getPermissionInfos(Constants.OSGI_DEFAULT_DEFAULT_PERMISSIONS);
+ baseImpliedPermissionInfos = getPermissionInfos(Constants.OSGI_BASE_IMPLIED_PERMISSIONS);
+
+// if (Debug.DEBUG)
+// {
+// // This is necessary to allow File.getAbsolutePath() in debug statements.
+// int _length = baseImpliedPermissionInfos.length;
+//
+// PermissionInfo[] debugBaseImpliedPermissionInfos = new PermissionInfo[_length + 1];
+//
+// System.arraycopy(baseImpliedPermissionInfos, 0, debugBaseImpliedPermissionInfos, 0, _length);
+//
+// debugBaseImpliedPermissionInfos[_length] = new PermissionInfo("(java.util.PropertyPermission \"user.dir\" \"read\")");
+//
+// baseImpliedPermissionInfos = debugBaseImpliedPermissionInfos;
+// }
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Default default assigned bundle permissions");
+ if (defaultDefaultPermissionInfos == null)
+ {
+ Debug.println(" <none>");
+ }
+ else
+ {
+ for (int i = 0; i < defaultDefaultPermissionInfos.length; i++)
+ {
+ Debug.println(" "+defaultDefaultPermissionInfos[i]);
+ }
+ }
+
+ Debug.println("Base implied bundle permissions");
+ if (baseImpliedPermissionInfos == null)
+ {
+ Debug.println(" <none>");
+ }
+ else
+ {
+ for (int i = 0; i < baseImpliedPermissionInfos.length; i++)
+ {
+ Debug.println(" "+baseImpliedPermissionInfos[i]);
+ }
+ }
+ }
+
+ defaultAssignedPermissions = new BundleCombinedPermissions(null);
+ defaultAssignedPermissions.setAssignedPermissions(createDefaultAssignedPermissions(getDefaultPermissions()));
+ }
+
+ /**
+ * Gets the permissions assigned to the bundle with the specified
+ * location.
+ *
+ * @param location The location of the bundle whose permissions are to
+ * be returned.
+ *
+ * @return The permissions assigned to the bundle with the specified
+ * location, or <tt>null</tt> if that bundle has not been assigned any
+ * permissions.
+ */
+ public PermissionInfo[] getPermissions(String location)
+ {
+ if (location == null)
+ {
+ throw new NullPointerException();
+ }
+
+ PermissionStorage storage = new org.eclipse.osgi.framework.security.action.PermissionStorage(this.storage);
+
+ try
+ {
+ String[] data = storage.getPermissionData(location);
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Getting permissions for location: "+location);
+ if (data == null)
+ {
+ Debug.println(" <none>");
+ }
+ else
+ {
+ for (int i = 0; i < data.length; i++)
+ {
+ Debug.println(" "+data[i]);
+ }
+ }
+ }
+
+ return makePermissionInfo(data);
+ }
+ catch (IOException e)
+ {
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
+
+ return null;
+ }
+ }
+
+ /**
+ * Assigns the specified permissions to the bundle with the specified
+ * location.
+ *
+ * @param location The location of the bundle that will be assigned the
+ * permissions.
+ * @param perms The permissions to be assigned, or <tt>null</tt>
+ * if the specified location is to be removed from the permission table.
+ * @exception SecurityException if the caller does not have the
+ * <tt>AdminPermission</tt>.
+ */
+ public void setPermissions(String location, PermissionInfo[] permissions)
+ {
+ framework.checkAdminPermission();
+
+ if (location == null)
+ {
+ throw new NullPointerException();
+ }
+
+ PermissionStorage storage = new org.eclipse.osgi.framework.security.action.PermissionStorage(this.storage);
+
+ try
+ {
+ String[] data = makePermissionData(permissions);
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Setting permissions for location: "+location);
+ if (data == null)
+ {
+ Debug.println(" <none>");
+ }
+ else
+ {
+ for (int i = 0; i < data.length; i++)
+ {
+ Debug.println(" "+data[i]);
+ }
+ }
+ }
+
+ storage.setPermissionData(location, data);
+ }
+ catch (IOException e)
+ {
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
+
+ return;
+ }
+
+ Bundle bundle = framework.getBundleByLocation(location);
+
+ if ((bundle != null) && (bundle.getBundleId() != 0))
+ {
+ ProtectionDomain domain = bundle.getProtectionDomain();
+
+ if (domain != null)
+ {
+ BundleCombinedPermissions combined = (BundleCombinedPermissions)domain.getPermissions();
+
+ if (permissions == null)
+ {
+ combined.setAssignedPermissions(defaultAssignedPermissions);
+ }
+ else
+ {
+ combined.setAssignedPermissions(createPermissions(permissions, bundle));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the bundle locations that have permissions assigned to them,
+ * that is, bundle locations for which an entry
+ * exists in the permission table.
+ *
+ * @return The locations of bundles that have been assigned any
+ * permissions, or <tt>null</tt> if the permission table is empty.
+ */
+ public String[] getLocations()
+ {
+ PermissionStorage storage = new org.eclipse.osgi.framework.security.action.PermissionStorage(this.storage);
+
+ try
+ {
+ String[] locations = storage.getLocations();
+
+ return locations;
+ }
+ catch (IOException e)
+ {
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
+
+ return null;
+ }
+ }
+
+ /**
+ * Gets the default permissions.
+ *
+ * <p>These are the permissions granted to any bundle that does not
+ * have permissions assigned to its location.
+ *
+ * @return The default permissions, or <tt>null</tt> if default
+ * permissions have not been defined.
+ */
+ public PermissionInfo[] getDefaultPermissions()
+ {
+ PermissionStorage storage = new org.eclipse.osgi.framework.security.action.PermissionStorage(this.storage);
+
+ try
+ {
+ String[] data = storage.getPermissionData(null);
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Getting default permissions");
+ if (data == null)
+ {
+ Debug.println(" <none>");
+ }
+ else
+ {
+ for (int i = 0; i < data.length; i++)
+ {
+ Debug.println(" "+data[i]);
+ }
+ }
+ }
+
+ return makePermissionInfo(data);
+ }
+ catch (IOException e)
+ {
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
+
+ return null;
+ }
+ }
+
+ /**
+ * Sets the default permissions.
+ *
+ * <p>These are the permissions granted to any bundle that does not
+ * have permissions assigned to its location.
+ *
+ * @param permissions The default permissions.
+ * @exception SecurityException if the caller does not have the
+ * <tt>AdminPermission</tt>.
+ */
+ public void setDefaultPermissions(PermissionInfo[] permissions)
+ {
+ framework.checkAdminPermission();
+
+ PermissionStorage storage = new org.eclipse.osgi.framework.security.action.PermissionStorage(this.storage);
+
+ try
+ {
+ String[] data = makePermissionData(permissions);
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Setting default permissions");
+ if (data == null)
+ {
+ Debug.println(" <none>");
+ }
+ else
+ {
+ for (int i = 0; i < data.length; i++)
+ {
+ Debug.println(" "+data[i]);
+ }
+ }
+ }
+
+ storage.setPermissionData(null, data);
+ }
+ catch (IOException e)
+ {
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, e);
+
+ return;
+ }
+
+ defaultAssignedPermissions.setAssignedPermissions(createDefaultAssignedPermissions(permissions));
+ }
+
+ /**
+ * Make a PermissionInfo array from an array of encoded permission Strings.
+ *
+ * @param data Array of encoded permission Strings
+ * @return Array of PermissionInfo objects.
+ */
+ protected PermissionInfo[] makePermissionInfo(String[] data)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ int size = data.length;
+
+ PermissionInfo[] permissions = new PermissionInfo[size];
+
+ for (int i = 0; i < size; i++)
+ {
+ permissions[i] = new PermissionInfo(data[i]);
+ }
+
+ return permissions;
+ }
+
+ /**
+ * Make an array of encoded permission Strings from a PermissionInfo array.
+ *
+ * @param permissions Array of PermissionInfor objects.
+ * @return Array of encoded permission Strings
+ */
+ protected String[] makePermissionData(PermissionInfo[] permissions)
+ {
+ if (permissions == null)
+ {
+ return null;
+ }
+
+ int size = permissions.length;
+
+ String[] data = new String[size];
+
+ for (int i = 0; i < size; i++)
+ {
+ data[i] = permissions[i].getEncoded();
+ }
+
+ return data;
+ }
+
+ /**
+ * This method is called by the Bundle object to create the
+ * PermissionCollection used by the bundle's ProtectionDomain.
+ *
+ * @param location Location string of the bundle.
+ * @return BundleCombinedPermission object with the bundle's
+ * dynamic permissions.
+ */
+ protected PermissionCollection createPermissionCollection(Bundle bundle)
+ {
+ BundlePermissionCollection implied = getImpliedPermissions(bundle);
+
+ BundleCombinedPermissions combined = new BundleCombinedPermissions(implied);
+
+ BundlePermissionCollection assigned = getAssignedPermissions(bundle);
+
+ combined.setAssignedPermissions(assigned);
+
+ return combined;
+ }
+
+ /**
+ * Creates the default assigned permissions for bundles that
+ * have no assigned permissions.
+ * The default permissions are assigned via the PermissionAdmin service
+ * and may change dynamically.
+ *
+ * @return A PermissionCollection of the default assigned permissions.
+ */
+ protected BundlePermissionCollection createDefaultAssignedPermissions(PermissionInfo[] info)
+ {
+ if (Debug.DEBUG &&Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Creating default assigned permissions");
+ }
+
+ if (info == null)
+ {
+ info = defaultDefaultPermissionInfos;
+ }
+
+ return createPermissions(info, null);
+ }
+
+ /**
+ * Returns the assigned permissions for a bundle.
+ * These permissions are assigned via the PermissionAdmin service
+ * and may change dynamically.
+ *
+ * @param bundle The bundle to create the permissions for.
+ * @return A PermissionCollection of the assigned permissions.
+ */
+ protected BundlePermissionCollection getAssignedPermissions(Bundle bundle)
+ {
+ String location = bundle.getLocation();
+
+ PermissionInfo[] info = getPermissions(location);
+
+ if (info == null)
+ {
+ return defaultAssignedPermissions;
+ }
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Creating assigned permissions for "+bundle);
+ }
+
+ return createPermissions(info, bundle);
+ }
+
+ /**
+ * Returns the implied permissions for a bundle.
+ * These permissions never change.
+ *
+ * @param bundle The bundle to create the permissions for.
+ * @return A PermissionCollection of the implied permissions.
+ */
+ protected BundlePermissionCollection getImpliedPermissions(Bundle bundle)
+ {
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Creating implied permissions for "+bundle);
+ }
+
+ BundlePermissionCollection collection = createPermissions(baseImpliedPermissionInfos, bundle);
+
+ Permission permission = new BundleResourcePermission(bundle.getBundleId());
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Created permission: "+permission);
+ }
+
+ collection.add(permission);
+
+ return collection;
+ }
+
+ /**
+ * Read the permissions from the specified resource.
+ *
+ * @return An array of PermissionInfo objects from the specified
+ * resource.
+ */
+ protected PermissionInfo[] getPermissionInfos(String resource)
+ {
+ PermissionInfo[] info = null;
+
+ InputStream in = getClass().getResourceAsStream(resource);
+
+ if (in != null)
+ {
+ try
+ {
+ Vector permissions = new Vector();
+
+ BufferedReader reader;
+ try
+ {
+ reader = new BufferedReader(new InputStreamReader(in, "UTF8"));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ reader = new BufferedReader(new InputStreamReader(in));
+ }
+
+ while (true)
+ {
+ String line = reader.readLine();
+
+ if (line == null) /* EOF */
+ {
+ break;
+ }
+
+ line = line.trim();
+
+ if ((line.length() == 0) || line.startsWith("#") || line.startsWith("//")) /* comments */
+ {
+ continue;
+ }
+
+ try
+ {
+ permissions.addElement(new PermissionInfo(line));
+ }
+ catch (IllegalArgumentException iae)
+ {
+ /* incorrectly encoded permission */
+
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, iae);
+ }
+ }
+
+ int size = permissions.size();
+
+ if (size > 0)
+ {
+ info = new PermissionInfo[size];
+
+ permissions.copyInto(info);
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ finally
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException ee)
+ {
+ }
+ }
+ }
+
+ return info;
+ }
+
+ /**
+ * Create a PermissionCollection from a PermissionInfo array.
+ *
+ * @param info Array of PermissionInfo objects.
+ * @param bundle The target bundle for the permissions.
+ * @return A PermissionCollection containing Permission objects.
+ */
+ protected BundlePermissionCollection createPermissions(PermissionInfo[] info, final Bundle bundle)
+ {
+ BundlePermissionCollection collection = new BundlePermissions(framework.packageAdmin);
+
+ /* add the permissions */
+ int size = info.length;
+ for (int i = 0; i < size; i++)
+ {
+ PermissionInfo perm = info[i];
+
+ String type = perm.getType();
+
+ if (type.equals("java.io.FilePermission"))
+ {
+ /* map FilePermissions for relative names to
+ * the bundle's data area
+ */
+ String name = perm.getName();
+
+ if (!name.equals("<<ALL FILES>>"))
+ {
+ File file = new File(name);
+
+ if (!file.isAbsolute()) /* relative name */
+ {
+ if (bundle == null) /* default permissions */
+ {
+ continue; /* no relative file permissions */
+ }
+
+ File target = framework.getDataFile(bundle, name);
+
+ if (target == null) /* no bundle data file area */
+ {
+ continue; /* no relative file permissions */
+ }
+
+ perm = new PermissionInfo(type, target.getPath(), perm.getActions());
+ }
+ }
+ }
+
+ collection.add(createPermission(perm));
+ }
+
+ return collection;
+ }
+
+ /**
+ * Create a Permission object from a PermissionInfo object.
+ * If the type of the permission is not loadable from
+ * this object's classloader (i.e. the system classloader)
+ * then an UnresolvedPermission is returned.
+ *
+ * @param info Description of the desired permission.
+ * @return A permission object.
+ */
+ protected Permission createPermission(PermissionInfo info)
+ {
+ String type = info.getType();
+ String name = info.getName();
+ String actions = info.getActions();
+
+ UnresolvedPermission permission = new UnresolvedPermission(type, name, actions);
+
+ try
+ {
+ /* Only search the system classloader (ours) at this point.
+ * Permission classes exported by bundles will be
+ * resolved later.
+ * This is done so that permission classes exported by bundles
+ * may be easily unresolved during packageRefresh.
+ */
+ Class clazz = Class.forName(type);
+
+ Permission resolved = permission.resolve(clazz);
+
+ if (resolved != null)
+ {
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Created permission: "+resolved);
+ }
+
+ return resolved;
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ }
+
+ if (Debug.DEBUG && Debug.DEBUG_SECURITY)
+ {
+ Debug.println("Created permission: "+permission);
+ }
+
+ return permission;
+ }
+}

Back to the top