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 2008/03/07 01:37:47 UTC
svn commit: r634480 [3/3] - in /felix/trunk/framework/security: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/felix/ src/main/java/org/apache/felix/framework/
src/main/java/org/apache/felix/frame...
Added: felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java?rev=634480&view=auto
==============================================================================
--- felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java (added)
+++ felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java Thu Mar 6 16:37:30 2008
@@ -0,0 +1,133 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleLocationCondition.java,v 1.18 2006/06/16 16:31:37 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Hashtable;
+
+import org.apache.felix.framework.FilterImpl;
+import org.osgi.framework.*;
+
+/**
+ * Condition to test if the location of a bundle matches a pattern. Pattern
+ * matching is done according to the filter string matching rules.
+ *
+ * @version $Revision: 1.18 $
+ */
+public class BundleLocationCondition
+{
+ private static final String CONDITION_TYPE =
+ "org.osgi.service.condpermadmin.BundleLocationCondition";
+
+ /**
+ * Constructs a condition that tries to match the passed Bundle's location
+ * to the location pattern.
+ *
+ * @param bundle
+ * The Bundle being evaluated.
+ * @param info
+ * The ConditionInfo to construct the condition for. The args
+ * of the ConditionInfo must be a single String which
+ * specifies the location pattern to match against the Bundle
+ * location. Matching is done according to the filter string
+ * matching rules. Any '*' characters in the location
+ * argument are used as wildcards when matching bundle
+ * locations unless they are escaped with a '\' character.
+ * @return Condition object for the requested condition.
+ */
+ static public Condition getCondition(final Bundle bundle, ConditionInfo info)
+ {
+ if (!CONDITION_TYPE.equals(info.getType()))
+ throw new IllegalArgumentException(
+ "ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+ String[] args = info.getArgs();
+ if (args.length != 1)
+ throw new IllegalArgumentException("Illegal number of args: "
+ + args.length);
+ String bundleLocation =
+ (String) AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return bundle.getLocation();
+ }
+ });
+ Filter filter = null;
+ try
+ {
+ filter =
+ new FilterImpl("(location=" + escapeLocation(args[0]) + ")");
+ }
+ catch (InvalidSyntaxException e)
+ {
+ // this should never happen, but just incase
+ throw new RuntimeException("Invalid filter: " + e.getFilter());
+ }
+ Hashtable matchProps = new Hashtable(2);
+ matchProps.put("location", bundleLocation);
+ return filter.match(matchProps) ? Condition.TRUE : Condition.FALSE;
+ }
+
+ private BundleLocationCondition()
+ {
+ // private constructor to prevent objects of this type
+ }
+
+ /**
+ * Escape the value string such that '(', ')' and '\' are escaped. The '\'
+ * char is only escaped if it is not followed by a '*'.
+ *
+ * @param value
+ * unescaped value string.
+ * @return escaped value string.
+ */
+ private static String escapeLocation(String value)
+ {
+ boolean escaped = false;
+ int inlen = value.length();
+ int outlen = inlen << 1; /* inlen * 2 */
+
+ char[] output = new char[outlen];
+ value.getChars(0, inlen, output, inlen);
+
+ int cursor = 0;
+ for (int i = inlen; i < outlen; i++)
+ {
+ char c = output[i];
+ switch (c)
+ {
+ case '\\':
+ if (i + 1 < outlen && output[i + 1] == '*')
+ break;
+ case '(':
+ case ')':
+ output[cursor] = '\\';
+ cursor++;
+ escaped = true;
+ break;
+ }
+
+ output[cursor] = c;
+ cursor++;
+ }
+
+ return escaped ? new String(output, 0, cursor) : value;
+ }
+}
Added: felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java?rev=634480&view=auto
==============================================================================
--- felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java (added)
+++ felix/trunk/framework/security/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java Thu Mar 6 16:37:30 2008
@@ -0,0 +1,229 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleSignerCondition.java,v 1.10 2006/06/16 16:31:37 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.framework.FilterImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Condition to test if the signer of a bundle matches a pattern. Since the
+ * bundle's signer can only change when the bundle is updated, this condition is
+ * immutable.
+ * <p>
+ * The condition expressed using a single String that specifies a Distinguished
+ * Name (DN) chain to match bundle signers against. DN's are encoded using IETF
+ * RFC 2253. Usually signers use certificates that are issued by certificate
+ * authorities, which also have a corresponding DN and certificate. The
+ * certificate authorities can form a chain of trust where the last DN and
+ * certificate is known by the framework. The signer of a bundle is expressed as
+ * signers DN followed by the DN of its issuer followed by the DN of the next
+ * issuer until the DN of the root certificate authority. Each DN is separated
+ * by a semicolon.
+ * <p>
+ * A bundle can satisfy this condition if one of its signers has a DN chain that
+ * matches the DN chain used to construct this condition. Wildcards (`*') can be
+ * used to allow greater flexibility in specifying the DN chains. Wildcards can
+ * be used in place of DNs, RDNs, or the value in an RDN. If a wildcard is used
+ * for a value of an RDN, the value must be exactly "*" and will match any value
+ * for the corresponding type in that RDN. If a wildcard is used for a RDN, it
+ * must be the first RDN and will match any number of RDNs (including zero
+ * RDNs).
+ *
+ * @version $Revision: 1.10 $
+ */
+/*
+ * TODO: In our case the above is not correct. We don't make this an immutable
+ * condition because the spec is somewhat ambiguous in regard to when the
+ * signature change. This probably has to be clarified and then revisited later.
+ */
+public class BundleSignerCondition
+{
+ /*
+ * NOTE: A framework implementor may also choose to replace this class in
+ * their distribution with a class that directly interfaces with the
+ * framework implementation. This replacement class MUST NOT alter the
+ * public/protected signature of this class.
+ */
+
+ private static final String CONDITION_TYPE =
+ "org.osgi.service.condpermadmin.BundleSignerCondition";
+
+ /**
+ * Constructs a Condition that tries to match the passed Bundle's location
+ * to the location pattern.
+ *
+ * @param bundle
+ * The Bundle being evaluated.
+ * @param info
+ * The ConditionInfo to construct the condition for. The args
+ * of the ConditionInfo specify a single String specifying
+ * the chain of distinguished names pattern to match against
+ * the signer of the Bundle.
+ * @return A Condition which checks the signers of the specified bundle.
+ */
+ static public Condition getCondition(Bundle bundle, ConditionInfo info)
+ {
+ if (!CONDITION_TYPE.equals(info.getType()))
+ throw new IllegalArgumentException(
+ "ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+ final String[] args = info.getArgs();
+ if (args.length != 1)
+ throw new IllegalArgumentException("Illegal number of args: "
+ + args.length);
+
+ return new ConditionImpl(bundle, "(signer=" + escapeFilter(args[0])
+ + ")");
+
+ }
+
+ private static String escapeFilter(String string)
+ {
+ boolean escaped = false;
+ int inlen = string.length();
+ int outlen = inlen << 1; /* inlen * 2 */
+
+ char[] output = new char[outlen];
+ string.getChars(0, inlen, output, inlen);
+
+ int cursor = 0;
+ for (int i = inlen; i < outlen; i++)
+ {
+ char c = output[i];
+ switch (c)
+ {
+ case '\\':
+ case '(':
+ case ')':
+ case '*':
+ output[cursor] = '\\';
+ cursor++;
+ escaped = true;
+ break;
+ }
+
+ output[cursor] = c;
+ cursor++;
+ }
+
+ return escaped ? new String(output, 0, cursor) : string;
+ }
+
+ private BundleSignerCondition()
+ {
+ // private constructor to prevent objects of this type
+ }
+}
+
+final class ConditionImpl implements Condition, PrivilegedExceptionAction
+{
+ private static final Method m_getSignerMatcher;
+
+ static
+ {
+ m_getSignerMatcher =
+ (Method) AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ Method getSignerMatcher = null;
+ try
+ {
+ getSignerMatcher =
+ Class.forName(
+ "org.apache.felix.framework.BundleImpl")
+ .getDeclaredMethod("getSignerMatcher", null);
+ getSignerMatcher.setAccessible(true);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ getSignerMatcher = null;
+ }
+ return getSignerMatcher;
+ }
+ });
+ }
+
+ private final Bundle m_bundle;
+ private final Filter m_filter;
+ private final Dictionary m_dict;
+
+ ConditionImpl(Bundle bundle, String filter)
+ {
+ m_bundle = bundle;
+ try
+ {
+ m_filter = new FilterImpl(filter);
+ }
+ catch (InvalidSyntaxException e)
+ {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ try
+ {
+ Object signerMatcher = AccessController.doPrivileged(this);
+ m_dict = new Hashtable();
+ m_dict.put("signer", signerMatcher);
+ }
+ catch (PrivilegedActionException e)
+ {
+ if (e.getException() instanceof RuntimeException)
+ {
+ throw (RuntimeException) e.getException();
+ }
+
+ throw new RuntimeException(e.getException().getMessage());
+ }
+ }
+
+ public boolean isMutable()
+ {
+ return true;
+ }
+
+ public boolean isPostponed()
+ {
+ return false;
+ }
+
+ public Object run() throws Exception
+ {
+ return m_getSignerMatcher.invoke(m_bundle, null);
+ }
+
+ public boolean isSatisfied()
+ {
+ return m_filter.match(m_dict);
+ }
+
+ public boolean isSatisfied(Condition[] conditions, Dictionary context)
+ {
+ return false;
+ }
+}
\ No newline at end of file