Mercurial > 510Connectbot
diff src/ch/ethz/ssh2/transport/ClientServerHello.java @ 342:175c7d68f3c4
merge ganymed into mainline
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 31 Jul 2014 16:33:38 -0700 |
parents | 126af684034e |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ch/ethz/ssh2/transport/ClientServerHello.java Thu Jul 31 16:33:38 2014 -0700 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. + * Please refer to the LICENSE.txt for licensing details. + */ + +package ch.ethz.ssh2.transport; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.OutputStream; + +import ch.ethz.ssh2.util.StringEncoder; + +/** + * @author Christian Plattner + * @version $Id: ClientServerHello.java 155 2014-04-28 12:01:19Z dkocher@sudo.ch $ + */ +public class ClientServerHello { + private final String client_line; + private final String server_line; + + public final static int readLineRN(InputStream is, byte[] buffer) throws IOException { + int pos = 0; + boolean need10 = false; + int len = 0; + + while (true) { + int c = is.read(); + + if (c == -1) + throw new IOException("Premature connection close"); + + buffer[pos++] = (byte) c; + + if (c == 13) { + need10 = true; + continue; + } + + if (c == 10) + break; + + if (need10 == true) + throw new IOException("Malformed line sent by the server, the line does not end correctly."); + + len++; + + if (pos >= buffer.length) + throw new IOException("The server sent a too long line."); + } + + return len; + } + + private ClientServerHello(String client_line, String server_line) { + this.client_line = client_line; + this.server_line = server_line; + } + + public static ClientServerHello clientHello(String softwareversion, InputStream bi, OutputStream bo) + throws IOException { + return exchange(softwareversion, bi, bo, true); + } + + public static ClientServerHello serverHello(String softwareversion, InputStream bi, OutputStream bo) + throws IOException { + return exchange(softwareversion, bi, bo, false); + } + + private static ClientServerHello exchange(String softwareversion, InputStream bi, OutputStream bo, boolean clientMode) + throws IOException { + String localIdentifier = String.format("SSH-2.0-%s", softwareversion); + bo.write(StringEncoder.GetBytes(String.format("%s\r\n", localIdentifier))); + bo.flush(); + // Expect SSH-protoversion-softwareversion SP comments CR LF + byte[] serverVersion = new byte[512]; + String remoteIdentifier = null; + for (int i = 0; i < 50; i++) { + int len = readLineRN(bi, serverVersion); + remoteIdentifier = new String(serverVersion, 0, len, "ISO-8859-1"); + if (remoteIdentifier.startsWith("SSH-")) break; + } + + if (remoteIdentifier.equals("")) { + throw new IOException("Premature connection close"); + } + + if (!remoteIdentifier.startsWith("SSH-")) { + throw new IOException(String.format("Malformed SSH identification %s", remoteIdentifier)); + } + + if (!remoteIdentifier.startsWith("SSH-1.99-") + && !remoteIdentifier.startsWith("SSH-2.0-")) { + throw new IOException(String.format("Incompatible remote protocol version %s", remoteIdentifier)); + } + + if (clientMode) { + return new ClientServerHello(localIdentifier, remoteIdentifier); + } + else { + return new ClientServerHello(remoteIdentifier, localIdentifier); + } + } + + /** + * @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); + } +}