changeset 3549:694951adefec

6964547: Impossible to set useV4 in SocksSocketImpl Summary: Add socksProxyVersion property Reviewed-by: alanb, michaelm
author chegar
date Thu, 13 Jan 2011 13:24:58 +0000
parents 9f265d55c1c4
children 067b5f603fc8
files make/sun/net/FILES_java.gmk src/share/classes/java/io/PrintStream.java src/share/classes/java/net/SocksSocketImpl.java src/share/classes/java/net/doc-files/net-properties.html src/share/classes/sun/net/SocksProxy.java src/share/classes/sun/net/spi/DefaultProxySelector.java test/java/net/Socks/SocksProxyVersion.java
diffstat 7 files changed, 182 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/make/sun/net/FILES_java.gmk	Thu Jan 13 11:02:28 2011 +0000
+++ b/make/sun/net/FILES_java.gmk	Thu Jan 13 13:24:58 2011 +0000
@@ -33,6 +33,7 @@
 	sun/net/ProgressEvent.java \
 	sun/net/ProgressListener.java \
 	sun/net/ProgressMeteringPolicy.java \
+	sun/net/SocksProxy.java \
 	sun/net/TelnetInputStream.java \
 	sun/net/TelnetOutputStream.java \
 	sun/net/TelnetProtocolException.java \
--- a/src/share/classes/java/io/PrintStream.java	Thu Jan 13 11:02:28 2011 +0000
+++ b/src/share/classes/java/io/PrintStream.java	Thu Jan 13 13:24:58 2011 +0000
@@ -70,7 +70,7 @@
     private OutputStreamWriter charOut;
 
     /**
-     * nonNull is explicitly delcared here so as not to create an extra
+     * nonNull is explicitly declared here so as not to create an extra
      * dependency on java.util.Objects.nonNull. PrintStream is loaded
      * early during system initialization.
      */
--- a/src/share/classes/java/net/SocksSocketImpl.java	Thu Jan 13 11:02:28 2011 +0000
+++ b/src/share/classes/java/net/SocksSocketImpl.java	Thu Jan 13 13:24:58 2011 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import java.io.BufferedOutputStream;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
+import sun.net.SocksProxy;
 import sun.net.www.ParseUtil;
 /* import org.ietf.jgss.*; */
 
@@ -397,6 +398,11 @@
                 // Use getHostString() to avoid reverse lookups
                 server = ((InetSocketAddress) p.address()).getHostString();
                 serverPort = ((InetSocketAddress) p.address()).getPort();
+                if (p instanceof SocksProxy) {
+                    if (((SocksProxy)p).protocolVersion() == 4) {
+                        useV4 = true;
+                    }
+                }
 
                 // Connects to the SOCKS server
                 try {
@@ -700,6 +706,11 @@
                 // Use getHostString() to avoid reverse lookups
                 server = ((InetSocketAddress) p.address()).getHostString();
                 serverPort = ((InetSocketAddress) p.address()).getPort();
+                if (p instanceof SocksProxy) {
+                    if (((SocksProxy)p).protocolVersion() == 4) {
+                        useV4 = true;
+                    }
+                }
 
                 // Connects to the SOCKS server
                 try {
--- a/src/share/classes/java/net/doc-files/net-properties.html	Thu Jan 13 11:02:28 2011 +0000
+++ b/src/share/classes/java/net/doc-files/net-properties.html	Thu Jan 13 13:24:58 2011 +0000
@@ -127,10 +127,15 @@
 	are specified. If SOCKS is supported by a Java SE implementation, the
 	following properties will be used:</P>
 	<UL>
-		<LI><P><B>socksProxyHost</B> (default: &lt;non&gt;)<BR>
+		<LI><P><B>socksProxyHost</B> (default: &lt;none&gt;)<BR>
 	        The hostname, or address, of the proxy server.</P>
 		<LI><P><B>socksProxyPort</B> (default: 1080)<BR>
 	        The port number of the proxy server.</P>
+                <LI><P><B>socksProxyVersion</B> (default: 5)<BR>
+                The version of the SOCKS protocol supported by the server. The
+                default is <code>5</code> indicating SOCKS V5, alternatively
+                <code>4</code> can be specified for SOCKS V4. Setting the property
+                to values other than these leads to unspecified behavior.</P>
 		<LI><P><B>java.net.socks.username</B> (default: &lt;none&gt;)<BR>
 	        Username to use if the SOCKSv5 server asks for authentication
 	        and no java.net.Authenticator instance was found.</P>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/net/SocksProxy.java	Thu Jan 13 13:24:58 2011 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net;
+
+import java.net.Proxy;
+import java.net.SocketAddress;
+
+/**
+ * Proxy wrapper class so we can determine the socks protocol version.
+ */
+public final class SocksProxy extends Proxy {
+    private final int version;
+
+    private SocksProxy(SocketAddress addr, int version) {
+        super(Proxy.Type.SOCKS, addr);
+        this.version = version;
+    }
+
+    public static SocksProxy create(SocketAddress addr, int version) {
+        return new SocksProxy(addr, version);
+    }
+
+    public int protocolVersion() {
+        return version;
+    }
+}
--- a/src/share/classes/sun/net/spi/DefaultProxySelector.java	Thu Jan 13 11:02:28 2011 +0000
+++ b/src/share/classes/sun/net/spi/DefaultProxySelector.java	Thu Jan 13 13:24:58 2011 +0000
@@ -25,13 +25,20 @@
 
 package sun.net.spi;
 
-import sun.net.NetProperties;
-import java.net.*;
-import java.util.*;
-import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.io.IOException;
 import sun.misc.RegexpPool;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import sun.net.NetProperties;
+import sun.net.SocksProxy;
 
 /**
  * Supports proxy settings using system properties This proxy selector
@@ -75,6 +82,8 @@
         {"socket", "socksProxy"}
     };
 
+    private static final String SOCKS_PROXY_VERSION = "socksProxyVersion";
+
     private static boolean hasSystemProxies = false;
 
     static {
@@ -287,7 +296,8 @@
                             saddr = InetSocketAddress.createUnresolved(phost, pport);
                             // Socks is *always* the last on the list.
                             if (j == (props[i].length - 1)) {
-                                return new Proxy(Proxy.Type.SOCKS, saddr);
+                                int version = NetProperties.getInteger(SOCKS_PROXY_VERSION, 5).intValue();
+                                return SocksProxy.create(saddr, version);
                             } else {
                                 return new Proxy(Proxy.Type.HTTP, saddr);
                             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/Socks/SocksProxyVersion.java	Thu Jan 13 13:24:58 2011 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6964547
+ * @run main/othervm SocksProxyVersion
+ * @summary test socksProxyVersion system property
+ */
+
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+public class SocksProxyVersion implements Runnable {
+    ServerSocket ss;
+    volatile boolean failed;
+
+    public static void main(String[] args) throws Exception {
+        new SocksProxyVersion();
+    }
+
+    public SocksProxyVersion() throws Exception {
+        ss = new ServerSocket(0);
+        int port = ss.getLocalPort();
+        Thread serverThread = new Thread(this);
+        serverThread.start();
+
+        System.setProperty("socksProxyHost", "localhost");
+        System.setProperty("socksProxyPort", Integer.toString(port));
+
+        // SOCKS V4
+        System.setProperty("socksProxyVersion", Integer.toString(4));
+        try (Socket s = new Socket()) {
+            s.connect(new InetSocketAddress("localhost", port));
+        } catch (SocketException e) {
+            // java.net.SocketException: Malformed reply from SOCKS server
+            // This exception is OK, since the "server" does not implement
+            // the socks protocol. It just verifies the version and closes.
+        }
+
+        // SOCKS V5
+        System.setProperty("socksProxyVersion", Integer.toString(5));
+        try (Socket s = new Socket()) {
+            s.connect(new InetSocketAddress("localhost", port));
+        } catch (SocketException e) { /* OK */ }
+
+        serverThread.join();
+        if (failed) {
+            throw new RuntimeException("socksProxyVersion not being set correctly");
+        }
+    }
+
+    public void run() {
+        try (ss) {
+            Socket s = ss.accept();
+            int version = (s.getInputStream()).read();
+            if (version != 4) {
+                System.out.println("Got " + version + ", expected 4");
+                failed = true;
+            }
+            s.close();
+
+            s = ss.accept();
+            version = (s.getInputStream()).read();
+            if (version != 5) {
+                System.out.println("Got " + version + ", expected 5");
+                failed = true;
+            }
+            s.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}