SocksSocketImpl.java revision 3393
3393N/A * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A/* import org.ietf.jgss.*; */ 0N/A * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). 0N/A * This is a subclass of PlainSocketImpl. 0N/A * Note this class should <b>NOT</b> be public. 1503N/A /* true if the Proxy has been set programatically */ 0N/A // Use getHostString() to avoid reverse lookups 0N/A * Provides the authentication machanism required by the proxy. 0N/A // No Authentication required. We're done then! 0N/A * - The application provided Authenticator, if any 0N/A * - the user.name & no password (backward compatibility behavior). 0N/A /* RFC 1929 specifies that the connection MUST be closed if 0N/A authentication fails */ 0N/A /* Authentication succeeded */ 0N/A * GSSAPI authentication mechanism. 0N/A * Unfortunately the RFC seems out of sync with the Reference 0N/A * implementation. I'll leave this in for future completion. 0N/A// if (method == GSSAPI) { 0N/A// GSSManager manager = GSSManager.getInstance(); 0N/A// GSSName name = manager.createName("SERVICE:socks@"+server, 0N/A// GSSContext context = manager.createContext(name, null, null, 0N/A// GSSContext.DEFAULT_LIFETIME); 0N/A// context.requestMutualAuth(true); 0N/A// context.requestReplayDet(true); 0N/A// context.requestSequenceDet(true); 0N/A// context.requestCredDeleg(true); 0N/A// byte []inToken = new byte[0]; 0N/A// while (!context.isEstablished()) { 0N/A// // send the output token if generated 0N/A// if (outToken != null) { 0N/A// out.writeShort(outToken.length); 0N/A// out.write(outToken); 0N/A// data = new byte[2]; 2226N/A// i = readSocksReply(in, data, deadlineMillis); 0N/A// if (i != 2 || data[1] == 0xff) { 2226N/A// i = readSocksReply(in, data, deadlineMillis); 0N/A// len = ((int)data[0] & 0xff) << 8; 0N/A// data = new byte[len]; 2226N/A// i = readSocksReply(in, data, deadlineMillis); 0N/A// } catch (GSSException e) { 0N/A// /* RFC 1961 states that if Context initialisation fails the connection 0N/A// e.printStackTrace(); 0N/A * Connects the Socks Socket to the specified endpoint. It will first 0N/A * connect to the SOCKS proxy and negotiate the access. If the proxy 0N/A * grants the connections, then the connect is successful and all 0N/A * further traffic will go to the "real" endpoint. 0N/A * @param endpoint the <code>SocketAddress</code> to connect to. 0N/A * @param timeout the timeout value in milliseconds 0N/A * @throws IOException if the connection can't be established. 0N/A * @throws SecurityException if there is a security manager and it 0N/A * doesn't allow the connection 0N/A * @throws IllegalArgumentException if endpoint is null or a 0N/A * SocketAddress subclass not supported by this socket 0N/A // This is the general case 0N/A // server is not null only when the socket was created with a 0N/A // specified proxy in which case it does bypass the ProxySelector 0N/A * No default proxySelector --> direct connection 0N/A // Use getHostString() to avoid reverse lookups 0N/A // This shouldn't happen 0N/A // Use getHostString() to avoid reverse lookups 0N/A // Connects to the SOCKS server 0N/A // Worked, let's get outta here 0N/A // Ooops, let's notify the ProxySelector 0N/A // Will continue the while loop and try the next proxy 0N/A * If server is still null at this point, none of the proxy 0N/A // Connects to the SOCKS server 0N/A // cmdIn & cmdOut were intialized during the privilegedConnect() call 0N/A // SOCKS Protocol version 4 doesn't know how to deal with 0N/A // DOMAIN type of addresses (unresolved addresses here) 0N/A // Maybe it's not a V5 sever after all 0N/A // Let's try V4 before we give up 0N/A // SOCKS Protocol version 4 doesn't know how to deal with 0N/A // DOMAIN type of addresses (unresolved addresses here) 0N/A /* Test for AnyLocal */ 0N/A * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind 0N/A * means "accept incoming connection from", so the SocketAddress is the 0N/A * the one of the host we do accept connection from. 0N/A * @param addr the Socket address of the remote host. 0N/A * @exception IOException if an I/O error occurs when binding this socket. 0N/A // this is a client socket, not a server socket, don't 0N/A // call the SOCKS proxy for a bind! 0N/A // Connects to the SOCKS server 0N/A // This is the general case 0N/A // server is not null only when the socket was created with a 0N/A // specified proxy in which case it does bypass the ProxySelector 0N/A * No default proxySelector --> direct connection 0N/A // Use getHostString() to avoid reverse lookups 0N/A // This shouldn't happen 0N/A // Use getHostString() to avoid reverse lookups 0N/A // Connects to the SOCKS server 0N/A // Ooops, let's notify the ProxySelector 0N/A // Will continue the while loop and try the next proxy 0N/A * If server is still null at this point, none of the proxy 0N/A // Maybe it's not a V5 sever after all 0N/A // Let's try V4 before we give up 0N/A // We're OK. Let's issue the BIND command. 0N/A * Accepts a connection from a specific host. 0N/A * @param s the accepted connection. 0N/A * @param saddr the socket address of the host we do accept 0N/A * @exception IOException if an I/O error occurs when accepting the 0N/A // Not a Socks ServerSocket. 0N/A // Sends the "SOCKS BIND" request. 0N/A * This is where we have to do some fancy stuff. 0N/A * The datastream from the socket "accepted" by the proxy will 0N/A * come through the cmdSocket. So we have to swap the socketImpls 0N/A // Need to do that so that the socket won't be closed 0N/A // when the ServerSocket is closed by the user. 0N/A // It kinds of detaches the Socket because it is now 0N/A * Returns the value of this socket's <code>address</code> field. 0N/A * @return the value of this socket's <code>address</code> field. 0N/A * @see java.net.SocketImpl#address 0N/A * Returns the value of this socket's <code>port</code> field. 0N/A * @return the value of this socket's <code>port</code> field. 0N/A * @see java.net.SocketImpl#port