From 840856ec3aa8269a493e82c1f304d2704fa1f378 Mon Sep 17 00:00:00 2001 From: M026875 Date: Tue, 3 Aug 2021 16:22:40 -0500 Subject: [PATCH 01/10] pushing changes to dhirenjoshi/IcedTea-Web/deploymentruleset-add branch --- core/pom.xml | 34 ++++ .../icedteaweb/resources/ResourceHandler.java | 44 ++++- .../jnlp/config/ConfigurationConstants.java | 4 + .../jnlp/deploymentrules/Action.java | 29 ++++ .../jnlp/deploymentrules/Certificate.java | 29 ++++ .../deploymentrules/DeploymentJarLoader.java | 16 ++ .../jnlp/deploymentrules/DeploymentRule.java | 87 ++++++++++ .../DeploymentRuleSetJarVerifier.java | 60 +++++++ .../deploymentrules/DeploymentRulesSet.java | 125 ++++++++++++++ .../deploymentrules/PermissionsConstant.java | 7 + .../jnlp/deploymentrules/RuleInfo.java | 51 ++++++ .../UrlDeploymentRulesSetUtils.java | 163 ++++++++++++++++++ .../jnlp/deploymentrules/jaxb.properties | 1 + 13 files changed, 649 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties diff --git a/core/pom.xml b/core/pom.xml index a9b803a06..ee59ec671 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -49,6 +49,40 @@ js 1.7R1 + + + + org.glassfish.jaxb + jaxb-runtime + 2.3.1 + + + + javax.activation + activation + 1.1 + + + javax.xml.bind + jaxb-api + 2.3.1 + + + + commons-io + commons-io + 2.5 + + + + + + org.eclipse.persistence + eclipselink + 2.5.0 + + + ${project.groupId} diff --git a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java index 470140a59..3850a02b8 100644 --- a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java @@ -12,6 +12,7 @@ import net.sourceforge.jnlp.cache.CacheUtil; import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils; +import net.sourceforge.jnlp.deploymentrules.UrlDeploymentRulesSetUtils; import java.io.File; import java.net.URL; @@ -23,7 +24,10 @@ import static net.adoptopenjdk.icedteaweb.resources.Resource.Status.ERROR; import static net.sourceforge.jnlp.util.UrlUtils.FILE_PROTOCOL; import static net.sourceforge.jnlp.util.UrlUtils.decodeUrlQuietly; - +/* + * Modified class to add DeploymentRuleSet + * DJ -03-02-2021 + */ class ResourceHandler { private static final Logger LOG = LoggerFactory.getLogger(ResourceHandler.class); @@ -117,6 +121,7 @@ private Resource downloadResource() { return resource; } + /** Original method private void validateWithWhitelist() { final URL url = resource.getLocation(); Assert.requireNonNull(url, "url"); @@ -129,4 +134,41 @@ private void validateWithWhitelist() { JNLPRuntime.exit(-1); } } + */ + private void validateWithWhitelist() { + final URL url = resource.getLocation(); + Assert.requireNonNull(url, "url"); + + // Validate with whitelist specified in deployment.properties. localhost is considered valid. + //commented out by DJ -final key word so that URL can be checked against whitelist as well as deploymentRuleset. + /*final*/ boolean found = UrlWhiteListUtils.isUrlInApplicationUrlWhitelist(url); + //If not found in the serverWhitelisting , check in DeploymentRuleSet.jar file. + LOG.debug("Resource URL not In Whitelist: {} found before calling Deployment rule set", found); + if (!found) { + LOG.debug("----------------------BEGIN DEPLOYMENT RULESET CALL------------------------------------------", found); + LOG.debug("Resource URL call inside (!found) before calling found=validateWithDeploymentRuleSet()", found); + found=validateWithDeploymentRuleSet() ; + LOG.debug("Resource URL call inside (!found) after calling found=validateWithDeploymentRuleSet()", found); + } + LOG.debug("Resource URL not In Whitelist: {} found after calling Deployment rule set", found); + if (!found) { + BasicExceptionDialog.show(new SecurityException(Translator.R("SWPInvalidURL") + ": " + url)); + LOG.error("Resource URL not In Whitelist: {}", resource.getLocation()); + JNLPRuntime.exit(-1); + } + } + + /** + * @author DJ 03-02-2021 + * Validates the resource URL with the deploymentRuleSet jar file + */ + private boolean validateWithDeploymentRuleSet() { + final URL url = resource.getLocation(); + Assert.requireNonNull(url, "url"); + + // Validate with whitelist specified in DeploymentRuleSet.jar localhost is considered valid. + final boolean found = UrlDeploymentRulesSetUtils.isUrlInDeploymentRuleSetlist(url); + return found; + } + } diff --git a/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java b/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java index 1b63e1d07..3421f878a 100644 --- a/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java +++ b/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java @@ -299,4 +299,8 @@ public interface ConfigurationConstants { */ String KEY_HTTPCONNECTION_CONNECT_TIMEOUT = "deployment.connection.connectTimeout"; String KEY_HTTPCONNECTION_READ_TIMEOUT = "deployment.connection.readTimeout"; + + /*DJ -adding deloymentruleset properties*/ + String KEY_DEPLOYMENT_RULE_SET = "deployment.deploymentruleset.jar"; + } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java new file mode 100644 index 000000000..701979998 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java @@ -0,0 +1,29 @@ +package net.sourceforge.jnlp.deploymentrules; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "action") +@XmlAccessorType(XmlAccessType.FIELD) +public class Action { + @XmlAttribute +private String permission; +public String getPermission() { + return permission; +} +public void setPermission(String permission) { + this.permission = permission; +} +@XmlElement +private String message; +public String getMessage() { + return message; +} +public void setMessage(String message) { + this.message = message; +} + +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java new file mode 100644 index 000000000..b2281bc2d --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java @@ -0,0 +1,29 @@ +package net.sourceforge.jnlp.deploymentrules; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +//import org.eclipse.persistence.oxm.annotations.XmlPath; + +@XmlRootElement(name = "certificate") +//If you want you can define the order in which the fields are written +//Optional +//@XmlType(propOrder = { "id", "action","message"}) + +@XmlAccessorType(XmlAccessType.FIELD) + +public class Certificate { +@XmlAttribute(name="hash") +private String hash; + + +public String getHash() { + return hash; +} + +public void setHash(String hash) { + this.hash = hash; +} +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java new file mode 100644 index 000000000..44b4fe5f0 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java @@ -0,0 +1,16 @@ +package net.sourceforge.jnlp.deploymentrules; + +import net.sourceforge.jnlp.security.AppVerifier; +import net.sourceforge.jnlp.security.JNLPAppVerifier; +import net.sourceforge.jnlp.tools.JarCertVerifier; + +public class DeploymentJarLoader { + + final AppVerifier verifier = new DeploymentRuleSetJarVerifier(); + + JarCertVerifier jcv = new JarCertVerifier(verifier); + + public boolean isJarSignedFully() { + return jcv.isFullySigned(); + } +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java new file mode 100644 index 000000000..113c764bf --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java @@ -0,0 +1,87 @@ +package net.sourceforge.jnlp.deploymentrules; +import javax.xml.bind.annotation.*; +import org.eclipse.persistence.oxm.annotations.XmlPath; +/* + * This class copies all the deployment Rule set to a class. + * + + + + + + + + + + + + + + + + Blocked by corporate. Contact J. Smith, smith@host.example.com, if you need to run this app. + + + + + + + + * */ +@XmlRootElement(name = "rule") +//If you want you can define the order in which the fields are written +//Optional +//@XmlType(propOrder = { "id", "action","message"}) + +@XmlAccessorType(XmlAccessType.FIELD) +public class DeploymentRule { + +@XmlElement(name="id") +private RuleInfo ruleInfo; + +public RuleInfo getRuleInfo() { + return ruleInfo; +} +public void setRuleInfo(RuleInfo ruleInfo) { + this.ruleInfo = ruleInfo; +} + + +private String name; + public String getName() { + return name; +} +public void setName(String name) { + this.name = name; +} +public String getTitle() { + return title; +} +public void setTitle(String title) { + this.title = title; +} +@XmlElement(name="action") +private Action ruleAction; + +public Action getRuleAction() { + return ruleAction; +} +public void setRuleAction(Action ruleAction) { + this.ruleAction = ruleAction; +} +@XmlAttribute +private String version; + + +public String getVersion() { + return version; +} +public void setVersion(String version) { + this.version = version; +} + +@XmlElement(name="title") +private String title; + + +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java new file mode 100644 index 000000000..7de92b910 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java @@ -0,0 +1,60 @@ +package net.sourceforge.jnlp.deploymentrules; + +import java.security.cert.CertPath; +import java.util.Map; + +import net.sourceforge.jnlp.JNLPFile; +import net.sourceforge.jnlp.LaunchException; +import net.sourceforge.jnlp.runtime.classloader.SecurityDelegate; +import net.sourceforge.jnlp.security.AppVerifier; +import net.sourceforge.jnlp.tools.CertInformation; +import net.sourceforge.jnlp.tools.JarCertVerifier; + +public class DeploymentRuleSetJarVerifier implements AppVerifier { + + @Override + public boolean hasAlreadyTrustedPublisher(Map certs, Map signedJars) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasRootInCacerts(Map certs, Map signedJars) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isFullySigned(Map certs, Map signedJars) { + + int sumOfSignableEntries = JarCertVerifier.getTotalJarEntries(signedJars); + for (CertPath cPath : certs.keySet()) { + // If this cert has signed everything, return true + if (hasCompletelySignedApp(certs.get(cPath), sumOfSignableEntries)) { + return true; + } + } + + // No cert found that signed all entries. Return false. + return false; + + } + + /** + * Find out if the CertPath with the given info has fully signed the app. + * @param info The information regarding the CertPath in question + * @param sumOfSignableEntries The total number of signable entries in the app. + * @return True if the signer has fully signed this app. + */ + public boolean hasCompletelySignedApp(CertInformation info, int sumOfSignableEntries) { + return JarCertVerifier.getTotalJarEntries(info.getSignedJars()) == sumOfSignableEntries; + } + + @Override + public void checkTrustWithUser(SecurityDelegate securityDelegate, JarCertVerifier jcv, JNLPFile file) + throws LaunchException { + // TODO Auto-generated method stub + + } + +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java new file mode 100644 index 000000000..c2c155829 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java @@ -0,0 +1,125 @@ +package net.sourceforge.jnlp.deploymentrules; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.*; + +import org.apache.commons.io.IOUtils; + + +@XmlRootElement//(namespace = "net.adoptopenjdk.icedtea.web") +@XmlAccessorType(XmlAccessType.FIELD) +public class DeploymentRulesSet { + private List list; + private List vettedUrls; + + public List getVettedUrls() { + return vettedUrls; + } + @XmlElementWrapper(name = "ruleset") + // XmlElement sets the name of the entities + @XmlElement(name = "rule") + private ArrayList ruleSet; + public ArrayList getRuleSet() { + return ruleSet; + } + public void setRuleSet(ArrayList ruleSet) { + this.ruleSet = ruleSet; + } + @XmlAttribute(name = "version") + private String version; + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + private static final String RULESET_XML = "./ruleset-jaxb.xml"; +public static void main(String[] args) { + DeploymentRulesSet ruleSet= new DeploymentRulesSet(); + ruleSet.parseDeploymentRuleSet("C:\\\\softwares\\\\icedtea-web\\\\DeploymentRuleSet.jar"); + //InputStream in = ruleSet.getResourceAsStream("C:\\softwares\\icedtea-web\\DeploymentRuleSetTest.jar\\ruleset.xml"); + //BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + +} + +public void parseDeploymentRuleSet(String jarFilePath) { + JarFile file; + JarEntry entry = null; + InputStream in=null; + String appendedXML=null; + if (new File(jarFilePath).exists()) { + try { + + file = new JarFile(new File(jarFilePath)); + //file = new JarFile(new File("C:\\\\softwares\\\\icedtea-web\\\\DeploymentRuleSetTest.jar")); + //entry = file.getJarEntry("ruleset-jaxb.xml"); + + entry = file.getJarEntry("ruleset.xml"); + if (entry!=null) { + in= file.getInputStream(entry); + String content = IOUtils.toString(file.getInputStream(entry)); + int insertCount=content.indexOf(""+fullXml+""; + } + System.out.println(appendedXML); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + + //URL url = ruleSet.getResourceAsStream("C:\\softwares\\icedtea-web\\ruleset.xml"); + //ServicesLoader jsl = new ServicesLoader( url.toString() ); + JAXBContext context; + if (appendedXML !=null) { + try { + context = JAXBContext.newInstance(DeploymentRulesSet.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + Unmarshaller um = context.createUnmarshaller(); + // DeploymentRulesSet bookstore2 = (DeploymentRulesSet) um.unmarshal(new FileReader( + // RULESET_XML)); + StringReader reader = new StringReader(appendedXML); + DeploymentRulesSet ruleSetDescriptor = (DeploymentRulesSet) um.unmarshal(reader); + + list = ruleSetDescriptor.getRuleSet(); + parseDeploymentRuleSet(); + System.out.println("Done"+list.toString()); + + } catch (JAXBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} + +private void parseDeploymentRuleSet() { + for (DeploymentRule rules: list) { + //Questions.. Do we also accept Urls to be vetted if DEFAULT permissions + if (rules.getRuleAction().getPermission().matches(PermissionsConstant.RUN)) { + vettedUrls.add(rules.getRuleInfo().getLocation()); + } + } +} + +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java new file mode 100644 index 000000000..6bdfe563a --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java @@ -0,0 +1,7 @@ +package net.sourceforge.jnlp.deploymentrules; + +public interface PermissionsConstant { + public static final String RUN="run"; + public static final String BLOCK="block"; + public static final String DEFAULT="default"; +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java new file mode 100644 index 000000000..184162437 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java @@ -0,0 +1,51 @@ +package net.sourceforge.jnlp.deploymentrules; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.eclipse.persistence.oxm.annotations.XmlPath; + +/* + * + + + + */ + +@XmlRootElement(name = "id") +@XmlAccessorType(XmlAccessType.FIELD) +public class RuleInfo { + @XmlElement(name="certificate") + private Certificate certificate; + public Certificate getCertificate() { + return certificate; + } + public void setcertificate(Certificate certificate) { + this.certificate = certificate; + } + @XmlAttribute(name="location") + private String location; + @XmlElement(name="action") + private Action action; + + + + public Action getAction() { + return action; + } + public void setAction(Action action) { + this.action = action; + } + public String getLocation() { + return location; + } + public void setLocation(String location) { + this.location = location; + } + + +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java new file mode 100644 index 000000000..894fcfc40 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -0,0 +1,163 @@ +package net.sourceforge.jnlp.deploymentrules; + +import net.adoptopenjdk.icedteaweb.Assert; +import net.adoptopenjdk.icedteaweb.StringUtils; +//import net.adoptopenjdk.icedteaweb.deploymentruleset.util.UrlDeploymentRuleSetUtil; +//import net.adoptopenjdk.icedteaweb.deploymentruleset.DeploymentRulesSet; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.IpUtil; +import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils; + +import java.net.URL; +import java.util.List; +import java.util.stream.Collectors; +/* + * Added DeploymentRuleSet white listing checks + * Added method call :isUrlInDeploymentRuleSetUrl + * This method will do the checks of the DeploymentRuleSet.jar file of ruleset.xml + * DJ- 3/02/2021 + * + */ +import static net.sourceforge.jnlp.config.ConfigurationConstants.KEY_DEPLOYMENT_RULE_SET; +/* + * @author DJ + * @date 03/02/2021 + * This class is implementing the DeplyomentRuleSet checks for the jar + * Added DeploymentRuleSet white listing checks + * Added method call :isUrlInDeploymentRuleSetUrl + * * + */ +public class UrlDeploymentRulesSetUtils { + + private static List applicationUrlDeploymentRuleSetList; + private static List applicationDeploymentRuleSetList; + private final static DeploymentRulesSet rulesSet= new DeploymentRulesSet(); + private static boolean isRuleSetInitialized=false; + + public static List getApplicationUrlDeploymentRuleSetList() { + if (applicationUrlDeploymentRuleSetList == null) { + applicationUrlDeploymentRuleSetList = loadDeploymentRuleSetFromConfiguration(KEY_DEPLOYMENT_RULE_SET); + } + return applicationUrlDeploymentRuleSetList; + } + + public static List getApplicationLinkDeploymentRuleSetList() { + if (applicationUrlDeploymentRuleSetList == null) { + applicationDeploymentRuleSetList = loadDeploymentRuleSetLinksFromConfiguration(KEY_DEPLOYMENT_RULE_SET); + } + return applicationDeploymentRuleSetList; + } + + /** + * @author-DJ + * @date 03/02/21 + * Added for deploymentRuleSet checks + * @param deploymentRuleSetJarPath + * @return + */ + public static List loadDeploymentRuleSetLinksFromConfiguration(final String deploymentRuleSetPropertyName) { + initRulesSet(deploymentRuleSetPropertyName); + return rulesSet.getVettedUrls(); + } + + private static void initRulesSet(final String deploymentRuleSetPropertyName) { + rulesSet.parseDeploymentRuleSet(deploymentRuleSetPropertyName); + isRuleSetInitialized=true; + } + + public static List loadRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { + List rulesSetList=null; + if (!isRuleSetInitialized) { + initRulesSet(deploymentRuleSetJarPath); + }else { + rulesSetList=rulesSet.getRuleSet(); + } + return rulesSetList; + } + + /** + * @author-DJ + * @date 03/02/21 + * Added for deploymentRuleSet checks + * @param deploymentRuleSetJarPath + * @return + */ + public static List loadDeploymentRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { + //Implement the DeplymentRuleSet parser here. DJ and create the DeploymentRuleSet. + return loadRuleSetFromConfiguration(deploymentRuleSetJarPath); + } + /** + * + * Adding by DJ 3/2/2021 to add DeploymentRuleSet functionality + * @param url + * @return + */ + public static boolean isUrlInDeploymentRuleSetlist(final URL url) { + return isUrlInDeploymentRuleSetUrl(url, getApplicationLinkDeploymentRuleSetList()); + } + + + /** + * isUrlInDeploymentRuleSetUrl + * Adding by DJ 3/2/2021 to add DeploymentRuleSet functionality + * @param url + * @param whiteList + * @return + */ + public static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List deploymentRuleSetList) { + Assert.requireNonNull(url, "url"); + Assert.requireNonNull(deploymentRuleSetList, "whiteList"); + + if (deploymentRuleSetList.isEmpty()) { + return false; // empty deploymentRuleSetList == allow none. Nothing is whitelisted + } + + + + return deploymentRuleSetList.stream().anyMatch(wlEntry -> wlEntry.matches(url.getHost())); + } + + /* + static WhitelistEntry parseEntry(final String wlUrlStr) { + Assert.requireNonNull(wlUrlStr, "wlUrlStr"); + return WhitelistEntry.parse(wlUrlStr); + } + /** + * Validate the security certificates (signers) for the class data. + * +private Certificate[] getSigners(String className, JarEntry je) throws IOException { + + try { + Certificate[] list = je.getCertificates(); + if ((list == null) || (list.length == 0)) { + return null; + } + + for (Certificate aList : list) { + if (!(aList instanceof X509Certificate)) { + String msg = MessageService.getTextMessage( + MessageId.CM_UNKNOWN_CERTIFICATE, className, + getJarName()); + + throw new SecurityException(msg); + } + + X509Certificate cert = (X509Certificate) aList; + + cert.checkValidity(); + } + + return list; + + } catch (GeneralSecurityException gse) { + // convert this into an unchecked security + // exception. Unchecked as eventually it has + // to pass through a method that's only throwing + // ClassNotFoundException + throw handleException(gse, className); + } + +} + +*/ +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties new file mode 100644 index 000000000..5837a4c25 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties @@ -0,0 +1 @@ +javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory \ No newline at end of file From dd726036e782315496e6262491bf3342a9d825e5 Mon Sep 17 00:00:00 2001 From: M026875 Date: Tue, 10 Aug 2021 18:56:44 -0500 Subject: [PATCH 02/10] pushing changes to dhirenjoshi/IcedTea-Web/deploymentruleset-add branch. Removed reference to jaxb . Only plain XML parsing is being done now. --- .../jnlp/deploymentrules/Action.java | 26 ++- .../jnlp/deploymentrules/Certificate.java | 24 +- .../jnlp/deploymentrules/DeploymentRule.java | 46 ++-- .../DeploymentRuleSetJarVerifier.java | 7 +- .../DeploymentRuleSetParser.java | 214 ++++++++++++++++++ .../deploymentrules/DeploymentRulesSet.java | 143 +++++++----- .../jnlp/deploymentrules/ParserSettings.java | 83 +++++++ .../{RuleInfo.java => Rule.java} | 22 +- .../UrlDeploymentRulesSetUtils.java | 74 ++---- 9 files changed, 454 insertions(+), 185 deletions(-) create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java rename core/src/main/java/net/sourceforge/jnlp/deploymentrules/{RuleInfo.java => Rule.java} (50%) diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java index 701979998..f8f4b276e 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java @@ -1,23 +1,27 @@ package net.sourceforge.jnlp.deploymentrules; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "action") -@XmlAccessorType(XmlAccessType.FIELD) +/** + * Action object of Rule from the rulset file + * Stores the attributes value from id tag + * permission and version. + * If permission is run, then location which is the url whitelisted is permitted to be accessible. + */ public class Action { - @XmlAttribute + private String permission; +private String version; +public String getVersion() { + return version; +} +public void setVersion(String version) { + this.version = version; +} public String getPermission() { return permission; } public void setPermission(String permission) { this.permission = permission; } -@XmlElement + private String message; public String getMessage() { return message; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java index b2281bc2d..1424cabf3 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java @@ -1,21 +1,13 @@ package net.sourceforge.jnlp.deploymentrules; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; - -//import org.eclipse.persistence.oxm.annotations.XmlPath; - -@XmlRootElement(name = "certificate") -//If you want you can define the order in which the fields are written -//Optional -//@XmlType(propOrder = { "id", "action","message"}) - -@XmlAccessorType(XmlAccessType.FIELD) - +/** + * Certificate object of Rule from the rulset file + * Stores the attributes value from action tag + * hash. + * This is class is rarely used yet and can be extended when a + * UI component to display the entire rulset.xml file and edit it will be enhanced + */ public class Certificate { -@XmlAttribute(name="hash") + private String hash; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java index 113c764bf..85611d45f 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java @@ -1,12 +1,12 @@ package net.sourceforge.jnlp.deploymentrules; -import javax.xml.bind.annotation.*; -import org.eclipse.persistence.oxm.annotations.XmlPath; + + /* * This class copies all the deployment Rule set to a class. * - + @@ -28,48 +28,33 @@ * */ -@XmlRootElement(name = "rule") -//If you want you can define the order in which the fields are written -//Optional -//@XmlType(propOrder = { "id", "action","message"}) -@XmlAccessorType(XmlAccessType.FIELD) + public class DeploymentRule { -@XmlElement(name="id") -private RuleInfo ruleInfo; +private Rule rule; -public RuleInfo getRuleInfo() { - return ruleInfo; +public Rule getRule() { + return rule; } -public void setRuleInfo(RuleInfo ruleInfo) { - this.ruleInfo = ruleInfo; -} - -private String name; - public String getName() { - return name; -} -public void setName(String name) { - this.name = name; -} public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } -@XmlElement(name="action") -private Action ruleAction; -public Action getRuleAction() { - return ruleAction; + +private Action action; + +public Action getAction() { + return action; } -public void setRuleAction(Action ruleAction) { - this.ruleAction = ruleAction; +public void setAction(Action action) { + this.action = action; } -@XmlAttribute + private String version; @@ -80,7 +65,6 @@ public void setVersion(String version) { this.version = version; } -@XmlElement(name="title") private String title; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java index 7de92b910..49bcfd1b5 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java @@ -9,7 +9,12 @@ import net.sourceforge.jnlp.security.AppVerifier; import net.sourceforge.jnlp.tools.CertInformation; import net.sourceforge.jnlp.tools.JarCertVerifier; - +/** + * DeploymentRuleSetJarVerifier object for accessing jar file. + * + * This is class is rarely used yet and can be extended when a + * UI component to display the entire rulset.xml file and edit it will be enhanced + */ public class DeploymentRuleSetJarVerifier implements AppVerifier { @Override diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java new file mode 100644 index 000000000..a13b4c111 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java @@ -0,0 +1,214 @@ +package net.sourceforge.jnlp.deploymentrules; + +import net.adoptopenjdk.icedteaweb.Assert; +import net.adoptopenjdk.icedteaweb.IcedTeaWebConstants; +import net.adoptopenjdk.icedteaweb.JavaSystemProperties; +import net.adoptopenjdk.icedteaweb.i18n.Translator; +import net.adoptopenjdk.icedteaweb.jnlp.element.EntryPoint; + +import net.adoptopenjdk.icedteaweb.jvm.JvmUtils; +import net.adoptopenjdk.icedteaweb.logging.Logger; +import net.adoptopenjdk.icedteaweb.logging.LoggerFactory; +import net.adoptopenjdk.icedteaweb.ui.swing.ScreenFinder; +import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; +import net.adoptopenjdk.icedteaweb.xmlparser.XMLParser; +import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; + + +import javax.swing.JOptionPane; +import java.awt.Rectangle; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.lang.Boolean.*; +import static java.util.Arrays.asList; + +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getAttribute; +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getChildNode; +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getChildNodes; +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getRequiredAttribute; +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getRequiredURL; +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getSpanText; +import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getURL; + + +/** +* Contains methods to parse an XML document into a DeploymentRuleSetFile. Implements JNLP +* specification version 1.0. +* +* @author Dhiren Joshi +* (JAM) - initial author +* @version $Revision: 1.13 $ +*/ +public final class DeploymentRuleSetParser { + + private static final Logger LOG = LoggerFactory.getLogger(DeploymentRuleSetParser.class); + + + + /** + * the file reference + */ + private DeploymentRulesSet file=null; // do not use (uninitialized) + + /** + * the root node + */ + private final XmlNode root; + /** + * whether to throw errors on non-fatal errors. + */ + private final boolean strict; // if strict==true parses a file with no error then strict==false should also + + /** + * whether to allow extensions to the JNLP specification + */ + private final boolean allowExtensions; + + + + /** + * Create a parser for the Deployment rule set file + * Reads the jar and ruleset.xml file is read and parsed. Adds a deploymentRuleSet tag to cover the legalities + * If any with using a Oracle ruleset.xml. + * + * * @throws ParseException if the DeploymentRuleSet string is invalid + */ + /** + * @param ruleSet the object created from the parsed ruleset.xml + * @param root , the root XmlNode + * @param settings , the parser settings + * @throws ParseException + */ +public DeploymentRuleSetParser(final DeploymentRulesSet ruleSet, final XmlNode root, final ParserSettings settings) throws ParseException { + this.file = file; + this.root = root; + this.strict = settings.isStrict(); + this.allowExtensions = settings.isExtensionAllowed(); + + // ensure it's a DeploymentRuleSet node + if (root == null || !root.getNodeName().equals(DeploymentRulesSet.DEPLOYMENTRULE_SET_ROOT_ELEMENT)) { + throw new ParseException("Root element is not a DeploymentRuleset element."); + } + processXmlParsingOfRuleSet(ruleSet,root); + + } + + + +/** + * Returns the rule attributes populated + * @param rule + * @param root + * @return rule object populated with attributes values + */ +public Rule getRuleIdAttributeValues(Rule rule, XmlNode root) { + //certificate element + final String hash = getAttribute(root, DeploymentRulesSet.HASH_ATTRIBUTE, null); + //id element + Certificate certs= new Certificate(); + certs.setHash(hash); + final String location = getAttribute(root, DeploymentRulesSet.LOCATION_ATTRIBUTE, null); + rule.setcertificate(certs); + rule.setLocation(location); + return rule; + } + + /** + * + * @param action + * @param root + * @return Action attributes sets + */ +public Action getActionAttributes(Action action, XmlNode root) { + //action element + final String permission = getAttribute(root, DeploymentRulesSet.PERMISSION_ATTRIBUTE, null); + String version = getAttribute(root, DeploymentRulesSet.VERSION_ATTRIBUTE, null); + action.setPermission(permission); + action.setVersion(version); + return action; + } + +/** + * @param ruleSet + * @param parent + * @throws ParseException + */ +public void processXmlParsingOfRuleSet(DeploymentRulesSet ruleSet, final XmlNode parent) throws ParseException { + Rule rule = null; + List rules= new ArrayList(); + XmlNode child = parent.getFirstChild(); + XmlNode childRuleSet =null; + if (child.getNodeName().equals(DeploymentRulesSet.RULE_SET_ELEMENT)) { + final XmlNode node = child; + if (!child.getNodeName().equals(DeploymentRulesSet.RULE_SET_ELEMENT)) { + throw new ParseException("Invalid Deployment rule set tag is missing"); + }else { + + rules = getRules(child); + } + + } + ruleSet.setRuleSet(rules); + + } + + + /** + * @param parent + * @return List list of Rules from deplyoment rule set + * @throws ParseException + */ +public List getRules(final XmlNode parent) + throws ParseException { + final List result = new ArrayList(); + final XmlNode rules[] = getChildNodes(parent, DeploymentRulesSet.RULE_ELEMENT); + + // ensure that there are at least one information section present + if (rules.length == 0 ) { + throw new ParseException("No rule element specified."); + } + for (final XmlNode rule : rules) { + result.add(getRule(rule)); + } + return result; + } + +/** + * @return the Rule element at the specified node. + * @param node + * @return + * @throws ParseException if the Rule eement does not exist + */ +private Rule getRule(final XmlNode node) throws ParseException { + + // create rules + Rule rule=new Rule(); + + // step through the elements + //first populate the id tag attribute + XmlNode child = node.getFirstChild(); + final String name = child.getNodeName(); + if (name.equals(DeploymentRulesSet.ID_ELEMENT)) { + getRuleIdAttributeValues(rule, child); + } + //next populate the action tag attribute. + child = child.getNextSibling(); + if (child.getNodeName().equals(DeploymentRulesSet.ACTION_ELEMENT)) { + Action action= new Action(); + rule.setAction(action); + getActionAttributes(action, child); + } + return rule; + } + +} + diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java index c2c155829..08d533453 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java @@ -1,47 +1,66 @@ package net.sourceforge.jnlp.deploymentrules; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.Reader; import java.io.StringReader; import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.*; +//import javax.xml.bind.JAXBContext; +//import javax.xml.bind.JAXBException; +//import javax.xml.bind.Marshaller; +//import javax.xml.bind.Unmarshaller; +//import javax.xml.bind.annotation.*; -import org.apache.commons.io.IOUtils; +import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; +import net.adoptopenjdk.icedteaweb.xmlparser.XMLParser; +import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; +import net.adoptopenjdk.icedteaweb.xmlparser.XmlParserFactory; +public class DeploymentRulesSet { + public static final String DEPLOYMENTRULE_SET_ROOT_ELEMENT = "deploymentRulesSet"; + public static final String RULE_SET_ELEMENT="ruleset"; + //From rule starts the actual list of rule and locations stored. + public static final String RULE_ELEMENT="rule"; + public static final String ID_ELEMENT="id"; + public static final String CERTIFICATE_ELEMENT="certificate"; + public static final String ACTION_ELEMENT="action"; + public static final String MESSAGE_ELEMENT="message"; + //id element + public static final String LOCATION_ATTRIBUTE = "location"; + //certificate element + public static final String HASH_ATTRIBUTE = "hash"; + //action element + public static final String VERSION_ATTRIBUTE = "version"; + public static final String PERMISSION_ATTRIBUTE = "permission"; -@XmlRootElement//(namespace = "net.adoptopenjdk.icedtea.web") -@XmlAccessorType(XmlAccessType.FIELD) -public class DeploymentRulesSet { - private List list; - private List vettedUrls; + private List list; + private List vettedUrls = new ArrayList();; + private ParserSettings parserSettings; public List getVettedUrls() { return vettedUrls; } - @XmlElementWrapper(name = "ruleset") - // XmlElement sets the name of the entities - @XmlElement(name = "rule") - private ArrayList ruleSet; - public ArrayList getRuleSet() { + + private ArrayList ruleSet; + public List getRuleSet() { return ruleSet; } - public void setRuleSet(ArrayList ruleSet) { - this.ruleSet = ruleSet; + public void setRuleSet(List rules) { + this.ruleSet = (ArrayList) rules; } - @XmlAttribute(name = "version") + private String version; public String getVersion() { return version; @@ -50,15 +69,24 @@ public void setVersion(String version) { this.version = version; } private static final String RULESET_XML = "./ruleset-jaxb.xml"; + public static void main(String[] args) { + //For testing DeploymentRulesSet ruleSet= new DeploymentRulesSet(); - ruleSet.parseDeploymentRuleSet("C:\\\\softwares\\\\icedtea-web\\\\DeploymentRuleSet.jar"); - //InputStream in = ruleSet.getResourceAsStream("C:\\softwares\\icedtea-web\\DeploymentRuleSetTest.jar\\ruleset.xml"); - //BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + try { + ruleSet.parseDeploymentRuleSet("C:\\\\softwares\\\\icedtea-web\\\\DeploymentRuleSet.jar"); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } -public void parseDeploymentRuleSet(String jarFilePath) { +/** + * @param jarFilePath + * @throws ParseException + */ +public void parseDeploymentRuleSet(String jarFilePath) throws ParseException{ JarFile file; JarEntry entry = null; InputStream in=null; @@ -67,14 +95,20 @@ public void parseDeploymentRuleSet(String jarFilePath) { try { file = new JarFile(new File(jarFilePath)); - //file = new JarFile(new File("C:\\\\softwares\\\\icedtea-web\\\\DeploymentRuleSetTest.jar")); - //entry = file.getJarEntry("ruleset-jaxb.xml"); - entry = file.getJarEntry("ruleset.xml"); if (entry!=null) { in= file.getInputStream(entry); - String content = IOUtils.toString(file.getInputStream(entry)); - int insertCount=content.indexOf(""+fullXml+""; @@ -82,42 +116,37 @@ public void parseDeploymentRuleSet(String jarFilePath) { System.out.println(appendedXML); } catch (IOException e1) { // TODO Auto-generated catch block - e1.printStackTrace(); + new ParseException("file IO exception accessing the ruleset or some network issues" + e1.getMessage()); } - - //URL url = ruleSet.getResourceAsStream("C:\\softwares\\icedtea-web\\ruleset.xml"); - //ServicesLoader jsl = new ServicesLoader( url.toString() ); - JAXBContext context; - if (appendedXML !=null) { - try { - context = JAXBContext.newInstance(DeploymentRulesSet.class); - Marshaller m = context.createMarshaller(); - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - Unmarshaller um = context.createUnmarshaller(); - // DeploymentRulesSet bookstore2 = (DeploymentRulesSet) um.unmarshal(new FileReader( - // RULESET_XML)); - StringReader reader = new StringReader(appendedXML); - DeploymentRulesSet ruleSetDescriptor = (DeploymentRulesSet) um.unmarshal(reader); - - list = ruleSetDescriptor.getRuleSet(); - parseDeploymentRuleSet(); - System.out.println("Done"+list.toString()); - - } catch (JAXBException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + + parserSettings = new ParserSettings(true, false,true); + final XMLParser xmlParser = XmlParserFactory.getParser(parserSettings.getParserType()); + InputStream is = new ByteArrayInputStream(appendedXML.getBytes(StandardCharsets.UTF_8)); + XmlNode root=null; + try { + root = xmlParser.getRootNode(is); + } catch (ParseException e) { + new ParseException("Could not parser the root Node" +e.getMessage()); + } + + DeploymentRulesSet ruleSetDescriptor = new DeploymentRulesSet(); + try { + DeploymentRuleSetParser parser= new DeploymentRuleSetParser(ruleSetDescriptor, root, parserSettings); + } catch (ParseException e) { + new ParseException("Could not intialize the DeploymentRuleSetParser" +e.getMessage()); + + } + list = ruleSetDescriptor.getRuleSet(); + parseDeploymentRuleSet(); } } private void parseDeploymentRuleSet() { - for (DeploymentRule rules: list) { + for (Rule rules: list) { //Questions.. Do we also accept Urls to be vetted if DEFAULT permissions - if (rules.getRuleAction().getPermission().matches(PermissionsConstant.RUN)) { - vettedUrls.add(rules.getRuleInfo().getLocation()); + if (rules.getAction().getPermission().matches(PermissionsConstant.RUN)) { + vettedUrls.add(rules.getLocation()); } } } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java new file mode 100644 index 000000000..4bd368be9 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java @@ -0,0 +1,83 @@ +/* ParserSettings.java + Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, version 2. + +IcedTea 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 for more details. + +You should have received a copy of the GNU General Public License along with +IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is making a +combined work based on this library. Thus, the terms and conditions of the GNU +General Public License cover the whole combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, and +to copy and distribute the resulting executable under terms of your choice, +provided that you also meet, for each linked independent module, the terms and +conditions of the license of that module. An independent module is a module +which is not derived from or based on this library. If you modify this library, +you may extend this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this exception +statement from your version. +*/ + +package net.sourceforge.jnlp.deploymentrules; + +import net.adoptopenjdk.icedteaweb.xmlparser.ParserType; + +import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.MALFORMED; +import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.NORMAL; + +/** + * Contains settings to be used by the Parser while parsing files. + * + * Immutable and therefore thread-safe. + */ +public class ParserSettings { + + private final boolean isStrict; + private final boolean extensionAllowed; + private final boolean malformedXmlAllowed; + + /** Create a new ParserSettings with the default parser settings */ + public ParserSettings() { + this(false, true, true); + } + + /** Create a new ParserSettings object + * @param strict true if parser should be strict + * @param extensionAllowed true if extensions are allowed + * @param malformedXmlAllowed true if xml sanitizer should be used + */ + public ParserSettings(boolean strict, boolean extensionAllowed, boolean malformedXmlAllowed) { + this.isStrict = strict; + this.extensionAllowed = extensionAllowed; + this.malformedXmlAllowed = malformedXmlAllowed; + } + + /** @return true if extensions to the spec are allowed */ + boolean isExtensionAllowed() { + return extensionAllowed; + } + + /** @return true if parsing malformed xml is allowed */ + ParserType getParserType() { + return malformedXmlAllowed ? MALFORMED : NORMAL; + } + + /** @return true if strict parsing mode is to be used */ + boolean isStrict() { + return isStrict; + } +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java similarity index 50% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java rename to core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java index 184162437..0c7f30d4c 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RuleInfo.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java @@ -1,25 +1,15 @@ package net.sourceforge.jnlp.deploymentrules; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -import org.eclipse.persistence.oxm.annotations.XmlPath; /* * - + */ - -@XmlRootElement(name = "id") -@XmlAccessorType(XmlAccessType.FIELD) -public class RuleInfo { - @XmlElement(name="certificate") +public class Rule { + private String location; + private Certificate certificate; public Certificate getCertificate() { return certificate; @@ -27,9 +17,7 @@ public Certificate getCertificate() { public void setcertificate(Certificate certificate) { this.certificate = certificate; } - @XmlAttribute(name="location") - private String location; - @XmlElement(name="action") + private Action action; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java index 894fcfc40..1098697fe 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -2,11 +2,14 @@ import net.adoptopenjdk.icedteaweb.Assert; import net.adoptopenjdk.icedteaweb.StringUtils; -//import net.adoptopenjdk.icedteaweb.deploymentruleset.util.UrlDeploymentRuleSetUtil; -//import net.adoptopenjdk.icedteaweb.deploymentruleset.DeploymentRulesSet; +import net.adoptopenjdk.icedteaweb.logging.Logger; +import net.adoptopenjdk.icedteaweb.logging.LoggerFactory; +import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.util.IpUtil; -import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils; +import net.sourceforge.jnlp.deploymentrules.DeploymentRule; +import net.sourceforge.jnlp.deploymentrules.DeploymentRulesSet; +//import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils; import java.net.URL; import java.util.List; @@ -29,12 +32,14 @@ */ public class UrlDeploymentRulesSetUtils { - private static List applicationUrlDeploymentRuleSetList; + private static List applicationUrlDeploymentRuleSetList; private static List applicationDeploymentRuleSetList; private final static DeploymentRulesSet rulesSet= new DeploymentRulesSet(); private static boolean isRuleSetInitialized=false; + private static final Logger LOG = LoggerFactory.getLogger(UrlDeploymentRulesSetUtils.class); - public static List getApplicationUrlDeploymentRuleSetList() { + + public static List getApplicationUrlDeploymentRuleSetList() { if (applicationUrlDeploymentRuleSetList == null) { applicationUrlDeploymentRuleSetList = loadDeploymentRuleSetFromConfiguration(KEY_DEPLOYMENT_RULE_SET); } @@ -61,12 +66,19 @@ public static List loadDeploymentRuleSetLinksFromConfiguration(final Str } private static void initRulesSet(final String deploymentRuleSetPropertyName) { - rulesSet.parseDeploymentRuleSet(deploymentRuleSetPropertyName); - isRuleSetInitialized=true; + try { + rulesSet.parseDeploymentRuleSet(deploymentRuleSetPropertyName); + isRuleSetInitialized=true; + } catch (ParseException e) { + LOG.error("Please Check property name . This should point to a valid DeploymentRuleSet jar file"+deploymentRuleSetPropertyName); + //absorb the Error and send error message for trouble shooting. + e.printStackTrace(); + } + } - public static List loadRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { - List rulesSetList=null; + public static List loadRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { + List rulesSetList=null; if (!isRuleSetInitialized) { initRulesSet(deploymentRuleSetJarPath); }else { @@ -82,7 +94,7 @@ public static List loadRuleSetFromConfiguration(final String de * @param deploymentRuleSetJarPath * @return */ - public static List loadDeploymentRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { + public static List loadDeploymentRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { //Implement the DeplymentRuleSet parser here. DJ and create the DeploymentRuleSet. return loadRuleSetFromConfiguration(deploymentRuleSetJarPath); } @@ -117,47 +129,5 @@ public static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List wlEntry.matches(url.getHost())); } - /* - static WhitelistEntry parseEntry(final String wlUrlStr) { - Assert.requireNonNull(wlUrlStr, "wlUrlStr"); - return WhitelistEntry.parse(wlUrlStr); - } - /** - * Validate the security certificates (signers) for the class data. - * -private Certificate[] getSigners(String className, JarEntry je) throws IOException { - - try { - Certificate[] list = je.getCertificates(); - if ((list == null) || (list.length == 0)) { - return null; - } - - for (Certificate aList : list) { - if (!(aList instanceof X509Certificate)) { - String msg = MessageService.getTextMessage( - MessageId.CM_UNKNOWN_CERTIFICATE, className, - getJarName()); - - throw new SecurityException(msg); - } - - X509Certificate cert = (X509Certificate) aList; - cert.checkValidity(); - } - - return list; - - } catch (GeneralSecurityException gse) { - // convert this into an unchecked security - // exception. Unchecked as eventually it has - // to pass through a method that's only throwing - // ClassNotFoundException - throw handleException(gse, className); - } - -} - -*/ } From c5f641bceb5aa46c708c39b17b72329e4d7a48f7 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 30 Aug 2021 23:46:54 +0200 Subject: [PATCH 03/10] code cleanup --- core/pom.xml | 34 -- .../icedteaweb/resources/ResourceHandler.java | 56 +--- .../jnlp/config/ConfigurationConstants.java | 2 +- .../jnlp/deploymentrules/Action.java | 33 -- .../jnlp/deploymentrules/Certificate.java | 21 -- .../deploymentrules/DeploymentJarLoader.java | 16 - .../jnlp/deploymentrules/DeploymentRule.java | 71 ----- .../DeploymentRuleSetJarVerifier.java | 65 ---- .../DeploymentRuleSetParser.java | 292 ++++++------------ .../deploymentrules/DeploymentRulesSet.java | 154 --------- .../DeploymentRulesSetFile.java | 94 ++++++ .../jnlp/deploymentrules/ParserSettings.java | 83 ----- .../deploymentrules/PermissionsConstant.java | 7 - .../jnlp/deploymentrules/Rule.java | 39 --- .../UrlDeploymentRulesSetUtils.java | 125 ++------ .../jnlp/deploymentrules/XmlAction.java | 37 +++ .../jnlp/deploymentrules/XmlCertificate.java | 20 ++ .../jnlp/deploymentrules/XmlRule.java | 31 ++ .../jnlp/deploymentrules/jaxb.properties | 1 - 19 files changed, 309 insertions(+), 872 deletions(-) delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java create mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java delete mode 100644 core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties diff --git a/core/pom.xml b/core/pom.xml index ee59ec671..a9b803a06 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -49,40 +49,6 @@ js 1.7R1 - - - - org.glassfish.jaxb - jaxb-runtime - 2.3.1 - - - - javax.activation - activation - 1.1 - - - javax.xml.bind - jaxb-api - 2.3.1 - - - - commons-io - commons-io - 2.5 - - - - - - org.eclipse.persistence - eclipselink - 2.5.0 - - - ${project.groupId} diff --git a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java index 3850a02b8..c9d16f688 100644 --- a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java @@ -24,10 +24,7 @@ import static net.adoptopenjdk.icedteaweb.resources.Resource.Status.ERROR; import static net.sourceforge.jnlp.util.UrlUtils.FILE_PROTOCOL; import static net.sourceforge.jnlp.util.UrlUtils.decodeUrlQuietly; -/* - * Modified class to add DeploymentRuleSet - * DJ -03-02-2021 - */ + class ResourceHandler { private static final Logger LOG = LoggerFactory.getLogger(ResourceHandler.class); @@ -46,7 +43,7 @@ Future putIntoCache(final Executor downloadExecutor) { // threads will return this future and ensure a resource is only processed by a single thread synchronized (resource) { final Future future = resource.getFutureForDownloaded(); - if(future == null) { + if (future == null) { LOG.debug("Download for {} has not been started until now", resource.getSimpleName()); final Future futureResource = getDownloadStateAndStartUnstartedDownload(downloadExecutor); resource.startProcessing(futureResource); @@ -121,54 +118,23 @@ private Resource downloadResource() { return resource; } - /** Original method private void validateWithWhitelist() { final URL url = resource.getLocation(); Assert.requireNonNull(url, "url"); // Validate with whitelist specified in deployment.properties. localhost is considered valid. - final boolean found = UrlWhiteListUtils.isUrlInApplicationUrlWhitelist(url); - if (!found) { - BasicExceptionDialog.show(new SecurityException(Translator.R("SWPInvalidURL") + ": " + url)); - LOG.error("Resource URL not In Whitelist: {}", resource.getLocation()); - JNLPRuntime.exit(-1); - } - } - */ - private void validateWithWhitelist() { - final URL url = resource.getLocation(); - Assert.requireNonNull(url, "url"); - - // Validate with whitelist specified in deployment.properties. localhost is considered valid. - //commented out by DJ -final key word so that URL can be checked against whitelist as well as deploymentRuleset. - /*final*/ boolean found = UrlWhiteListUtils.isUrlInApplicationUrlWhitelist(url); - //If not found in the serverWhitelisting , check in DeploymentRuleSet.jar file. - LOG.debug("Resource URL not In Whitelist: {} found before calling Deployment rule set", found); - if (!found) { - LOG.debug("----------------------BEGIN DEPLOYMENT RULESET CALL------------------------------------------", found); - LOG.debug("Resource URL call inside (!found) before calling found=validateWithDeploymentRuleSet()", found); - found=validateWithDeploymentRuleSet() ; - LOG.debug("Resource URL call inside (!found) after calling found=validateWithDeploymentRuleSet()", found); + if (UrlWhiteListUtils.isUrlInApplicationUrlWhitelist(url)) { + return; } - LOG.debug("Resource URL not In Whitelist: {} found after calling Deployment rule set", found); - if (!found) { - BasicExceptionDialog.show(new SecurityException(Translator.R("SWPInvalidURL") + ": " + url)); - LOG.error("Resource URL not In Whitelist: {}", resource.getLocation()); - JNLPRuntime.exit(-1); - } - } - - /** - * @author DJ 03-02-2021 - * Validates the resource URL with the deploymentRuleSet jar file - */ - private boolean validateWithDeploymentRuleSet() { - final URL url = resource.getLocation(); - Assert.requireNonNull(url, "url"); // Validate with whitelist specified in DeploymentRuleSet.jar localhost is considered valid. - final boolean found = UrlDeploymentRulesSetUtils.isUrlInDeploymentRuleSetlist(url); - return found; + if (UrlDeploymentRulesSetUtils.isUrlInDeploymentRuleSet(url)) { + return; + } + + BasicExceptionDialog.show(new SecurityException(Translator.R("SWPInvalidURL") + ": " + url)); + LOG.error("Resource URL not In Whitelist: {}", resource.getLocation()); + JNLPRuntime.exit(-1); } } diff --git a/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java b/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java index 3421f878a..7a9f51ef6 100644 --- a/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java +++ b/core/src/main/java/net/sourceforge/jnlp/config/ConfigurationConstants.java @@ -300,7 +300,7 @@ public interface ConfigurationConstants { String KEY_HTTPCONNECTION_CONNECT_TIMEOUT = "deployment.connection.connectTimeout"; String KEY_HTTPCONNECTION_READ_TIMEOUT = "deployment.connection.readTimeout"; - /*DJ -adding deloymentruleset properties*/ + /* deployment ruleset properties*/ String KEY_DEPLOYMENT_RULE_SET = "deployment.deploymentruleset.jar"; } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java deleted file mode 100644 index f8f4b276e..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; -/** - * Action object of Rule from the rulset file - * Stores the attributes value from id tag - * permission and version. - * If permission is run, then location which is the url whitelisted is permitted to be accessible. - */ -public class Action { - -private String permission; -private String version; -public String getVersion() { - return version; -} -public void setVersion(String version) { - this.version = version; -} -public String getPermission() { - return permission; -} -public void setPermission(String permission) { - this.permission = permission; -} - -private String message; -public String getMessage() { - return message; -} -public void setMessage(String message) { - this.message = message; -} - -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java deleted file mode 100644 index 1424cabf3..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; -/** - * Certificate object of Rule from the rulset file - * Stores the attributes value from action tag - * hash. - * This is class is rarely used yet and can be extended when a - * UI component to display the entire rulset.xml file and edit it will be enhanced - */ -public class Certificate { - -private String hash; - - -public String getHash() { - return hash; -} - -public void setHash(String hash) { - this.hash = hash; -} -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java deleted file mode 100644 index 44b4fe5f0..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentJarLoader.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; - -import net.sourceforge.jnlp.security.AppVerifier; -import net.sourceforge.jnlp.security.JNLPAppVerifier; -import net.sourceforge.jnlp.tools.JarCertVerifier; - -public class DeploymentJarLoader { - - final AppVerifier verifier = new DeploymentRuleSetJarVerifier(); - - JarCertVerifier jcv = new JarCertVerifier(verifier); - - public boolean isJarSignedFully() { - return jcv.isFullySigned(); - } -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java deleted file mode 100644 index 85611d45f..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRule.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; - - -/* - * This class copies all the deployment Rule set to a class. - * - - - - - - - - - - - - - - - - Blocked by corporate. Contact J. Smith, smith@host.example.com, if you need to run this app. - - - - - - - - * */ - - -public class DeploymentRule { - -private Rule rule; - -public Rule getRule() { - return rule; -} - -public String getTitle() { - return title; -} -public void setTitle(String title) { - this.title = title; -} - - -private Action action; - -public Action getAction() { - return action; -} -public void setAction(Action action) { - this.action = action; -} - -private String version; - - -public String getVersion() { - return version; -} -public void setVersion(String version) { - this.version = version; -} - -private String title; - - -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java deleted file mode 100644 index 49bcfd1b5..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetJarVerifier.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; - -import java.security.cert.CertPath; -import java.util.Map; - -import net.sourceforge.jnlp.JNLPFile; -import net.sourceforge.jnlp.LaunchException; -import net.sourceforge.jnlp.runtime.classloader.SecurityDelegate; -import net.sourceforge.jnlp.security.AppVerifier; -import net.sourceforge.jnlp.tools.CertInformation; -import net.sourceforge.jnlp.tools.JarCertVerifier; -/** - * DeploymentRuleSetJarVerifier object for accessing jar file. - * - * This is class is rarely used yet and can be extended when a - * UI component to display the entire rulset.xml file and edit it will be enhanced - */ -public class DeploymentRuleSetJarVerifier implements AppVerifier { - - @Override - public boolean hasAlreadyTrustedPublisher(Map certs, Map signedJars) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean hasRootInCacerts(Map certs, Map signedJars) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isFullySigned(Map certs, Map signedJars) { - - int sumOfSignableEntries = JarCertVerifier.getTotalJarEntries(signedJars); - for (CertPath cPath : certs.keySet()) { - // If this cert has signed everything, return true - if (hasCompletelySignedApp(certs.get(cPath), sumOfSignableEntries)) { - return true; - } - } - - // No cert found that signed all entries. Return false. - return false; - - } - - /** - * Find out if the CertPath with the given info has fully signed the app. - * @param info The information regarding the CertPath in question - * @param sumOfSignableEntries The total number of signable entries in the app. - * @return True if the signer has fully signed this app. - */ - public boolean hasCompletelySignedApp(CertInformation info, int sumOfSignableEntries) { - return JarCertVerifier.getTotalJarEntries(info.getSignedJars()) == sumOfSignableEntries; - } - - @Override - public void checkTrustWithUser(SecurityDelegate securityDelegate, JarCertVerifier jcv, JNLPFile file) - throws LaunchException { - // TODO Auto-generated method stub - - } - -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java index a13b4c111..c3bf8eac0 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java @@ -1,214 +1,110 @@ package net.sourceforge.jnlp.deploymentrules; -import net.adoptopenjdk.icedteaweb.Assert; -import net.adoptopenjdk.icedteaweb.IcedTeaWebConstants; -import net.adoptopenjdk.icedteaweb.JavaSystemProperties; -import net.adoptopenjdk.icedteaweb.i18n.Translator; -import net.adoptopenjdk.icedteaweb.jnlp.element.EntryPoint; - -import net.adoptopenjdk.icedteaweb.jvm.JvmUtils; -import net.adoptopenjdk.icedteaweb.logging.Logger; -import net.adoptopenjdk.icedteaweb.logging.LoggerFactory; -import net.adoptopenjdk.icedteaweb.ui.swing.ScreenFinder; import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; -import net.adoptopenjdk.icedteaweb.xmlparser.XMLParser; import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; - -import javax.swing.JOptionPane; -import java.awt.Rectangle; -import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static java.lang.Boolean.*; -import static java.util.Arrays.asList; import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getAttribute; -import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getChildNode; import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getChildNodes; -import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getRequiredAttribute; -import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getRequiredURL; -import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getSpanText; -import static net.adoptopenjdk.icedteaweb.xmlparser.NodeUtils.getURL; /** -* Contains methods to parse an XML document into a DeploymentRuleSetFile. Implements JNLP -* specification version 1.0. -* -* @author Dhiren Joshi -* (JAM) - initial author -* @version $Revision: 1.13 $ -*/ -public final class DeploymentRuleSetParser { - - private static final Logger LOG = LoggerFactory.getLogger(DeploymentRuleSetParser.class); - - - - /** - * the file reference - */ - private DeploymentRulesSet file=null; // do not use (uninitialized) - - /** - * the root node - */ - private final XmlNode root; - /** - * whether to throw errors on non-fatal errors. - */ - private final boolean strict; // if strict==true parses a file with no error then strict==false should also - - /** - * whether to allow extensions to the JNLP specification - */ - private final boolean allowExtensions; - - - - /** - * Create a parser for the Deployment rule set file - * Reads the jar and ruleset.xml file is read and parsed. Adds a deploymentRuleSet tag to cover the legalities - * If any with using a Oracle ruleset.xml. - * - * * @throws ParseException if the DeploymentRuleSet string is invalid - */ - /** - * @param ruleSet the object created from the parsed ruleset.xml - * @param root , the root XmlNode - * @param settings , the parser settings - * @throws ParseException - */ -public DeploymentRuleSetParser(final DeploymentRulesSet ruleSet, final XmlNode root, final ParserSettings settings) throws ParseException { - this.file = file; - this.root = root; - this.strict = settings.isStrict(); - this.allowExtensions = settings.isExtensionAllowed(); - - // ensure it's a DeploymentRuleSet node - if (root == null || !root.getNodeName().equals(DeploymentRulesSet.DEPLOYMENTRULE_SET_ROOT_ELEMENT)) { - throw new ParseException("Root element is not a DeploymentRuleset element."); - } - processXmlParsingOfRuleSet(ruleSet,root); - - } - - - -/** - * Returns the rule attributes populated - * @param rule - * @param root - * @return rule object populated with attributes values - */ -public Rule getRuleIdAttributeValues(Rule rule, XmlNode root) { - //certificate element - final String hash = getAttribute(root, DeploymentRulesSet.HASH_ATTRIBUTE, null); - //id element - Certificate certs= new Certificate(); - certs.setHash(hash); - final String location = getAttribute(root, DeploymentRulesSet.LOCATION_ATTRIBUTE, null); - rule.setcertificate(certs); - rule.setLocation(location); - return rule; - } - - /** - * - * @param action - * @param root - * @return Action attributes sets - */ -public Action getActionAttributes(Action action, XmlNode root) { - //action element - final String permission = getAttribute(root, DeploymentRulesSet.PERMISSION_ATTRIBUTE, null); - String version = getAttribute(root, DeploymentRulesSet.VERSION_ATTRIBUTE, null); - action.setPermission(permission); - action.setVersion(version); - return action; - } - -/** - * @param ruleSet - * @param parent - * @throws ParseException - */ -public void processXmlParsingOfRuleSet(DeploymentRulesSet ruleSet, final XmlNode parent) throws ParseException { - Rule rule = null; - List rules= new ArrayList(); - XmlNode child = parent.getFirstChild(); - XmlNode childRuleSet =null; - if (child.getNodeName().equals(DeploymentRulesSet.RULE_SET_ELEMENT)) { - final XmlNode node = child; - if (!child.getNodeName().equals(DeploymentRulesSet.RULE_SET_ELEMENT)) { - throw new ParseException("Invalid Deployment rule set tag is missing"); - }else { - - rules = getRules(child); - } - - } - ruleSet.setRuleSet(rules); - - } - - - /** - * @param parent - * @return List list of Rules from deplyoment rule set - * @throws ParseException - */ -public List getRules(final XmlNode parent) - throws ParseException { - final List result = new ArrayList(); - final XmlNode rules[] = getChildNodes(parent, DeploymentRulesSet.RULE_ELEMENT); - - // ensure that there are at least one information section present - if (rules.length == 0 ) { - throw new ParseException("No rule element specified."); - } - for (final XmlNode rule : rules) { - result.add(getRule(rule)); - } - return result; - } - -/** - * @return the Rule element at the specified node. - * @param node - * @return - * @throws ParseException if the Rule eement does not exist + * Contains methods to parse an XML document into a DeploymentRuleSetFile. + * Implements JNLP specification version 1.0. */ -private Rule getRule(final XmlNode node) throws ParseException { - - // create rules - Rule rule=new Rule(); - - // step through the elements - //first populate the id tag attribute - XmlNode child = node.getFirstChild(); - final String name = child.getNodeName(); - if (name.equals(DeploymentRulesSet.ID_ELEMENT)) { - getRuleIdAttributeValues(rule, child); - } - //next populate the action tag attribute. - child = child.getNextSibling(); - if (child.getNodeName().equals(DeploymentRulesSet.ACTION_ELEMENT)) { - Action action= new Action(); - rule.setAction(action); - getActionAttributes(action, child); - } - return rule; - } - +class DeploymentRuleSetParser { + + private static final String DEPLOYMENT_RULESET_ROOT_ELEMENT = "deploymentRulesSet"; + private static final String ID_ELEMENT = "id"; + private static final String RULE_SET_ELEMENT = "ruleset"; + + //From rule starts the actual list of rule and locations stored. + private static final String RULE_ELEMENT = "rule"; + private static final String ACTION_ELEMENT = "action"; + //id element + private static final String LOCATION_ATTRIBUTE = "location"; + //certificate element + private static final String HASH_ATTRIBUTE = "hash"; + //action element + private static final String VERSION_ATTRIBUTE = "version"; + private static final String PERMISSION_ATTRIBUTE = "permission"; + + /** + * Create a parser for the Deployment rule set file + * Reads the jar and ruleset.xml file is read and parsed. Adds a deploymentRuleSet tag to cover the legalities + * If any with using a Oracle ruleset.xml. + *

+ * + * @param root the root XmlNode + * @throws ParseException if the DeploymentRuleSet string is invalid + */ + public List getRules(final XmlNode root) throws ParseException { + // ensure it's a DeploymentRuleSet node + if (root == null || !root.getNodeName().equals(DEPLOYMENT_RULESET_ROOT_ELEMENT)) { + throw new ParseException("Root element is not a DeploymentRuleset element."); + } + return processXmlParsingOfRuleSet(root); + } + + private List processXmlParsingOfRuleSet(final XmlNode parent) throws ParseException { + final XmlNode child = parent.getFirstChild(); + final boolean isRuleSetElement = child.getNodeName().equals(RULE_SET_ELEMENT); + if (isRuleSetElement) { + return getRulesFromRuleset(child); + } else { + return new ArrayList<>(); + } + } + + private List getRulesFromRuleset(final XmlNode parent) throws ParseException { + final List result = new ArrayList<>(); + final XmlNode[] rules = getChildNodes(parent, RULE_ELEMENT); + + // ensure that there are at least one information section present + if (rules.length == 0) { + throw new ParseException("No rule element specified."); + } + for (final XmlNode rule : rules) { + result.add(getRule(rule)); + } + return result; + } + + private XmlRule getRule(final XmlNode node) { + + // create rules + final XmlRule rule = new XmlRule(); + + // step through the elements + // first populate the id tag attribute + final XmlNode potentialIdPart = node.getFirstChild(); + if (potentialIdPart.getNodeName().equals(ID_ELEMENT)) { + //certificate element + final String hash = getAttribute(potentialIdPart, HASH_ATTRIBUTE, null); + //id element + final XmlCertificate certs = new XmlCertificate(); + certs.setHash(hash); + + final String location = getAttribute(potentialIdPart, LOCATION_ATTRIBUTE, null); + rule.setCertificate(certs); + rule.setLocation(location); + } + + // next populate the action tag attribute. + final XmlNode potentialActionPart = potentialIdPart.getNextSibling(); + if (potentialActionPart.getNodeName().equals(ACTION_ELEMENT)) { + final XmlAction action = new XmlAction(); + //action element + final String permission = getAttribute(potentialActionPart, PERMISSION_ATTRIBUTE, null); + final String version = getAttribute(potentialActionPart, VERSION_ATTRIBUTE, null); + action.setPermission(permission); + action.setVersion(version); + rule.setAction(action); + } + + return rule; + } } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java deleted file mode 100644 index 08d533453..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSet.java +++ /dev/null @@ -1,154 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -//import javax.xml.bind.JAXBContext; -//import javax.xml.bind.JAXBException; -//import javax.xml.bind.Marshaller; -//import javax.xml.bind.Unmarshaller; -//import javax.xml.bind.annotation.*; - -import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; -import net.adoptopenjdk.icedteaweb.xmlparser.XMLParser; -import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; -import net.adoptopenjdk.icedteaweb.xmlparser.XmlParserFactory; -public class DeploymentRulesSet { - public static final String DEPLOYMENTRULE_SET_ROOT_ELEMENT = "deploymentRulesSet"; - public static final String RULE_SET_ELEMENT="ruleset"; - //From rule starts the actual list of rule and locations stored. - public static final String RULE_ELEMENT="rule"; - public static final String ID_ELEMENT="id"; - public static final String CERTIFICATE_ELEMENT="certificate"; - public static final String ACTION_ELEMENT="action"; - public static final String MESSAGE_ELEMENT="message"; - //id element - public static final String LOCATION_ATTRIBUTE = "location"; - //certificate element - public static final String HASH_ATTRIBUTE = "hash"; - //action element - public static final String VERSION_ATTRIBUTE = "version"; - public static final String PERMISSION_ATTRIBUTE = "permission"; - - - private List list; - private List vettedUrls = new ArrayList();; - private ParserSettings parserSettings; - - public List getVettedUrls() { - return vettedUrls; - } - - private ArrayList ruleSet; - public List getRuleSet() { - return ruleSet; - } - public void setRuleSet(List rules) { - this.ruleSet = (ArrayList) rules; - } - - private String version; - public String getVersion() { - return version; - } - public void setVersion(String version) { - this.version = version; - } - private static final String RULESET_XML = "./ruleset-jaxb.xml"; - -public static void main(String[] args) { - //For testing - DeploymentRulesSet ruleSet= new DeploymentRulesSet(); - try { - ruleSet.parseDeploymentRuleSet("C:\\\\softwares\\\\icedtea-web\\\\DeploymentRuleSet.jar"); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - -} - -/** - * @param jarFilePath - * @throws ParseException - */ -public void parseDeploymentRuleSet(String jarFilePath) throws ParseException{ - JarFile file; - JarEntry entry = null; - InputStream in=null; - String appendedXML=null; - if (new File(jarFilePath).exists()) { - try { - - file = new JarFile(new File(jarFilePath)); - entry = file.getJarEntry("ruleset.xml"); - if (entry!=null) { - in= file.getInputStream(entry); - - StringBuilder textBuilder = new StringBuilder(); - try (Reader reader = new BufferedReader(new InputStreamReader - (in, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - textBuilder.append((char) c); - } - } - String content= textBuilder.toString(); - int insertCount=content.indexOf(""+fullXml+""; - } - System.out.println(appendedXML); - } catch (IOException e1) { - // TODO Auto-generated catch block - new ParseException("file IO exception accessing the ruleset or some network issues" + e1.getMessage()); - } - - - parserSettings = new ParserSettings(true, false,true); - final XMLParser xmlParser = XmlParserFactory.getParser(parserSettings.getParserType()); - InputStream is = new ByteArrayInputStream(appendedXML.getBytes(StandardCharsets.UTF_8)); - XmlNode root=null; - try { - root = xmlParser.getRootNode(is); - } catch (ParseException e) { - new ParseException("Could not parser the root Node" +e.getMessage()); - } - - DeploymentRulesSet ruleSetDescriptor = new DeploymentRulesSet(); - try { - DeploymentRuleSetParser parser= new DeploymentRuleSetParser(ruleSetDescriptor, root, parserSettings); - } catch (ParseException e) { - new ParseException("Could not intialize the DeploymentRuleSetParser" +e.getMessage()); - - } - list = ruleSetDescriptor.getRuleSet(); - parseDeploymentRuleSet(); - } -} - -private void parseDeploymentRuleSet() { - for (Rule rules: list) { - //Questions.. Do we also accept Urls to be vetted if DEFAULT permissions - if (rules.getAction().getPermission().matches(PermissionsConstant.RUN)) { - vettedUrls.add(rules.getLocation()); - } - } -} - -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java new file mode 100644 index 000000000..dc9569c08 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java @@ -0,0 +1,94 @@ +package net.sourceforge.jnlp.deploymentrules; + +import net.adoptopenjdk.icedteaweb.io.IOUtils; +import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; +import net.adoptopenjdk.icedteaweb.xmlparser.XMLParser; +import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; +import net.adoptopenjdk.icedteaweb.xmlparser.XmlParserFactory; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.MALFORMED; + +class DeploymentRulesSetFile { + + private static final String RULESET_XML = "ruleset.xml"; + private static final String RUN = "run"; + + private final String rulesetPath; + + public DeploymentRulesSetFile(String rulesetPath) { + this.rulesetPath = rulesetPath; + } + + public List parseDeploymentRuleSet() throws ParseException { + final File rulesetJarFile = new File(rulesetPath); + if (rulesetJarFile.exists()) { + final String rawContent = getRulesetXmlContent(rulesetJarFile); + final String content = wrapInArtificialRoot(rawContent); + final XmlNode root = parseXml(content); + final List rules = extractRules(root); + + return rules.stream() + .filter(rule -> Objects.equals(rule.getAction().getPermission(), RUN)) + .map(XmlRule::getLocation) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + private String getRulesetXmlContent(File rulesetJarFile) throws ParseException { + try { + final JarFile file = new JarFile(rulesetJarFile); + final JarEntry entry = file.getJarEntry(RULESET_XML); + if (entry == null) { + throw new ParseException("could not find a " + RULESET_XML + " in the jar " + rulesetJarFile); + } + + try (final InputStream in = file.getInputStream(entry)) { + return IOUtils.readContentAsUtf8String(in); + } + } catch (IOException e) { + throw new ParseException("file IO exception accessing the ruleset or some network issues", e); + } + } + + private String wrapInArtificialRoot(String content) throws ParseException { + final int idx = content.indexOf(""); + } + final String prefix = content.substring(0, idx); + final String fullXml = content.substring(idx); + return prefix + "" + fullXml + ""; + } + + private XmlNode parseXml(String content) throws ParseException { + try { + final InputStream is = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); + final XMLParser xmlParser = XmlParserFactory.getParser(MALFORMED); + return xmlParser.getRootNode(is); + } catch (ParseException e) { + throw new ParseException("Could not parser the root Node" + e.getMessage()); + } + } + + private List extractRules(XmlNode root) throws ParseException { + try { + return new DeploymentRuleSetParser().getRules(root); + } catch (ParseException e) { + throw new ParseException("Could not initialize the DeploymentRuleSetParser" + e.getMessage()); + } + } + +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java deleted file mode 100644 index 4bd368be9..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/ParserSettings.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ParserSettings.java - Copyright (C) 2011 Red Hat, Inc. - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, version 2. - -IcedTea 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 for more details. - -You should have received a copy of the GNU General Public License along with -IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is making a -combined work based on this library. Thus, the terms and conditions of the GNU -General Public License cover the whole combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent modules, and -to copy and distribute the resulting executable under terms of your choice, -provided that you also meet, for each linked independent module, the terms and -conditions of the license of that module. An independent module is a module -which is not derived from or based on this library. If you modify this library, -you may extend this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this exception -statement from your version. -*/ - -package net.sourceforge.jnlp.deploymentrules; - -import net.adoptopenjdk.icedteaweb.xmlparser.ParserType; - -import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.MALFORMED; -import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.NORMAL; - -/** - * Contains settings to be used by the Parser while parsing files. - * - * Immutable and therefore thread-safe. - */ -public class ParserSettings { - - private final boolean isStrict; - private final boolean extensionAllowed; - private final boolean malformedXmlAllowed; - - /** Create a new ParserSettings with the default parser settings */ - public ParserSettings() { - this(false, true, true); - } - - /** Create a new ParserSettings object - * @param strict true if parser should be strict - * @param extensionAllowed true if extensions are allowed - * @param malformedXmlAllowed true if xml sanitizer should be used - */ - public ParserSettings(boolean strict, boolean extensionAllowed, boolean malformedXmlAllowed) { - this.isStrict = strict; - this.extensionAllowed = extensionAllowed; - this.malformedXmlAllowed = malformedXmlAllowed; - } - - /** @return true if extensions to the spec are allowed */ - boolean isExtensionAllowed() { - return extensionAllowed; - } - - /** @return true if parsing malformed xml is allowed */ - ParserType getParserType() { - return malformedXmlAllowed ? MALFORMED : NORMAL; - } - - /** @return true if strict parsing mode is to be used */ - boolean isStrict() { - return isStrict; - } -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java deleted file mode 100644 index 6bdfe563a..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/PermissionsConstant.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; - -public interface PermissionsConstant { - public static final String RUN="run"; - public static final String BLOCK="block"; - public static final String DEFAULT="default"; -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java deleted file mode 100644 index 0c7f30d4c..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.sourceforge.jnlp.deploymentrules; - - -/* - * - - - - */ -public class Rule { - private String location; - - private Certificate certificate; - public Certificate getCertificate() { - return certificate; - } - public void setcertificate(Certificate certificate) { - this.certificate = certificate; - } - - private Action action; - - - - public Action getAction() { - return action; - } - public void setAction(Action action) { - this.action = action; - } - public String getLocation() { - return location; - } - public void setLocation(String location) { - this.location = location; - } - - -} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java index 1098697fe..68ebf4020 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -1,133 +1,50 @@ package net.sourceforge.jnlp.deploymentrules; import net.adoptopenjdk.icedteaweb.Assert; -import net.adoptopenjdk.icedteaweb.StringUtils; import net.adoptopenjdk.icedteaweb.logging.Logger; import net.adoptopenjdk.icedteaweb.logging.LoggerFactory; import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; import net.sourceforge.jnlp.runtime.JNLPRuntime; -import net.sourceforge.jnlp.util.IpUtil; -import net.sourceforge.jnlp.deploymentrules.DeploymentRule; -import net.sourceforge.jnlp.deploymentrules.DeploymentRulesSet; -//import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils; import java.net.URL; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; -/* - * Added DeploymentRuleSet white listing checks - * Added method call :isUrlInDeploymentRuleSetUrl - * This method will do the checks of the DeploymentRuleSet.jar file of ruleset.xml - * DJ- 3/02/2021 - * - */ + import static net.sourceforge.jnlp.config.ConfigurationConstants.KEY_DEPLOYMENT_RULE_SET; -/* - * @author DJ - * @date 03/02/2021 - * This class is implementing the DeplyomentRuleSet checks for the jar - * Added DeploymentRuleSet white listing checks - * Added method call :isUrlInDeploymentRuleSetUrl - * * - */ -public class UrlDeploymentRulesSetUtils { - private static List applicationUrlDeploymentRuleSetList; - private static List applicationDeploymentRuleSetList; - private final static DeploymentRulesSet rulesSet= new DeploymentRulesSet(); - private static boolean isRuleSetInitialized=false; +public class UrlDeploymentRulesSetUtils { + private static final Logger LOG = LoggerFactory.getLogger(UrlDeploymentRulesSetUtils.class); + private static List applicationDeploymentRuleSetList; - public static List getApplicationUrlDeploymentRuleSetList() { - if (applicationUrlDeploymentRuleSetList == null) { - applicationUrlDeploymentRuleSetList = loadDeploymentRuleSetFromConfiguration(KEY_DEPLOYMENT_RULE_SET); - } - return applicationUrlDeploymentRuleSetList; - } - - public static List getApplicationLinkDeploymentRuleSetList() { - if (applicationUrlDeploymentRuleSetList == null) { - applicationDeploymentRuleSetList = loadDeploymentRuleSetLinksFromConfiguration(KEY_DEPLOYMENT_RULE_SET); + private static List getApplicationLinkDeploymentRuleSetList() { + if (applicationDeploymentRuleSetList == null) { + applicationDeploymentRuleSetList = loadDeploymentRuleSetLinksFromConfiguration(); } return applicationDeploymentRuleSetList; } - /** - * @author-DJ - * @date 03/02/21 - * Added for deploymentRuleSet checks - * @param deploymentRuleSetJarPath - * @return - */ - public static List loadDeploymentRuleSetLinksFromConfiguration(final String deploymentRuleSetPropertyName) { - initRulesSet(deploymentRuleSetPropertyName); - return rulesSet.getVettedUrls(); - } - - private static void initRulesSet(final String deploymentRuleSetPropertyName) { - try { - rulesSet.parseDeploymentRuleSet(deploymentRuleSetPropertyName); - isRuleSetInitialized=true; - } catch (ParseException e) { - LOG.error("Please Check property name . This should point to a valid DeploymentRuleSet jar file"+deploymentRuleSetPropertyName); - //absorb the Error and send error message for trouble shooting. - e.printStackTrace(); - } - - } - - public static List loadRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { - List rulesSetList=null; - if (!isRuleSetInitialized) { - initRulesSet(deploymentRuleSetJarPath); - }else { - rulesSetList=rulesSet.getRuleSet(); - } - return rulesSetList; - } - - /** - * @author-DJ - * @date 03/02/21 - * Added for deploymentRuleSet checks - * @param deploymentRuleSetJarPath - * @return - */ - public static List loadDeploymentRuleSetFromConfiguration(final String deploymentRuleSetJarPath) { - //Implement the DeplymentRuleSet parser here. DJ and create the DeploymentRuleSet. - return loadRuleSetFromConfiguration(deploymentRuleSetJarPath); - } - /** - * - * Adding by DJ 3/2/2021 to add DeploymentRuleSet functionality - * @param url - * @return - */ - public static boolean isUrlInDeploymentRuleSetlist(final URL url) { - return isUrlInDeploymentRuleSetUrl(url, getApplicationLinkDeploymentRuleSetList()); + private static List loadDeploymentRuleSetLinksFromConfiguration() { + try { + final String rulesetPath = JNLPRuntime.getConfiguration().getProperty(KEY_DEPLOYMENT_RULE_SET); + final DeploymentRulesSetFile rulesSetFile = new DeploymentRulesSetFile(rulesetPath); + return rulesSetFile.parseDeploymentRuleSet(); + } catch (ParseException e) { + LOG.error("Please Check config property " + KEY_DEPLOYMENT_RULE_SET + ". This should point to a valid DeploymentRuleSet jar file: ", e); + return Collections.emptyList(); + } } - - /** - * isUrlInDeploymentRuleSetUrl - * Adding by DJ 3/2/2021 to add DeploymentRuleSet functionality - * @param url - * @param whiteList - * @return - */ - public static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List deploymentRuleSetList) { + public static boolean isUrlInDeploymentRuleSet(final URL url) { Assert.requireNonNull(url, "url"); - Assert.requireNonNull(deploymentRuleSetList, "whiteList"); + return isUrlInDeploymentRuleSetUrl(url, getApplicationLinkDeploymentRuleSetList()); + } + private static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List deploymentRuleSetList) { if (deploymentRuleSetList.isEmpty()) { return false; // empty deploymentRuleSetList == allow none. Nothing is whitelisted } - - - return deploymentRuleSetList.stream().anyMatch(wlEntry -> wlEntry.matches(url.getHost())); } - - } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java new file mode 100644 index 000000000..01bd81e9f --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java @@ -0,0 +1,37 @@ +package net.sourceforge.jnlp.deploymentrules; + +/** + * Action object of Rule from the ruleset file + * Stores the attributes value from id tag permission and version. + * If permission is run, then location which is the url whitelisted is permitted to be accessible. + */ +class XmlAction { + + private String permission; + private String version; + private String message; + + public String getPermission() { + return permission; + } + + public void setPermission(final String permission) { + this.permission = permission; + } + + public String getVersion() { + return version; + } + + public void setVersion(final String version) { + this.version = version; + } + + public String getMessage() { + return message; + } + + public void setMessage(final String message) { + this.message = message; + } +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java new file mode 100644 index 000000000..9609c79ad --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java @@ -0,0 +1,20 @@ +package net.sourceforge.jnlp.deploymentrules; + +/** + * Certificate object of Rule from the ruleset file + * Stores the attributes value from action tag hash. + * This is class is rarely used yet and can be extended when a + * UI component to display the entire ruleset.xml file and edit it will be enhanced + */ +class XmlCertificate { + + private String hash; + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java new file mode 100644 index 000000000..9125bd0c2 --- /dev/null +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java @@ -0,0 +1,31 @@ +package net.sourceforge.jnlp.deploymentrules; + +class XmlRule { + private String location; + private XmlCertificate certificate; + private XmlAction action; + + public String getLocation() { + return location; + } + + public void setLocation(final String location) { + this.location = location; + } + + public XmlCertificate getCertificate() { + return certificate; + } + + public void setCertificate(final XmlCertificate certificate) { + this.certificate = certificate; + } + + public XmlAction getAction() { + return action; + } + + public void setAction(final XmlAction action) { + this.action = action; + } +} diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties deleted file mode 100644 index 5837a4c25..000000000 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/jaxb.properties +++ /dev/null @@ -1 +0,0 @@ -javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory \ No newline at end of file From b98b21cb159ae3d8acea45fbfbf762340938b053 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Tue, 31 Aug 2021 00:20:57 +0200 Subject: [PATCH 04/10] make disjuction more explicit --- .../icedteaweb/resources/ResourceHandler.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java index 3f8833e23..ccaf7ed4d 100644 --- a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java @@ -92,13 +92,9 @@ private static Resource processResource(final Resource resource) { } private static void validateWithWhitelist(URL url) { - // Validate with whitelist specified in deployment.properties. localhost is considered valid. - if (isUrlInWhitelist(url, getApplicationUrlWhiteList())) { - return; - } - - // Validate with whitelist specified in DeploymentRuleSet.jar localhost is considered valid. - if (isUrlInDeploymentRuleSet(url)) { + // Validate with whitelist specified in deployment.properties or deployment ruleset. + // localhost is considered valid. + if (isUrlInWhitelist(url, getApplicationUrlWhiteList()) || isUrlInDeploymentRuleSet(url)) { return; } From ee650217f34040a9e5074196be7cafcdb9b5cddd Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 13 Sep 2021 10:12:40 +0200 Subject: [PATCH 05/10] remove artifical root as the ruleset has a dedicated root --- .../DeploymentRuleSetParser.java | 17 +++-------------- .../deploymentrules/DeploymentRulesSetFile.java | 13 +------------ 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java index c3bf8eac0..06ed338ce 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java @@ -16,7 +16,6 @@ */ class DeploymentRuleSetParser { - private static final String DEPLOYMENT_RULESET_ROOT_ELEMENT = "deploymentRulesSet"; private static final String ID_ELEMENT = "id"; private static final String RULE_SET_ELEMENT = "ruleset"; @@ -42,20 +41,10 @@ class DeploymentRuleSetParser { */ public List getRules(final XmlNode root) throws ParseException { // ensure it's a DeploymentRuleSet node - if (root == null || !root.getNodeName().equals(DEPLOYMENT_RULESET_ROOT_ELEMENT)) { - throw new ParseException("Root element is not a DeploymentRuleset element."); - } - return processXmlParsingOfRuleSet(root); - } - - private List processXmlParsingOfRuleSet(final XmlNode parent) throws ParseException { - final XmlNode child = parent.getFirstChild(); - final boolean isRuleSetElement = child.getNodeName().equals(RULE_SET_ELEMENT); - if (isRuleSetElement) { - return getRulesFromRuleset(child); - } else { - return new ArrayList<>(); + if (root == null || !root.getNodeName().equals(RULE_SET_ELEMENT)) { + throw new ParseException("Root element is not a <" + RULE_SET_ELEMENT + "> element."); } + return getRulesFromRuleset(root); } private List getRulesFromRuleset(final XmlNode parent) throws ParseException { diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java index dc9569c08..affac2743 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java @@ -34,8 +34,7 @@ public DeploymentRulesSetFile(String rulesetPath) { public List parseDeploymentRuleSet() throws ParseException { final File rulesetJarFile = new File(rulesetPath); if (rulesetJarFile.exists()) { - final String rawContent = getRulesetXmlContent(rulesetJarFile); - final String content = wrapInArtificialRoot(rawContent); + final String content = getRulesetXmlContent(rulesetJarFile); final XmlNode root = parseXml(content); final List rules = extractRules(root); @@ -63,16 +62,6 @@ private String getRulesetXmlContent(File rulesetJarFile) throws ParseException { } } - private String wrapInArtificialRoot(String content) throws ParseException { - final int idx = content.indexOf(""); - } - final String prefix = content.substring(0, idx); - final String fullXml = content.substring(idx); - return prefix + "" + fullXml + ""; - } - private XmlNode parseXml(String content) throws ParseException { try { final InputStream is = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); From 981dff695a73ad26eb9c901958e73fc2119ff647 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 13 Sep 2021 10:27:36 +0200 Subject: [PATCH 06/10] rename classes and add some javadoc --- .../{XmlAction.java => Action.java} | 2 +- .../{XmlCertificate.java => Certificate.java} | 2 +- .../{XmlRule.java => Rule.java} | 17 ++++++----- ...tRulesSetFile.java => RulesetJarFile.java} | 12 ++++---- ...tRuleSetParser.java => RulesetParser.java} | 30 +++++++++++++------ .../UrlDeploymentRulesSetUtils.java | 2 +- 6 files changed, 40 insertions(+), 25 deletions(-) rename core/src/main/java/net/sourceforge/jnlp/deploymentrules/{XmlAction.java => Action.java} (97%) rename core/src/main/java/net/sourceforge/jnlp/deploymentrules/{XmlCertificate.java => Certificate.java} (95%) rename core/src/main/java/net/sourceforge/jnlp/deploymentrules/{XmlRule.java => Rule.java} (50%) rename core/src/main/java/net/sourceforge/jnlp/deploymentrules/{DeploymentRulesSetFile.java => RulesetJarFile.java} (89%) rename core/src/main/java/net/sourceforge/jnlp/deploymentrules/{DeploymentRuleSetParser.java => RulesetParser.java} (76%) diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java similarity index 97% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java rename to core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java index 01bd81e9f..9fcb24230 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlAction.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java @@ -5,7 +5,7 @@ * Stores the attributes value from id tag permission and version. * If permission is run, then location which is the url whitelisted is permitted to be accessible. */ -class XmlAction { +class Action { private String permission; private String version; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java similarity index 95% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java rename to core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java index 9609c79ad..aea10b0b1 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlCertificate.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java @@ -6,7 +6,7 @@ * This is class is rarely used yet and can be extended when a * UI component to display the entire ruleset.xml file and edit it will be enhanced */ -class XmlCertificate { +class Certificate { private String hash; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java similarity index 50% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java rename to core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java index 9125bd0c2..45447c92f 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/XmlRule.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java @@ -1,9 +1,12 @@ package net.sourceforge.jnlp.deploymentrules; -class XmlRule { +/** + * See https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_rules.html#CIHDCEDE + */ +class Rule { private String location; - private XmlCertificate certificate; - private XmlAction action; + private Certificate certificate; + private Action action; public String getLocation() { return location; @@ -13,19 +16,19 @@ public void setLocation(final String location) { this.location = location; } - public XmlCertificate getCertificate() { + public Certificate getCertificate() { return certificate; } - public void setCertificate(final XmlCertificate certificate) { + public void setCertificate(final Certificate certificate) { this.certificate = certificate; } - public XmlAction getAction() { + public Action getAction() { return action; } - public void setAction(final XmlAction action) { + public void setAction(final Action action) { this.action = action; } } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java similarity index 89% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java rename to core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java index affac2743..4f427a5c8 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRulesSetFile.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java @@ -20,14 +20,14 @@ import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.MALFORMED; -class DeploymentRulesSetFile { +class RulesetJarFile { private static final String RULESET_XML = "ruleset.xml"; private static final String RUN = "run"; private final String rulesetPath; - public DeploymentRulesSetFile(String rulesetPath) { + public RulesetJarFile(String rulesetPath) { this.rulesetPath = rulesetPath; } @@ -36,11 +36,11 @@ public List parseDeploymentRuleSet() throws ParseException { if (rulesetJarFile.exists()) { final String content = getRulesetXmlContent(rulesetJarFile); final XmlNode root = parseXml(content); - final List rules = extractRules(root); + final List rules = extractRules(root); return rules.stream() .filter(rule -> Objects.equals(rule.getAction().getPermission(), RUN)) - .map(XmlRule::getLocation) + .map(Rule::getLocation) .collect(Collectors.toList()); } return Collections.emptyList(); @@ -72,9 +72,9 @@ private XmlNode parseXml(String content) throws ParseException { } } - private List extractRules(XmlNode root) throws ParseException { + private List extractRules(XmlNode root) throws ParseException { try { - return new DeploymentRuleSetParser().getRules(root); + return new RulesetParser().getRules(root); } catch (ParseException e) { throw new ParseException("Could not initialize the DeploymentRuleSetParser" + e.getMessage()); } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetParser.java similarity index 76% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java rename to core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetParser.java index 06ed338ce..19015d466 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/DeploymentRuleSetParser.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetParser.java @@ -13,8 +13,11 @@ /** * Contains methods to parse an XML document into a DeploymentRuleSetFile. * Implements JNLP specification version 1.0. + * + * See DTD: https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_rules.html#CIHBAJBB + * See: https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_rules.html#CIHGIDJI */ -class DeploymentRuleSetParser { +class RulesetParser { private static final String ID_ELEMENT = "id"; private static final String RULE_SET_ELEMENT = "ruleset"; @@ -39,7 +42,7 @@ class DeploymentRuleSetParser { * @param root the root XmlNode * @throws ParseException if the DeploymentRuleSet string is invalid */ - public List getRules(final XmlNode root) throws ParseException { + public List getRules(final XmlNode root) throws ParseException { // ensure it's a DeploymentRuleSet node if (root == null || !root.getNodeName().equals(RULE_SET_ELEMENT)) { throw new ParseException("Root element is not a <" + RULE_SET_ELEMENT + "> element."); @@ -47,24 +50,33 @@ public List getRules(final XmlNode root) throws ParseException { return getRulesFromRuleset(root); } - private List getRulesFromRuleset(final XmlNode parent) throws ParseException { - final List result = new ArrayList<>(); + /** + * Extracts rules from the xml tree. + * The {@code version} attribute of the {@code ruleset} element is ignored + * since there will be no new version of the schema in the future. + * + * @param parent the root node + * @return all rules found. + * @throws ParseException if the xml is not valid. + */ + private List getRulesFromRuleset(final XmlNode parent) throws ParseException { + final List result = new ArrayList<>(); final XmlNode[] rules = getChildNodes(parent, RULE_ELEMENT); - // ensure that there are at least one information section present if (rules.length == 0) { throw new ParseException("No rule element specified."); } + for (final XmlNode rule : rules) { result.add(getRule(rule)); } return result; } - private XmlRule getRule(final XmlNode node) { + private Rule getRule(final XmlNode node) { // create rules - final XmlRule rule = new XmlRule(); + final Rule rule = new Rule(); // step through the elements // first populate the id tag attribute @@ -73,7 +85,7 @@ private XmlRule getRule(final XmlNode node) { //certificate element final String hash = getAttribute(potentialIdPart, HASH_ATTRIBUTE, null); //id element - final XmlCertificate certs = new XmlCertificate(); + final Certificate certs = new Certificate(); certs.setHash(hash); final String location = getAttribute(potentialIdPart, LOCATION_ATTRIBUTE, null); @@ -84,7 +96,7 @@ private XmlRule getRule(final XmlNode node) { // next populate the action tag attribute. final XmlNode potentialActionPart = potentialIdPart.getNextSibling(); if (potentialActionPart.getNodeName().equals(ACTION_ELEMENT)) { - final XmlAction action = new XmlAction(); + final Action action = new Action(); //action element final String permission = getAttribute(potentialActionPart, PERMISSION_ATTRIBUTE, null); final String version = getAttribute(potentialActionPart, VERSION_ATTRIBUTE, null); diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java index 68ebf4020..5c73efcb7 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -28,7 +28,7 @@ private static List getApplicationLinkDeploymentRuleSetList() { private static List loadDeploymentRuleSetLinksFromConfiguration() { try { final String rulesetPath = JNLPRuntime.getConfiguration().getProperty(KEY_DEPLOYMENT_RULE_SET); - final DeploymentRulesSetFile rulesSetFile = new DeploymentRulesSetFile(rulesetPath); + final RulesetJarFile rulesSetFile = new RulesetJarFile(rulesetPath); return rulesSetFile.parseDeploymentRuleSet(); } catch (ParseException e) { LOG.error("Please Check config property " + KEY_DEPLOYMENT_RULE_SET + ". This should point to a valid DeploymentRuleSet jar file: ", e); From 8bbb7c909c41378eae30b046be623ea7cc915dd1 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 13 Sep 2021 11:14:01 +0200 Subject: [PATCH 07/10] re-arange the code to better follow single responsability principle --- .../jnlp/deploymentrules/Rule.java | 8 +++ .../jnlp/deploymentrules/RulesetJarFile.java | 38 ++++--------- .../UrlDeploymentRulesSetUtils.java | 55 ++++++++++++------- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java index 45447c92f..2e4113004 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java @@ -1,5 +1,7 @@ package net.sourceforge.jnlp.deploymentrules; +import java.net.URL; + /** * See https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_rules.html#CIHDCEDE */ @@ -31,4 +33,10 @@ public Action getAction() { public void setAction(final Action action) { this.action = action; } + + public boolean matches(URL url) { + // TODO: implement according to https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_rules.html#CIHDCEDE + // Maybe take some inspiration from ParsedWhitelistEntry.matches(URL) + return false; + } } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java index 4f427a5c8..c1c3f1450 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java @@ -11,42 +11,33 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; -import java.util.Objects; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.stream.Collectors; import static net.adoptopenjdk.icedteaweb.xmlparser.ParserType.MALFORMED; class RulesetJarFile { private static final String RULESET_XML = "ruleset.xml"; - private static final String RUN = "run"; - private final String rulesetPath; + private final File jarFile; public RulesetJarFile(String rulesetPath) { - this.rulesetPath = rulesetPath; + jarFile = new File(rulesetPath); } - public List parseDeploymentRuleSet() throws ParseException { - final File rulesetJarFile = new File(rulesetPath); - if (rulesetJarFile.exists()) { - final String content = getRulesetXmlContent(rulesetJarFile); - final XmlNode root = parseXml(content); - final List rules = extractRules(root); + public XmlNode getRulesetXml() throws ParseException { + final File rulesetJarFile = jarFile; - return rules.stream() - .filter(rule -> Objects.equals(rule.getAction().getPermission(), RUN)) - .map(Rule::getLocation) - .collect(Collectors.toList()); + if (!rulesetJarFile.exists()) { + throw new RuntimeException("Ruleset jar file is missing"); } - return Collections.emptyList(); + + final String content = getRulesetXmlContent(rulesetJarFile); + return parseXml(content); } - private String getRulesetXmlContent(File rulesetJarFile) throws ParseException { + public String getRulesetXmlContent(File rulesetJarFile) throws ParseException { try { final JarFile file = new JarFile(rulesetJarFile); final JarEntry entry = file.getJarEntry(RULESET_XML); @@ -72,12 +63,7 @@ private XmlNode parseXml(String content) throws ParseException { } } - private List extractRules(XmlNode root) throws ParseException { - try { - return new RulesetParser().getRules(root); - } catch (ParseException e) { - throw new ParseException("Could not initialize the DeploymentRuleSetParser" + e.getMessage()); - } + public boolean isNotPresent() { + return !jarFile.exists(); } - } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java index 5c73efcb7..6bcb0452a 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -4,47 +4,64 @@ import net.adoptopenjdk.icedteaweb.logging.Logger; import net.adoptopenjdk.icedteaweb.logging.LoggerFactory; import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; +import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.IpUtil; import java.net.URL; -import java.util.Collections; import java.util.List; +import static java.util.Collections.emptyList; import static net.sourceforge.jnlp.config.ConfigurationConstants.KEY_DEPLOYMENT_RULE_SET; public class UrlDeploymentRulesSetUtils { private static final Logger LOG = LoggerFactory.getLogger(UrlDeploymentRulesSetUtils.class); - private static List applicationDeploymentRuleSetList; + private static List deploymentRules; - private static List getApplicationLinkDeploymentRuleSetList() { - if (applicationDeploymentRuleSetList == null) { - applicationDeploymentRuleSetList = loadDeploymentRuleSetLinksFromConfiguration(); + public static boolean isUrlInDeploymentRuleSet(final URL url) { + Assert.requireNonNull(url, "url"); + return isUrlInDeploymentRuleSetUrl(url, getApplicationLinkDeploymentRuleSetList()); + } + + private static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List deploymentRuleSetList) { + if (deploymentRuleSetList.isEmpty()) { + return true; // empty deploymentRuleset == allow all connection + } + + if (IpUtil.isLocalhostOrLoopback(url)) { + return true; // localhost need not be in whitelist } - return applicationDeploymentRuleSetList; + + return deploymentRuleSetList.stream().anyMatch(wlEntry -> wlEntry.matches(url)); } - private static List loadDeploymentRuleSetLinksFromConfiguration() { + private static List getApplicationLinkDeploymentRuleSetList() { + if (deploymentRules == null) { + deploymentRules = loadDeploymentRuleSetLinksFromConfiguration(); + } + return deploymentRules; + } + + private static List loadDeploymentRuleSetLinksFromConfiguration() { try { final String rulesetPath = JNLPRuntime.getConfiguration().getProperty(KEY_DEPLOYMENT_RULE_SET); - final RulesetJarFile rulesSetFile = new RulesetJarFile(rulesetPath); - return rulesSetFile.parseDeploymentRuleSet(); + return parseDeploymentRuleSet(rulesetPath); } catch (ParseException e) { LOG.error("Please Check config property " + KEY_DEPLOYMENT_RULE_SET + ". This should point to a valid DeploymentRuleSet jar file: ", e); - return Collections.emptyList(); + return emptyList(); } } - public static boolean isUrlInDeploymentRuleSet(final URL url) { - Assert.requireNonNull(url, "url"); - return isUrlInDeploymentRuleSetUrl(url, getApplicationLinkDeploymentRuleSetList()); - } - - private static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List deploymentRuleSetList) { - if (deploymentRuleSetList.isEmpty()) { - return false; // empty deploymentRuleSetList == allow none. Nothing is whitelisted + private static List parseDeploymentRuleSet(String rulesetPath) throws ParseException { + final RulesetJarFile rulesetJarFile = new RulesetJarFile(rulesetPath); + if (rulesetJarFile.isNotPresent()) { + return emptyList(); } - return deploymentRuleSetList.stream().anyMatch(wlEntry -> wlEntry.matches(url.getHost())); + + final XmlNode root = rulesetJarFile.getRulesetXml(); + final RulesetParser parser = new RulesetParser(); + return parser.getRules(root); } } From af574af75da378e0f0759e829296ba96a6e42799 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 4 Oct 2021 21:42:49 +0200 Subject: [PATCH 08/10] only consider the first rule which matches --- .../java/net/sourceforge/jnlp/deploymentrules/Rule.java | 5 +++++ .../jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java index 2e4113004..86369eb94 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java @@ -39,4 +39,9 @@ public boolean matches(URL url) { // Maybe take some inspiration from ParsedWhitelistEntry.matches(URL) return false; } + + public boolean isAllowedToRun() { + // TODO: return true if this is allowed to run according to the action + return false; + } } diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java index 6bcb0452a..0f5f804f1 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java +++ b/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -34,7 +34,11 @@ private static boolean isUrlInDeploymentRuleSetUrl(final URL url, final List wlEntry.matches(url)); + return deploymentRuleSetList.stream() + .filter(wlEntry -> wlEntry.matches(url)) + .findFirst() + .map(Rule::isAllowedToRun) + .orElse(Boolean.TRUE); } private static List getApplicationLinkDeploymentRuleSetList() { From 5ed6644d8435e49384a7188e373adc12c527d4f8 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 4 Oct 2021 21:52:00 +0200 Subject: [PATCH 09/10] move deployment ruleset code to new package --- .../icedteaweb}/deploymentrules/Action.java | 2 +- .../icedteaweb}/deploymentrules/Certificate.java | 2 +- .../icedteaweb}/deploymentrules/Rule.java | 2 +- .../icedteaweb}/deploymentrules/RulesetJarFile.java | 2 +- .../icedteaweb}/deploymentrules/RulesetParser.java | 2 +- .../deploymentrules/UrlDeploymentRulesSetUtils.java | 2 +- .../adoptopenjdk/icedteaweb/resources/ResourceHandler.java | 4 +--- 7 files changed, 7 insertions(+), 9 deletions(-) rename core/src/main/java/net/{sourceforge/jnlp => adoptopenjdk/icedteaweb}/deploymentrules/Action.java (93%) rename core/src/main/java/net/{sourceforge/jnlp => adoptopenjdk/icedteaweb}/deploymentrules/Certificate.java (89%) rename core/src/main/java/net/{sourceforge/jnlp => adoptopenjdk/icedteaweb}/deploymentrules/Rule.java (95%) rename core/src/main/java/net/{sourceforge/jnlp => adoptopenjdk/icedteaweb}/deploymentrules/RulesetJarFile.java (97%) rename core/src/main/java/net/{sourceforge/jnlp => adoptopenjdk/icedteaweb}/deploymentrules/RulesetParser.java (98%) rename core/src/main/java/net/{sourceforge/jnlp => adoptopenjdk/icedteaweb}/deploymentrules/UrlDeploymentRulesSetUtils.java (98%) diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Action.java similarity index 93% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java rename to core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Action.java index 9fcb24230..531a0ae9b 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Action.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Action.java @@ -1,4 +1,4 @@ -package net.sourceforge.jnlp.deploymentrules; +package net.adoptopenjdk.icedteaweb.deploymentrules; /** * Action object of Rule from the ruleset file diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Certificate.java similarity index 89% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java rename to core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Certificate.java index aea10b0b1..5282ccd60 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Certificate.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Certificate.java @@ -1,4 +1,4 @@ -package net.sourceforge.jnlp.deploymentrules; +package net.adoptopenjdk.icedteaweb.deploymentrules; /** * Certificate object of Rule from the ruleset file diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java similarity index 95% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java rename to core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java index 86369eb94..ed5f7cc9e 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/Rule.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java @@ -1,4 +1,4 @@ -package net.sourceforge.jnlp.deploymentrules; +package net.adoptopenjdk.icedteaweb.deploymentrules; import java.net.URL; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/RulesetJarFile.java similarity index 97% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java rename to core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/RulesetJarFile.java index c1c3f1450..3302b5c08 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetJarFile.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/RulesetJarFile.java @@ -1,4 +1,4 @@ -package net.sourceforge.jnlp.deploymentrules; +package net.adoptopenjdk.icedteaweb.deploymentrules; import net.adoptopenjdk.icedteaweb.io.IOUtils; import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetParser.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/RulesetParser.java similarity index 98% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetParser.java rename to core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/RulesetParser.java index 19015d466..f477afca4 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/RulesetParser.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/RulesetParser.java @@ -1,4 +1,4 @@ -package net.sourceforge.jnlp.deploymentrules; +package net.adoptopenjdk.icedteaweb.deploymentrules; import net.adoptopenjdk.icedteaweb.xmlparser.ParseException; import net.adoptopenjdk.icedteaweb.xmlparser.XmlNode; diff --git a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/UrlDeploymentRulesSetUtils.java similarity index 98% rename from core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java rename to core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/UrlDeploymentRulesSetUtils.java index 0f5f804f1..c507ae5a8 100644 --- a/core/src/main/java/net/sourceforge/jnlp/deploymentrules/UrlDeploymentRulesSetUtils.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/UrlDeploymentRulesSetUtils.java @@ -1,4 +1,4 @@ -package net.sourceforge.jnlp.deploymentrules; +package net.adoptopenjdk.icedteaweb.deploymentrules; import net.adoptopenjdk.icedteaweb.Assert; import net.adoptopenjdk.icedteaweb.logging.Logger; diff --git a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java index ccaf7ed4d..46ff471fa 100644 --- a/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/resources/ResourceHandler.java @@ -9,8 +9,6 @@ import net.adoptopenjdk.icedteaweb.resources.initializer.InitializationResult; import net.adoptopenjdk.icedteaweb.resources.initializer.ResourceInitializer; import net.sourceforge.jnlp.runtime.JNLPRuntime; -import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils; -import net.sourceforge.jnlp.deploymentrules.UrlDeploymentRulesSetUtils; import java.io.File; import java.net.URL; @@ -18,10 +16,10 @@ import java.util.concurrent.Executor; import java.util.concurrent.Future; +import static net.adoptopenjdk.icedteaweb.deploymentrules.UrlDeploymentRulesSetUtils.isUrlInDeploymentRuleSet; import static net.adoptopenjdk.icedteaweb.resources.ResourceStatus.DOWNLOADED; import static net.adoptopenjdk.icedteaweb.resources.ResourceStatus.ERROR; import static net.sourceforge.jnlp.cache.CacheUtil.isNonCacheable; -import static net.sourceforge.jnlp.deploymentrules.UrlDeploymentRulesSetUtils.isUrlInDeploymentRuleSet; import static net.sourceforge.jnlp.util.UrlUtils.FILE_PROTOCOL; import static net.sourceforge.jnlp.util.UrlUtils.decodeUrlQuietly; import static net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils.getApplicationUrlWhiteList; From bee8b2b084c1d3500d145e7b8029929587b79501 Mon Sep 17 00:00:00 2001 From: Stephan Classen Date: Mon, 4 Oct 2021 22:14:02 +0200 Subject: [PATCH 10/10] update documentation url --- .../java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java index ed5f7cc9e..4057882a7 100644 --- a/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java +++ b/core/src/main/java/net/adoptopenjdk/icedteaweb/deploymentrules/Rule.java @@ -35,7 +35,7 @@ public void setAction(final Action action) { } public boolean matches(URL url) { - // TODO: implement according to https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_rules.html#CIHDCEDE + // TODO: implement according to https://docs.oracle.com/javase/10/deploy/deployment-rule-set.htm#GUID-413F29CF-81B5-4154-9C52-22D993819C2B // Maybe take some inspiration from ParsedWhitelistEntry.matches(URL) return false; }