예제 #1
0
        internal override void request(Session session, Channel channel)
        {
            base.request(session, channel);

            Buffer buf = new Buffer();
            Packet packet = new Packet(buf);

            // byte      SSH_MSG_CHANNEL_REQUEST(98)
            // uint32 recipient channel
            // string request type        // "x11-req"
            // bool want reply         // 0
            // bool   single connection
            // string    x11 authentication protocol // "MIT-MAGIC-COOKIE-1".
            // string    x11 authentication cookie
            // uint32    x11 screen number
            packet.reset();
            buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
            buf.putInt(channel.getRecipient());
            buf.putString("x11-req".getBytes());
            buf.putByte((byte)(waitForReply() ? 1 : 0));
            buf.putByte((byte)0);
            buf.putString("MIT-MAGIC-COOKIE-1".getBytes());
            buf.putString(ChannelX11.getFakedCookie(session));
            buf.putInt(0);
            write(packet);

            session.x11_forwarding = true;
        }
        internal override void request(Session session, Channel channel)
        {
            base.request(session, channel);

            Buffer buf = new Buffer();
            Packet packet = new Packet(buf);

            //byte      SSH_MSG_CHANNEL_REQUEST
            //uint32    recipient_channel
            //string    "window-change"
            //bool   FALSE
            //uint32    terminal width, columns
            //uint32    terminal height, rows
            //uint32    terminal width, pixels
            //uint32    terminal height, pixels
            packet.reset();
            buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
            buf.putInt(channel.getRecipient());
            buf.putString("window-change".getBytes());
            buf.putByte((byte)(waitForReply() ? 1 : 0));
            buf.putInt(width_columns);
            buf.putInt(height_rows);
            buf.putInt(width_pixels);
            buf.putInt(height_pixels);
            write(packet);
        }
예제 #3
0
        protected void write(Packet packet)
        {
            if (reply)
            {
                channel.reply = -1;
            }
            session.write(packet);
            if (reply)
            {
                long start = JavaCompat.CurrentTimeMillis();
                long timeout = channel.connectTimeout;
                while (channel.Connected && channel.reply == -1)
                {
                    try { Thread.Sleep(10); }
                    catch //(Exception ee)
                    {
                    }
                    if (timeout > 0L &&
                       (JavaCompat.CurrentTimeMillis() - start) > timeout)
                    {
                        channel.reply = 0;
                        throw new JSchException("channel request: timeout");
                    }
                }

                if (channel.reply == 0)
                {
                    throw new JSchException("failed to send channel request");
                }
            }
        }
예제 #4
0
 public virtual bool start(Session session)
 {
     this.userinfo = session.getUserInfo();
     this.packet = session.packet;
     this.buf = packet.getBuffer();
     this.username = session.getUserName();
     return true;
 }
예제 #5
0
        public override void run()
        {
            try
            {
                socket = Util.createSocket(host, port, TIMEOUT);
                socket.NoDelay=true;
                io = new IO();
                io.setInputStream(socket.GetStream());
                io.setOutputStream(socket.GetStream());
                sendOpenConfirmation();
            }
            catch //(Exception e)
            {
                sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
                close = true;
                disconnect();
                return;
            }

            thread = Thread.CurrentThread;
            Buffer buf = new Buffer(rmpsize);
            Packet packet = new Packet(buf);
            int i = 0;
            try
            {
                while (thread != null &&
                      io != null &&
                      io.In != null)
                {
                    i = io.In.Read(buf.buffer,
                         14,
                         buf.buffer.Length - 14
                         - 32 - 20 // padding and mac
                         );
                    if (i <= 0)
                    {
                        eof();
                        break;
                    }
                    if (close) break;
                    packet.reset();
                    buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
                    buf.putInt(recipient);
                    buf.putInt(i);
                    buf.skip(i);
                    getSession().write(packet, this, i);
                }
            }
            catch //(Exception e)
            {
                //Console.Error.WriteLine(e);
            }
            disconnect();
        }
예제 #6
0
        //private byte[] f;
        public override void init(Session session,
            byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
        {
            this.session = session;
            this.V_S = V_S;
            this.V_C = V_C;
            this.I_S = I_S;
            this.I_C = I_C;

            try
            {
                Type c = Type.GetType(session.getConfig("sha-1"));
                sha = (HASH)(c.newInstance());
                sha.init();
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }

            buf = new Buffer();
            packet = new Packet(buf);

            try
            {
                Type c = Type.GetType(session.getConfig("dh"));
                dh = (DH)(c.newInstance());
                dh.init();
            }
            catch (Exception e)
            {
                //      Console.Error.WriteLine(e);
                throw e;
            }

            packet.reset();
            buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
            buf.putInt(min);
            buf.putInt(preferred);
            buf.putInt(max);
            session.write(packet);

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "SSH_MSG_KEX_DH_GEX_REQUEST(" + min + "<" + preferred + "<" + max + ") sent");
                JSch.getLogger().log(Logger.INFO,
                                     "expecting SSH_MSG_KEX_DH_GEX_GROUP");
            }

            state = SSH_MSG_KEX_DH_GEX_GROUP;
        }
예제 #7
0
        internal override void request(Session session, Channel channel)
        {
            base.request(session, channel);

            Buffer buf = new Buffer();
            Packet packet = new Packet(buf);
            packet.reset();
            buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
            buf.putInt(channel.getRecipient());
            buf.putString("subsystem".getBytes());
            buf.putByte((byte)(waitForReply() ? 1 : 0));
            buf.putString("sftp".getBytes());
            write(packet);
        }
예제 #8
0
        public override void run()
        {
            //Console.Error.WriteLine(this+":run >");

            Buffer buf = new Buffer(rmpsize);
            Packet packet = new Packet(buf);
            int i = -1;
            try
            {
                while (isConnected() &&
                  thread != null &&
                      io != null &&
                      io.In != null)
                {
                    i = io.In.Read(buf.buffer,
                                 14,
                                 buf.buffer.Length - 14
                                 - 32 - 20 // padding and mac
                         );
                    if (i == 0) continue;
                    if (i == -1)
                    {
                        eof();
                        break;
                    }
                    if (close) break;
                    //System.Out.println("write: "+i);
                    packet.reset();
                    buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
                    buf.putInt(recipient);
                    buf.putInt(i);
                    buf.skip(i);
                    getSession().write(packet, this, i);
                }
            }
            catch //(Exception e)
            {
                //Console.Error.WriteLine("# ChannelExec.run");
                //e.printStackTrace();
            }
            if (thread != null)
            {
                lock (thread) { Monitor.PulseAll(this); }
            }
            thread = null;
            //Console.Error.WriteLine(this+":run <");
        }
예제 #9
0
        internal override void request(Session session, Channel channel)
        {
            base.request(session, channel);

            Buffer buf = new Buffer();
            Packet packet = new Packet(buf);

            // send
            // byte     SSH_MSG_CHANNEL_REQUEST(98)
            // uint32 recipient channel
            // string request type       // "shell"
            // bool want reply        // 0
            packet.reset();
            buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
            buf.putInt(channel.getRecipient());
            buf.putString("shell".getBytes());
            buf.putByte((byte)(waitForReply() ? 1 : 0));
            write(packet);
        }
예제 #10
0
        internal override void request(Session session, Channel channel)
        {
            base.request(session, channel);

            Buffer buf = new Buffer();
            Packet packet = new Packet(buf);

            packet.reset();
            buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
            buf.putInt(channel.getRecipient());
            buf.putString("pty-req".getBytes());
            buf.putByte((byte)(waitForReply() ? 1 : 0));
            buf.putString(ttype.getBytes());
            buf.putInt(tcol);
            buf.putInt(trow);
            buf.putInt(twp);
            buf.putInt(thp);
            buf.putString(terminal_mode);
            write(packet);
        }
예제 #11
0
 private void _write(Packet packet)
 {
     lock (_lock)
     {
         encode(packet);
         if (io != null)
         {
             io.put(packet);
             seqo++;
         }
     }
 }
예제 #12
0
        private void send_kexinit()
        {
            if (in_kex)
                return;

            string cipherc2s = getConfig("cipher.c2s");
            string ciphers2c = getConfig("cipher.s2c");

            string[] not_available = checkCiphers(getConfig("CheckCiphers"));
            if (not_available != null && not_available.Length > 0)
            {
                cipherc2s = Util.diffString(cipherc2s, not_available);
                ciphers2c = Util.diffString(ciphers2c, not_available);
                if (cipherc2s == null || ciphers2c == null)
                {
                    throw new JSchException("There are not any available ciphers.");
                }
            }

            in_kex = true;

            // byte      SSH_MSG_KEXINIT(20)
            // byte[16]  cookie (random bytes)
            // string    kex_algorithms
            // string    server_host_key_algorithms
            // string    encryption_algorithms_client_to_server
            // string    encryption_algorithms_server_to_client
            // string    mac_algorithms_client_to_server
            // string    mac_algorithms_server_to_client
            // string    compression_algorithms_client_to_server
            // string    compression_algorithms_server_to_client
            // string    languages_client_to_server
            // string    languages_server_to_client
            Buffer buf = new Buffer();                // send_kexinit may be invoked
            Packet packet = new Packet(buf);          // by user thread.
            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(cipherc2s.getBytes());
            buf.putString(ciphers2c.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);

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "SSH_MSG_KEXINIT sent");
            }
        }
예제 #13
0
        private void setPortForwarding(string bind_address, int rport)
        {
            lock (grr)
            {
                Buffer buf = new Buffer(100); // ??
                Packet packet = new Packet(buf);

                string address_to_bind = ChannelForwardedTCPIP.normalize(bind_address);

                try
                {
                    // byte SSH_MSG_GLOBAL_REQUEST 80
                    // string "tcpip-forward"
                    // bool want_reply
                    // string  address_to_bind
                    // uint32  port number to bind
                    packet.reset();
                    buf.putByte((byte)SSH_MSG_GLOBAL_REQUEST);
                    buf.putString("tcpip-forward".getBytes());
                    //      buf.putByte((byte)0);
                    buf.putByte((byte)1);
                    buf.putString(address_to_bind.getBytes());
                    buf.putInt(rport);
                    write(packet);
                }
                catch (Exception e)
                {
                    throw new JSchException(e.Message,e);
                }

                grr.setThread(Thread.CurrentThread);
                try { Thread.Sleep(10000); }
                catch //(Exception e)
                {
                }
                int reply = grr.getReply();
                grr.setThread(null);
                if (reply == 0)
                {
                    throw new JSchException("remote port forwarding failed for listen port " + rport);
                }
            }
        }
예제 #14
0
 public void write(Packet packet)
 {
     // Console.Error.WriteLine("in_kex="+in_kex+" "+(packet.buffer.getCommand()));
     while (in_kex)
     {
         byte command = packet.buffer.getCommand();
         //Console.Error.WriteLine("command: "+command);
         if (command == SSH_MSG_KEXINIT ||
            command == SSH_MSG_NEWKEYS ||
            command == SSH_MSG_KEXDH_INIT ||
            command == SSH_MSG_KEXDH_REPLY ||
            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 ||
            command == SSH_MSG_DISCONNECT)
         {
             break;
         }
         try { Thread.Sleep(10); }
         catch (ThreadInterruptedException ) { };
     }
     _write(packet);
 }
예제 #15
0
        /*[MethodImpl(MethodImplOptions.Synchronized)]*/
        /*public*/
        /*synchronized*/
        internal void write(Packet packet, Channel c, int length)
        {
            while (true)
            {
                if (in_kex)
                {
                    Thread.Sleep(10);
                    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.getCommand();
                        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 (in_kex)
                    {
                        continue;
                    }
                    if (c.rwsize >= length)
                    {
                        c.rwsize -= length;
                        break;
                    }
                    try
                    {
                        c.notifyme++;
                        Monitor.Wait(c, 100);
                    }
                    catch (ThreadInterruptedException )
                    {
                    }
                    finally
                    {
                        c.notifyme--;
                    }
                }

            }
            _write(packet);
        }
예제 #16
0
 protected void sendOpenFailure(int reasoncode)
 {
     try
     {
         Buffer buf = new Buffer(100);
         Packet packet = new Packet(buf);
         packet.reset();
         buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
         buf.putInt(getRecipient());
         buf.putInt(reasoncode);
         buf.putString("open failed".getBytes());
         buf.putString("".getBytes());
         getSession().write(packet);
     }
     catch //(Exception e)
     {
     }
 }
예제 #17
0
        /*
        http://www1.ietf.org/internet-drafts/draft-ietf-secsh-connect-24.txt

          5.3  Closing a Channel
        When a party will no longer send more data to a channel, it SHOULD
         send SSH_MSG_CHANNEL_EOF.

                  byte      SSH_MSG_CHANNEL_EOF
                  uint32    recipient_channel

        No explicit response is sent to this message.  However, the
         application may send EOF to whatever is at the other end of the
        channel.  Note that the channel remains open after this message, and
         more data may still be sent in the other direction.  This message
         does not consume window space and can be sent even if no window space
         is available.

           When either party wishes to terminate the channel, it sends
           SSH_MSG_CHANNEL_CLOSE.  Upon receiving this message, a party MUST
         send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
         message for the channel.  The channel is considered closed for a
           party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
         the party may then reuse the channel number.  A party MAY send
         SSH_MSG_CHANNEL_CLOSE without having sent or received
         SSH_MSG_CHANNEL_EOF.

                  byte      SSH_MSG_CHANNEL_CLOSE
                  uint32    recipient_channel

         This message does not consume window space and can be sent even if no
         window space is available.

         It is recommended that any data sent before this message is delivered
           to the actual destination, if possible.
        */
        protected void Close()
        {
            //Console.Error.WriteLine("close!!!!");
            if (close) return;
            close = true;

            eof_local = eof_remote = true;

            try
            {
                Buffer buf = new Buffer(100);
                Packet packet = new Packet(buf);
                packet.reset();
                buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
                buf.putInt(getRecipient());
                getSession().write(packet);
            }
            catch //(Exception e)
            {
                //e.printStackTrace();
            }
        }
예제 #18
0
 protected void sendOpenConfirmation()
 {
     Buffer buf = new Buffer(100);
     Packet packet = new Packet(buf);
     packet.reset();
     buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
     buf.putInt(getRecipient());
     buf.putInt(id);
     buf.putInt(lwsize);
     buf.putInt(lmpsize);
     getSession().write(packet);
 }
예제 #19
0
 internal Session(JSch jsch)
     : base()
 {
     this.jsch = jsch;
     buf = new Buffer();
     packet = new Packet(buf);
 }
예제 #20
0
        public void connect(int connectTimeout)
        {
            Session _session = getSession();
            if (!_session.Connected)
            {
                throw new JSchException("session is down");
            }
            this.connectTimeout = connectTimeout;
            try
            {
                Buffer buf = new Buffer(100);
                Packet packet = new Packet(buf);
                // send
                // byte   SSH_MSG_CHANNEL_OPEN(90)
                // string channel type         //
                // uint32 sender channel       // 0
                // uint32 initial window size  // 0x100000(65536)
                // uint32 maxmum packet size   // 0x4000(16384)
                packet.reset();
                buf.putByte((byte)90);
                buf.putString(this.type);
                buf.putInt(this.id);
                buf.putInt(this.lwsize);
                buf.putInt(this.lmpsize);
                _session.write(packet);
                int retry = 1000;
                long start = JavaCompat.CurrentTimeMillis();
                long timeout = connectTimeout;
                while (this.getRecipient() == -1 &&
                  _session.Connected &&
                  retry > 0)
                {
                    if (timeout > 0L)
                    {
                        if ((JavaCompat.CurrentTimeMillis() - start) > timeout)
                        {
                            retry = 0;
                            continue;
                        }
                    }
                    try { Thread.Sleep(50); }
                    catch  { }
                    retry--;
                }
                if (!_session.Connected)
                {
                    throw new JSchException("session is down");
                }
                if (retry == 0)
                {
                    throw new JSchException("channel is not opened.");
                }

                /*
                 * At the failure in opening the channel on the sshd,
                 * 'SSH_MSG_CHANNEL_OPEN_FAILURE' will be sent from sshd and it will
                 * be processed in Session#run().
                 */
                if (this.isClosed())
                {
                    throw new JSchException("channel is not opened.");
                }
                connected = true;
                Start();
            }
            catch (Exception e)
            {
                connected = false;
                if (e is JSchException)
                    throw (JSchException)e;
                throw new JSchException(e.ToString(), e);
            }
        }
예제 #21
0
            private void Init()
            {
                buffer = new Buffer(channel.rmpsize);
                packet = new Packet(buffer);

                byte[] _buf = buffer.buffer;
                if (_buf.Length - (14 + 0) - 32 - 20 <= 0)
                {
                    buffer = null;
                    packet = null;
                    throw new IOException("failed to initialize the channel.");
                }
            }
예제 #22
0
 public void put(Packet p)
 {
     Out.Write(p.buffer.buffer, 0, p.buffer.index);
     Out.Flush();
 }
        public override void run()
        {
            try
            {
                if (lport == -1)
                {
                    Type c = Type.GetType(target);
                    daemon = (ForwardedTCPIPDaemon)c.newInstance();

                    PipedMemoryStream Out = new PipedMemoryStream(32 * 1024);
                    /*
                    PipedOutputStream Out = new PipedOutputStream();
                    io.setInputStream(new PassiveInputStream(Out
                                                             , 32 * 1024
                                                             ), false);
                    */
                    io.setInputStream(Out);
                    daemon.setChannel(this, getInputStream(), Out);
                    object[] foo = getPort(getSession(), rport);
                    daemon.setArg((object[])foo[3]);

                    new Thread(new ThreadStart(daemon.run)).Start();
                }
                else
                {
                    socket = (factory == null) ?
                       Util.createSocket(target, lport, TIMEOUT) :
                      factory.createSocket(target, lport);
                    socket.NoDelay=true;
                    io.setInputStream(socket.GetStream());
                    io.setOutputStream(socket.GetStream());
                }
                sendOpenConfirmation();
            }
            catch //(Exception e)
            {
                sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
                close = true;
                disconnect();
                return;
            }

            thread = Thread.CurrentThread;
            Buffer buf = new Buffer(rmpsize);
            Packet packet = new Packet(buf);
            int i = 0;
            try
            {
                while (thread != null &&
                      io != null &&
                      io.In != null)
                {
                    i = io.In.Read(buf.buffer,
                                 14,
                                 buf.buffer.Length - 14
                                 - 32 - 20 // padding and mac
                                 );
                    if (i <= 0)
                    {
                        eof();
                        break;
                    }
                    packet.reset();
                    if (close) break;
                    buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
                    buf.putInt(recipient);
                    buf.putInt(i);
                    buf.skip(i);
                    getSession().write(packet, this, i);
                }
            }
            catch //(Exception e)
            {
                //Console.Error.WriteLine(e);
            }
            //thread=null;
            //eof();
            disconnect();
        }
        internal static void delPort(Session session, string address_to_bind, int rport)
        {
            lock (pool)
            {
                object[] foo = null;
                for (int i = 0; i < pool.Count; i++)
                {
                    object[] bar = (object[])(pool[i]);
                    if (bar[0] != session) continue;
                    if (((int)bar[1]) != rport) continue;
                    foo = bar;
                    break;
                }
                if (foo == null) return;
                pool.Remove(foo);
                if (address_to_bind == null)
                {
                    address_to_bind = (string)foo[4];
                }
                if (address_to_bind == null)
                {
                    address_to_bind = "0.0.0.0";
                }
            }

            Buffer buf = new Buffer(100); // ??
            Packet packet = new Packet(buf);

            try
            {
                // byte SSH_MSG_GLOBAL_REQUEST 80
                // string "cancel-tcpip-forward"
                // bool want_reply
                // string  address_to_bind (e.g. "127.0.0.1")
                // uint32  port number to bind
                packet.reset();
                buf.putByte((byte)80/*SSH_MSG_GLOBAL_REQUEST*/);
                buf.putString("cancel-tcpip-forward".getBytes());
                buf.putByte((byte)0);
                buf.putString(address_to_bind.getBytes());
                buf.putInt(rport);
                session.write(packet);
            }
            catch //(Exception e)
            {
                //    throw new JSchException(e.ToString());
            }
        }
예제 #25
0
        // encode will bin invoked in write with synchronization.
        public void encode(Packet packet)
        {
            //Console.Error.WriteLine("encode: "+packet.buffer.getCommand());
            //Console.Error.WriteLine("        "+packet.buffer.index);
            //if(packet.buffer.getCommand()==96){
            //Thread.dumpStack();
            //}
            if (deflater != null)
            {
                packet.buffer.index = deflater.compress(packet.buffer.buffer,
                                  5, packet.buffer.index);
            }
            if (c2scipher != null)
            {
                //packet.padding(c2scipher.getIVSize());
                packet.padding(c2scipher_size);
                int pad = packet.buffer.buffer[4];
                lock (random)
                {
                    random.fill(packet.buffer.buffer, packet.buffer.index - pad, pad);
                }
            }
            else
            {
                packet.padding(8);
            }

            if (c2smac != null)
            {
                c2smac.update(seqo);
                c2smac.update(packet.buffer.buffer, 0, packet.buffer.index);
                c2smac.doFinal(packet.buffer.buffer, packet.buffer.index);
            }
            if (c2scipher != null)
            {
                byte[] buf = packet.buffer.buffer;
                c2scipher.update(buf, 0, packet.buffer.index, buf, 0);
            }
            if (c2smac != null)
            {
                packet.buffer.skip(c2smac.getBlockSize());
            }
        }
예제 #26
0
 public void sendIgnore()
 {
     Buffer buf = new Buffer();
     Packet packet = new Packet(buf);
     packet.reset();
     buf.putByte((byte)SSH_MSG_IGNORE);
     write(packet);
 }
예제 #27
0
        public void run()
        {
            thread = new Thread(this.run);

            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;

            int stimeout = 0;
            try
            {
                while (isConnected &&
                  thread != null)
                {
                    try
                    {
                        buf = Read(buf);
                        stimeout = 0;
                    }
                    catch (IOException/*SocketTimeoutException*/ ee)
                    {
                        if (!in_kex && stimeout < serverAliveCountMax)
                        {
                            sendKeepAliveMsg();
                            stimeout++;
                            continue;
                        }
                        throw ee;
                    }

                    int msgType = buf.getCommand() & 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:
                            //Console.Error.WriteLine("KEXINIT");
                            kex = receive_kexinit(buf);
                            break;

                        case SSH_MSG_NEWKEYS:
                            //Console.Error.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;
                            }

                            if (length[0] == 0)
                            {
                                break;
                            }

                            try
                            {
                                channel.write(foo, start[0], length[0]);
                            }
                            catch //(Exception e)
                            {
                                //Console.Error.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);
                            //Console.Error.WriteLine("stderr: "+Encoding.UTF8.GetString(foo,start[0],length[0]));
                            if (channel == null)
                            {
                                break;
                            }

                            if (length[0] == 0)
                            {
                                break;
                            }

                            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.EofRemote();
                            }
                            /*
                            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;
                            }
                            int r = buf.getInt();
                            int rws = buf.getInt();
                            int rps = buf.getInt();

                            channel.setRemoteWindowSize(rws);
                            channel.setRemotePacketSize(rps);
                            channel.setRecipient(r);
                            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 ((Encoding.UTF8.GetString(foo)).Equals("exit-status"))
                                {
                                    i = buf.getInt();             // exit-status
                                    channel.setExitStatus(i);
                                    //	    Console.Error.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();
                            foo = buf.getString();
                            string ctyp = Encoding.UTF8.GetString(foo);
                            if (!"forwarded-tcpip".Equals(ctyp) &&
                           !("x11".Equals(ctyp) && x11_forwarding) &&
                           !("*****@*****.**".Equals(ctyp) && agent_forwarding))
                            {
                                //Console.Error.WriteLine("Session.run: CHANNEL OPEN "+ctyp);
                                //throw new IOException("Session.run: CHANNEL OPEN "+ctyp);
                                packet.reset();
                                buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
                                buf.putInt(buf.getInt());
                                buf.putInt(Channel.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
                                buf.putString("".getBytes());
                                buf.putString("".getBytes());
                                write(packet);
                                break;
                            }
                            else
                            {
                                channel = Channel.getChannel(ctyp);
                                addChannel(channel);
                                channel.getData(buf);
                                channel.init();

                                Thread tmp = new Thread(channel.run);
                                tmp.Name="Channel " + ctyp + " " + host;
                                if (daemon_thread)
                                {
                                    tmp.IsBackground=daemon_thread;
                                }
                                tmp.Start();
                                break;
                            }
                        case SSH_MSG_CHANNEL_SUCCESS:
                            buf.getInt();
                            buf.getShort();
                            i = buf.getInt();
                            channel = Channel.getChannel(i, this);
                            if (channel == null)
                            {
                                break;
                            }
                            channel.reply = 1;
                            break;
                        case SSH_MSG_CHANNEL_FAILURE:
                            buf.getInt();
                            buf.getShort();
                            i = buf.getInt();
                            channel = Channel.getChannel(i, this);
                            if (channel == null)
                            {
                                break;
                            }
                            channel.reply = 0;
                            break;
                        case SSH_MSG_GLOBAL_REQUEST:
                            buf.getInt();
                            buf.getShort();
                            foo = buf.getString();       // request name
                            reply = (buf.getByte() != 0);
                            if (reply)
                            {
                                packet.reset();
                                buf.putByte((byte)SSH_MSG_REQUEST_FAILURE);
                                write(packet);
                            }
                            break;
                        case SSH_MSG_REQUEST_FAILURE:
                        case SSH_MSG_REQUEST_SUCCESS:
                            Thread t = grr.getThread();
                            if (t != null)
                            {
                                grr.setReply(msgType == SSH_MSG_REQUEST_SUCCESS ? 1 : 0);
                                t.Interrupt();
                            }
                            break;
                        default:
                            //Console.Error.WriteLine("Session.run: unsupported type "+msgType);
                            throw new IOException("Unknown SSH message type " + msgType);
                    }
                }
            }
            catch (Exception e)
            {
                if (JSch.getLogger().isEnabled(Logger.INFO))
                {
                    JSch.getLogger().log(Logger.INFO,
                                         "Caught an exception, leaving main loop due to " + e.Message);
                }
                //Console.Error.WriteLine("# Session.run");
                //e.printStackTrace();
            }
            try
            {
                disconnect();
            }
            catch (NullReferenceException )
            {
                //Console.Error.WriteLine("@1");
                //e.printStackTrace();
            }
            catch //(Exception e)
            {
                //Console.Error.WriteLine("@2");
                //e.printStackTrace();
            }
            isConnected = false;
        }
예제 #28
0
 public void sendKeepAliveMsg()
 {
     Buffer buf = new Buffer();
     Packet packet = new Packet(buf);
     packet.reset();
     buf.putByte((byte)SSH_MSG_GLOBAL_REQUEST);
     buf.putString(keepalivemsg);
     buf.putByte((byte)1);
     write(packet);
 }
예제 #29
0
 protected void eof()
 {
     //Console.Error.WriteLine("EOF!!!! "+this);
     if (close) return;
     if (eof_local) return;
     eof_local = true;
     //close=eof;
     try
     {
         Buffer buf = new Buffer(100);
         Packet packet = new Packet(buf);
         packet.reset();
         buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
         buf.putInt(getRecipient());
         getSession().write(packet);
     }
     catch //(Exception e)
     {
         //Console.Error.WriteLine("Channel.eof");
         //e.printStackTrace();
     }
     /*
     if(!isConnected()){ disconnect(); }
     */
 }
        internal override void write(byte[] foo, int s, int l)
        {
            if (packet == null)
            {
                wbuf = new Buffer(rmpsize);
                packet = new Packet(wbuf);
            }

            rbuf.shift();
            if (rbuf.buffer.Length < rbuf.index + l)
            {
                byte[] newbuf = new byte[rbuf.s + l];
                Array.Copy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.Length);
                rbuf.buffer = newbuf;
            }

            rbuf.putByte(foo, s, l);

            int mlen = rbuf.getInt();
            if (mlen > rbuf.getLength())
            {
                rbuf.s -= 4;
                return;
            }

            int typ = rbuf.getByte();

            Session _session = null;
            try
            {
                _session = getSession();
            }
            catch (JSchException e)
            {
                throw new IOException(e.ToString());
            }

            List<Identity> identities = _session.jsch.identities;
            UserInfo userinfo = _session.getUserInfo();

            if (typ == SSH2_AGENTC_REQUEST_IDENTITIES)
            {
                mbuf.reset();
                mbuf.putByte((byte)SSH2_AGENT_IDENTITIES_ANSWER);
                lock (identities)
                {
                    int count = 0;
                    for (int i = 0; i < identities.Count; i++)
                    {
                        Identity identity = identities[i];
                        if (identity.getPublicKeyBlob() != null)
                            count++;
                    }
                    mbuf.putInt(count);
                    for (int i = 0; i < identities.Count; i++)
                    {
                        Identity identity = identities[i];
                        byte[] pubkeyblob = identity.getPublicKeyBlob();
                        if (pubkeyblob == null)
                            continue;
                        mbuf.putString(pubkeyblob);
                        mbuf.putString("".getBytes());
                    }
                }
                byte[] bar = new byte[mbuf.getLength()];
                mbuf.getByte(bar);

                send(bar);
            }
            else if (typ == SSH2_AGENTC_SIGN_REQUEST)
            {
                byte[] blob = rbuf.getString();
                byte[] data = rbuf.getString();
                int flags = rbuf.getInt();

                //      if((flags & 1)!=0){ //SSH_AGENT_OLD_SIGNATURE // old OpenSSH 2.0, 2.1
                //        datafellows = SSH_BUG_SIGBLOB;
                //      }

                Identity identity = null;
                lock (identities)
                {
                    for (int i = 0; i < identities.Count; i++)
                    {
                        Identity _identity = identities[i];
                        if (_identity.getPublicKeyBlob() == null)
                            continue;
                        if (!Util.array_equals(blob, _identity.getPublicKeyBlob()))
                        {
                            continue;
                        }
                        if (_identity.isEncrypted())
                        {
                            if (userinfo == null)
                                continue;
                            while (_identity.isEncrypted())
                            {
                                if (!userinfo.promptPassphrase("Passphrase for " + _identity.getName()))
                                {
                                    break;
                                }

                                string _passphrase = userinfo.getPassphrase();
                                if (_passphrase == null)
                                {
                                    break;
                                }

                                byte[] passphrase = Util.str2byte(_passphrase);
                                try
                                {
                                    if (_identity.setPassphrase(passphrase))
                                    {
                                        break;
                                    }
                                }
                                catch (JSchException )
                                {
                                    break;
                                }
                            }
                        }

                        if (!_identity.isEncrypted())
                        {
                            identity = _identity;
                            break;
                        }
                    }
                }

                byte[] signature = null;

                if (identity != null)
                {
                    signature = identity.getSignature(data);
                }

                mbuf.reset();
                if (signature == null)
                {
                    mbuf.putByte((byte)SSH2_AGENT_FAILURE);
                }
                else
                {
                    mbuf.putByte((byte)SSH2_AGENT_SIGN_RESPONSE);
                    mbuf.putString(signature);
                }

                byte[] bar = new byte[mbuf.getLength()];
                mbuf.getByte(bar);

                send(bar);
            }
        }