/SharpSSH/jsch/Session.cs
C# | 1856 lines | 1580 code | 182 blank | 94 comment | 255 complexity | 75d56596e1ea5e0464560fb64b2a1635 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- //using System;
-
- using System;
- using System.Collections;
- using System.IO;
- using System.Runtime.CompilerServices;
- using System.Threading;
- using Tamir.SharpSsh.java;
- using Tamir.SharpSsh.java.lang;
- using Tamir.SharpSsh.java.net;
-
- namespace Tamir.SharpSsh.jsch
- {
- public class Session : JavaRunnable
- {
- private static String version = "SharpSSH-" + SshBase.Version.ToString() + "-JSCH-0.1.28";
-
- // http://ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-01.txt
- internal const int SSH_MSG_DISCONNECT = 1;
- internal const int SSH_MSG_IGNORE = 2;
- internal const int SSH_MSG_UNIMPLEMENTED = 3;
- internal const int SSH_MSG_DEBUG = 4;
- internal const int SSH_MSG_SERVICE_REQUEST = 5;
- internal const int SSH_MSG_SERVICE_ACCEPT = 6;
- internal const int SSH_MSG_KEXINIT = 20;
- internal const int SSH_MSG_NEWKEYS = 21;
- internal const int SSH_MSG_KEXDH_INIT = 30;
- internal const int SSH_MSG_KEXDH_REPLY = 31;
- internal const int SSH_MSG_KEX_DH_GEX_GROUP = 31;
- internal const int SSH_MSG_KEX_DH_GEX_INIT = 32;
- internal const int SSH_MSG_KEX_DH_GEX_REPLY = 33;
- internal const int SSH_MSG_KEX_DH_GEX_REQUEST = 34;
- internal const int SSH_MSG_USERAUTH_REQUEST = 50;
- internal const int SSH_MSG_USERAUTH_FAILURE = 51;
- internal const int SSH_MSG_USERAUTH_SUCCESS = 52;
- internal const int SSH_MSG_USERAUTH_BANNER = 53;
- internal const int SSH_MSG_USERAUTH_INFO_REQUEST = 60;
- internal const int SSH_MSG_USERAUTH_INFO_RESPONSE = 61;
- internal const int SSH_MSG_USERAUTH_PK_OK = 60;
- internal const int SSH_MSG_GLOBAL_REQUEST = 80;
- internal const int SSH_MSG_REQUEST_SUCCESS = 81;
- internal const int SSH_MSG_REQUEST_FAILURE = 82;
- internal const int SSH_MSG_CHANNEL_OPEN = 90;
- internal const int SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91;
- internal const int SSH_MSG_CHANNEL_OPEN_FAILURE = 92;
- internal const int SSH_MSG_CHANNEL_WINDOW_ADJUST = 93;
- internal const int SSH_MSG_CHANNEL_DATA = 94;
- internal const int SSH_MSG_CHANNEL_EXTENDED_DATA = 95;
- internal const int SSH_MSG_CHANNEL_EOF = 96;
- internal const int SSH_MSG_CHANNEL_CLOSE = 97;
- internal const int SSH_MSG_CHANNEL_REQUEST = 98;
- internal const int SSH_MSG_CHANNEL_SUCCESS = 99;
- internal const int SSH_MSG_CHANNEL_FAILURE = 100;
-
- private byte[] V_S; // server version
- private byte[] V_C = ("SSH-2.0-" + version).GetBytes(); // client version
-
- private byte[] I_C; // the payload of the client's SSH_MSG_KEXINIT
- private byte[] I_S; // the payload of the server's SSH_MSG_KEXINIT
- private byte[] K_S; // the host key
-
- private byte[] session_id;
-
- private byte[] IVc2s;
- private byte[] IVs2c;
- private byte[] Ec2s;
- private byte[] Es2c;
- private byte[] MACc2s;
- private byte[] MACs2c;
-
- private int seqi = 0;
- private int seqo = 0;
-
- private Cipher s2ccipher;
- private Cipher c2scipher;
- private MAC s2cmac;
- private MAC c2smac;
- private byte[] mac_buf;
-
- private Compression deflater;
- private Compression inflater;
-
- private IO io;
- private Socket socket;
- private int timeout = 0;
-
- private bool _isConnected = false;
-
- private bool isAuthed = false;
-
- private JavaThread connectThread = null;
-
- internal bool x11_forwarding = false;
-
- internal Stream In = null;
- internal Stream Out = null;
-
- internal static Random random;
-
- internal Buffer buf;
- internal Packet packet;
-
- internal SocketFactory socket_factory = null;
-
- private Hashtable config = null;
-
- private IProxy proxy = null;
- private UserInfo userinfo;
-
- internal String host = "127.0.0.1";
- internal int port = 22;
-
- internal String username = null;
- internal String password = null;
-
- internal JSch jsch;
-
- internal Session(JSch jsch)
- {
- ;
- this.jsch = jsch;
- buf = new Buffer();
- packet = new Packet(buf);
- }
-
- public void connect()
- {
- connect(timeout);
- }
-
- public void connect(int connectTimeout)
- {
- if (_isConnected)
- {
- throw new JSchException("session is already connected");
- }
- io = new IO();
- if (random == null)
- {
- try
- {
- var c = Type.GetType(getConfig("random"));
- random = (Random) Activator.CreateInstance(c);
-
- }
- catch (Exception e)
- {
- Console.Error.WriteLine("connect: random " + e);
- }
- }
- Packet.setRandom(random);
-
- try
- {
- int i, j;
- int pad = 0;
-
- if (proxy == null)
- {
- proxy = jsch.getProxy(host);
- if (proxy != null)
- {
- lock (proxy)
- {
- proxy.Close();
- }
- }
- }
-
- if (proxy == null)
- {
- Stream In;
- Stream Out;
- if (socket_factory == null)
- {
- socket = Util.createSocket(host, port, connectTimeout);
- In = socket.getInputStream();
- Out = socket.getOutputStream();
- }
- else
- {
- socket = socket_factory.createSocket(host, port);
- In = socket_factory.getInputStream(socket);
- Out = socket_factory.getOutputStream(socket);
- }
- //if(timeout>0){ socket.setSoTimeout(timeout); }
- socket.setTcpNoDelay(true);
- io.setInputStream(In);
- io.setOutputStream(Out);
- }
- else
- {
- lock (proxy)
- {
- proxy.Connect(socket_factory, host, port, connectTimeout);
- io.setInputStream(proxy.InputStream);
- io.setOutputStream(proxy.OutputStream);
- socket = proxy.Socket;
- }
- }
-
- if (connectTimeout > 0 && socket != null)
- {
- socket.setSoTimeout(connectTimeout);
- }
-
- _isConnected = true;
-
- while (true)
- {
- i = 0;
- j = 0;
- while (i < buf.buffer.Length)
- {
- j = io.getByte();
- if (j < 0) break;
- buf.buffer[i] = (byte) j;
- i++;
- if (j == 10) break;
- }
- if (j < 0)
- {
- throw new JSchException("connection is closed by foreign host");
- }
-
- if (buf.buffer[i - 1] == 10)
- {
- // 0x0a
- i--;
- if (buf.buffer[i - 1] == 13)
- {
- // 0x0d
- i--;
- }
- }
-
- if (i > 4 && (i != buf.buffer.Length) &&
- (buf.buffer[0] != 'S' || buf.buffer[1] != 'S' ||
- buf.buffer[2] != 'H' || buf.buffer[3] != '-'))
- {
- //System.err.println(new String(buf.buffer, 0, i);
- continue;
- }
-
- if (i == buf.buffer.Length ||
- i < 7 || // SSH-1.99 or SSH-2.0
- (buf.buffer[4] == '1' && buf.buffer[6] != '9') // SSH-1.5
- )
- {
- throw new JSchException("invalid server's version String");
- }
- break;
- }
-
- V_S = new byte[i];
- Array.Copy(buf.buffer, 0, V_S, 0, i);
- {
- // Some Cisco devices will miss to read '\n' if it is sent separately.
- byte[] foo = new byte[V_C.Length + 1];
- Array.Copy(V_C, 0, foo, 0, V_C.Length);
- foo[foo.Length - 1] = (byte) '\n';
- io.put(foo, 0, foo.Length);
- }
-
- buf = read(buf);
- //System.Console.WriteLine("read: 20 ? "+buf.buffer[5]);
- if (buf.buffer[5] != SSH_MSG_KEXINIT)
- {
- throw new JSchException("invalid protocol: " + buf.buffer[5]);
- }
- KeyExchange kex = receive_kexinit(buf);
-
- while (true)
- {
- buf = read(buf);
- if (kex.getState() == buf.buffer[5])
- {
- bool result = kex.next(buf);
- if (!result)
- {
- //System.Console.WriteLine("verify: "+result);
- in_kex = false;
- throw new JSchException("verify: " + result);
- }
- }
- else
- {
- in_kex = false;
- throw new JSchException("invalid protocol(kex): " + buf.buffer[5]);
- }
- if (kex.getState() == KeyExchange.STATE_END)
- {
- break;
- }
- }
-
- try
- {
- checkHost(host, kex);
- }
- catch (JSchException ee)
- {
- in_kex = false;
- throw ee;
- }
-
- send_newkeys();
-
- // receive SSH_MSG_NEWKEYS(21)
- buf = read(buf);
- //System.Console.WriteLine("read: 21 ? "+buf.buffer[5]);
- if (buf.buffer[5] == SSH_MSG_NEWKEYS)
- {
- receive_newkeys(buf, kex);
- }
- else
- {
- in_kex = false;
- throw new JSchException("invalid protocol(newkyes): " + buf.buffer[5]);
- }
-
- bool auth = false;
- bool auth_cancel = false;
-
- UserAuthNone usn = new UserAuthNone(userinfo);
- auth = usn.start(this);
-
- String methods = null;
- if (!auth)
- {
- methods = usn.getMethods();
- if (methods != null)
- {
- methods = methods.ToLower();
- }
- else
- {
- // methods: publickey,password,keyboard-interactive
- methods = "publickey,password,keyboard-interactive";
- }
- }
-
- while (true)
- {
- while (!auth && methods != null && methods.Length > 0)
- {
- UserAuth us = null;
- if (methods.StartsWith("publickey"))
- {
- lock (jsch.identities)
- {
- if (jsch.identities.Count > 0)
- {
- us = new UserAuthPublicKey(userinfo);
- }
- }
- }
- else if (methods.StartsWith("keyboard-interactive"))
- {
- if (userinfo is UIKeyboardInteractive)
- {
- us = new UserAuthKeyboardInteractive(userinfo);
- }
- }
- else if (methods.StartsWith("password"))
- {
- us = new UserAuthPassword(userinfo);
- }
- if (us != null)
- {
- try
- {
- auth = us.start(this);
- auth_cancel = false;
- }
- catch (JSchAuthCancelException ee)
- {
- auth_cancel = true;
- }
- catch (JSchPartialAuthException ee)
- {
- methods = ee.getMethods();
- auth_cancel = false;
- continue;
- }
- catch (Exception ee)
- {
- Console.WriteLine("ee: " + ee);
- }
- }
- if (!auth)
- {
- int comma = methods.IndexOf(",");
- if (comma == -1) break;
- methods = methods.Substring(comma + 1);
- }
- }
- break;
- }
-
- if (connectTimeout > 0 || timeout > 0)
- {
- socket.setSoTimeout(timeout);
- }
-
- if (auth)
- {
- isAuthed = true;
- connectThread = new JavaThread(this);
- connectThread.Name("Connect thread " + host + " session");
- connectThread.Start();
- return;
- }
- if (auth_cancel)
- throw new JSchException("Auth cancel");
- throw new JSchException("Auth fail");
- }
- catch (Exception e)
- {
- in_kex = false;
- if (_isConnected)
- {
- try
- {
- packet.reset();
- buf.putByte((byte) SSH_MSG_DISCONNECT);
- buf.putInt(3);
- buf.putString(new JavaString(e.ToString()).GetBytes());
- buf.putString(new JavaString("en").GetBytes());
- write(packet);
- disconnect();
- }
- catch (Exception ee)
- {
- }
- }
- _isConnected = false;
- if (e is JSchException) throw (JSchException) e;
- throw new JSchException("Session.connect: " + e);
- }
- }
-
- private KeyExchange receive_kexinit(Buffer buf)
- {
- int j = buf.getInt();
- if (j != buf.getLength())
- {
- // packet was compressed and
- buf.getByte(); // j is the size of deflated packet.
- I_S = new byte[buf.index - 5];
- }
- else
- {
- I_S = new byte[j - 1 - buf.getByte()];
- }
- Array.Copy(buf.buffer, buf.s, I_S, 0, I_S.Length);
-
- send_kexinit();
- String[] guess = KeyExchange.guess(I_S, I_C);
- if (guess == null)
- {
- throw new JSchException("Algorithm negotiation fail");
- }
-
- if (!isAuthed &&
- (guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS].Equals("none") ||
- (guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC].Equals("none"))))
- {
- throw new JSchException("NONE Cipher should not be chosen before authentification is successed.");
- }
-
- KeyExchange kex = null;
- try
- {
- var c = Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS]));
- kex = (KeyExchange) Activator.CreateInstance(c);
- }
- catch (Exception e)
- {
- Console.Error.WriteLine("kex: " + e);
- }
- kex._guess = guess;
- kex.init(this, V_S, V_C, I_S, I_C);
- return kex;
- }
-
- private bool in_kex = false;
-
- public void rekey()
- {
- send_kexinit();
- }
-
- private void send_kexinit()
- {
- if (in_kex) return;
- in_kex = true;
-
- packet.reset();
- buf.putByte((byte) SSH_MSG_KEXINIT);
- lock (random)
- {
- random.fill(buf.buffer, buf.index, 16);
- buf.skip(16);
- }
- buf.putString(getConfig("kex").GetBytes());
- buf.putString(getConfig("server_host_key").GetBytes());
- buf.putString(getConfig("cipher.c2s").GetBytes());
- buf.putString(getConfig("cipher.s2c").GetBytes());
- buf.putString(getConfig("mac.c2s").GetBytes());
- buf.putString(getConfig("mac.s2c").GetBytes());
- buf.putString(getConfig("compression.c2s").GetBytes());
- buf.putString(getConfig("compression.s2c").GetBytes());
- buf.putString(getConfig("lang.c2s").GetBytes());
- buf.putString(getConfig("lang.s2c").GetBytes());
- buf.putByte((byte) 0);
- buf.putInt(0);
-
- buf.setOffSet(5);
- I_C = new byte[buf.getLength()];
- buf.getByte(I_C);
-
- write(packet);
- }
-
- private void send_newkeys()
- {
- // send SSH_MSG_NEWKEYS(21)
- packet.reset();
- buf.putByte((byte) SSH_MSG_NEWKEYS);
- write(packet);
- }
-
- private void checkHost(String host, KeyExchange kex)
- {
- String shkc = getConfig("StrictHostKeyChecking");
-
- byte[] K_S = kex.getHostKey();
- String key_type = kex.getKeyType();
- String key_fprint = kex.getFingerPrint();
-
- hostkey = new HostKey(host, K_S);
-
- HostKeyRepository hkr = jsch.getHostKeyRepository();
- int i = 0;
- lock (hkr)
- {
- i = hkr.check(host, K_S);
- }
-
- bool insert = false;
-
- if ((shkc.Equals("ask") || shkc.Equals("yes")) &&
- i == HostKeyRepository.CHANGED)
- {
- String file = null;
- lock (hkr)
- {
- file = hkr.getKnownHostsRepositoryID();
- }
- if (file == null)
- {
- file = "known_hosts";
- }
- String message =
- "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n" +
- "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n" +
- "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n" +
- "It is also possible that the " + key_type + " host key has just been changed.\n" +
- "The fingerprint for the " + key_type + " key sent by the remote host is\n" +
- key_fprint + ".\n" +
- "Please contact your system administrator.\n" +
- "Add correct host key in " + file + " to get rid of this message.";
-
- bool b = false;
-
- if (userinfo != null)
- {
- b = userinfo.promptYesNo(message +
- "\nDo you want to delete the old key and insert the new key?");
- }
-
- if (!b)
- {
- throw new JSchException("HostKey has been changed: " + host);
- }
- else
- {
- lock (hkr)
- {
- hkr.remove(host,
- (key_type.Equals("DSA") ? "ssh-dss" : "ssh-rsa"),
- null);
- insert = true;
- }
- }
- }
-
- if ((shkc.Equals("ask") || shkc.Equals("yes")) &&
- (i != HostKeyRepository.OK) && !insert)
- {
- if (shkc.Equals("yes"))
- {
- throw new JSchException("reject HostKey: " + host);
- }
-
- if (userinfo != null)
- {
- bool foo = userinfo.promptYesNo(
- "The authenticity of host '" + host + "' can't be established.\n" +
- key_type + " key fingerprint is " + key_fprint + ".\n" +
- "Are you sure you want to continue connecting?"
- );
- if (!foo)
- {
- throw new JSchException("reject HostKey: " + host);
- }
- insert = true;
- }
- else
- {
- if (i == HostKeyRepository.NOT_INCLUDED)
- throw new JSchException("UnknownHostKey: " + host + ". " + key_type + " key fingerprint is " + key_fprint);
- else throw new JSchException("HostKey has been changed: " + host);
- }
- }
-
- if (shkc.Equals("no") &&
- HostKeyRepository.NOT_INCLUDED == i)
- {
- insert = true;
- }
-
- if (insert)
- {
- lock (hkr)
- {
- hkr.add(host, K_S, userinfo);
- }
- }
- }
-
- public Channel openChannel(String type)
- {
- if (!_isConnected)
- {
- throw new JSchException("session is down");
- }
- try
- {
- Channel channel = Channel.getChannel(type);
- addChannel(channel);
- channel.init();
- return channel;
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- return null;
- }
-
- // encode will bin invoked in write with synchronization.
- public void encode(Packet packet)
- {
- if (deflater != null)
- {
- packet.buffer.index = deflater.compress(packet.buffer.buffer,
- 5, packet.buffer.index);
- }
- if (c2scipher != null)
- {
- packet.padding(c2scipher.getIVSize());
- int pad = packet.buffer.buffer[4];
- lock (random)
- {
- random.fill(packet.buffer.buffer, packet.buffer.index - pad, pad);
- }
- }
- else
- {
- packet.padding(8);
- }
- byte[] mac = null;
- if (c2smac != null)
- {
- c2smac.update(seqo);
- c2smac.update(packet.buffer.buffer, 0, packet.buffer.index);
- mac = c2smac.doFinal();
- }
- if (c2scipher != null)
- {
- byte[] buf = packet.buffer.buffer;
- c2scipher.update(buf, 0, packet.buffer.index, buf, 0);
- }
- if (mac != null)
- {
- packet.buffer.putByte(mac);
- }
- }
-
- private int[] uncompress_len = new int[1];
-
- private int cipher_size = 8;
-
- public Buffer read(Buffer buf)
- {
- int j = 0;
- while (true)
- {
- buf.reset();
- io.getByte(buf.buffer, buf.index, cipher_size);
- buf.index += cipher_size;
- if (s2ccipher != null)
- {
- s2ccipher.update(buf.buffer, 0, cipher_size, buf.buffer, 0);
- }
-
- j = Util.ToInt32(buf.buffer, 0);
- j = j - 4 - cipher_size + 8;
- if (j < 0 || (buf.index + j) > buf.buffer.Length)
- {
- throw new IOException("invalid data");
- }
- if (j > 0)
- {
- io.getByte(buf.buffer, buf.index, j);
- buf.index += (j);
- if (s2ccipher != null)
- {
- s2ccipher.update(buf.buffer, cipher_size, j, buf.buffer, cipher_size);
- }
- }
-
- if (s2cmac != null)
- {
- s2cmac.update(seqi);
- s2cmac.update(buf.buffer, 0, buf.index);
- byte[] result = s2cmac.doFinal();
- io.getByte(mac_buf, 0, mac_buf.Length);
-
- if (result.Length != mac_buf.Length) throw new IOException("MAC Error");
-
- for (int i = 0; i < result.Length; i++)
- {
- if (result[i] != mac_buf[i])
- {
- throw new IOException("MAC Error");
- }
- }
- }
- seqi++;
-
- if (inflater != null)
- {
- //inflater.uncompress(buf);
- int pad = buf.buffer[4];
- uncompress_len[0] = buf.index - 5 - pad;
- byte[] foo = inflater.uncompress(buf.buffer, 5, uncompress_len);
- if (foo != null)
- {
- buf.buffer = foo;
- buf.index = 5 + uncompress_len[0];
- }
- else
- {
- Console.Error.WriteLine("fail in inflater");
- break;
- }
- }
-
- int type = buf.buffer[5] & 0xff;
- //System.Console.WriteLine("read: "+type);
- if (type == SSH_MSG_DISCONNECT)
- {
- buf.rewind();
- buf.getInt();
- buf.getShort();
- int reason_code = buf.getInt();
- byte[] description = buf.getString();
- byte[] language_tag = buf.getString();
- /*
- System.Console.Error.WriteLine("SSH_MSG_DISCONNECT:"+
- " "+reason_code+
- " "+new String(description)+
- " "+new String(language_tag));
- */
- throw new JSchException("SSH_MSG_DISCONNECT:" +
- " " + reason_code +
- " " + new JavaString(description) +
- " " + new JavaString(language_tag));
- //break;
- }
- else if (type == SSH_MSG_IGNORE)
- {
- }
- else if (type == SSH_MSG_DEBUG)
- {
- buf.rewind();
- buf.getInt();
- buf.getShort();
- }
- else if (type == SSH_MSG_CHANNEL_WINDOW_ADJUST)
- {
- buf.rewind();
- buf.getInt();
- buf.getShort();
- Channel c = Channel.getChannel(buf.getInt(), this);
- if (c == null)
- {
- }
- else
- {
- c.addRemoteWindowSize(buf.getInt());
- }
- }
- else
- {
- break;
- }
- }
- buf.rewind();
- return buf;
- }
-
- internal byte[] getSessionId()
- {
- return session_id;
- }
-
- private void receive_newkeys(Buffer buf, KeyExchange kex)
- {
- updateKeys(kex);
- in_kex = false;
- }
-
- private void updateKeys(KeyExchange kex)
- {
- byte[] K = kex.getK();
- byte[] H = kex.getH();
- HASH hash = kex.getHash();
-
- String[] guess = kex._guess;
-
- if (session_id == null)
- {
- session_id = new byte[H.Length];
- Array.Copy(H, 0, session_id, 0, H.Length);
- }
-
- /*
- Initial IV client to server: HASH (K || H || "A" || session_id)
- Initial IV server to client: HASH (K || H || "B" || session_id)
- Encryption key client to server: HASH (K || H || "C" || session_id)
- Encryption key server to client: HASH (K || H || "D" || session_id)
- Integrity key client to server: HASH (K || H || "E" || session_id)
- Integrity key server to client: HASH (K || H || "F" || session_id)
- */
-
- buf.reset();
- buf.putMPInt(K);
- buf.putByte(H);
- buf.putByte((byte) 0x41);
- buf.putByte(session_id);
- hash.update(buf.buffer, 0, buf.index);
- IVc2s = hash.digest();
-
- int j = buf.index - session_id.Length - 1;
-
- buf.buffer[j]++;
- hash.update(buf.buffer, 0, buf.index);
- IVs2c = hash.digest();
-
- buf.buffer[j]++;
- hash.update(buf.buffer, 0, buf.index);
- Ec2s = hash.digest();
-
- buf.buffer[j]++;
- hash.update(buf.buffer, 0, buf.index);
- Es2c = hash.digest();
-
- buf.buffer[j]++;
- hash.update(buf.buffer, 0, buf.index);
- MACc2s = hash.digest();
-
- buf.buffer[j]++;
- hash.update(buf.buffer, 0, buf.index);
- MACs2c = hash.digest();
-
- try
- {
- var c = Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC]));
- s2ccipher = (Cipher) (Activator.CreateInstance(c));
- while (s2ccipher.getBlockSize() > Es2c.Length)
- {
- buf.reset();
- buf.putMPInt(K);
- buf.putByte(H);
- buf.putByte(Es2c);
- hash.update(buf.buffer, 0, buf.index);
- byte[] foo = hash.digest();
- byte[] bar = new byte[Es2c.Length + foo.Length];
- Array.Copy(Es2c, 0, bar, 0, Es2c.Length);
- Array.Copy(foo, 0, bar, Es2c.Length, foo.Length);
- Es2c = bar;
- }
- s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c);
- cipher_size = s2ccipher.getIVSize();
- c = Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]));
- s2cmac = (MAC) (Activator.CreateInstance(c));
- s2cmac.init(MACs2c);
- mac_buf = new byte[s2cmac.getBlockSize()];
-
- c = Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS]));
- c2scipher = (Cipher) (Activator.CreateInstance(c));
- while (c2scipher.getBlockSize() > Ec2s.Length)
- {
- buf.reset();
- buf.putMPInt(K);
- buf.putByte(H);
- buf.putByte(Ec2s);
- hash.update(buf.buffer, 0, buf.index);
- byte[] foo = hash.digest();
- byte[] bar = new byte[Ec2s.Length + foo.Length];
- Array.Copy(Ec2s, 0, bar, 0, Ec2s.Length);
- Array.Copy(foo, 0, bar, Ec2s.Length, foo.Length);
- Ec2s = bar;
- }
- c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s);
-
- c = Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]));
- c2smac = (MAC) (Activator.CreateInstance(c));
- c2smac.init(MACc2s);
-
- if (!guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS].Equals("none"))
- {
- String foo = getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]);
- if (foo != null)
- {
- try
- {
- c = Type.GetType(foo);
- deflater = (Compression)(Activator.CreateInstance(c));
- int level = 6;
- try
- {
- level = Int32.Parse(getConfig("compression_level"));
- }
- catch (Exception ee)
- {
- }
- deflater.init(Compression.DEFLATER, level);
- }
- catch (Exception ee)
- {
- Console.Error.WriteLine(foo + " isn't accessible.");
- }
- }
- }
- else
- {
- if (deflater != null)
- {
- deflater = null;
- }
- }
- if (!guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC].Equals("none"))
- {
- String foo = getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]);
- if (foo != null)
- {
- try
- {
- c = Type.GetType(foo);
- inflater = (Compression)(Activator.CreateInstance(c));
- inflater.init(Compression.INFLATER, 0);
- }
- catch (Exception ee)
- {
- Console.Error.WriteLine(foo + " isn't accessible.");
- }
- }
- }
- else
- {
- if (inflater != null)
- {
- inflater = null;
- }
- }
- }
- catch (Exception e)
- {
- Console.Error.WriteLine("updatekeys: " + e);
- }
- }
-
- public void write(Packet packet, Channel c, int length)
- {
- while (true)
- {
- if (in_kex)
- {
- try
- {
- Thread.Sleep(10);
- }
- catch (ThreadInterruptedException e)
- {
- }
- ;
- continue;
- }
- lock (c)
- {
- if (c.rwsize >= length)
- {
- c.rwsize -= length;
- break;
- }
- }
- if (c._close || !c.isConnected())
- {
- throw new IOException("channel is broken");
- }
-
- bool sendit = false;
- int s = 0;
- byte command = 0;
- int recipient = -1;
- lock (c)
- {
- if (c.rwsize > 0)
- {
- int len = c.rwsize;
- if (len > length)
- {
- len = length;
- }
- if (len != length)
- {
- s = packet.shift(len, (c2smac != null ? c2smac.getBlockSize() : 0));
- }
- command = packet.buffer.buffer[5];
- recipient = c.getRecipient();
- length -= len;
- c.rwsize -= len;
- sendit = true;
- }
- }
- if (sendit)
- {
- _write(packet);
- if (length == 0)
- {
- return;
- }
- packet.unshift(command, recipient, s, length);
- lock (c)
- {
- if (c.rwsize >= length)
- {
- c.rwsize -= length;
- break;
- }
- }
- }
-
- try
- {
- Thread.Sleep(100);
- }
- catch (ThreadInterruptedException e)
- {
- }
- ;
- }
- _write(packet);
- }
-
- public void write(Packet packet)
- {
- while (in_kex)
- {
- byte command = packet.buffer.buffer[5];
-
- if (command == SSH_MSG_KEXINIT ||
- command == SSH_MSG_NEWKEYS ||
- command == SSH_MSG_KEXDH_INIT ||
- command == SSH_MSG_KEXDH_REPLY ||
- command == SSH_MSG_DISCONNECT ||
- command == SSH_MSG_KEX_DH_GEX_GROUP ||
- command == SSH_MSG_KEX_DH_GEX_INIT ||
- command == SSH_MSG_KEX_DH_GEX_REPLY ||
- command == SSH_MSG_KEX_DH_GEX_REQUEST)
- {
- break;
- }
- try
- {
- Thread.Sleep(10);
- }
- catch (ThreadInterruptedException e)
- {
- }
- ;
- }
- _write(packet);
- }
-
- [MethodImpl(MethodImplOptions.Synchronized)]
- private void _write(Packet packet)
- {
- encode(packet);
- if (io != null)
- {
- io.put(packet);
- seqo++;
- }
- }
-
- private JavaRunnable thread;
-
- public void run()
- {
- thread = this;
-
- byte[] foo;
- Buffer buf = new Buffer();
- Packet packet = new Packet(buf);
- int i = 0;
- Channel channel;
- int[] start = new int[1];
- int[] length = new int[1];
- KeyExchange kex = null;
-
- try
- {
- while (_isConnected &&
- thread != null)
- {
- buf = read(buf);
- int msgType = buf.buffer[5] & 0xff;
-
- if (kex != null && kex.getState() == msgType)
- {
- bool result = kex.next(buf);
- if (!result)
- {
- throw new JSchException("verify: " + result);
- }
- continue;
- }
-
- switch (msgType)
- {
- case SSH_MSG_KEXINIT:
- //System.Console.WriteLine("KEXINIT");
- kex = receive_kexinit(buf);
- break;
-
- case SSH_MSG_NEWKEYS:
- //System.Console.WriteLine("NEWKEYS");
- send_newkeys();
- receive_newkeys(buf, kex);
- kex = null;
- break;
-
- case SSH_MSG_CHANNEL_DATA:
- buf.getInt();
- buf.getByte();
- buf.getByte();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- foo = buf.getString(start, length);
- if (channel == null)
- {
- break;
- }
- try
- {
- channel.write(foo, start[0], length[0]);
- }
- catch (Exception e)
- {
- //System.Console.WriteLine(e);
- try
- {
- channel.disconnect();
- }
- catch (Exception ee)
- {
- }
- break;
- }
- int len = length[0];
- channel.setLocalWindowSize(channel.lwsize - len);
- if (channel.lwsize < channel.lwsize_max/2)
- {
- packet.reset();
- buf.putByte((byte) SSH_MSG_CHANNEL_WINDOW_ADJUST);
- buf.putInt(channel.getRecipient());
- buf.putInt(channel.lwsize_max - channel.lwsize);
- write(packet);
- channel.setLocalWindowSize(channel.lwsize_max);
- }
- break;
-
- case SSH_MSG_CHANNEL_EXTENDED_DATA:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- buf.getInt(); // data_type_code == 1
- foo = buf.getString(start, length);
- //System.Console.WriteLine("stderr: "+new String(foo,start[0],length[0]));
- if (channel == null)
- {
- break;
- }
- //channel.write(foo, start[0], length[0]);
- channel.write_ext(foo, start[0], length[0]);
-
- len = length[0];
- channel.setLocalWindowSize(channel.lwsize - len);
- if (channel.lwsize < channel.lwsize_max/2)
- {
- packet.reset();
- buf.putByte((byte) SSH_MSG_CHANNEL_WINDOW_ADJUST);
- buf.putInt(channel.getRecipient());
- buf.putInt(channel.lwsize_max - channel.lwsize);
- write(packet);
- channel.setLocalWindowSize(channel.lwsize_max);
- }
- break;
-
- case SSH_MSG_CHANNEL_WINDOW_ADJUST:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- if (channel == null)
- {
- break;
- }
- channel.addRemoteWindowSize(buf.getInt());
- break;
-
- case SSH_MSG_CHANNEL_EOF:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- if (channel != null)
- {
- //channel._eof_remote=true;
- //channel.eof();
- channel.eof_remote();
- }
- /*
- packet.reset();
- buf.putByte((byte)SSH_MSG_CHANNEL_EOF);
- buf.putInt(channel.getRecipient());
- write(packet);
- */
- break;
- case SSH_MSG_CHANNEL_CLOSE:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- if (channel != null)
- {
- // channel.close();
- channel.disconnect();
- }
- /*
- if(Channel.pool.Count==0){
- thread=null;
- }
- */
- break;
- case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- if (channel == null)
- {
- //break;
- }
- channel.setRecipient(buf.getInt());
- channel.setRemoteWindowSize(buf.getInt());
- channel.setRemotePacketSize(buf.getInt());
- break;
- case SSH_MSG_CHANNEL_OPEN_FAILURE:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- channel = Channel.getChannel(i, this);
- if (channel == null)
- {
- //break;
- }
- int reason_code = buf.getInt();
- //foo=buf.getString(); // additional textual information
- //foo=buf.getString(); // language tag
- channel.exitstatus = reason_code;
- channel._close = true;
- channel._eof_remote = true;
- channel.setRecipient(0);
- break;
- case SSH_MSG_CHANNEL_REQUEST:
- buf.getInt();
- buf.getShort();
- i = buf.getInt();
- foo = buf.getString();
- bool reply = (buf.getByte() != 0);
- channel = Channel.getChannel(i, this);
- if (channel != null)
- {
- byte reply_type = (byte) SSH_MSG_CHANNEL_FAILURE;
- if ((new JavaString(foo)).Equals("exit-status"))
- {
- i = buf.getInt(); // exit-status
- channel.setExitStatus(i);
- // System.Console.WriteLine("exit-stauts: "+i);
- // channel.close();
- reply_type = (byte) SSH_MSG_CHANNEL_SUCCESS;
- }
- if (reply)
- {
- packet.reset();
- buf.putByte(reply_type);
- buf.putInt(channel.getRecipient());
- write(packet);
- }
- }
- else
- {
- }
- break;
- case SSH_MSG_CHANNEL_OPEN:
- buf.getInt();
- buf.getShort();
- …
Large files files are truncated, but you can click here to view the full file