?? sshio.java
字號:
/** * SshIO * -- * * This file implments the SSH protocol 1.5 * * $Id: SshIO.java,v 1.18 2000/12/20 21:48:30 marcus Exp $ * * The protocol version used in this document is SSH protocol version 1.5. * This file is part of "The Java Ssh Applet". */package de.mud.ssh;import java.io.IOException;//import java.security.SecureRandom; //not supported by netscapeimport de.mud.ssh.MD5; public abstract class SshIO { private MD5 md5 = new MD5(); /** * variables for the connection */ private String identification_string = ""; //("SSH-<protocolmajor>.<protocolminor>-<version>\n") private String identification_string_sent = "SSH-1.5-Java Ssh 1.1 (16/09/99) leo@mud.de, original by Cedric Gourio (javassh@france-mail.com)\n"; /** * Debug level. This results in additional diagnostic messages on the * java console. */ private static int debug = 0; /** * State variable for Ssh negotiation reader */ private boolean encryption = false; private SshCrypto crypto; SshPacket lastPacketReceived; String cipher_type = "IDEA"; private String login = "", password = ""; //nobody is to access those fields : better to use pivate, nobody knows :-) public String dataToSend = null; public String hashHostKey = null; // equals to the applet parameter if any byte lastPacketSentType; // phase : handleBytes private int phase = 0; private final int PHASE_INIT = 0; private final int PHASE_SSH_RECEIVE_PACKET = 1; //handlePacket //messages // The supported packet types and the corresponding message numbers are // given in the following table. Messages with _MSG_ in their name may // be sent by either side. Messages with _CMSG_ are only sent by the // client, and messages with _SMSG_ only by the server. // private final int SSH_MSG_DISCONNECT = 1; private final int SSH_SMSG_PUBLIC_KEY = 2; private final int SSH_CMSG_SESSION_KEY = 3; private final int SSH_CMSG_USER = 4; private final int SSH_CMSG_AUTH_PASSWORD = 9; private final int SSH_CMSG_REQUEST_PTY = 10; private final int SSH_CMSG_EXEC_SHELL = 12; private final int SSH_SMSG_SUCCESS = 14; private final int SSH_SMSG_FAILURE = 15; private final int SSH_CMSG_STDIN_DATA = 16; private final int SSH_SMSG_STDOUT_DATA = 17; private final int SSH_SMSG_STDERR_DATA = 18; private final int SSH_SMSG_EXITSTATUS = 20; private final int SSH_CMSG_EXIT_CONFIRMATION = 33; private final int SSH_MSG_DEBUG = 36; //used in getPacket private int position = 0; // used to know, how far we are in packet_length_array[], padding[] ... // // encryption types // private int SSH_CIPHER_NONE = 0; // No encryption private int SSH_CIPHER_IDEA = 1; // IDEA in CFB mode (patented) private int SSH_CIPHER_DES = 2; // DES in CBC mode private int SSH_CIPHER_3DES = 3; // Triple-DES in CBC mode private int SSH_CIPHER_TSS = 4; // An experimental stream cipher private int SSH_CIPHER_RC4 = 5; // RC4 (patented) private int SSH_CIPHER_BLOWFISH = 6; // Bruce Scheiers blowfish (public d) // // authentication methods // private final int SSH_AUTH_RHOSTS = 1; //.rhosts or /etc/hosts.equiv private final int SSH_AUTH_RSA = 2; //pure RSA authentication private final int SSH_AUTH_PASSWORD = 3; //password authentication, implemented ! private final int SSH_AUTH_RHOSTS_RSA = 4; //.rhosts with RSA host authentication private boolean cansenddata = false; /** * Initialise SshIO */ public SshIO() { encryption = false; } public void setLogin(String user) { if(user == null) user = ""; login = user; } public void setPassword(String password) { if(password == null) password = ""; this.password = password; } /** * Read data from the remote host. Blocks until data is available. * * Returns an array of bytes that will be displayed. * */ synchronized public byte[] handleSSH(byte[] b) throws IOException { byte[] result = packetDone(handleBytes(b, 0, b.length)); while(lastPacketReceived != null && lastPacketReceived.toBeFinished) { byte[] buff = lastPacketReceived.unfinishedBuffer; int start = lastPacketReceived.positionInUnfinishedBuffer; if(buff != null) { byte[] rest = packetDone(handleBytes(buff, start, buff.length)); if(rest != null) { if(result != null) { byte[] tmp = new byte[rest.length + result.length]; System.arraycopy(result, 0, tmp, 0, result.length); System.arraycopy(rest, 0, tmp, result.length , rest.length); result = tmp; } else result=rest; } } } // while /* for(int i = 0; result != null && i < result.length; i++) System.err.print(result[i]+":"+(char)result[i]+" "); */ return result; } private byte[] packetDone(SshPacket packet) throws IOException { if(packet == null) return null; lastPacketReceived = packet; byte result[] = handlePacket(lastPacketReceived.getType(), lastPacketReceived.getData()); return result; } protected abstract void write(byte[] buf) throws IOException; public abstract String getTerminalType(); byte[] one = new byte[1]; private void write(byte b) throws IOException { one[0] = b; write(one); } public void disconnect() { // System.err.println("In Disconnect"); login = ""; password = ""; phase=0; encryption = false; lastPacketReceived = null; } synchronized public void sendData(String str) throws IOException { if(debug > 1) System.out.println( "SshIO.send(" + str + ")" ); if (dataToSend==null) dataToSend = str; else dataToSend += str; if (cansenddata) { Send_SSH_CMSG_STDIN_DATA(dataToSend); dataToSend = null; } } private SshPacket handleBytes(byte buff[], int offset, int count) throws IOException { if(debug > 1) System.out.println("SshIO.getPacket(" + buff + "," + count + ")" ); byte b; // of course, byte is a signed entity (-128 -> 127) int boffset = offset; // offset in the buffer received while(boffset < count) { b=buff[boffset++]; switch(phase) { case PHASE_INIT: // both sides MUST send an identification string of the form // "SSH-protoversion-softwareversion comments", // followed by newline character(ascii 10 = '\n' or '\r') identification_string += (char) b; if (b=='\n') { phase++; write(identification_string_sent.getBytes()); position = 0; byte[] data = SshMisc.createString(identification_string); byte packet_type = SSH_SMSG_STDOUT_DATA; return createPacket(packet_type, data); } break; case PHASE_SSH_RECEIVE_PACKET: SshPacket result = lastPacketReceived.getPacketfromBytes(buff,boffset-1,count,encryption,crypto); return result; } // switch(phase) } //while(boffset < count) return null; }//getPacket // // Create a packet // private SshPacket createPacket(byte newType, byte[] newData) throws IOException { return new SshPacket(newType, newData,encryption,crypto); } private byte[] handlePacket(byte packetType, byte[] packetData) throws IOException { //the message to handle is data and its length is //if(debug > 1) w //System.out.println("SshIO.handlePacket("+data+","+ (packet_length - 5) +")"); byte b; // of course, byte is a signed entity (-128 -> 127) int boffset = 0; //offset in the buffer received //we have to deal with data.... if(debug > 0) System.out.println("1 packet to handle, type "+packetType); switch(packetType) { case SSH_MSG_DISCONNECT: String str = SshMisc.getString(boffset, packetData); disconnect(); return str.getBytes(); case SSH_SMSG_PUBLIC_KEY: byte[] anti_spoofing_cookie = new byte[8]; //8 bytes byte[] server_key_bits = new byte[4]; //32-bit int byte[] server_key_public_exponent; //mp-int byte[] server_key_public_modulus; //mp-int byte[] host_key_bits = new byte[4]; //32-bit int byte[] host_key_public_exponent; //mp-int byte[] host_key_public_modulus; //mp-int byte[] protocol_flags = new byte[4]; //32-bit int byte[] supported_ciphers_mask = new byte[4]; //32-bit int byte[] supported_authentications_mask = new byte[4]; //32-bit int for(int i=0;i<=7;i++) anti_spoofing_cookie[i] = packetData[boffset++]; for(int i=0;i<=3;i++) server_key_bits[i] = packetData[boffset++]; server_key_public_exponent = SshMisc.getMpInt(boffset,packetData); //boffset is not modified :-( boffset += server_key_public_exponent.length+2; server_key_public_modulus = SshMisc.getMpInt(boffset,packetData); boffset += server_key_public_modulus.length+2; for(int i=0;i<=3;i++) host_key_bits[i] = packetData[boffset++]; host_key_public_exponent = SshMisc.getMpInt(boffset,packetData); boffset += host_key_public_exponent.length+2; host_key_public_modulus = SshMisc.getMpInt(boffset,packetData); // boffset can not be modified (Java = crap Language) boffset += host_key_public_modulus.length+2; for(int i=0;i<4;i++) protocol_flags[i] = packetData[boffset++]; for(int i=0;i<4;i++) supported_ciphers_mask[i] = packetData[boffset++]; for(int i=0;i<4;i++) supported_authentications_mask[i] = packetData[boffset++]; // we have completely received the PUBLIC_KEY // we prepare the answer ... byte ret[] = Send_SSH_CMSG_SESSION_KEY( anti_spoofing_cookie, server_key_public_modulus, host_key_public_modulus, supported_ciphers_mask, server_key_public_exponent, host_key_public_exponent ); if (ret != null) return ret; // we check if MD5(server_key_public_exponent) is equals to the // applet parameter if any . if (hashHostKey!=null && hashHostKey.compareTo("")!=0) { // we compute hashHostKeyBis the hash value in hexa of // host_key_public_modulus byte[] Md5_hostKey = md5.hash(host_key_public_modulus); String hashHostKeyBis = ""; for(int i=0; i < Md5_hostKey.length; i++) { String hex = ""; int[] v = new int[2]; v[0] = (Md5_hostKey[i]&240)>>4; v[1] = (Md5_hostKey[i]&15); for (int j=0; j<1; j++) switch (v[j]) { case 10 : hex +="a"; break; case 11 : hex +="b"; break; case 12 : hex +="c"; break; case 13 : hex +="d"; break; case 14 : hex +="e"; break; case 15 : hex +="f"; break; default : hex +=String.valueOf(v[j]);break; } hashHostKeyBis = hashHostKeyBis + hex; } //we compare the 2 values if (hashHostKeyBis.compareTo(hashHostKey)!=0) { login = password = ""; return ("\nHash value of the host key not correct \r\n" +"login & password have been reset \r\n" +"- erase the 'hashHostKey' parameter in the Html\r\n" +"(it is used for auhentificating the server and " +"prevent you from connecting \r\n" +"to any other)\r\n").getBytes(); } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -