SocksSocketImpl.java revision 381
0N/A * Copyright 2000-2008 Sun Microsystems, Inc. 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 0N/A * published by the Free Software Foundation. Sun designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Sun 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. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A/* import org.ietf.jgss.*; */ * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). * This is a subclass of PlainSocketImpl. * Note this class should <b>NOT</b> be public. private boolean useV4 =
false;
// Use getHostString() to avoid reverse lookups * Provides the authentication machanism required by the proxy. // No Authentication required. We're done then! * - The application provided Authenticator, if any * - The user preferences java.net.socks.username & * java.net.socks.password * - the user.name & no password (backward compatibility behavior). if (i !=
2 ||
data[
1] !=
0) {
/* RFC 1929 specifies that the connection MUST be closed if /* Authentication succeeded */ * GSSAPI authentication mechanism. * Unfortunately the RFC seems out of sync with the Reference * implementation. I'll leave this in for future completion. // if (method == GSSAPI) { // GSSManager manager = GSSManager.getInstance(); // GSSName name = manager.createName("SERVICE:socks@"+server, // GSSContext context = manager.createContext(name, null, null, // GSSContext.DEFAULT_LIFETIME); // context.requestMutualAuth(true); // context.requestReplayDet(true); // context.requestSequenceDet(true); // context.requestCredDeleg(true); // byte []inToken = new byte[0]; // while (!context.isEstablished()) { // = context.initSecContext(inToken, 0, inToken.length); // // send the output token if generated // if (outToken != null) { // out.writeShort(outToken.length); // i = readSocksReply(in, data); // if (i != 2 || data[1] == 0xff) { // i = readSocksReply(in, data); // len = ((int)data[0] & 0xff) << 8; // i = readSocksReply(in, data); // } catch (GSSException e) { // /* RFC 1961 states that if Context initialisation fails the connection byte[]
data =
new byte[
8];
* Connects the Socks Socket to the specified endpoint. It will first * connect to the SOCKS proxy and negotiate the access. If the proxy * grants the connections, then the connect is successful and all * further traffic will go to the "real" endpoint. * @param endpoint the <code>SocketAddress</code> to connect to. * @param timeout the timeout value in milliseconds * @throws IOException if the connection can't be established. * @throws SecurityException if there is a security manager and it * doesn't allow the connection * @throws IllegalArgumentException if endpoint is null or a * SocketAddress subclass not supported by this socket // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector * No default proxySelector --> direct connection // Use getHostString() to avoid reverse lookups // Use getHostString() to avoid reverse lookups // Connects to the SOCKS server // Worked, let's get outta here // Ooops, let's notify the ProxySelector // Will continue the while loop and try the next proxy * If server is still null at this point, none of the proxy // Connects to the SOCKS server // cmdIn & cmdOut were intialized during the privilegedConnect() call // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) byte[]
data =
new byte[
2];
// Maybe it's not a V5 sever after all // Let's try V4 before we give up // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) byte[]
data =
new byte[
8];
* Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind * means "accept incoming connection from", so the SocketAddress is the * the one of the host we do accept connection from. * @param addr the Socket address of the remote host. * @exception IOException if an I/O error occurs when binding this socket. // this is a client socket, not a server socket, don't // call the SOCKS proxy for a bind! // Connects to the SOCKS server // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector * No default proxySelector --> direct connection // Use getHostString() to avoid reverse lookups // Use getHostString() to avoid reverse lookups // Connects to the SOCKS server // Ooops, let's notify the ProxySelector // Will continue the while loop and try the next proxy * If server is still null at this point, none of the proxy byte[]
data =
new byte[
2];
// Maybe it's not a V5 sever after all // Let's try V4 before we give up // We're OK. Let's issue the BIND command. * Accepts a connection from a specific host. * @param s the accepted connection. * @param saddr the socket address of the host we do accept * @exception IOException if an I/O error occurs when accepting the // Not a Socks ServerSocket. // Sends the "SOCKS BIND" request. * This is where we have to do some fancy stuff. * The datastream from the socket "accepted" by the proxy will * come through the cmdSocket. So we have to swap the socketImpls // Need to do that so that the socket won't be closed // when the ServerSocket is closed by the user. // It kinds of detaches the Socket because it is now * Returns the value of this socket's <code>address</code> field. * @return the value of this socket's <code>address</code> field. * @see java.net.SocketImpl#address * Returns the value of this socket's <code>port</code> field. * @return the value of this socket's <code>port</code> field. * @see java.net.SocketImpl#port