You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2012/04/02 21:36:22 UTC

svn commit: r1308500 - in /bval/branches/privileged: bval-core/src/main/java/org/apache/bval/ bval-core/src/main/java/org/apache/bval/util/ bval-xstream/src/main/java/org/apache/bval/xml/

Author: mbenson
Date: Mon Apr  2 19:36:22 2012
New Revision: 1308500

URL: http://svn.apache.org/viewvc?rev=1308500&view=rev
Log:
refactor privileged work to satisfy security AND convenience, at the cost of requiring users to grant a custom permission; some occasional refactorings I was too lazy to separate :o

Added:
    bval/branches/privileged/bval-core/src/main/java/org/apache/bval/BValPermission.java   (with props)
    bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/Privileged.java   (with props)
Removed:
    bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/PrivilegedActions.java
Modified:
    bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/BValVersion.java
    bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/FieldAccess.java
    bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/MethodAccess.java
    bval/branches/privileged/bval-xstream/src/main/java/org/apache/bval/xml/XMLMetaBeanManager.java

Added: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/BValPermission.java
URL: http://svn.apache.org/viewvc/bval/branches/privileged/bval-core/src/main/java/org/apache/bval/BValPermission.java?rev=1308500&view=auto
==============================================================================
--- bval/branches/privileged/bval-core/src/main/java/org/apache/bval/BValPermission.java (added)
+++ bval/branches/privileged/bval-core/src/main/java/org/apache/bval/BValPermission.java Mon Apr  2 19:36:22 2012
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.bval;
+
+import java.security.BasicPermission;
+
+/**
+ * BVal permissions.
+ */
+public class BValPermission extends BasicPermission {
+    /** Serialization version */
+    private static final long serialVersionUID = -4969913657757082112L;
+
+    /**
+     * Enumeration of permission names.
+     */
+    public enum Name {
+        /**
+         * Allows the creation of a {@link Privileged} instance.
+         */
+        doPrivileged;
+    }
+
+    /**
+     * Create a new {@link BValPermission} instance.
+     * @param name
+     */
+    public BValPermission(String name) {
+        super(name);
+    }
+
+    /**
+     * Create a new {@link BValPermission} instance.
+     * @param name
+     * @param actions
+     */
+    public BValPermission(String name, String actions) {
+        super(name, actions);
+    }
+
+    /**
+     * Create a new {@link BValPermission} instance.
+     * @param name
+     */
+    public BValPermission(Name name) {
+        super(name.name());
+    }
+
+}

Propchange: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/BValPermission.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/BValVersion.java
URL: http://svn.apache.org/viewvc/bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/BValVersion.java?rev=1308500&r1=1308499&r2=1308500&view=diff
==============================================================================
--- bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/BValVersion.java (original)
+++ bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/BValVersion.java Mon Apr  2 19:36:22 2012
@@ -18,14 +18,15 @@
  */
 package org.apache.bval.util;
 
+import org.apache.bval.util.Privileged;
+
 import java.io.InputStream;
 import java.io.IOException;
 import java.util.Properties;
 import java.util.StringTokenizer;
 
 /**
- * This class contains version information for BVal.
- * It uses Ant's filter tokens to convert the template into a java
+ * This class contains version information for BVal. It uses Ant's filter tokens to convert the template into a java
  * file with current information.
  */
 public class BValVersion {
@@ -47,11 +48,12 @@ public class BValVersion {
     /** Version control revision number */
     public static final String REVISION_NUMBER;
 
+    private static final Privileged PRIVILEGED = new Privileged();
+
     static {
         Properties revisionProps = new Properties();
         try {
-            InputStream in = BValVersion.class.getResourceAsStream
-                ("/META-INF/org.apache.bval.revision.properties");
+            InputStream in = BValVersion.class.getResourceAsStream("/META-INF/org.apache.bval.revision.properties");
             if (in != null) {
                 try {
                     revisionProps.load(in);
@@ -113,6 +115,7 @@ public class BValVersion {
 
     /**
      * Get the project version number.
+     * 
      * @return String
      */
     public static String getVersion() {
@@ -121,6 +124,7 @@ public class BValVersion {
 
     /**
      * Get the version control revision number.
+     * 
      * @return String
      */
     public static String getRevision() {
@@ -129,6 +133,7 @@ public class BValVersion {
 
     /**
      * Get the project name.
+     * 
      * @return String
      */
     public static String getName() {
@@ -137,6 +142,7 @@ public class BValVersion {
 
     /**
      * Get the fully-qualified project id.
+     * 
      * @return String
      */
     public static String getID() {
@@ -145,9 +151,11 @@ public class BValVersion {
 
     /**
      * Main method of this class that prints the {@link #toString()} to <code>System.out</code>.
-     * @param args ignored
+     * 
+     * @param args
+     *            ignored
      */
-    public static void main(String [] args) {
+    public static void main(String[] args) {
         System.out.println(new BValVersion().toString());
     }
 
@@ -167,8 +175,8 @@ public class BValVersion {
         appendProperty("java.vendor", buf).append("\n\n");
 
         buf.append("java.class.path:\n");
-        StringTokenizer tok = new StringTokenizer(
-            PrivilegedActions.getProperty("java.class.path"));
+        final String cp = PRIVILEGED.getProperty("java.class.path");
+        StringTokenizer tok = new StringTokenizer(cp);
         while (tok.hasMoreTokens()) {
             buf.append("\t").append(tok.nextToken());
             buf.append("\n");
@@ -189,7 +197,6 @@ public class BValVersion {
     }
 
     private StringBuilder appendProperty(String prop, StringBuilder buf) {
-        return buf.append(prop).append(": ").append(
-            PrivilegedActions.getProperty(prop));
+        return buf.append(prop).append(": ").append(PRIVILEGED.getProperty(prop));
     }
 }

Modified: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/FieldAccess.java
URL: http://svn.apache.org/viewvc/bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/FieldAccess.java?rev=1308500&r1=1308499&r2=1308500&view=diff
==============================================================================
--- bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/FieldAccess.java (original)
+++ bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/FieldAccess.java Mon Apr  2 19:36:22 2012
@@ -25,17 +25,19 @@ import java.security.PrivilegedAction;
  * Description: direct field access strategy.<br/>
  */
 public class FieldAccess extends AccessStrategy {
+    private static final Privileged PRIVILEGED = new Privileged();
 
     private final Field field;
 
     /**
      * Create a new FieldAccess instance.
+     * 
      * @param field
      */
     public FieldAccess(final Field field) {
         this.field = field;
-        if(!field.isAccessible()) {
-            PrivilegedActions.run( new PrivilegedAction<Object>() {
+        if (!field.isAccessible()) {
+            PRIVILEGED.run(new PrivilegedAction<Object>() {
                 public Object run() {
                     field.setAccessible(true);
                     return (Object) null;
@@ -87,8 +89,10 @@ public class FieldAccess extends AccessS
      * {@inheritDoc}
      */
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
 
         FieldAccess that = (FieldAccess) o;
 

Modified: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/MethodAccess.java
URL: http://svn.apache.org/viewvc/bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/MethodAccess.java?rev=1308500&r1=1308499&r2=1308500&view=diff
==============================================================================
--- bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/MethodAccess.java (original)
+++ bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/MethodAccess.java Mon Apr  2 19:36:22 2012
@@ -27,11 +27,14 @@ import java.security.PrivilegedAction;
  * Description: invoke a zero-argument method (getter)<br/>
  */
 public class MethodAccess extends AccessStrategy {
+    private static final Privileged PRIVILEGED = new Privileged();
+
     private final Method method;
     private final String propertyName;
 
     /**
      * Create a new MethodAccess instance.
+     * 
      * @param method
      */
     public MethodAccess(Method method) {
@@ -40,6 +43,7 @@ public class MethodAccess extends Access
 
     /**
      * Create a new MethodAccess instance.
+     * 
      * @param propertyName
      * @param method
      */
@@ -47,10 +51,10 @@ public class MethodAccess extends Access
         this.method = method;
         this.propertyName = propertyName;
         if (!method.isAccessible()) {
-            PrivilegedActions.run( new PrivilegedAction<Object>() {
-                public Object run() {
+            PRIVILEGED.run(new PrivilegedAction<Void>() {
+                public Void run() {
                     method.setAccessible(true);
-                    return (Object) null;
+                    return null;
                 }
             });
         }
@@ -58,23 +62,25 @@ public class MethodAccess extends Access
 
     /**
      * Process bean properties getter by applying the JavaBean naming conventions.
-     *
-     * @param member the member for which to get the property name.
-     * @return The bean method name with the "is" or "get" prefix stripped off, <code>null</code>
-     *         the method name id not according to the JavaBeans standard.
+     * 
+     * @param member
+     *            the member for which to get the property name.
+     * @return The bean method name with the "is" or "get" prefix stripped off, <code>null</code> the method name id not
+     *         according to the JavaBeans standard.
      */
     public static String getPropertyName(Method member) {
         String name = null;
         String methodName = member.getName();
         if (methodName.startsWith("is")) {
             name = Introspector.decapitalize(methodName.substring(2));
-        } /* else if ( methodName.startsWith("has")) {
-				name = Introspector.decapitalize( methodName.substring( 3 ) );
-			} */
+        } /*
+           * else if ( methodName.startsWith("has")) { name = Introspector.decapitalize( methodName.substring( 3 ) ); }
+           */
         // setter annotation is NOT supported in the spec
-        /*  else if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) {
-           propName = Introspector.decapitalize(method.getName().substring(3));
-       } */
+        /*
+         * else if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { propName =
+         * Introspector.decapitalize(method.getName().substring(3)); }
+         */
         else if (methodName.startsWith("get")) {
             name = Introspector.decapitalize(methodName.substring(3));
         }
@@ -82,8 +88,7 @@ public class MethodAccess extends Access
     }
 
     /**
-     * {@inheritDoc}
-     * normally the propertyName of the getter method, e.g.<br>
+     * {@inheritDoc} normally the propertyName of the getter method, e.g.<br>
      * method: getName() -> propertyName: name<br>
      * method: isValid() -> propertyName: valid<br>
      */
@@ -129,8 +134,10 @@ public class MethodAccess extends Access
      * {@inheritDoc}
      */
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
 
         MethodAccess that = (MethodAccess) o;
 

Added: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/Privileged.java
URL: http://svn.apache.org/viewvc/bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/Privileged.java?rev=1308500&view=auto
==============================================================================
--- bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/Privileged.java (added)
+++ bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/Privileged.java Mon Apr  2 19:36:22 2012
@@ -0,0 +1,183 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.bval.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.bval.BValPermission;
+import org.apache.commons.lang3.ClassUtils;
+
+/**
+ * Utility object for privileged work.
+ */
+public class Privileged {
+    {
+        if (System.getSecurityManager() != null) {
+            AccessController.checkPermission(new BValPermission(BValPermission.Name.doPrivileged));
+        }
+    }
+
+    /**
+     * Construct a new {@link Privileged} instance. Requires {@link BValPermission}
+     * {@link BValPermission.Name#doPrivileged}.
+     */
+    public Privileged() {
+    }
+
+    /**
+     * Perform action with AccessController.doPrivileged() if security enabled.
+     * 
+     * @param action
+     *            - the action to run
+     * @return result of running the action
+     */
+    public final <T> T run(PrivilegedAction<T> action) {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(action);
+        }
+        return action.run();
+    }
+
+    /**
+     * Perform action with AccessController.doPrivileged() if security enabled. Unwraps
+     * {@link PrivilegedActionException}s.
+     * 
+     * @param action
+     *            - the action to run
+     * @return result of running the action
+     */
+    public final <T> T run(final PrivilegedExceptionAction<T> action) throws Exception {
+        if (System.getSecurityManager() != null) {
+            try {
+                return AccessController.doPrivileged(action);
+            } catch (PrivilegedActionException e) {
+                throw e.getException();
+            }
+        }
+        return action.run();
+    }
+
+    /**
+     * Get the context classloader of the current thread.
+     * 
+     * @see Thread#getContextClassLoader()
+     */
+    public ClassLoader getContextClassLoader() {
+        return run(new PrivilegedAction<ClassLoader>() {
+
+            public ClassLoader run() {
+                return Thread.currentThread().getContextClassLoader();
+            }
+        });
+    }
+
+    /**
+     * Get a Class by name.
+     * 
+     * @param classLoader
+     * @param className
+     * @return Class
+     * @exception ClassNotFoundException
+     */
+    public Class<?> getClass(final ClassLoader classLoader, final String className) throws ClassNotFoundException {
+        try {
+            return run(new PrivilegedExceptionAction<Class<?>>() {
+                public Class<?> run() throws ClassNotFoundException {
+                    return ClassUtils.getClass(classLoader, className, true);
+                }
+            });
+        } catch (Exception e) {
+            throw (ClassNotFoundException) e;
+        }
+    }
+
+    /**
+     * Use the privilege APIs to read an annotation value.
+     * 
+     * Requires security policy 'permission java.lang.RuntimePermission "accessDeclaredMembers";' 'permission
+     * java.lang.reflect.ReflectPermission "suppressAccessChecks";'
+     * 
+     * @return Object
+     * @exception IllegalAccessException
+     *                , InvocationTargetException
+     */
+    public Object getAnnotationValue(final Annotation annotation, final String name) {
+        return run(new PrivilegedAction<Object>() {
+            public Object run() {
+                Method valueMethod;
+                try {
+                    valueMethod = annotation.annotationType().getDeclaredMethod(name);
+                } catch (NoSuchMethodException ex) {
+                    // do nothing
+                    valueMethod = null;
+                }
+                if (null != valueMethod) {
+                    try {
+                        valueMethod.setAccessible(true);
+                        return valueMethod.invoke(annotation);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Returns the most appropriate {@link ClassLoader} for most situations.
+     * This is defined for the purposes of BVal as the context {@link ClassLoader},
+     * if available; otherwise the loader of {@code clazz} is returned.
+     * 
+     * Requires security policy: 'permission java.lang.RuntimePermission "getClassLoader";'
+     * 
+     * @return Classloader
+     */
+    public ClassLoader getClassLoader(final Class<?> clazz) {
+        return run(new PrivilegedAction<ClassLoader>() {
+            public ClassLoader run() {
+                ClassLoader cl = Thread.currentThread().getContextClassLoader();
+                if (cl == null) {
+                    cl = clazz.getClassLoader();
+                }
+                return cl;
+            }
+        });
+    }
+
+    /**
+     * Get a system property.
+     * 
+     * Requires security policy: 'permission java.util.PropertyPermission "read";'
+     * 
+     * @see System#getProperty(String)
+     * @return String
+     */
+    public String getProperty(final String name) {
+        return run(new PrivilegedAction<String>() {
+            public String run() {
+                return System.getProperty(name);
+            }
+        });
+    }
+
+}

Propchange: bval/branches/privileged/bval-core/src/main/java/org/apache/bval/util/Privileged.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bval/branches/privileged/bval-xstream/src/main/java/org/apache/bval/xml/XMLMetaBeanManager.java
URL: http://svn.apache.org/viewvc/bval/branches/privileged/bval-xstream/src/main/java/org/apache/bval/xml/XMLMetaBeanManager.java?rev=1308500&r1=1308499&r2=1308500&view=diff
==============================================================================
--- bval/branches/privileged/bval-xstream/src/main/java/org/apache/bval/xml/XMLMetaBeanManager.java (original)
+++ bval/branches/privileged/bval-xstream/src/main/java/org/apache/bval/xml/XMLMetaBeanManager.java Mon Apr  2 19:36:22 2012
@@ -19,7 +19,7 @@ package org.apache.bval.xml;
 import org.apache.bval.MetaBeanManager;
 import org.apache.bval.model.MetaBean;
 import org.apache.bval.model.MetaProperty;
-import org.apache.bval.util.PrivilegedActions;
+import org.apache.bval.util.Privileged;
 
 import java.util.Map;
 
@@ -36,6 +36,8 @@ import static org.apache.bval.model.Feat
  * Time: 09:47:14<br>
  */
 public class XMLMetaBeanManager extends MetaBeanManager implements XMLMetaBeanRegistry, MetaBeanEnricher {
+    private static final Privileged PRIVILEGED = new Privileged();
+
     public XMLMetaBeanManager() {
         this(new XMLMetaBeanBuilder());
     }
@@ -45,7 +47,7 @@ public class XMLMetaBeanManager extends 
     }
 
     public void addResourceLoader(String resource) {
-        addLoader(new XMLMetaBeanURLLoader(PrivilegedActions.getClassLoader(getClass()).getResource(resource)));
+        addLoader(new XMLMetaBeanURLLoader(PRIVILEGED.getClassLoader(getClass()).getResource(resource)));
     }
 
     public synchronized void addLoader(XMLMetaBeanLoader loader) {
@@ -128,4 +130,5 @@ public class XMLMetaBeanManager extends 
             super.computeRelatedMetaBean(prop, beanRef);
         }
     }
+
 }