8050402: Tests to check for use of policy files
authoramjiang
Sat, 26 Sep 2015 12:08:55 +0300
changeset 32775 cab3b72f31b7
parent 32774 6a38398a04f7
child 32776 a0ed816fbf97
8050402: Tests to check for use of policy files Reviewed-by: mullan
jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java
jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy
jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy
jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy
jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java
jdk/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java	Sat Sep 26 12:08:55 2015 +0300
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import TVJar.TVPermission;
+import java.security.AccessController;
+
+/**
+ * @test @bug 8050402
+ * @summary Check policy is extensible with user defined permissions
+ * @run main/othervm/policy=ExtensiblePolicyTest1.policy
+ *      ExtensiblePolicyTest false
+ * @run main/othervm/policy=ExtensiblePolicyTest2.policy
+ *      ExtensiblePolicyTest true
+ * @run main/othervm/policy=ExtensiblePolicyTest3.policy
+ *      ExtensiblePolicyTest true
+ */
+public class ExtensiblePolicyTest {
+
+    public static void main(String args[]) throws Throwable {
+        // ExtensiblePolicyTest1.policy: policy file grants permission to
+        // watch TVChannel 3-6
+        // ExtensiblePolicyTest2.policy: policy file grants permission to
+        // watch TVChanel 4
+        // ExtensiblePolicyTest3.policy: policy file grants permission signed
+        // by duke2 to watch TVChanel 5
+
+        TVPermission perm = new TVPermission("channel:5", "watch");
+        boolean getException = false;
+        String exceptionMessage = null;
+        boolean expectException = Boolean.parseBoolean(args[0]);
+        try {
+            AccessController.checkPermission(perm);
+        } catch (SecurityException se) {
+            getException = true;
+            exceptionMessage = se.getMessage();
+        }
+
+        if (expectException ^ getException) {
+            throw new RuntimeException("Test Failed: expectException = "
+                    + expectException + " getException = " + getException
+                    + "\n" + exceptionMessage);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy	Sat Sep 26 12:08:55 2015 +0300
@@ -0,0 +1,4 @@
+grant {
+	permission TVJar.TVPermission "channel:3-6", "watch";
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy	Sat Sep 26 12:08:55 2015 +0300
@@ -0,0 +1,3 @@
+grant {
+	permission TVJar.TVPermission "channel:4", "watch";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy	Sat Sep 26 12:08:55 2015 +0300
@@ -0,0 +1,5 @@
+keystore "file:${user.dir}/epkeystore";
+
+grant {
+	permission TVJar.TVPermission "channel:5", "watch", SignedBy "duke2";
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java	Sat Sep 26 12:08:55 2015 +0300
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import TVJar.TVPermission;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8050402
+ * @summary Check policy is extensible with user defined permissions
+ * @library /lib/testlibrary
+ * @compile TVJar/TVPermission.java
+ * @run main ExtensiblePolicyWithJarTest
+ */
+public class ExtensiblePolicyWithJarTest {
+
+    public static void main(String args[]) throws Throwable {
+        final String FS = File.separator;
+        final String PS = File.pathSeparator;
+        final String POL = "ExtensiblePolicyTest3.policy";
+        final String JAVA_HOME = System.getProperty("test.jdk");
+        final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
+        final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
+        final String KEYSTORE = "epkeystore";
+        final String PASSWORD = "password";
+        final String ALIAS = "duke2";
+        final String CLASSPATH = System.getProperty("test.class.path", "");
+        final String TESTCLASSES = System.getProperty("test.classes", "");
+        final String TVPERMJAR = "tvPerm.jar";
+        final String PATHTOJAR = System.getProperty("user.dir", "")
+                                + FS + TVPERMJAR;
+
+        // create jar file for TVpermission
+        new File("TVJar").mkdir();
+        Files.copy(Paths.get(TESTCLASSES + FS + "TVJar", "TVPermission.class"),
+                Paths.get("TVJar", "TVPermission.class"));
+        Files.copy(Paths.get(TESTCLASSES + FS + "TVJar",
+                "TVPermissionCollection.class"),
+                Paths.get("TVJar", "TVPermissionCollection.class"));
+        JarUtils.createJar(TVPERMJAR, "TVJar/TVPermission.class",
+                "TVJar/TVPermissionCollection.class");
+
+        // create key pair for jar signing
+        ProcessTools.executeCommand(KEYTOOL,
+                "-genkey",
+                "-alias", ALIAS,
+                "-keystore", KEYSTORE,
+                "-storetype", "JKS",
+                "-keypass", PASSWORD,
+                "-dname", "cn=Blah",
+                "-storepass", PASSWORD
+        ).shouldHaveExitValue(0);
+        // sign jar
+        ProcessTools.executeCommand(JARSIGNER,
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                TVPERMJAR,
+                ALIAS).shouldHaveExitValue(0);
+        // add jar file to classpath
+        String cp = PATHTOJAR + PS + CLASSPATH;
+
+        // policy file grants permission signed by duke2 to watch TVChanel 5
+        try {
+            String[] cmd = {
+            "-classpath", cp,
+            "-Djava.security.manager",
+            "-Djava.security.policy=" + POL,
+            "ExtensiblePolicyTest_orig$TestMain"};
+            ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+        } catch (Exception ex) {
+            System.out.println("ExtensiblePolicyWithJarTest Failed");
+        }
+
+    }
+
+    public static class TestMain {
+        public static void main(String args[]) {
+            TVPermission perm = new TVPermission("channel:5", "watch");
+            try {
+                AccessController.checkPermission(perm);
+            } catch (SecurityException se) {
+                throw new RuntimeException(se);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java	Sat Sep 26 12:08:55 2015 +0300
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package TVJar;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.StringJoiner;
+import java.util.StringTokenizer;
+
+public class TVPermission extends Permission {
+
+    /**
+     * Watch
+     */
+    private final static int WATCH = 0x1;
+
+    /**
+     * Preview
+     */
+    private final static int PREVIEW = 0x2;
+
+    /**
+     * No actions
+     */
+    private final static int NONE = 0x0;
+
+    /**
+     * All actions
+     */
+    private final static int ALL = WATCH | PREVIEW;
+
+    // the actions mask
+    private int mask;
+
+    // the actions string
+    private String actions;
+
+    // the canonical name of the channel
+    private String cname;
+
+    // true if the channelname is a wildcard
+    private boolean wildcard;
+
+    // num range on channel
+    private int[] numrange;
+
+    // various num constants
+    private final static int NUM_MIN = 1;
+    private final static int NUM_MAX = 128;
+
+    public TVPermission(String channel, String action) {
+        this(channel, getMask(action));
+    }
+
+    TVPermission(String channel, int mask) {
+        super(channel);
+        init(channel, mask);
+    }
+
+    private synchronized int[] parseNum(String num)
+            throws Exception {
+
+        if (num == null || num.equals("") || num.equals("*")) {
+            wildcard = true;
+            return new int[]{NUM_MIN, NUM_MAX};
+        }
+
+        int dash = num.indexOf('-');
+
+        if (dash == -1) {
+            int p = 0;
+            try {
+                p = Integer.parseInt(num);
+            } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid input" + num);
+            }
+            return new int[]{p, p};
+        } else {
+            String low = num.substring(0, dash);
+            String high = num.substring(dash + 1);
+            int l, h;
+
+            if (low.equals("")) {
+                l = NUM_MIN;
+            } else {
+                try {
+                    l = Integer.parseInt(low);
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("invalid input" + num);
+                }
+            }
+
+            if (high.equals("")) {
+                h = NUM_MAX;
+            } else {
+                try {
+                    h = Integer.parseInt(high);
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("invalid input" + num);
+                }
+            }
+            if (h < l || l < NUM_MIN || h > NUM_MAX) {
+                throw new IllegalArgumentException("invalid num range");
+            }
+
+            return new int[]{l, h};
+        }
+    }
+
+    /**
+     * Initialize the TVPermission object.
+     */
+    private synchronized void init(String channel, int mask) {
+
+        // Parse the channel name.
+        int sep = channel.indexOf(':');
+
+        if (sep != -1) {
+            String num = channel.substring(sep + 1);
+            cname = channel.substring(0, sep);
+            try {
+                numrange = parseNum(num);
+            } catch (Exception e) {
+                throw new IllegalArgumentException("invalid num range: " + num);
+            }
+        } else {
+            numrange = new int[]{NUM_MIN, NUM_MAX};
+        }
+    }
+
+    /**
+     * Convert an action string to an integer actions mask.
+     *
+     * @param action the action string
+     * @return the action mask
+     */
+    private synchronized static int getMask(String action) {
+        int mask = NONE;
+
+        if (action == null) {
+            return mask;
+        }
+
+        StringTokenizer st = new StringTokenizer(action.toLowerCase(), ",");
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if (token.equals("watch")) {
+                mask |= WATCH;
+            } else if (token.equals("preview")) {
+                mask |= PREVIEW;
+            } else {
+                throw new IllegalArgumentException("invalid TV permission: " + token);
+            }
+        }
+        return mask;
+    }
+
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TVPermission)) {
+            return false;
+        }
+
+        if (this.wildcard) {
+            return true;
+        }
+
+        TVPermission that = (TVPermission) p;
+
+        if ((this.mask & that.mask) != that.mask) {
+            System.out.println("Masks are not ok this = "
+                    + this.mask + "THat = " + that.mask);
+            return false;
+        }
+
+        if ((this.numrange[0] > that.numrange[0])
+                || (this.numrange[1] < that.numrange[1])) {
+
+            System.out.println("This 0= " + this.numrange[0]
+                    + " 1 = " + this.numrange[1]);
+            System.out.println("That 0= " + that.numrange[0]
+                    + " 1 = " + that.numrange[1]);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Checks two TVPermission objects for equality.
+     * <p>
+     * @param obj the object we are testing for equality.
+     * @return true if obj is a TVPermission, and has the same channelname and
+     * action mask as this TVPermission object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (!(obj instanceof TVPermission)) {
+            return false;
+        }
+
+        TVPermission that = (TVPermission) obj;
+
+        // check the mask first
+        if (this.mask != that.mask) {
+            return false;
+        }
+
+        // now check the num range...
+        if ((this.numrange[0] != that.numrange[0])
+                || (this.numrange[1] != that.numrange[1])) {
+            return false;
+        }
+
+        return this.getName().equals(that.getName());
+    }
+
+    /**
+     * Returns the hash code value for this object.
+     *
+     * @return a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getName().hashCode();
+    }
+
+    /**
+     * Return the canonical string representation of the actions. Always returns
+     * actions in the following order: watch,preview.
+     *
+     * @param mask a specific integer action mask to translate into a string
+     * @return the canonical string representation of the actions
+     */
+    private synchronized static String getActions(int mask) {
+        StringJoiner sj = new StringJoiner(",");
+        if ((mask & WATCH) == WATCH) {
+            sj.add("watch");
+        }
+        if ((mask & PREVIEW) == PREVIEW) {
+            sj.add("preview");
+        }
+        return sj.toString();
+    }
+
+    /**
+     * Return the canonical string representation of the actions. Always returns
+     * actions in the following order: watch,preview.
+     *
+     * @return the canonical string representation of the actions.
+     */
+    @Override
+    public String getActions() {
+        if (actions == null) {
+            actions = getActions(this.mask);
+        }
+
+        return actions;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "\n"
+                + "cname = " + cname + "\n"
+                + "wildcard = " + wildcard + "\n"
+                + "numrange = " + numrange[0] + "," + numrange[1] + "\n";
+
+    }
+
+    @Override
+    public PermissionCollection newPermissionCollection() {
+        return new TVPermissionCollection();
+    }
+}
+
+final class TVPermissionCollection extends PermissionCollection {
+
+    /**
+     * The TVPermissions for this set.
+     */
+    private final ArrayList<TVPermission> permissions = new ArrayList<>();
+
+    /**
+     * Adds a permission to the TVPermissions. The key for the hash is the name
+     * in the case of wildcards, or all the IP addresses.
+     *
+     * @param permission the Permission object to add.
+     */
+    @Override
+    public void add(Permission permission) {
+        if (!(permission instanceof TVPermission)) {
+            throw new IllegalArgumentException("invalid permission: " + permission);
+        }
+        permissions.add((TVPermission) permission);
+    }
+
+    /**
+     * Check and see if this collection of permissions implies the permissions
+     * expressed in "permission".
+     *
+     * @param p the Permission object to compare
+     *
+     * @return true if "permission" is a proper subset of a permission in the
+     * collection, false if not.
+     */
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TVPermission)) {
+            return false;
+        }
+
+        Iterator<TVPermission> i = permissions.iterator();
+        while (i.hasNext()) {
+            if (((TVPermission) i.next()).implies(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns an enumeration of all the TVPermission objects in the container.
+     *
+     * @return an enumeration of all the TVPermission objects.
+     */
+    @Override
+    public Enumeration elements() {
+        return Collections.enumeration(permissions);
+    }
+
+}