private static ClientServerHello exchange( String softwareversion, InputStream bi, OutputStream bo, boolean clientMode) throws IOException { String localIdentifier = "SSH-2.0-" + softwareversion; String remoteIdentifier = null; bo.write(StringEncoder.GetBytes(localIdentifier + "\r\n")); bo.flush(); byte[] remoteData = new byte[1024]; for (int i = 0; i < 50; i++) { int len = readLineRN(bi, remoteData); remoteIdentifier = StringEncoder.GetString(remoteData, 0, len); if (remoteIdentifier.startsWith("SSH-")) break; } if (remoteIdentifier.startsWith("SSH-") == false) throw new IOException( "Malformed SSH identification string. There was no line starting with 'SSH-' amongst the first 50 lines."); if (!remoteIdentifier.startsWith("SSH-1.99-") && !remoteIdentifier.startsWith("SSH-2.0-")) throw new IOException("Remote party uses incompatible protocol, it is not SSH-2 compatible."); if (clientMode) return new ClientServerHello(localIdentifier, remoteIdentifier); else return new ClientServerHello(remoteIdentifier, localIdentifier); }
public String readString() throws IOException { int len = readUINT32(); if ((len + pos) > max) throw new IOException("Malformed SSH string."); String res = StringEncoder.GetString(arr, pos, len); pos += len; return res; }
private void establishConnection(ProxyData proxyData, int connectTimeout) throws IOException { /* See the comment for createInetAddress() */ if (proxyData == null) { InetAddress addr = createInetAddress(hostname); sock.connect(new InetSocketAddress(addr, port), connectTimeout); return; } if (proxyData instanceof HTTPProxyData) { HTTPProxyData pd = (HTTPProxyData) proxyData; /* At the moment, we only support HTTP proxies */ InetAddress addr = createInetAddress(pd.proxyHost); sock.connect(new InetSocketAddress(addr, pd.proxyPort), connectTimeout); /* OK, now tell the proxy where we actually want to connect to */ StringBuilder sb = new StringBuilder(); sb.append("CONNECT "); sb.append(hostname); sb.append(':'); sb.append(port); sb.append(" HTTP/1.0\r\n"); if ((pd.proxyUser != null) && (pd.proxyPass != null)) { String credentials = pd.proxyUser + ":" + pd.proxyPass; char[] encoded = Base64.encode(StringEncoder.GetBytes(credentials)); sb.append("Proxy-Authorization: Basic "); sb.append(encoded); sb.append("\r\n"); } if (pd.requestHeaderLines != null) { for (int i = 0; i < pd.requestHeaderLines.length; i++) { if (pd.requestHeaderLines[i] != null) { sb.append(pd.requestHeaderLines[i]); sb.append("\r\n"); } } } sb.append("\r\n"); OutputStream out = sock.getOutputStream(); out.write(StringEncoder.GetBytes(sb.toString())); out.flush(); /* Now parse the HTTP response */ byte[] buffer = new byte[1024]; InputStream in = sock.getInputStream(); int len = ClientServerHello.readLineRN(in, buffer); String httpReponse = StringEncoder.GetString(buffer, 0, len); 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; } throw new IOException("Unsupported ProxyData"); }
/** @return Returns the client_versioncomment. */ public byte[] getClientString() { return StringEncoder.GetBytes(client_line); }
/** @return Returns the server_versioncomment. */ public byte[] getServerString() { return StringEncoder.GetBytes(server_line); }