You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2010/01/10 23:11:28 UTC

svn commit: r897721 [2/2] - in /felix/trunk/framework.security: ./ src/main/java/org/apache/felix/framework/ src/main/java/org/apache/felix/framework/security/ src/main/java/org/apache/felix/framework/security/condpermadmin/ src/main/java/org/apache/fe...

Modified: felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java?rev=897721&r1=897720&r2=897721&view=diff
==============================================================================
--- felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java (original)
+++ felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Conditions.java Sun Jan 10 22:11:27 2010
@@ -18,21 +18,20 @@
  */
 package org.apache.felix.framework.security.util;
 
-import java.util.ArrayList;
+import java.security.Permission;
+import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.WeakHashMap;
-import java.util.Map.Entry;
 
-import org.apache.felix.framework.security.verifier.SignerMatcher;
+import org.apache.felix.framework.security.condpermadmin.ConditionalPermissionInfoImpl;
 import org.apache.felix.framework.util.SecureAction;
+import org.apache.felix.moduleloader.IModule;
 import org.osgi.framework.Bundle;
-import org.osgi.service.condpermadmin.BundleSignerCondition;
 import org.osgi.service.condpermadmin.Condition;
 import org.osgi.service.condpermadmin.ConditionInfo;
 
@@ -44,11 +43,11 @@
 public final class Conditions
 {
     private static final ThreadLocal m_conditionStack = new ThreadLocal();
+    private static final Map m_conditionCache = new WeakHashMap();
 
     private final Map m_cache = new WeakHashMap();
-    
-    private final Bundle m_bundle;
-    private final String[] m_signers;
+
+    private final IModule m_module;
 
     private final ConditionInfo[] m_conditionInfos;
     private final Condition[] m_conditions;
@@ -56,21 +55,44 @@
 
     public Conditions(SecureAction action)
     {
-        this(null, null, null, action);
+        this(null, null, action);
     }
-    
-    private Conditions(Bundle bundle, String[] signers,
-        ConditionInfo[] conditions, SecureAction action)
+
+    private Conditions(IModule module, ConditionInfo[] conditionInfos,
+        SecureAction action)
     {
-        m_bundle = bundle;
-        m_signers = signers;
-        m_conditionInfos = conditions;
-        m_conditions = ((conditions != null) && (bundle != null)) ? new Condition[m_conditionInfos.length] : null;
+        m_module = module;
+        m_conditionInfos = conditionInfos;
+        if ((module != null) && (conditionInfos != null))
+        {
+            synchronized (m_conditionCache)
+            {
+                Map conditionMap = (Map) m_conditionCache.get(module);
+                if (conditionMap == null)
+                {
+                    conditionMap = new HashMap();
+                    conditionMap.put(m_conditionInfos,
+                        new Condition[m_conditionInfos.length]);
+                    m_conditionCache.put(module, conditionMap);
+                }
+                Condition[] conditions = (Condition[]) conditionMap
+                    .get(m_conditionInfos);
+                if (conditions == null)
+                {
+                    conditions = new Condition[m_conditionInfos.length];
+                    conditionMap.put(m_conditionInfos, conditions);
+                }
+                m_conditions = conditions;
+            }
+        }
+        else
+        {
+            m_conditions = null;
+        }
         m_action = action;
     }
 
-    public Conditions getConditions(Bundle bundle, String[] signers,
-        ConditionInfo[] conditions)
+    public Conditions getConditions(IModule key, ConditionInfo[] conditions)
     {
         Conditions result = null;
         Map index = null;
@@ -85,90 +107,85 @@
         }
         synchronized (index)
         {
-            if (bundle != null)
+            if (key != null)
             {
-                result = (Conditions) index.get(bundle);
+                result = (Conditions) index.get(key);
             }
         }
-        
+
         if (result == null)
         {
-            result = new Conditions(bundle, signers, conditions, m_action);
+            result = new Conditions(key, conditions, m_action);
             synchronized (index)
             {
-                index.put(bundle, result);
+                index.put(key, result);
             }
         }
-        
+
         return result;
     }
 
     // See whether the given list is satisfied or not
-    public boolean isSatisfied(List posts)
+    public boolean isSatisfied(List posts, Permissions permissions,
+        Permission permission)
     {
-        for (int i = 0; i < m_conditions.length; i++)
+        boolean check = true;
+        for (int i = 0; i < m_conditionInfos.length; i++)
         {
-            if (m_bundle == null)
+            if (m_module == null)
             {
-                if (!m_conditionInfos[i].getType().equals(
-                    BundleSignerCondition.class.getName()))
-                {
-                    return false;
-                }
-                String[] args = m_conditionInfos[i].getArgs();
-
-                boolean match = false;
-                if (args.length == 0)
-                {
-                    for (int j = 0; j < m_signers.length; j++)
-                    {
-                        if (SignerMatcher.match(args[0], m_signers[j]))
-                        {
-                            match = true;
-                            break;
-                        }
-                    }
-                }
-                if (!match)
-                {
-                    return false;
-                }
-                continue;
+                // TODO: check whether this is correct!
+                break;
             }
             try
             {
                 Condition condition = null;
                 boolean add = false;
                 Class clazz = Class.forName(m_conditionInfos[i].getType());
-                
-                synchronized (m_conditionInfos)
+
+                synchronized (m_conditions)
                 {
+                    if (m_conditions[i] == null)
+                    {
+                        m_conditions[i] = createCondition(m_module.getBundle(),
+                            clazz, m_conditionInfos[i]);
+                    }
                     condition = m_conditions[i];
                 }
-                
-                if (condition == null)
+
+                Object current = m_conditionStack.get();
+                if (current != null)
                 {
-                    add = true;
-                    condition = createCondition(m_bundle, clazz, m_conditionInfos[i]);
+                    if (current instanceof HashSet)
+                    {
+                        if (((HashSet) current).contains(clazz))
+                        {
+                            return false;
+                        }
+                    }
+                    else
+                    {
+                        if (current == clazz)
+                        {
+                            return false;
+                        }
+                    }
                 }
-                
+
                 if (condition.isPostponed())
                 {
-                    posts.add(condition);
-                    if (add)
+                    if (check && !permissions.implies(permission, null))
                     {
-                        synchronized (m_conditionInfos)
-                        {
-                            if (m_conditions[i] == null)
-                            {
-                                m_conditions[i] = condition;
-                            }
-                        }
+                        return false;
+                    }
+                    else
+                    {
+                        check = false;
                     }
+                    posts.add(new Object[] { condition, new Integer(i) });
                 }
                 else
                 {
-                    Object current = m_conditionStack.get();
 
                     if (current == null)
                     {
@@ -199,20 +216,16 @@
                     }
                     try
                     {
+                        boolean mutable = condition.isMutable();
                         boolean result = condition.isSatisfied();
 
-                        if (!condition.isMutable() && ((condition != Condition.TRUE) && (condition != Condition.FALSE)))
+                        if (!mutable
+                            && ((condition != Condition.TRUE) && (condition != Condition.FALSE)))
                         {
-                            synchronized (m_conditionInfos)
+                            synchronized (m_conditions)
                             {
-                                m_conditions[i] = result ? Condition.TRUE : Condition.FALSE;
-                            }
-                        }
-                        else
-                        {
-                            synchronized (m_conditionInfos)
-                            {
-                                m_conditions[i] = condition;
+                                m_conditions[i] = result ? Condition.TRUE
+                                    : Condition.FALSE;
                             }
                         }
                         if (!result)
@@ -249,121 +262,99 @@
 
     public boolean evalRecursive(List entries)
     {
-        return _evalRecursive(entries, 0, new ArrayList(), new HashMap());
-    }
-
-    private boolean _evalRecursive(List entries, int pos, List acc, Map contexts)
-    {
-        if (pos == entries.size())
+        Map contexts = new HashMap();
+        outer: for (Iterator iter = entries.iterator(); iter.hasNext();)
         {
-            // we need to group by type by tuple
-            Map conditions = new HashMap();
-            for (Iterator iter = acc.iterator(); iter.hasNext();)
+            List tuples = (List) iter.next();
+            inner: for (Iterator inner = tuples.iterator(); inner.hasNext();)
             {
-                for (Iterator iter2 = ((List) iter.next()).iterator(); iter2
-                    .hasNext();)
+                Object[] entry = (Object[]) inner.next();
+                List conditions = (List) entry[1];
+                if (conditions == null)
                 {
-                    Object entry = iter2.next();
-                    Set group = (Set) conditions.get(entry.getClass());
-
-                    if (group == null)
+                    if (!((ConditionalPermissionInfoImpl) entry[0]).isAllow())
                     {
-                        group = new HashSet();
+                        return false;
                     }
-                    group.add(entry);
-
-                    conditions.put(entry.getClass(), group);
-                }
-            }
-
-            // and then eval per group
-            for (Iterator iter = conditions.entrySet().iterator(); iter.hasNext();)
-            {
-                Entry entry = (Entry) iter.next();
-                Class key = (Class) entry.getKey();
-                
-                Hashtable context = (Hashtable) contexts.get(key);
-                if (context == null)
-                {
-                    context = new Hashtable();
-                    contexts.put(key, context);
-                }
-                Set set = (Set) entry.getValue();
-                Condition[] current =
-                    (Condition[]) set.toArray(new Condition[set.size()]);
-
-                // We must be catching recursive evaluation as per spec, hence use a thread
-                // local stack to do so
-                Object currentCond = m_conditionStack.get();
-
-                if (currentCond == null)
-                {
-                    m_conditionStack.set(key);
+                    continue outer;
                 }
-                else
+                for (Iterator iter2 = conditions.iterator(); iter2.hasNext();)
                 {
-                    if (currentCond instanceof HashSet)
+                    Object[] condEntry = (Object[]) iter2.next();
+                    Condition cond = (Condition) condEntry[0];
+                    Dictionary context = (Dictionary) contexts.get(cond
+                        .getClass());
+                    if (context == null)
                     {
-                        if (((HashSet) currentCond).contains(key))
-                        {
-                            return false;
-                        }
-                        ((HashSet) currentCond).add(key);
+                        context = new Hashtable();
+                        contexts.put(cond.getClass(), context);
+                    }
+                    Object current = m_conditionStack.get();
+                    if (current == null)
+                    {
+                        m_conditionStack.set(cond.getClass());
                     }
                     else
                     {
-                        if (currentCond == key)
+                        if (current instanceof HashSet)
                         {
-                            return false;
+                            ((HashSet) current).add(cond.getClass());
+                        }
+                        else
+                        {
+                            HashSet frame = new HashSet();
+                            frame.add(current);
+                            frame.add(cond.getClass());
+                            m_conditionStack.set(frame);
+                            current = frame;
                         }
-                        HashSet frame = new HashSet();
-                        frame.add(current);
-                        frame.add(key);
-                        m_conditionStack.set(frame);
-                        currentCond = frame;
                     }
-                }
-                try
-                {
-                    if (!current[0].isSatisfied(current, context))
+                    boolean result;
+                    boolean mutable = cond.isMutable();
+                    try
                     {
-                        return false;
+                        result = cond.isSatisfied(new Condition[] { cond },
+                            context);
                     }
-                }
-                finally
-                {
-                    if (currentCond == null)
+                    finally
                     {
-                        m_conditionStack.set(null);
+                        if (current == null)
+                        {
+                            m_conditionStack.set(null);
+                        }
+                        else
+                        {
+                            ((HashSet) current).remove(cond.getClass());
+                            if (((HashSet) current).isEmpty())
+                            {
+                                m_conditionStack.set(null);
+                            }
+                        }
                     }
-                    else
+                    if (!mutable && (cond != Condition.TRUE)
+                        && (cond != Condition.FALSE))
                     {
-                        ((HashSet) currentCond).remove(key);
-                        if (((HashSet) currentCond).isEmpty())
+                        synchronized (((Conditions) entry[2]).m_conditions)
                         {
-                            m_conditionStack.set(null);
+                            ((Conditions) entry[2]).m_conditions[((Integer) condEntry[1])
+                                .intValue()] = result ? Condition.TRUE
+                                : Condition.FALSE;
                         }
                     }
+                    if (!result)
+                    {
+                        continue inner;
+                    }
                 }
+                if (!((ConditionalPermissionInfoImpl) entry[0]).isAllow())
+                {
+                    return false;
+                }
+                continue outer;
             }
-            return true;
-        }
-
-        List entry = (List) entries.get(pos);
-
-        for (int i = 0; i < entry.size(); i++)
-        {
-            acc.add(entry.get(i));
-
-            if (_evalRecursive(entries, pos + 1, acc, contexts))
-            {
-                return true;
-            }
-
-            acc.remove(acc.size() - 1);
+            return false;
         }
-
-        return false;
+        return true;
     }
 
     private Condition createCondition(final Bundle bundle, final Class clazz,

Modified: felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java?rev=897721&r1=897720&r2=897721&view=diff
==============================================================================
--- felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java (original)
+++ felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/LocalPermissions.java Sun Jan 10 22:11:27 2010
@@ -25,13 +25,9 @@
 import java.security.AllPermission;
 import java.security.Permission;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Map.Entry;
+import java.util.WeakHashMap;
 
-import org.apache.felix.framework.security.util.Permissions;
-import org.apache.felix.framework.security.util.PropertiesCache;
 import org.apache.felix.moduleloader.IContent;
 import org.osgi.framework.Bundle;
 import org.osgi.service.permissionadmin.PermissionInfo;
@@ -43,31 +39,15 @@
 // TODO: maybe use bundle events to clean thing up or weak/soft references
 public final class LocalPermissions
 {
-    private static final PermissionInfo[] ALL_PERMISSION =
-        new PermissionInfo[] { new PermissionInfo(
-            AllPermission.class.getName(), "", "") };
-    
-    private final Map m_cache = new HashMap();
+    private static final PermissionInfo[] ALL_PERMISSION = new PermissionInfo[] { new PermissionInfo(
+        AllPermission.class.getName(), "", "") };
+
+    private final Map m_cache = new WeakHashMap();
     private final Permissions m_permissions;
 
-    public LocalPermissions(Permissions permissions, PropertiesCache cache)
-        throws IOException
+    public LocalPermissions(Permissions permissions) throws IOException
     {
         m_permissions = permissions;
-        for (Iterator iter =
-            cache.read(PermissionInfo[].class).entrySet().iterator(); iter
-            .hasNext();)
-        {
-            Entry entry = (Entry) iter.next();
-            PermissionInfo[] value = (PermissionInfo[]) entry.getValue();
-            if ((value.length == 1)
-                && (AllPermission.class.getName().equals(value[0].getType())))
-            {
-                value = ALL_PERMISSION;
-            }
-
-            m_cache.put(entry.getKey(), value);
-        }
     }
 
     /**
@@ -75,20 +55,24 @@
      * permissions of the given bundle or if there are none otherwise, false.
      * See core spec 9.2.1.
      * 
-     * @param root the root to use for cacheing as a key
-     * @param loader the loader to get the content of the bundle from
-     * @param bundle the bundle in quesiton
-     * @param permission the permission to check
+     * @param root
+     *            the root to use for cacheing as a key
+     * @param loader
+     *            the loader to get the content of the bundle from
+     * @param bundle
+     *            the bundle in quesiton
+     * @param permission
+     *            the permission to check
      * @return true if implied by local permissions.
      */
-    public boolean implies(String root, IContent content, Bundle bundle,
+    public boolean implies(IContent content, Bundle bundle,
         Permission permission)
     {
         PermissionInfo[] permissions = null;
 
         synchronized (m_cache)
         {
-            if (!m_cache.containsKey(root))
+            if (!m_cache.containsKey(content))
             {
                 InputStream in = null;
                 try
@@ -98,28 +82,26 @@
                     {
                         ArrayList perms = new ArrayList();
 
-                        BufferedReader reader =
-                            new BufferedReader(new InputStreamReader(in,
-                                "UTF-8"));
-                        for (String line = reader.readLine(); line != null; line =
-                            reader.readLine())
+                        BufferedReader reader = new BufferedReader(
+                            new InputStreamReader(in, "UTF-8"));
+                        for (String line = reader.readLine(); line != null; line = reader
+                            .readLine())
                         {
                             String trim = line.trim();
-                            if (trim.startsWith("#") || trim.startsWith("//"))
+                            if (trim.startsWith("#") || trim.startsWith("//")
+                                || (trim.length() == 0))
                             {
                                 continue;
                             }
                             perms.add(new PermissionInfo(line));
                         }
 
-                        permissions =
-                            (PermissionInfo[]) perms
-                                .toArray(new PermissionInfo[perms.size()]);
+                        permissions = (PermissionInfo[]) perms
+                            .toArray(new PermissionInfo[perms.size()]);
                     }
                 }
                 catch (Exception ex)
                 {
-                    ex.printStackTrace();
                 }
                 finally
                 {
@@ -142,23 +124,15 @@
                     permissions = ALL_PERMISSION;
                 }
 
-                m_cache.put(root, permissions);
+                m_cache.put(content, permissions);
             }
             else
             {
-                permissions = (PermissionInfo[]) m_cache.get(root);
+                permissions = (PermissionInfo[]) m_cache.get(content);
             }
         }
 
         return m_permissions.getPermissions(permissions).implies(permission,
             bundle);
     }
-
-    public Map getStore() 
-    {
-        synchronized (m_cache)
-        {
-            return new HashMap(m_cache);
-        }
-    }
 }

Modified: felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java?rev=897721&r1=897720&r2=897721&view=diff
==============================================================================
--- felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java (original)
+++ felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/Permissions.java Sun Jan 10 22:11:27 2010
@@ -23,10 +23,11 @@
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
+import java.security.AccessController;
 import java.security.AllPermission;
 import java.security.Permission;
 import java.security.PermissionCollection;
-import java.security.*;
+import java.security.PrivilegedAction;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -44,19 +45,18 @@
 import org.osgi.service.permissionadmin.PermissionInfo;
 
 /**
- * A permission cache that uses permisssion infos as keys. Permission are created
- * from the parent classloader or any exported package. 
+ * A permission cache that uses permisssion infos as keys. Permission are
+ * created from the parent classloader or any exported package.
  */
 // TODO: maybe use bundle events instead of soft/weak references
 public final class Permissions
 {
-    private static final ClassLoader m_classLoader =
-        Permissions.class.getClassLoader();
+    private static final ClassLoader m_classLoader = Permissions.class
+        .getClassLoader();
 
     private static final Map m_permissionCache = new HashMap();
     private static final Map m_permissions = new HashMap();
-    private static final ReferenceQueue m_permissionsQueue =
-        new ReferenceQueue();
+    private static final ReferenceQueue m_permissionsQueue = new ReferenceQueue();
 
     private static final ThreadLocal m_stack = new ThreadLocal();
 
@@ -69,9 +69,8 @@
 
     public static final AllPermission ALL_PERMISSION = new AllPermission();
 
-    private static final PermissionInfo[] IMPLICIT =
-        new PermissionInfo[] { new PermissionInfo(FilePermission.class
-            .getName(), "-", "read,write,delete") };
+    private static final PermissionInfo[] IMPLICIT = new PermissionInfo[] { new PermissionInfo(
+        FilePermission.class.getName(), "-", "read,write,delete") };
 
     Permissions(PermissionInfo[] permissionInfos, BundleContext context,
         SecureAction action)
@@ -102,13 +101,17 @@
         m_allPermission = true;
         m_action = action;
     }
-    
+
     public PermissionInfo[] getImplicit(Bundle bundle)
     {
         return new PermissionInfo[] {
             IMPLICIT[0],
             new PermissionInfo(AdminPermission.class.getName(), "(id="
-                + bundle.getBundleId() + ")", AdminPermission.METADATA) };
+                + bundle.getBundleId() + ")", AdminPermission.METADATA),
+            new PermissionInfo(AdminPermission.class.getName(), "(id="
+                + bundle.getBundleId() + ")", AdminPermission.RESOURCE),
+            new PermissionInfo(AdminPermission.class.getName(), "(id="
+                + bundle.getBundleId() + ")", AdminPermission.CONTEXT) };
     }
 
     public Permissions getPermissions(PermissionInfo[] permissionInfos)
@@ -177,11 +180,11 @@
                 return false;
             }
 
-            if (o instanceof Entry) 
+            if (o instanceof Entry)
             {
-                return entry.equals(((Entry)o).get());
-            } 
-            else 
+                return entry.equals(((Entry) o).get());
+            }
+            else
             {
                 return false;
             }
@@ -237,8 +240,8 @@
 
     private void cleanUp(ReferenceQueue queue, Map cache)
     {
-        for (Entry entry = (Entry) queue.poll(); entry != null; entry =
-            (Entry) queue.poll())
+        for (Entry entry = (Entry) queue.poll(); entry != null; entry = (Entry) queue
+            .poll())
         {
             synchronized (cache)
             {
@@ -248,12 +251,14 @@
     }
 
     /**
-     * @param target the permission to be implied
-     * @param bundle if not null then allow implicit permissions like file 
-     *     access to local data area
+     * @param target
+     *            the permission to be implied
+     * @param bundle
+     *            if not null then allow implicit permissions like file access
+     *            to local data area
      * @return true if the permission is implied by this permissions object.
      */
-    public boolean implies(Permission target, Bundle bundle)
+    public boolean implies(Permission target, final Bundle bundle)
     {
         if (m_allPermission)
         {
@@ -273,7 +278,48 @@
                 {
                     String postfix = "";
                     String name = m_permissionInfos[i].getName();
-                    if (!"<<ALL FILES>>".equals(name)) 
+                    if (!"<<ALL FILES>>".equals(name))
+                    {
+                        if (name.endsWith("*") || name.endsWith("-"))
+                        {
+                            postfix = name.substring(name.length() - 1);
+                            name = name.substring(0, name.length() - 1);
+                        }
+                        if (!(new File(name)).isAbsolute())
+                        {
+                            BundleContext context = (BundleContext) AccessController
+                                .doPrivileged(new PrivilegedAction()
+                                {
+                                    public Object run()
+                                    {
+                                        return bundle.getBundleContext();
+                                    }
+                                });
+                            if (context == null)
+                            {
+                                break;
+                            }
+                            name = m_action.getAbsolutePath(new File(context
+                                .getDataFile(""), name));
+                        }
+                        if (postfix.length() > 0)
+                        {
+                            if ((name.length() > 0) && !name.endsWith("/"))
+                            {
+                                name += "/" + postfix;
+                            }
+                            else
+                            {
+                                name += postfix;
+                            }
+                        }
+                    }
+                    Permission source = createPermission(new PermissionInfo(
+                        FilePermission.class.getName(), name,
+                        m_permissionInfos[i].getActions()), targetClass);
+                    postfix = "";
+                    name = target.getName();
+                    if (!"<<ALL FILES>>".equals(name))
                     {
                         if (name.endsWith("*") || name.endsWith("-"))
                         {
@@ -282,13 +328,20 @@
                         }
                         if (!(new File(name)).isAbsolute())
                         {
-                            BundleContext context = bundle.getBundleContext();
+                            BundleContext context = (BundleContext) AccessController
+                                .doPrivileged(new PrivilegedAction()
+                                {
+                                    public Object run()
+                                    {
+                                        return bundle.getBundleContext();
+                                    }
+                                });
                             if (context == null)
                             {
                                 break;
                             }
-                            name =
-                                m_action.getAbsolutePath(new File(context.getDataFile(""), name));
+                            name = m_action.getAbsolutePath(new File(context
+                                .getDataFile(""), name));
                         }
                         if (postfix.length() > 0)
                         {
@@ -302,10 +355,13 @@
                             }
                         }
                     }
-                    return createPermission(
+                    Permission realTarget = createPermission(
                         new PermissionInfo(FilePermission.class.getName(),
-                            name, m_permissionInfos[i].getActions()),
-                        targetClass).implies(target);
+                            name, target.getActions()), targetClass);
+                    if (source.implies(realTarget))
+                    {
+                        return true;
+                    }
                 }
             }
             return false;
@@ -374,8 +430,8 @@
 
                     if (infoType.equals(permissionType))
                     {
-                        Permission permission =
-                            createPermission(permissionInfo, targetClass);
+                        Permission permission = createPermission(
+                            permissionInfo, targetClass);
 
                         if (permission != null)
                         {
@@ -478,86 +534,94 @@
     private Permission createPermission(final PermissionInfo permissionInfo,
         final Class target)
     {
-        return (Permission) AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run()
+        return (Permission) AccessController
+            .doPrivileged(new PrivilegedAction()
             {
-        Permission cached = getFromCache(permissionInfo.getEncoded(), target);
-
-        if (cached != null)
-        {
-            return cached;
-        }
+                public Object run()
+                {
+                    Permission cached = getFromCache(permissionInfo
+                        .getEncoded(), target);
 
-        try
-        {
-            if (m_classLoader.loadClass(target.getName()) == target)
-            {
-                return addToCache(permissionInfo.getEncoded(),
-                    createPermission(permissionInfo.getName(), permissionInfo
-                        .getActions(), target));
-            }
-        }
-        catch (ClassNotFoundException e1)
-        {
-        }
+                    if (cached != null)
+                    {
+                        return cached;
+                    }
 
-        ServiceReference[] refs = null;
-        try
-        {
-            refs =
-                m_context.getServiceReferences(PackageAdmin.class.getName(),
-                    null);
-        }
-        catch (InvalidSyntaxException e)
-        {
-        }
-        if (refs != null)
-        {
-            for (int i = 0; i < refs.length; i++)
-            {
-                PackageAdmin admin =
-                    (PackageAdmin) m_context.getService(refs[i]);
+                    try
+                    {
+                        if (m_classLoader.loadClass(target.getName()) == target)
+                        {
+                            return addToCache(permissionInfo.getEncoded(),
+                                createPermission(permissionInfo.getName(),
+                                    permissionInfo.getActions(), target));
+                        }
+                    }
+                    catch (ClassNotFoundException e1)
+                    {
+                    }
 
-                if (admin != null)
-                {
-                    Permission result = null;
-                    Bundle bundle = admin.getBundle(target);
-                    if (bundle != null)
+                    ServiceReference[] refs = null;
+                    try
+                    {
+                        refs = m_context.getServiceReferences(
+                            PackageAdmin.class.getName(), null);
+                    }
+                    catch (InvalidSyntaxException e)
                     {
-                        ExportedPackage[] exports =
-                            admin.getExportedPackages(bundle);
-                        if (exports != null)
+                    }
+                    if (refs != null)
+                    {
+                        for (int i = 0; i < refs.length; i++)
                         {
-                            String name = target.getName();
-                            name = name.substring(0, name.lastIndexOf('.'));
+                            PackageAdmin admin = (PackageAdmin) m_context
+                                .getService(refs[i]);
 
-                            for (int j = 0; j < exports.length; j++)
+                            if (admin != null)
                             {
-                                if (exports[j].getName().equals(name))
+                                Permission result = null;
+                                Bundle bundle = admin.getBundle(target);
+                                if (bundle != null)
                                 {
-                                    result =
-                                        createPermission(permissionInfo
-                                            .getName(), permissionInfo
-                                            .getActions(), target);
-                                    break;
+                                    ExportedPackage[] exports = admin
+                                        .getExportedPackages(bundle);
+                                    if (exports != null)
+                                    {
+                                        String name = target.getName();
+                                        name = name.substring(0, name
+                                            .lastIndexOf('.'));
+
+                                        for (int j = 0; j < exports.length; j++)
+                                        {
+                                            if (exports[j].getName().equals(
+                                                name))
+                                            {
+                                                result = createPermission(
+                                                    permissionInfo.getName(),
+                                                    permissionInfo.getActions(),
+                                                    target);
+                                                break;
+                                            }
+                                        }
+                                    }
                                 }
+
+                                m_context.ungetService(refs[i]);
+
+                                return addToCache(permissionInfo.getEncoded(),
+                                    result);
                             }
                         }
                     }
 
-                    m_context.ungetService(refs[i]);
-
-                    return addToCache(permissionInfo.getEncoded(), result);
+                    return null;
                 }
-            }
-        }
-
-        return null;
-        }});
+            });
     }
 
     private Permission createPermission(String name, String action, Class target)
     {
+        // System.out.println("\n\n|" + name + "|\n--\n|" + action + "|\n--\n" +
+        // target + "\n\n");
         try
         {
             return (Permission) m_action.getConstructor(target,
@@ -566,7 +630,7 @@
         }
         catch (Exception ex)
         {
-            ex.printStackTrace();
+            // TODO: log this or something
         }
 
         return null;

Modified: felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java?rev=897721&r1=897720&r2=897721&view=diff
==============================================================================
--- felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java (original)
+++ felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/PropertiesCache.java Sun Jan 10 22:11:27 2010
@@ -26,10 +26,10 @@
 import java.io.OutputStream;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
+import java.util.TreeMap;
 import java.util.Map.Entry;
 
 import org.apache.felix.framework.util.SecureAction;
@@ -66,11 +66,13 @@
 
                 Properties store = new Properties();
 
+                int count = 0;
+
                 for (Iterator iter = data.entrySet().iterator(); iter.hasNext();)
                 {
                     Entry entry = (Entry) iter.next();
-                    store.setProperty((String) entry.getKey(), getEncoded(entry
-                        .getValue()));
+                    store.setProperty(count++ + "-" + (String) entry.getKey(),
+                        getEncoded(entry.getValue()));
                 }
 
                 store.store(out, null);
@@ -126,15 +128,15 @@
         }
     }
 
-    public Map read(Class target) throws IOException
+    public void read(Class target, Map map) throws IOException
     {
         if (!m_file.isFile())
         {
-            return null;
+            return;
         }
         InputStream in = null;
         Exception other = null;
-        Map result = new HashMap();
+        Map result = new TreeMap();
         try
         {
             in = m_action.getFileInputStream(m_file);
@@ -171,7 +173,12 @@
                 }
             }
         }
-        return result;
+        for (Iterator iter = result.entrySet().iterator(); iter.hasNext();)
+        {
+            Entry entry = (Entry) iter.next();
+            String key = (String) entry.getKey();
+            map.put(key.substring(key.indexOf("-")), entry.getValue());
+        }
     }
 
     private String getEncoded(Object target) throws IOException
@@ -204,26 +211,25 @@
                 Properties props = new Properties();
                 props.load(new ByteArrayInputStream(encoded.getBytes()));
                 Class componentType = target.getComponentType();
-                Constructor constructor =
-                    m_action.getConstructor(componentType,
-                        new Class[] { String.class });
+                Constructor constructor = m_action.getConstructor(
+                    componentType, new Class[] { String.class });
                 Object[] params = new Object[1];
-                Object[] result =
-                    (Object[]) Array.newInstance(componentType, props.size());
+                Object[] result = (Object[]) Array.newInstance(componentType,
+                    props.size());
 
                 for (Iterator iter = props.entrySet().iterator(); iter
                     .hasNext();)
                 {
                     Entry entry = (Entry) iter.next();
                     params[0] = entry.getValue();
-                    result[Integer.parseInt((String) entry.getKey())] =
-                        constructor.newInstance(params);
+                    result[Integer.parseInt((String) entry.getKey())] = constructor
+                        .newInstance(params);
                 }
 
                 return result;
             }
 
-            return m_action.invoke(m_action.getConstructor(target, 
+            return m_action.invoke(m_action.getConstructor(target,
                 new Class[] { String.class }), new Object[] { encoded });
         }
         catch (Exception ex)

Modified: felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java?rev=897721&r1=897720&r2=897721&view=diff
==============================================================================
--- felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java (original)
+++ felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/util/TrustManager.java Sun Jan 10 22:11:27 2010
@@ -78,19 +78,17 @@
 
         if (m_crlList.trim().length() != 0)
         {
-            CertificateFactory fac =
-                CertificateFactory.getInstance("X509");
-            
+            CertificateFactory fac = CertificateFactory.getInstance("X509");
+
             for (StringTokenizer tok = new StringTokenizer(m_crlList, "|"); tok
                 .hasMoreElements();)
             {
                 InputStream input = null;
                 try
                 {
-                    input =
-                        m_action.getURLConnectionInputStream(m_action
-                            .createURL(null, tok.nextToken(), null)
-                            .openConnection());
+                    input = m_action.getURLConnectionInputStream(m_action
+                        .createURL(null, tok.nextToken(), null)
+                        .openConnection());
                     result.addAll(fac.generateCRLs(input));
                 }
                 catch (Exception ex)
@@ -137,20 +135,18 @@
                 InputStream input = null;
                 try
                 {
-                    input =
-                        m_action.getURLConnectionInputStream(m_action
-                            .createURL(null, storeTok.nextToken().trim(), null)
-                            .openConnection());
+                    input = m_action.getURLConnectionInputStream(m_action
+                        .createURL(null, storeTok.nextToken().trim(), null)
+                        .openConnection());
+                    String pass = passwdTok.nextToken().trim();
 
-                    ks.load(input, passwdTok.nextToken().trim().toCharArray());
+                    ks.load(input, (pass.length() > 0) ? pass.toCharArray()
+                        : null);
 
                     for (Enumeration e = ks.aliases(); e.hasMoreElements();)
                     {
                         String alias = (String) e.nextElement();
-                        if (ks.isCertificateEntry(alias))
-                        {
-                            result.add(ks.getCertificate(alias));
-                        }
+                        result.add(ks.getCertificate(alias));
                     }
                 }
                 catch (Exception ex)

Modified: felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java?rev=897721&r1=897720&r2=897721&view=diff
==============================================================================
--- felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java (original)
+++ felix/trunk/framework.security/src/main/java/org/apache/felix/framework/security/verifier/BundleDNParser.java Sun Jan 10 22:11:27 2010
@@ -30,13 +30,15 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.WeakHashMap;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
-import org.apache.felix.framework.cache.BundleRevision;
 import org.apache.felix.framework.security.util.BundleInputStream;
 import org.apache.felix.framework.security.util.TrustManager;
 import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.moduleloader.IModule;
+import org.osgi.framework.Bundle;
 
 public final class BundleDNParser
 {
@@ -51,15 +53,12 @@
         Method getCertificates = null;
         try
         {
-            getCodeSigners =
-                Class.forName("java.util.jar.JarEntry").getMethod(
-                    "getCodeSigners", null);
-            getSignerCertPath =
-                Class.forName("java.security.CodeSigner").getMethod(
-                    "getSignerCertPath", null);
-            getCertificates =
-                Class.forName("java.security.cert.CertPath").getMethod(
-                    "getCertificates", null);
+            getCodeSigners = Class.forName("java.util.jar.JarEntry").getMethod(
+                "getCodeSigners", null);
+            getSignerCertPath = Class.forName("java.security.CodeSigner")
+                .getMethod("getSignerCertPath", null);
+            getCertificates = Class.forName("java.security.cert.CertPath")
+                .getMethod("getCertificates", null);
         }
         catch (Exception ex)
         {
@@ -73,7 +72,9 @@
         m_getCertificates = getCertificates;
     }
 
-    private final Map m_cache = new HashMap();
+    private final Map m_cache = new WeakHashMap();
+    private final Map m_allCache = new WeakHashMap();
+
     private final TrustManager m_manager;
 
     public BundleDNParser(TrustManager manager)
@@ -89,7 +90,7 @@
         }
     }
 
-    public void put(String root, String[] dnChains)
+    public void put(String root, X509Certificate[] dnChains)
     {
         synchronized (m_cache)
         {
@@ -97,35 +98,65 @@
         }
     }
 
-    public void checkDNChains(String root, IContent content) throws Exception
+    public void checkDNChains(IModule root, IContent content, int signersType)
+        throws Exception
     {
-        synchronized (m_cache)
+        if (signersType == Bundle.SIGNERS_TRUSTED)
         {
-            if (m_cache.containsKey(root))
+            synchronized (m_cache)
             {
-                String[] result = (String[]) m_cache.get(root);
-                if ((result != null) && (result.length == 0))
+                if (m_cache.containsKey(root))
                 {
-                    throw new IOException("Bundle not properly signed");
+                    Map result = (Map) m_cache.get(root);
+                    if ((result != null) && (result.isEmpty()))
+                    {
+                        throw new IOException("Bundle not properly signed");
+                    }
+                    return;
+                }
+            }
+        }
+        else
+        {
+            synchronized (m_allCache)
+            {
+                if (m_allCache.containsKey(root))
+                {
+                    Map result = (Map) m_allCache.get(root);
+                    if ((result != null) && (result.isEmpty()))
+                    {
+                        throw new IOException("Bundle not properly signed");
+                    }
+                    return;
                 }
-                return;
             }
         }
 
-        String[] result = new String[0];
+        Map result = null;
         Exception org = null;
         try
         {
-            result = _getDNChains(root, content);
+            result = _getDNChains(content,
+                signersType == Bundle.SIGNERS_TRUSTED);
         }
         catch (Exception ex)
         {
             org = ex;
         }
 
-        synchronized (m_cache)
+        if (signersType == Bundle.SIGNERS_TRUSTED)
         {
-            m_cache.put(root, result);
+            synchronized (m_cache)
+            {
+                m_cache.put(root, result);
+            }
+        }
+        else
+        {
+            synchronized (m_allCache)
+            {
+                m_allCache.put(root, result);
+            }
         }
 
         if (org != null)
@@ -134,46 +165,70 @@
         }
     }
 
-    public String[] getDNChains(String root, IContent bundleRevision)
+    public Map getDNChains(IModule root, IContent bundleRevision,
+        int signersType)
     {
-        synchronized (m_cache)
+        if (signersType == Bundle.SIGNERS_TRUSTED)
+        {
+            synchronized (m_cache)
+            {
+                if (m_cache.containsKey(root))
+                {
+                    Map result = (Map) m_cache.get(root);
+                    return (result == null) ? new HashMap() : new HashMap(
+                        result);
+                }
+            }
+        }
+        else
         {
-            if (m_cache.containsKey(root))
+            synchronized (m_allCache)
             {
-                String[] result = (String[]) m_cache.get(root);
-                if ((result != null) && (result.length == 0))
+                if (m_allCache.containsKey(root))
                 {
-                    return null;
+                    Map result = (Map) m_allCache.get(root);
+                    return (result == null) ? new HashMap() : new HashMap(
+                        result);
                 }
-                return result;
             }
         }
 
-        String[] result = new String[0];
-        
+        Map result = null;
+
         try
         {
-            result = _getDNChains(root, bundleRevision);
+            result = _getDNChains(bundleRevision,
+                signersType == Bundle.SIGNERS_TRUSTED);
         }
         catch (Exception ex)
         {
             // Ignore
         }
 
-        synchronized (m_cache)
+        if (signersType == Bundle.SIGNERS_TRUSTED)
         {
-            m_cache.put(root, result);
+            synchronized (m_cache)
+            {
+                m_cache.put(root, result);
+            }
+        }
+        else
+        {
+            synchronized (m_allCache)
+            {
+                m_allCache.put(root, result);
+            }
         }
 
-        return result;
-    } 
+        return (result == null) ? new HashMap() : new HashMap(result);
+    }
 
-    private String[] _getDNChains(String root, IContent content)
+    private Map _getDNChains(IContent content, boolean check)
         throws IOException
     {
         X509Certificate[] certificates = null;
 
-        certificates = getCertificates(new BundleInputStream(content));
+        certificates = getCertificates(new BundleInputStream(content), check);
 
         if (certificates == null)
         {
@@ -182,11 +237,9 @@
 
         List rootChains = new ArrayList();
 
-        getRootChains(certificates, rootChains);
+        getRootChains(certificates, rootChains, check);
 
-        List result = new ArrayList();
-
-        SubjectDNParser parser = new SubjectDNParser();
+        Map result = new HashMap();
 
         for (Iterator rootIter = rootChains.iterator(); rootIter.hasNext();)
         {
@@ -198,42 +251,18 @@
 
             X509Certificate current = (X509Certificate) iter.next();
 
-            try
-            {
-                buffer.append(parser
-                    .parseSubjectDN(current.getTBSCertificate()));
-
-                while (iter.hasNext())
-                {
-                    buffer.append(';');
-
-                    current = (X509Certificate) iter.next();
-
-                    buffer.append(parser.parseSubjectDN(current
-                        .getTBSCertificate()));
-                }
-
-                result.add(buffer.toString());
-
-            }
-            catch (Exception ex)
-            {
-                // something went wrong during parsing -
-                // it might be that the cert contained an unsupported OID
-                // TODO: log this or something
-                ex.printStackTrace();
-            }
+            result.put(current, chain);
         }
 
         if (!result.isEmpty())
         {
-            return (String[]) result.toArray(new String[result.size()]);
+            return result;
         }
 
         throw new IOException();
     }
 
-    private X509Certificate[] getCertificates(InputStream input)
+    private X509Certificate[] getCertificates(InputStream input, boolean check)
         throws IOException
     {
         JarInputStream bundle = new JarInputStream(input, true);
@@ -250,9 +279,9 @@
         // This is tricky: jdk1.3 doesn't say anything about what is happening
         // if a bad sig is detected on an entry - later jdk's do say that they
         // will throw a security Exception. The below should cater for both
-        // behaviors. 
-        for (JarEntry entry = bundle.getNextJarEntry(); entry != null; entry =
-            bundle.getNextJarEntry())
+        // behaviors.
+        for (JarEntry entry = bundle.getNextJarEntry(); entry != null; entry = bundle
+            .getNextJarEntry())
         {
 
             if (entry.isDirectory() || entry.getName().startsWith("META-INF"))
@@ -277,8 +306,8 @@
             {
                 try
                 {
-                    Object[] signers =
-                        (Object[]) m_getCodeSigners.invoke(entry, null);
+                    Object[] signers = (Object[]) m_getCodeSigners.invoke(
+                        entry, null);
 
                     if (signers != null)
                     {
@@ -286,16 +315,15 @@
 
                         for (int i = 0; i < signers.length; i++)
                         {
-                            Object path =
-                                m_getSignerCertPath.invoke(signers[i], null);
+                            Object path = m_getSignerCertPath.invoke(
+                                signers[i], null);
 
                             certChains.addAll((List) m_getCertificates.invoke(
                                 path, null));
                         }
 
-                        certificates =
-                            (Certificate[]) certChains
-                                .toArray(new Certificate[certChains.size()]);
+                        certificates = (Certificate[]) certChains
+                            .toArray(new Certificate[certChains.size()]);
                     }
                 }
                 catch (Exception ex)
@@ -312,7 +340,7 @@
 
             List chains = new ArrayList();
 
-            getRootChains(certificates, chains);
+            getRootChains(certificates, chains, check);
 
             if (certificateChains.isEmpty())
             {
@@ -324,13 +352,13 @@
                 for (Iterator iter2 = certificateChains.iterator(); iter2
                     .hasNext();)
                 {
-                    X509Certificate cert =
-                        (X509Certificate) ((List) iter2.next()).get(0);
+                    X509Certificate cert = (X509Certificate) ((List) iter2
+                        .next()).get(0);
                     boolean found = false;
                     for (Iterator iter3 = chains.iterator(); iter3.hasNext();)
                     {
-                        X509Certificate cert2 =
-                            (X509Certificate) ((List) iter3.next()).get(0);
+                        X509Certificate cert2 = (X509Certificate) ((List) iter3
+                            .next()).get(0);
 
                         if (cert.getSubjectDN().equals(cert2.getSubjectDN())
                             && cert.equals(cert2))
@@ -380,7 +408,8 @@
         return false;
     }
 
-    private void getRootChains(Certificate[] certificates, List chains)
+    private void getRootChains(Certificate[] certificates, List chains,
+        boolean check)
     {
         List chain = new ArrayList();
 
@@ -394,11 +423,14 @@
             {
                 revoked = true;
             }
-            else if (!revoked)
+            if (!check || !revoked)
             {
                 try
                 {
-                    certificate.checkValidity();
+                    if (check)
+                    {
+                        certificate.checkValidity();
+                    }
 
                     chain.add(certificate);
                 }
@@ -412,7 +444,7 @@
             if (!((X509Certificate) certificates[i + 1]).getSubjectDN().equals(
                 certificate.getIssuerDN()))
             {
-                if (!revoked && trusted(certificate))
+                if (!check || (!revoked && trusted(certificate)))
                 {
                     chains.add(chain);
                 }
@@ -427,10 +459,11 @@
         }
         // The final entry in the certs array is always
         // a "root" certificate
-        if (!revoked)
+        if (!check || !revoked)
         {
             chain.add(certificates[certificates.length - 1]);
-            if (trusted((X509Certificate) certificates[certificates.length - 1]))
+            if (!check
+                || trusted((X509Certificate) certificates[certificates.length - 1]))
             {
                 chains.add(chain);
             }