From bd9f683112c37baef10fd5514ec2dfd571d0c0dc Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Thu, 8 Oct 2015 09:57:51 -0700 Subject: Move socket creation out to its own function Newer proxy types will need to have a way to create their own sockets, so move this out to its own function to allow that later. --- .../main/java/com/trilead/ssh2/HTTPProxyData.java | 114 ++++++++++++++++++++- 1 file changed, 109 insertions(+), 5 deletions(-) (limited to 'sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java') diff --git a/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java b/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java index 2edffe6..3c3c54a 100644 --- a/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java +++ b/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java @@ -1,6 +1,16 @@ package com.trilead.ssh2; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; + +import com.trilead.ssh2.crypto.Base64; +import com.trilead.ssh2.transport.ClientServerHello; + /** * A HTTPProxyData object is used to specify the needed connection data * to connect through a HTTP proxy. @@ -13,11 +23,11 @@ package com.trilead.ssh2; public class HTTPProxyData implements ProxyData { - public final String proxyHost; - public final int proxyPort; - public final String proxyUser; - public final String proxyPass; - public final String[] requestHeaderLines; + private final String proxyHost; + private final int proxyPort; + private final String proxyUser; + private final String proxyPass; + private final String[] requestHeaderLines; /** * Same as calling {@link #HTTPProxyData(String, int, String, String) HTTPProxyData(proxyHost, proxyPort, null, null)} @@ -80,4 +90,98 @@ public class HTTPProxyData implements ProxyData this.proxyPass = proxyPass; this.requestHeaderLines = requestHeaderLines; } + + @Override + public Socket openConnection(String hostname, int port, int connectTimeout) throws IOException { + Socket sock = new Socket(); + + InetAddress addr = InetAddress.getByName(proxyHost); + sock.connect(new InetSocketAddress(addr, proxyPort), connectTimeout); + sock.setSoTimeout(0); + + /* OK, now tell the proxy where we actually want to connect to */ + + StringBuffer sb = new StringBuffer(); + + sb.append("CONNECT "); + sb.append(hostname); + sb.append(':'); + sb.append(port); + sb.append(" HTTP/1.0\r\n"); + + if ((proxyUser != null) && (proxyPass != null)) + { + String credentials = proxyUser + ":" + proxyPass; + char[] encoded = Base64.encode(credentials.getBytes("ISO-8859-1")); + sb.append("Proxy-Authorization: Basic "); + sb.append(encoded); + sb.append("\r\n"); + } + + if (requestHeaderLines != null) + { + for (int i = 0; i < requestHeaderLines.length; i++) + { + if (requestHeaderLines[i] != null) + { + sb.append(requestHeaderLines[i]); + sb.append("\r\n"); + } + } + } + + sb.append("\r\n"); + + OutputStream out = sock.getOutputStream(); + + out.write(sb.toString().getBytes("ISO-8859-1")); + out.flush(); + + /* Now parse the HTTP response */ + + byte[] buffer = new byte[1024]; + InputStream in = sock.getInputStream(); + + int len = ClientServerHello.readLineRN(in, buffer); + + String httpReponse = new String(buffer, 0, len, "ISO-8859-1"); + + if (httpReponse.startsWith("HTTP/") == false) + throw new IOException("The proxy did not send back a valid HTTP response."); + + /* "HTTP/1.X XYZ X" => 14 characters minimum */ + + if ((httpReponse.length() < 14) || (httpReponse.charAt(8) != ' ') || (httpReponse.charAt(12) != ' ')) + throw new IOException("The proxy did not send back a valid HTTP response."); + + int errorCode = 0; + + try + { + errorCode = Integer.parseInt(httpReponse.substring(9, 12)); + } + catch (NumberFormatException ignore) + { + throw new IOException("The proxy did not send back a valid HTTP response."); + } + + if ((errorCode < 0) || (errorCode > 999)) + throw new IOException("The proxy did not send back a valid HTTP response."); + + if (errorCode != 200) + { + throw new HTTPProxyException(httpReponse.substring(13), errorCode); + } + + /* OK, read until empty line */ + + while (true) + { + len = ClientServerHello.readLineRN(in, buffer); + if (len == 0) + break; + } + + return sock; + } } -- cgit v1.2.3