/*
* #%L
* pro-grade
* %%
* Copyright (C) 2013 - 2014 Ondřej Lukáš, Josef Cacek
* %%
* 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.
* #L%
*/
package net.sourceforge.prograde.policy;
import java.awt.AWTPermission;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilePermission;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.SerializablePermission;
import java.lang.reflect.Constructor;
import java.lang.reflect.ReflectPermission;
import java.net.NetPermission;
import java.net.SocketPermission;
import java.net.URI;
import java.net.URL;
import java.security.AccessControlException;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.KeyStore;
import java.security.Permission;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.SecurityPermission;
import java.security.UnresolvedPermission;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.PropertyPermission;
import java.util.regex.Pattern;
import javax.security.auth.AuthPermission;
import javax.security.auth.x500.X500Principal;
import net.sourceforge.prograde.debug.ProGradePolicyDebugger;
import net.sourceforge.prograde.policyparser.ParsedKeystoreEntry;
import net.sourceforge.prograde.policyparser.ParsedPermission;
import net.sourceforge.prograde.policyparser.ParsedPolicy;
import net.sourceforge.prograde.policyparser.ParsedPolicyEntry;
import net.sourceforge.prograde.policyparser.ParsedPrincipal;
import net.sourceforge.prograde.policyparser.Parser;
import net.sourceforge.prograde.type.Priority;
/**
* Policy file class which works with grant and deny policy rules in policy file.
*
* @author Ondrej Lukas
*/
public class ProGradePolicy extends Policy {
private Priority priority; // true for grant, false for deny
private List<ProGradePolicyEntry> allGrantEntries;
private List<ProGradePolicyEntry> allDenyEntries;
private final boolean debug;
private final boolean expandProperties;
private final File file;
private final boolean skipDefaultPolicies;
/**
* Constructor of ProgradePolicyFile.
*/
public ProGradePolicy() {
String debugProperty = null;
try {
debugProperty = SecurityActions.getSystemProperty("java.security.debug");
} catch (AccessControlException ace) {
System.err.println("Unable to check if policy debugging is enabled.");
ace.printStackTrace();
}
boolean debugPolicy = false;
if (debugProperty != null) {
String[] splitDebugProperty = debugProperty.split(",");
for (int i = 0; i < splitDebugProperty.length; i++) {
String split = splitDebugProperty[i].trim();
split = split.replaceAll("\"", "");
// only these types of debug are connected with policy
if (split.equals("all") || split.equals("policy")) {
debugPolicy = true;
break;
}
}
}
debug = debugPolicy;
expandProperties = Boolean.parseBoolean(SecurityActions.getSecurityProperty("policy.expandProperties"));
String policyFile = SecurityActions.getSystemProperty("java.security.policy");
if (policyFile != null) {
skipDefaultPolicies = policyFile.startsWith("=");
if (skipDefaultPolicies) {
policyFile = policyFile.substring(1);
}
file = new File(policyFile);
} else {
skipDefaultPolicies = false;
file = null;
}
refresh();
}
/**
* Method which loads policy data from policy file.
*/
@Override
public void refresh() {
FileReader fr = null;
if (file != null) {
try {
fr = new FileReader(file);
} catch (Exception e) {
System.err.println("Unable to read policy file " + file + ": " + e.getMessage());
}
}
loadPolicy(fr, skipDefaultPolicies);
}
protected void loadPolicy(final Reader reader, final boolean exclusiveMode) {
final List<ParsedPolicy> parsedPolicies = new ArrayList<ParsedPolicy>();
final List<ProGradePolicyEntry> newGrantEntries = new ArrayList<ProGradePolicyEntry>();
final List<ProGradePolicyEntry> newDenyEntries = new ArrayList<ProGradePolicyEntry>();
Priority newPriority = null;
try {
if (reader != null) {
try {
parsedPolicies.add(new Parser(debug).parse(reader));
} catch (Exception ex) {
System.err.println("Unbale to parse policy. Exception message: " + ex.getMessage());
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// parse policies specified in java.security when not in exclusive mode (==)
if (!exclusiveMode) {
try {
parsedPolicies.addAll(getJavaPolicies());
} catch (Exception ex) {
System.err.println("Static policy wasn't successfully loaded! Exception message: " + ex.getMessage());
}
}
if (!exclusiveMode && parsedPolicies.isEmpty()) {
try {
initializeStaticPolicy(newGrantEntries);
} catch (Exception ex) {
System.err.println("Static policy wasn't successfully loaded! Exception message: " + ex.getMessage());
}
} else {
try {
// initializePolicy
if (parsedPolicies.isEmpty()) {
throw new Exception("Policy wasn't initialized!");
}
// set priority - priority is set according first loaded policy
newPriority = null;
for (ParsedPolicy pp : parsedPolicies) {
newPriority = pp.getPriority();
if (newPriority != null)
break;
}
if (newPriority == null)
newPriority = Priority.DEFAULT;
for (ParsedPolicy p : parsedPolicies) {
KeyStore keystore = null;
try {
keystore = createKeystore(p.getKeystore(), p.getKeystorePasswordURL(), file);
} catch (Exception ex) {
System.err.println("Keystore wasn't successfully initialized! Exception message: "
+ ex.getMessage());
}
// add grant and deny policy entry
addParsedPolicyEntries(p.getGrantEntries(), newGrantEntries, keystore, true);
addParsedPolicyEntries(p.getDenyEntries(), newDenyEntries, keystore, false);
}
} catch (Exception ex) {
System.err.println("Policy wasn't successfully initialized! Exception message: " + ex.getMessage());
}
}
} finally {
allGrantEntries = newGrantEntries;
allDenyEntries = newDenyEntries;
priority = newPriority;
}
}
/**
* Private method which adds parsedEntries to entries.
*
* @param parsedEntries parsed entries from policy file which will be added to entries
* @param entries entries will add parsed entries to themselves
* @param keystore KeyStore which is used by this policy file
* @param grant true for priority grant, false for priority deny
* @throws Exception when there was any problem during adding entries to policy
*/
private void addParsedPolicyEntries(List<ParsedPolicyEntry> parsedEntries, List<ProGradePolicyEntry> entries,
KeyStore keystore, boolean grant) throws Exception {
for (ParsedPolicyEntry p : parsedEntries) {
try {
entries.add(initializePolicyEntry(p, keystore, grant));
} catch (Exception e) {
System.err.println("Unable to initialize policy entry: " + e.getMessage());
}
}
}
/**
* Private method for initializing one policy entry.
*
* @param parsedEntry parsed entry using for creating new entry ProgradePolicyEntry
* @param keystore KeyStore which is used by this policy file
* @param grant true for priority grant, false for priority deny
* @return ProgradePolicyEntry which represents this parsedEntry
* @throws Exception when there was any problem during initializing of policy entry
*/
private ProGradePolicyEntry initializePolicyEntry(ParsedPolicyEntry parsedEntry, KeyStore keystore, boolean grant)
throws Exception {
ProGradePolicyEntry entry = new ProGradePolicyEntry(grant, debug);
// codesource
if (parsedEntry.getCodebase() != null || parsedEntry.getSignedBy() != null) {
CodeSource cs = createCodeSource(parsedEntry, keystore);
if (cs != null) {
entry.setCodeSource(cs);
} else {
// it happens if there is signedBy which isn't contain in keystore
entry.setNeverImplies(true);
// any next isn't needed because entry will never implies anything
return entry;
}
}
// principals
for (ParsedPrincipal p : parsedEntry.getPrincipals()) {
if (p.hasAlias()) {
String principal = gainPrincipalFromAlias(expandStringWithProperty(p.getAlias()), keystore);
if (principal != null) {
entry.addPrincipal(new ProGradePrincipal("javax.security.auth.x500.X500Principal", principal, false, false));
} else {
// it happens if there is alias which isn't contain in keystore
entry.setNeverImplies(true);
// any next isn't needed because entry will never implies anything
return entry;
}
} else {
entry.addPrincipal(new ProGradePrincipal(p.getPrincipalClass(), expandStringWithProperty(p.getPrincipalName()),
p.hasClassWildcard(), p.hasNameWildcard()));
}
}
// permissions
for (ParsedPermission p : parsedEntry.getPermissions()) {
Permission perm = createPermission(p, keystore);
if (perm != null) {
entry.addPermission(perm);
}
}
return entry;
}
/**
* Method for determining whether this ProgradePolicyEntry implies given permission.
*
* @param protectionDomain active ProtectionDomain to test
* @param permission Permission which need to be determined
* @return true if ProgradePolicyFile implies given Permission, false otherwise
*/
@Override
public boolean implies(ProtectionDomain protectionDomain, Permission permission) {
// this should never happen
if (protectionDomain == null) {
return false;
}
// everything is granted in this case
if (protectionDomain.getCodeSource() == null) {
return true;
}
if (Priority.GRANT.equals(priority)) { // branch for grant priority
if (debug) {
ProGradePolicyDebugger.log("Searching for granting for permission: " + permission + " ...");
}
if (grantEntriesImplies(protectionDomain, permission)) {
if (debug) {
ProGradePolicyDebugger.log("Granting permission found, grant access.");
}
return true;
} else {
if (debug) {
ProGradePolicyDebugger.log("Granting permission wasn't found, searching for denying...");
}
boolean toReturn = !denyEntriesImplies(protectionDomain, permission);
if (debug) {
if (toReturn) {
ProGradePolicyDebugger.log("Denying permission wasn't found, grant access.");
} else {
ProGradePolicyDebugger.log("Denying permission found, deny access.");
}
}
return toReturn;
}
} else { // branch for deny priority
if (debug) {
ProGradePolicyDebugger.log("Searching for denying for permission: " + permission + " ...");
}
if (denyEntriesImplies(protectionDomain, permission)) {
if (debug) {
ProGradePolicyDebugger.log("Denying permission found, deny access.");
}
return false;
} else {
if (debug) {
ProGradePolicyDebugger.log("Denying permission wasn't found, searching for granting...");
}
boolean toReturn = grantEntriesImplies(protectionDomain, permission);
if (debug) {
if (toReturn) {
ProGradePolicyDebugger.log("Granting permission found, grant access.");
} else {
ProGradePolicyDebugger.log("Granting permission wasn't found, deny access.");
}
}
return toReturn;
}
}
}
/**
* Private method for determining whether grant entries of ProgradePolicyFile imply given Permission.
*
* @param domain active ProtectionDomain to test
* @param permission Permission which need to be determined
* @return true if grant entries of this ProgradePolicyFile grant given Permission, false otherwise
*/
private boolean grantEntriesImplies(ProtectionDomain domain, Permission permission) {
return entriesImplyPermission(allGrantEntries, domain, permission);
}
/**
* Private method for determining whether deny entries of ProgradePolicyFile imply given Permission which means denying it.
*
* @param domain active ProtectionDomain to test
* @param permission Permission which need to be determined
* @return true if deny entries of this ProgradePolicyFile deny given Permission, false otherwise
*/
private boolean denyEntriesImplies(ProtectionDomain domain, Permission permission) {
return entriesImplyPermission(allDenyEntries, domain, permission);
}
/**
* Private method for determining whether grant or deny entries of ProgradePolicyFile imply given Permission.
*
* @param domain active ProtectionDomain to test
* @param permission Permission which need to be determined
*
* @return true if grant or deny entries of this ProgradePolicyFile imply given Permission, false otherwise
*/
private boolean entriesImplyPermission(List<ProGradePolicyEntry> policyEntriesList, ProtectionDomain domain,
Permission permission) {
for (ProGradePolicyEntry entry : policyEntriesList) {
if (entry.implies(domain, permission)) {
return true;
}
}
return false;
}
/**
* Private method for creating new Permission object from ParsedPermission.
*
* @param p ParsedPermission with informations about Permission.
* @param keystore KeyStore which is used by this policy file
* @return new created Permission or null if Permission doesn't exist or doesn't be created.
* @throws Exception when there was any problem during creating Permission
*/
private Permission createPermission(ParsedPermission p, KeyStore keystore) throws Exception {
if (p == null) {
return null;
}
String permissionName = expandStringWithProperty(p.getPermissionName());
String actions = expandStringWithProperty(p.getActions());
Class<?> clazz;
try {
clazz = Class.forName(p.getPermissionType());
} catch (ClassNotFoundException ex) {
Certificate[] certificates = getCertificates(expandStringWithProperty(p.getSignedBy()), keystore);
if (p.getSignedBy() != null && certificates == null) {
if (debug) {
ProGradePolicyDebugger.log("Permission with signedBy " + p.getSignedBy()
+ " is ignored. Certificate wasn't successfully found or loaded " + "from keystore");
}
return null;
}
return new UnresolvedPermission(p.getPermissionType(), permissionName, actions, certificates);
}
try {
if (clazz.equals(FilePermission.class)) {
return new FilePermission(permissionName, actions);
} else if (clazz.equals(SocketPermission.class)) {
return new SocketPermission(permissionName, actions);
} else if (clazz.equals(PropertyPermission.class)) {
return new PropertyPermission(permissionName, actions);
} else if (clazz.equals(RuntimePermission.class)) {
return new RuntimePermission(permissionName, actions);
} else if (clazz.equals(AWTPermission.class)) {
return new AWTPermission(permissionName, actions);
} else if (clazz.equals(NetPermission.class)) {
return new NetPermission(permissionName, actions);
} else if (clazz.equals(ReflectPermission.class)) {
return new ReflectPermission(permissionName, actions);
} else if (clazz.equals(SerializablePermission.class)) {
return new SerializablePermission(permissionName, actions);
} else if (clazz.equals(SecurityPermission.class)) {
return new SecurityPermission(permissionName, actions);
} else if (clazz.equals(AllPermission.class)) {
return new AllPermission(permissionName, actions);
} else if (clazz.equals(AuthPermission.class)) {
return new AuthPermission(permissionName, actions);
}
} catch (IllegalArgumentException ex) {
System.err.println("IllegalArgumentException in permission: [" + p.getPermissionType() + ", " + permissionName
+ ", " + actions + "]");
return null;
}
// check signedBy permission for classes which weren't loaded by boostrap classloader
// in some java clazz.getClassLoader() returns null for boostrap classloader
if (clazz.getClassLoader() != null) {
// another check whether clazz.getClassLoader() isn't bootstrap classloader
if (!clazz.getClassLoader().equals(clazz.getClassLoader().getParent())) {
if (p.getSignedBy() != null) {
Certificate[] signers = (Certificate[]) clazz.getSigners();
if (signers == null) {
return null;
} else {
Certificate[] certificates = getCertificates(expandStringWithProperty(p.getSignedBy()), keystore);
if (certificates == null) {
return null;
} else {
for (int i = 0; i < certificates.length; i++) {
Certificate certificate = certificates[i];
boolean contain = false;
for (int j = 0; j < signers.length; j++) {
Certificate signedCertificate = signers[j];
if (certificate.equals(signedCertificate)) {
contain = true;
break;
}
}
if (!contain) {
return null;
}
}
}
}
}
}
}
try {
Constructor<?> c = clazz.getConstructor(String.class, String.class);
return (Permission) c.newInstance(new Object[] { permissionName, actions });
} catch (NoSuchMethodException ex1) {
try {
Constructor<?> c = clazz.getConstructor(String.class);
return (Permission) c.newInstance(new Object[] { permissionName });
} catch (NoSuchMethodException ex2) {
Constructor<?> c = clazz.getConstructor();
return (Permission) c.newInstance(new Object[] {});
}
}
}
/**
* Private method for expanding String which contains any property.
*
* @param s String for expanding
* @return expanded String
* @throws Exception when any ends without '}' or contains inner property expansion
*/
private String expandStringWithProperty(String s) throws Exception {
// if expandProperties is false, don't expand property
if (!expandProperties) {
return s;
}
// if string doesn't contain property, returns original string
if (s == null || s.indexOf("${") == -1) {
return s;
}
String toReturn = "";
String[] split = s.split(Pattern.quote("${"));
toReturn += split[0];
for (int i = 1; i < split.length; i++) {
String part = split[i];
// don't expand ${{...}}
if (part.startsWith("{")) {
toReturn += ("${" + part);
continue;
}
String[] splitPart = part.split("}", 2);
if (splitPart.length < 2) {
throw new Exception("ER001: Expand property without end } or inner property expansion!");
} else {
// add expanded property
// ${/} = file.separator
if (splitPart[0].equals("/")) {
toReturn += File.separator;
} else {
toReturn += SecurityActions.getSystemProperty(splitPart[0]);
}
toReturn += splitPart[1];
}
}
return toReturn;
}
/**
* Private method for creating new CodeSource object from ParsedEntry.
*
* @param parsedEntry ParsedEntry with informations about CodeSource
* @param keystore KeyStore which is used by this policy file
* @return new created CodeSource
* @throws Exception when there was any problem during creating CodeSource
*/
private CodeSource createCodeSource(ParsedPolicyEntry parsedEntry, KeyStore keystore) throws Exception {
String parsedCodebase = expandStringWithProperty(parsedEntry.getCodebase());
String parsedCertificates = expandStringWithProperty(parsedEntry.getSignedBy());
String[] splitCertificates = new String[0];
if (parsedCertificates != null) {
splitCertificates = parsedCertificates.split(",");
}
if (splitCertificates.length > 0 && keystore == null) {
throw new Exception("ER002: Keystore must be defined if signedBy is used");
}
List<Certificate> certList = new ArrayList<Certificate>();
for (int i = 0; i < splitCertificates.length; i++) {
Certificate certificate = keystore.getCertificate(splitCertificates[i]);
if (certificate != null) {
certList.add(certificate);
} else {
// return null to indicate that it never implies any permission
return null;
}
}
Certificate[] certificates;
if (certList.isEmpty()) {
certificates = null;
} else {
certificates = new Certificate[certList.size()];
certList.toArray(certificates);
}
URL url;
if (parsedCodebase == null) {
url = null;
} else {
url = new URL(parsedCodebase);
}
CodeSource cs = new CodeSource(adaptURL(url), certificates);
return cs;
}
/**
* Private method for adapting URL for using of this ProgradePolicyFile.
*
* @param url URL for adapting
* @return adapted URL
* @throws Exception when there was any problem during adapting URL
*/
private URL adaptURL(URL url) throws Exception {
if (url != null && url.getProtocol().equals("file")) {
url = new URL(fixEncodedURI(url.toURI().toASCIIString()));
}
return url;
}
/**
* Private method for creating KeyStore object from ParsedKeystoreEntry and other information from policy file.
*
* @param parsedKeystoreEntry parsedKeystoreEntry containing information about keystore
* @param keystorePasswordURL URL to file which contain password for given keystore
* @param policyFile used policy file
* @return new created KeyStore
* @throws Exception when there was any problem during creating KeyStore
*/
private KeyStore createKeystore(ParsedKeystoreEntry parsedKeystoreEntry, String keystorePasswordURL, File policyFile)
throws Exception {
if (parsedKeystoreEntry == null) {
return null;
}
KeyStore toReturn;
String keystoreURL = expandStringWithProperty(parsedKeystoreEntry.getKeystoreURL());
String keystoreType = expandStringWithProperty(parsedKeystoreEntry.getKeystoreType());
String keystoreProvider = expandStringWithProperty(parsedKeystoreEntry.getKeystoreProvider());
if (keystoreURL == null) {
throw new Exception("ER003: Null keystore url!");
}
if (keystoreType == null) {
keystoreType = KeyStore.getDefaultType();
}
if (keystoreProvider == null) {
toReturn = KeyStore.getInstance(keystoreType);
} else {
toReturn = KeyStore.getInstance(keystoreType, keystoreProvider);
}
char[] keystorePassword = null;
if (keystorePasswordURL != null) {
keystorePassword = readKeystorePassword(expandStringWithProperty(keystorePasswordURL), policyFile);
}
// try relative path to policy file
String path = getPolicyFileHome(policyFile);
File f = null;
if (path != null) {
f = new File(path, keystoreURL);
}
if (f == null || !f.exists()) {
// try absoluth path
f = new File(keystoreURL);
if (!f.exists()) {
throw new Exception("ER004: KeyStore doesn't exists!");
}
}
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
toReturn.load(fis, keystorePassword);
} finally {
if (fis != null) {
fis.close();
}
}
return toReturn;
}
/**
* Private method for reading password for keystore from file.
*
* @param keystorePasswordURL URL to file which contain password for keystore
* @param policyFile used policy file
* @return password for keystore
* @throws Exception when there was any problem during reading keystore password
*/
private char[] readKeystorePassword(String keystorePasswordURL, File policyFile) throws Exception {
// try relative path to policy file
File f = new File(getPolicyFileHome(policyFile), keystorePasswordURL);
if (!f.exists()) {
// try absoluth path
f = new File(keystorePasswordURL);
if (!f.exists()) {
throw new Exception("ER005: File on keystorePasswordURL doesn't exists!");
}
}
Reader reader = new FileReader(f);
StringBuilder sb = new StringBuilder();
char buffer[] = new char[64];
int len;
while ((len = reader.read(buffer)) > 0) {
sb.append(buffer, 0, len);
}
reader.close();
return sb.toString().trim().toCharArray();
}
/**
* Private method for gaining X500Principal from keystore according its alias.
*
* @param alias alias of principal
* @param keystore KeyStore which is used by this policy file
* @return name of gained X500Principal
* @throws Exception when there was any problem during gaining Principal
*/
private String gainPrincipalFromAlias(String alias, KeyStore keystore) throws Exception {
if (keystore == null) {
return null;
}
if (!keystore.containsAlias(alias)) {
return null;
}
Certificate certificate = keystore.getCertificate(alias);
if (certificate == null || !(certificate instanceof X509Certificate)) {
return null;
}
X509Certificate x509Certificate = (X509Certificate) certificate;
X500Principal principal = new X500Principal(x509Certificate.getSubjectX500Principal().toString());
return principal.getName();
}
/**
* Private method for gaining absolute path of folder with policy file .
*
* @param file file with policy
* @return absolute path for folder with policy file or null if file doesn't exist
*/
private String getPolicyFileHome(File file) {
if (file == null || !file.exists()) {
return null;
}
return file.getAbsoluteFile().getParent();
}
/**
* Private method for gaining and parsing all policies defined in java.security file.
*
* @return Parsed policies in list of ParsedPolicy
*/
private List<ParsedPolicy> getJavaPolicies() {
List<ParsedPolicy> list = new ArrayList<ParsedPolicy>();
int counter = 1;
String policyUrl = null;
while ((policyUrl = SecurityActions.getSecurityProperty("policy.url." + counter)) != null) {
try {
policyUrl = expandStringWithProperty(policyUrl);
} catch (Exception ex) {
System.err.println("Expanding filepath in policy policy.url." + counter + "=" + policyUrl
+ " failed. Exception message: " + ex.getMessage());
counter++;
continue;
}
ParsedPolicy p = null;
InputStreamReader reader = null;
try {
reader = new InputStreamReader(new URL(policyUrl).openStream(), "UTF-8");
p = new Parser(debug).parse(reader);
if (p != null) {
list.add(p);
} else {
System.err.println("Parsed policy policy.url." + counter + "=" + policyUrl + " is null");
}
} catch (Exception ex) {
System.err.println("Policy policy.url." + counter + "=" + policyUrl
+ " wasn't successfully parsed. Exception message: " + ex.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
counter++;
}
return list;
}
/**
* Private method for initializing static policy.
*
* @throws Exception when there was any problem during initializing static policy
*/
private void initializeStaticPolicy(List<ProGradePolicyEntry> grantEntriesList) throws Exception {
// grant codeBase "file:${{java.ext.dirs}}/*" {
// permission java.security.AllPermission;
// };
ProGradePolicyEntry p1 = new ProGradePolicyEntry(true, debug);
Certificate[] certificates = null;
URL url = new URL(expandStringWithProperty("file:${{java.ext.dirs}}/*"));
CodeSource cs = new CodeSource(adaptURL(url), certificates);
p1.setCodeSource(cs);
p1.addPermission(new AllPermission());
grantEntriesList.add(p1);
// grant {
// permission java.lang.RuntimePermission "stopThread";
// permission java.net.SocketPermission "localhost:1024-", "listen";
// permission java.util.PropertyPermission "java.version", "read";
// permission java.util.PropertyPermission "java.vendor", "read";
// permission java.util.PropertyPermission "java.vendor.url", "read";
// permission java.util.PropertyPermission "java.class.version", "read";
// permission java.util.PropertyPermission "os.name", "read";
// permission java.util.PropertyPermission "os.version", "read";
// permission java.util.PropertyPermission "os.arch", "read";
// permission java.util.PropertyPermission "file.separator", "read";
// permission java.util.PropertyPermission "path.separator", "read";
// permission java.util.PropertyPermission "line.separator", "read";
// permission java.util.PropertyPermission "java.specification.version", "read";
// permission java.util.PropertyPermission "java.specification.vendor", "read";
// permission java.util.PropertyPermission "java.specification.name", "read";
// permission java.util.PropertyPermission "java.vm.specification.version", "read";
// permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
// permission java.util.PropertyPermission "java.vm.specification.name", "read";
// permission java.util.PropertyPermission "java.vm.version", "read";
// permission java.util.PropertyPermission "java.vm.vendor", "read";
// permission java.util.PropertyPermission "java.vm.name", "read";
// };
ProGradePolicyEntry p2 = new ProGradePolicyEntry(true, debug);
p2.addPermission(new RuntimePermission("stopThread"));
p2.addPermission(new SocketPermission("localhost:1024-", "listen"));
p2.addPermission(new PropertyPermission("java.version", "read"));
p2.addPermission(new PropertyPermission("java.vendor", "read"));
p2.addPermission(new PropertyPermission("java.vendor.url", "read"));
p2.addPermission(new PropertyPermission("java.class.version", "read"));
p2.addPermission(new PropertyPermission("os.name", "read"));
p2.addPermission(new PropertyPermission("os.version", "read"));
p2.addPermission(new PropertyPermission("os.arch", "read"));
p2.addPermission(new PropertyPermission("file.separator", "read"));
p2.addPermission(new PropertyPermission("path.separator", "read"));
p2.addPermission(new PropertyPermission("line.separator", "read"));
p2.addPermission(new PropertyPermission("java.specification.version", "read"));
p2.addPermission(new PropertyPermission("java.specification.vendor", "read"));
p2.addPermission(new PropertyPermission("java.specification.name", "read"));
p2.addPermission(new PropertyPermission("java.vm.specification.version", "read"));
p2.addPermission(new PropertyPermission("java.vm.specification.vendor", "read"));
p2.addPermission(new PropertyPermission("java.vm.specification.name", "read"));
p2.addPermission(new PropertyPermission("java.vm.version", "read"));
p2.addPermission(new PropertyPermission("java.vm.vendor", "read"));
p2.addPermission(new PropertyPermission("java.vm.name", "read"));
grantEntriesList.add(p2);
}
/**
* Gets {@link URI#toASCIIString()} as an input and the escaped octets %XX are converted to lower case (because of the
* Oracle PolicyFile implementation of CodeSource comparing).
*
* @param encodedUri
* @return given URI String with lower-cased codes of non-ascii characters
*/
private static String fixEncodedURI(final String encodedUri) {
if (encodedUri == null) {
return null;
}
final StringBuilder sb = new StringBuilder();
int lastPercIdx = -3; // we will check position-2
for (int i = 0, n = encodedUri.length(); i < n; i++) {
char c = encodedUri.charAt(i);
if (c == '%') {
lastPercIdx = i;
} else if (lastPercIdx >= i - 2 && c >= 'A' && c <= 'F') {
c = (char) (c - 'A' + 'a');
}
sb.append(c);
}
return sb.toString();
}
/**
* Private method for getting certificates from KeyStore.
*
* @param parsedCertificates signedBy part of policy file defines certificates
* @param keystore KeyStore which is used by this policy file
* @return array of Certificates
* @throws Exception when there was any problem during getting Certificates
*/
private Certificate[] getCertificates(String parsedCertificates, KeyStore keystore) throws Exception {
String[] splitCertificates = new String[0];
if (parsedCertificates != null) {
splitCertificates = parsedCertificates.split(",");
}
if (splitCertificates.length > 0 && keystore == null) {
throw new Exception("ER006: Keystore must be defined if signedBy is used");
}
List<Certificate> certList = new ArrayList<Certificate>();
for (int i = 0; i < splitCertificates.length; i++) {
Certificate certificate = keystore.getCertificate(splitCertificates[i]);
if (certificate != null) {
certList.add(certificate);
} else {
// return null to indicate that this permission is ignored
return null;
}
}
Certificate[] certificates;
if (certList.isEmpty()) {
certificates = null;
} else {
certificates = new Certificate[certList.size()];
certList.toArray(certificates);
}
return certificates;
}
}