Package org.jnode.security

Source Code of org.jnode.security.JNodePolicy

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.security;

import gnu.java.security.PolicyFile;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.jnode.bootlog.BootLogInstance;
import org.jnode.plugin.ConfigurationElement;
import org.jnode.plugin.Extension;
import org.jnode.plugin.ExtensionPoint;

/**
* Default policy implementation for JNode.
*
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
final class JNodePolicy extends Policy {

    /**
     * The permissions extension point
     */
    private final ExtensionPoint permissionsEp;

    /**
     * The configured policies
     */
    private final PolicyFile policyFile;

    /**
     * Mapping between a codesource (derived from plugin id) and a set of
     * permissions
     */
    private final HashMap<CodeSource, PermissionCollection> codeSource2Permissions;

    /**
     * Initialize this instance.
     */
    public JNodePolicy(ExtensionPoint permissionsEp) {
        this.policyFile = new PolicyFile(ClassLoader
            .getSystemResource("/org/jnode/security/jnode.policy"));
        this.codeSource2Permissions = new HashMap<CodeSource, PermissionCollection>();
        this.permissionsEp = permissionsEp;
        loadExtensions();
    }

    /**
     * Gets the permissions for a given code source.
     *
     * @see java.security.Policy#getPermissions(java.security.CodeSource)
     */
    public PermissionCollection getPermissions(CodeSource codesource) {
        PermissionCollection coll = policyFile.getPermissions(codesource);
        addPermissions(codesource, coll);
        return coll;
    }

    /**
     * Allow extended classes to add permissions before the permissions
     * collection is set to read-only.
     *
     * @param codeSource
     * @param perms
     */
    protected void addPermissions(CodeSource codeSource,
                                  PermissionCollection perms) {
        for (Map.Entry<CodeSource, PermissionCollection> e : codeSource2Permissions
            .entrySet()) {
            final CodeSource cs = e.getKey();
            if (cs.implies(codeSource)) {
                // BootLogInstance.get().info(cs + " -> " + codeSource);
                final PermissionCollection pc = e.getValue();
                for (Enumeration<?> ee = pc.elements(); ee.hasMoreElements();) {
                    perms.add((Permission) ee.nextElement());
                }
            }
        }
    }

    /**
     * @see java.security.Policy#refresh()
     */
    public synchronized void refresh() {
        policyFile.refresh();
        loadExtensions();
    }

    /**
     * Fill the plugin2Permissions map from the extensions connected to the
     * extensionpoint.
     */
    private final void loadExtensions() {
        if (permissionsEp != null) {
            codeSource2Permissions.clear();
            final Extension[] exts = permissionsEp.getExtensions();
            final int count = exts.length;
            for (int i = 0; i < count; i++) {
                loadExtension(exts[i]);
            }
        }
    }

    private static final Class[] NAME_ACTIONS_ARGS = new Class[]{
        String.class, String.class};

    private static final Class[] NAME_ARGS = new Class[]{String.class};

    private final void loadExtension(Extension ext) {
        final String id = ext.getDeclaringPluginDescriptor().getId();
        final URL url;
        try {
            //note: ".../-" match everything starting with "plugin:" + id + "!/"
            url = new URL("plugin:" + id + "!/-");
            final ClassLoader cl = ext.getDeclaringPluginDescriptor()
                .getPluginClassLoader();
            final CodeSource cs = new CodeSource(url, (Certificate[]) null);
            final Permissions perms = new Permissions();
            codeSource2Permissions.put(cs, perms);
            // BootLogInstance.get().debug("Adding permissions for " + cs);
            final ConfigurationElement[] elems = ext.getConfigurationElements();
            final int count = elems.length;
            for (int i = 0; i < count; i++) {
                final ConfigurationElement elem = elems[i];
                final String type = elem.getAttribute("class");
                final String name = elem.getAttribute("name");
                final String actions = elem.getAttribute("actions");

                if (type != null) {
                    final Object perm;
                    try {
                        final Class permClass = cl.loadClass(type);
                        if ((name != null) && (actions != null)) {
                            final Constructor c = permClass
                                .getConstructor(NAME_ACTIONS_ARGS);
                            perm = c
                                .newInstance(new Object[]{name, actions});
                        } else if (name != null) {
                            final Constructor c = permClass
                                .getConstructor(NAME_ARGS);
                            perm = c.newInstance(new Object[]{name});
                        } else {
                            perm = permClass.newInstance();
                        }
                        final Permission p = (Permission) perm;
                        perms.add(p);
                    } catch (ClassNotFoundException ex) {
                        BootLogInstance.get()
                            .error("Permission class " + type
                                + " not found");
                    } catch (InstantiationException ex) {
                        BootLogInstance.get().error("Cannot instantiate permission class "
                            + type);
                    } catch (IllegalAccessException ex) {
                        BootLogInstance.get().error("Illegal access to permission class "
                            + type);
                    } catch (NoSuchMethodException ex) {
                        BootLogInstance.get()
                            .error("Constructor not found on permission class "
                                + type + " in plugin " + id);
                    } catch (InvocationTargetException ex) {
                        BootLogInstance.get().error("Error constructing permission class "
                            + type, ex);
                    } catch (ClassCastException ex) {
                        BootLogInstance.get().error("Permission class " + type
                            + " not instance of Permission");
                    }
                }
            }
        } catch (MalformedURLException ex) {
            BootLogInstance.get().error("Cannot create plugin codesource", ex);
        }
    }
}
TOP

Related Classes of org.jnode.security.JNodePolicy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.