changeset 1266:2b1af623e3a8

All connection restrictions now consider also port
author Jiri Vanek <jvanek@redhat.com>
date Thu, 08 Oct 2015 12:11:49 +0200
parents cbc3174bed98
children 3049b4003737
files ChangeLog NEWS netx/net/sourceforge/jnlp/Parser.java netx/net/sourceforge/jnlp/PluginBridge.java netx/net/sourceforge/jnlp/SecurityDesc.java netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java netx/net/sourceforge/jnlp/util/UrlUtils.java plugin/icedteanp/java/sun/applet/PluginAppletViewer.java tests/netx/unit/net/sourceforge/jnlp/SecurityDescTest.java tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java
diffstat 10 files changed, 96 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Oct 02 15:35:30 2015 +0200
+++ b/ChangeLog	Thu Oct 08 12:11:49 2015 +0200
@@ -1,3 +1,20 @@
+2015-10-07  Jiri Vanek  <jvanek@redhat.com>
+
+	All connection restrictions now consider also port
+	* NEWS: mentioned restriction about ports
+	* netx/net/sourceforge/jnlp/SecurityDesc.java: downloadHost redeclared to URL
+	and made final. All set/gets adapted
+	* netx/net/sourceforge/jnlp/Parser.java: (base) passes url to SecurityDesc
+	* netx/net/sourceforge/jnlp/PluginBridge.java: (PluginBridge) same
+	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: same
+	* plugin/icedteanp/java/sun/applet/PluginAppletViewer.java: (getApplet)
+	(getApplets) same
+	* netx/net/sourceforge/jnlp/util/UrlUtils.java:	added methods sanitizePort and
+	getPort, which always returns port. If no port goes in, default port is going
+	out. Added getHostAndPort which returns host also with port.
+	* tests/netx/unit/net/sourceforge/jnlp/SecurityDescTest.java: adapted to new api
+	* tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java: tested new methods
+	
 2015-10-02  Jiri Vanek  <jvanek@redhat.com>
 
 	Fixed possible segfault during files on and debug on
--- a/NEWS	Fri Oct 02 15:35:30 2015 +0200
+++ b/NEWS	Thu Oct 08 12:11:49 2015 +0200
@@ -9,6 +9,7 @@
 CVE-XXXX-YYYY: http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY
 
 New in release 1.6.2 (YYYY-MM-DD):
+* all connection restrictions now consider also port
 
 New in release 1.6.1 (2015-09-11):
 * Enabled Entry-Point attribute check
--- a/netx/net/sourceforge/jnlp/Parser.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/netx/net/sourceforge/jnlp/Parser.java	Thu Oct 08 12:11:49 2015 +0200
@@ -622,7 +622,7 @@
         }
 
         if (base != null) {
-            return new SecurityDesc(file, requestedPermissionLevel, type, base.getHost());
+            return new SecurityDesc(file, requestedPermissionLevel, type, base);
         } else {
             return new SecurityDesc(file, requestedPermissionLevel, type, null);
         }
--- a/netx/net/sourceforge/jnlp/PluginBridge.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/netx/net/sourceforge/jnlp/PluginBridge.java	Thu Oct 08 12:11:49 2015 +0200
@@ -224,7 +224,7 @@
 
         if (main.endsWith(".class")) //single class file only
             security = new SecurityDesc(this, SecurityDesc.SANDBOX_PERMISSIONS,
-                                        codebase.getHost());
+                                        codebase);
         else
             security = null;
 
--- a/netx/net/sourceforge/jnlp/SecurityDesc.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/netx/net/sourceforge/jnlp/SecurityDesc.java	Thu Oct 08 12:11:49 2015 +0200
@@ -22,6 +22,7 @@
 import java.net.SocketPermission;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.security.AllPermission;
 import java.security.CodeSource;
 import java.security.Permission;
@@ -33,6 +34,7 @@
 
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.util.UrlUtils;
 import net.sourceforge.jnlp.util.logging.OutputController;
 
 /**
@@ -132,7 +134,7 @@
     private Object type;
 
     /** the download host */
-    private String downloadHost;
+    final private URL downloadHost;
 
     /** whether sandbox applications should get the show window without banner permission */
     private final boolean grantAwtPermissions;
@@ -256,7 +258,7 @@
      * @param type the type of security
      * @param downloadHost the download host (can always connect to)
      */
-    public SecurityDesc(JNLPFile file, RequestedPermissionLevel requestedPermissionLevel, Object type, String downloadHost) {
+    public SecurityDesc(JNLPFile file, RequestedPermissionLevel requestedPermissionLevel, Object type, URL downloadHost) {
         if (file == null) {
             throw new NullJnlpFileException();
         }
@@ -278,7 +280,7 @@
      * @param type the type of security
      * @param downloadHost the download host (can always connect to)
      */
-    public SecurityDesc(JNLPFile file, Object type, String downloadHost) {
+    public SecurityDesc(JNLPFile file, Object type, URL downloadHost) {
         this(file, RequestedPermissionLevel.NONE, type, downloadHost);
     }
 
@@ -375,9 +377,10 @@
             }
         }
 
-        if (downloadHost != null && downloadHost.length() > 0)
-            permissions.add(new SocketPermission(downloadHost,
-                                                 "connect, accept"));
+        if (downloadHost != null && downloadHost.getHost().length() > 0) {
+            permissions.add(new SocketPermission(UrlUtils.getHostAndPort(downloadHost),
+                    "connect, accept"));
+        }
 
         final Collection<Permission> urlPermissions = getUrlPermissions();
         for (final Permission permission : urlPermissions) {
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Thu Oct 08 12:11:49 2015 +0200
@@ -318,7 +318,7 @@
 
     private void setSecurity() throws LaunchException {
         URL codebase = UrlUtils.guessCodeBase(file);
-        this.security = securityDelegate.getClassLoaderSecurity(codebase.getHost());
+        this.security = securityDelegate.getClassLoaderSecurity(codebase);
     }
 
     /**
@@ -754,7 +754,7 @@
             validJars.add(jarDesc);
             final URL codebase = getJnlpFileCodebase();
 
-            final SecurityDesc jarSecurity = securityDelegate.getCodebaseSecurityDesc(jarDesc, codebase.getHost());
+            final SecurityDesc jarSecurity = securityDelegate.getCodebaseSecurityDesc(jarDesc, codebase);
             if (jarSecurity.getSecurityType().equals(SecurityDesc.SANDBOX_PERMISSIONS)) {
                 containsUnsignedJar = true;
             } else {
@@ -778,7 +778,7 @@
 
         for (JARDesc jarDesc : validJars) {
             final URL codebase = getJnlpFileCodebase();
-            final SecurityDesc jarSecurity = securityDelegate.getCodebaseSecurityDesc(jarDesc, codebase.getHost());
+            final SecurityDesc jarSecurity = securityDelegate.getCodebaseSecurityDesc(jarDesc, codebase);
             jarLocationSecurityMap.put(jarDesc.getLocation(), jarSecurity);
         }
 
@@ -1188,7 +1188,7 @@
 
             // Class from host X should be allowed to connect to host X
             if (cs.getLocation() != null && cs.getLocation().getHost().length() > 0)
-                result.add(new SocketPermission(cs.getLocation().getHost(),
+                result.add(new SocketPermission(UrlUtils.getHostAndPort(cs.getLocation()),
                         "connect, accept"));
 
             return result;
@@ -1302,7 +1302,7 @@
                                             codebase = file.getResources().getMainJAR().getLocation();
                                         }
                                         
-                                        final SecurityDesc jarSecurity = securityDelegate.getJarPermissions(codebase.getHost());
+                                        final SecurityDesc jarSecurity = securityDelegate.getJarPermissions(codebase);
                                         
                                         try {
                                             URL fileURL = new URL("file://" + extractedJarLocation);
@@ -1630,7 +1630,7 @@
 
                     checkTrustWithUser();
 
-                    final SecurityDesc security = securityDelegate.getJarPermissions(file.getCodeBase().getHost());
+                    final SecurityDesc security = securityDelegate.getJarPermissions(file.getCodeBase());
 
                     jarLocationSecurityMap.put(remoteURL, security);
 
@@ -2249,7 +2249,7 @@
         // Permissions for all remote hosting urls
         synchronized (jarLocationSecurityMap) {
             for (URL u : jarLocationSecurityMap.keySet()) {
-                permissions.add(new SocketPermission(u.getHost(),
+                    permissions.add(new SocketPermission(UrlUtils.getHostAndPort(u),
                         "connect, accept"));
             }
         }
@@ -2257,7 +2257,7 @@
         // Permissions for codebase urls (if there is a loader)
         if (codeBaseLoader != null) {
             for (URL u : codeBaseLoader.getURLs()) {
-                permissions.add(new SocketPermission(u.getHost(),
+                permissions.add(new SocketPermission(UrlUtils.getHostAndPort(u),
                         "connect, accept"));
             }
         }
@@ -2290,11 +2290,11 @@
 
         public boolean userPromptedForSandbox();
 
-        public SecurityDesc getCodebaseSecurityDesc(final JARDesc jarDesc, final String codebaseHost);
-
-        public SecurityDesc getClassLoaderSecurity(final String codebaseHost) throws LaunchException;
-
-        public SecurityDesc getJarPermissions(final String codebaseHost);
+        public SecurityDesc getCodebaseSecurityDesc(final JARDesc jarDesc, final URL codebaseHost);
+
+        public SecurityDesc getClassLoaderSecurity(final URL codebaseHost) throws LaunchException;
+
+        public SecurityDesc getJarPermissions(final URL codebaseHost);
 
         public void promptUserOnPartialSigning() throws LaunchException;
 
@@ -2331,7 +2331,7 @@
         }
 
         @Override
-        public SecurityDesc getCodebaseSecurityDesc(final JARDesc jarDesc, final String codebaseHost) {
+        public SecurityDesc getCodebaseSecurityDesc(final JARDesc jarDesc, final URL codebaseHost) {
             if (runInSandbox) {
                 return new SecurityDesc(classLoader.file,
                         SecurityDesc.SANDBOX_PERMISSIONS,
@@ -2361,7 +2361,7 @@
         }
 
         @Override
-        public SecurityDesc getClassLoaderSecurity(final String codebaseHost) throws LaunchException {
+        public SecurityDesc getClassLoaderSecurity(final URL codebaseHost) throws LaunchException {
             if (isPluginApplet()) {
                 if (!runInSandbox && classLoader.getSigning()) {
                     return new SecurityDesc(classLoader.file,
@@ -2403,7 +2403,7 @@
         }
 
         @Override
-        public SecurityDesc getJarPermissions(final String codebaseHost) {
+        public SecurityDesc getJarPermissions(final URL codebaseHost) {
             if (!runInSandbox && classLoader.jcv.isFullySigned()) {
                 // Already trust application, nested jar should be given
                 return new SecurityDesc(classLoader.file,
--- a/netx/net/sourceforge/jnlp/util/UrlUtils.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/netx/net/sourceforge/jnlp/util/UrlUtils.java	Thu Oct 08 12:11:49 2015 +0200
@@ -332,7 +332,19 @@
         }
     }
     
+    public static int getSanitizedPort(final URL u) {
+        if (u.getPort() < 0) {
+            return u.getDefaultPort();
+        }
+        return u.getPort();
+    }
 
+    public static int getPort(final URL url) {
+        return getSanitizedPort(url);
+    }
 
+    public static String getHostAndPort(final URL url) {
+        return url.getHost() + ":" + getSanitizedPort(url);
+    }
 
 }
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Thu Oct 08 12:11:49 2015 +0200
@@ -113,6 +113,7 @@
 import net.sourceforge.jnlp.splashscreen.SplashController;
 import net.sourceforge.jnlp.splashscreen.SplashPanel;
 import net.sourceforge.jnlp.splashscreen.SplashUtils;
+import net.sourceforge.jnlp.util.UrlUtils;
 import net.sourceforge.jnlp.util.logging.OutputController;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
@@ -887,7 +888,7 @@
     public Applet getApplet(String name) {
         name = name.toLowerCase();
         SocketPermission panelSp =
-                new SocketPermission(panel.getCodeBase().getHost(), "connect");
+                new SocketPermission(UrlUtils.getHostAndPort(panel.getCodeBase()), "connect");
         synchronized(appletPanels) {
             for (Enumeration<NetxPanel> e = appletPanels.elements(); e.hasMoreElements();) {
                 AppletPanel p = e.nextElement();
@@ -899,7 +900,7 @@
                         p.getDocumentBase().equals(panel.getDocumentBase())) {
 
                     SocketPermission sp =
-                        new SocketPermission(p.getCodeBase().getHost(), "connect");
+                        new SocketPermission(UrlUtils.getHostAndPort(p.getCodeBase()), "connect");
 
                     if (panelSp.implies(sp)) {
                         return p.applet;
@@ -918,7 +919,7 @@
     public Enumeration<Applet> getApplets() {
         Vector<Applet> v = new Vector<Applet>();
         SocketPermission panelSp =
-                new SocketPermission(panel.getCodeBase().getHost(), "connect");
+                new SocketPermission(UrlUtils.getHostAndPort(panel.getCodeBase()), "connect");
 
         synchronized(appletPanels) {
             for (Enumeration<NetxPanel> e = appletPanels.elements(); e.hasMoreElements();) {
@@ -926,7 +927,7 @@
                 if (p.getDocumentBase().equals(panel.getDocumentBase())) {
 
                     SocketPermission sp =
-                        new SocketPermission(p.getCodeBase().getHost(), "connect");
+                        new SocketPermission(UrlUtils.getHostAndPort(p.getCodeBase()), "connect");
                     if (panelSp.implies(sp)) {
                         v.addElement(p.applet);
                     }
--- a/tests/netx/unit/net/sourceforge/jnlp/SecurityDescTest.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/SecurityDescTest.java	Thu Oct 08 12:11:49 2015 +0200
@@ -48,7 +48,7 @@
     public void testNotNullJnlpFile() throws Exception {
         Throwable t = null;
         try {
-            new SecurityDesc(new DummyJNLPFile(), SecurityDesc.SANDBOX_PERMISSIONS, "hey!");
+            new SecurityDesc(new DummyJNLPFile(), SecurityDesc.SANDBOX_PERMISSIONS, null);
         } catch (Exception ex) {
             t = ex;
         }
@@ -57,7 +57,7 @@
 
     @Test(expected = NullPointerException.class)
     public void testNullJnlpFile() throws Exception {
-        new SecurityDesc(null, SecurityDesc.SANDBOX_PERMISSIONS, "hey!");
+        new SecurityDesc(null, SecurityDesc.SANDBOX_PERMISSIONS, null);
     }
 
     @Test
--- a/tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java	Fri Oct 02 15:35:30 2015 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java	Thu Oct 08 12:11:49 2015 +0200
@@ -42,6 +42,7 @@
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.net.MalformedURLException;
 import java.net.URL;
 import net.sourceforge.jnlp.annotations.KnownToFail;
 import org.junit.Assert;
@@ -325,5 +326,36 @@
         Assert.assertFalse(UrlUtils.compareNullableStrings("BBB", "aaa", false));
 
     }
+    
+    @Test
+    public void sanitizePortTest() throws MalformedURLException {
+        Assert.assertEquals(0, UrlUtils.getSanitizedPort(new URL("http://aaa.cz:0")));
+        Assert.assertEquals(1, UrlUtils.getSanitizedPort(new URL("https://aaa.cz:1")));
+        Assert.assertEquals(100, UrlUtils.getSanitizedPort(new URL("ftp://aaa.cz:100")));
+        //Assert.assertEquals(1001, UrlUtils.getSanitizedPort(new URL("ssh://aaa.cz:1001"))); unknown protocol :(
+        //Assert.assertEquals(22, UrlUtils.getSanitizedPort(new URL("ssh://aaa.cz")));
+        Assert.assertEquals(80, UrlUtils.getSanitizedPort(new URL("http://aaa.cz")));
+        Assert.assertEquals(443, UrlUtils.getSanitizedPort(new URL("https://aaa.cz")));
+        Assert.assertEquals(21, UrlUtils.getSanitizedPort(new URL("ftp://aaa.cz")));
+        
+   }
+
+    public void getPortTest() throws MalformedURLException {
+        Assert.assertEquals(1, UrlUtils.getPort(new URL("http://aa.bb:1")));
+        Assert.assertEquals(10, UrlUtils.getPort(new URL("http://aa.bb:10/aa")));
+        Assert.assertEquals(1000, UrlUtils.getPort(new URL("http://aa.bb:1000/aa.fs")));
+        Assert.assertEquals(443, UrlUtils.getPort(new URL("https://aa.bb/aa.fs")));
+        Assert.assertEquals(80, UrlUtils.getPort(new URL("http://aa.bb")));
+        Assert.assertEquals(80, UrlUtils.getPort(new URL("http://aa.bb:80/a/b/c")));
+    }
+
+    public void getHostAndPortTest() throws MalformedURLException {
+        Assert.assertEquals("aa.bb:2", UrlUtils.getHostAndPort(new URL("http://aa.bb:2")));
+        Assert.assertEquals("aa.bb:12", UrlUtils.getHostAndPort(new URL("http://aa.bb:12/aa")));
+        Assert.assertEquals("aa.bb:1002", UrlUtils.getHostAndPort(new URL("http://aa.bb:1002/aa.fs")));
+        Assert.assertEquals("aa.bb:443", UrlUtils.getHostAndPort(new URL("https://aa.bb/aa.fs")));
+        Assert.assertEquals("aa.bb:80", UrlUtils.getHostAndPort(new URL("http://aa.bb")));
+        Assert.assertEquals("aa.bb:80", UrlUtils.getHostAndPort(new URL("http://aa.bb:80/a/b/c")));
+    }
 
 }