예제 #1
0
        private void ServiceRequest(string servicename)
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_SERVICE_REQUEST);
            wr.Write(servicename);
            TransmitPacket(wr.ToByteArray());

            byte[] response = ReceivePacket().Data;
            SSH2DataReader re = new SSH2DataReader(response);
            PacketType t = re.ReadPacketType();
            if(t!=PacketType.SSH_MSG_SERVICE_ACCEPT) {
                throw new SSHException("service establishment failed "+t);
            }

            string s = Encoding.ASCII.GetString(re.ReadString());
            if(servicename!=s)
                throw new SSHException("protocol error");
        }
예제 #2
0
        private bool ProcessPacket(SSH2Packet packet)
        {
            SSH2DataReader r = new SSH2DataReader(packet.Data);
            PacketType pt = r.ReadPacketType();
            //Debug.WriteLine("ProcessPacket pt="+pt);

            if(pt==PacketType.SSH_MSG_DISCONNECT) {
                int errorcode = r.ReadInt32();
                //string description = Encoding.ASCII.GetString(r.ReadString());
                _eventReceiver.OnConnectionClosed();
                return false;
            }
            else if(_waitingForPortForwardingResponse) {
                if(pt!=PacketType.SSH_MSG_REQUEST_SUCCESS)
                    _eventReceiver.OnUnknownMessage((byte)pt, r.Image);
                _waitingForPortForwardingResponse = false;
                return true;
            }
            else if(pt==PacketType.SSH_MSG_CHANNEL_OPEN) {
                ProcessPortforwardingRequest(_eventReceiver, r);
                return true;
            }
            else if(pt>=PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION && pt<=PacketType.SSH_MSG_CHANNEL_FAILURE) {
                int local_channel = r.ReadInt32();
                ChannelEntry e = FindChannelEntry(local_channel);
                if(e!=null) //throw new SSHException("Unknown channel "+local_channel);
                    ((SSH2Channel)e._channel).ProcessPacket(e._receiver, pt, 5+r.Rest, r);
                else
                    Debug.WriteLine("unexpected channel pt="+pt+" local_channel="+local_channel.ToString());
                return true;
            }
            else if(pt==PacketType.SSH_MSG_IGNORE) {
                _eventReceiver.OnIgnoreMessage(r.ReadString());
                return true;
            }
            else if(_asyncKeyExchanger!=null) {
                _asyncKeyExchanger.AsyncProcessPacket(packet);
                return true;
            }
            else if(pt==PacketType.SSH_MSG_KEXINIT) {
                Debug.WriteLine("Host sent KEXINIT");
                _asyncKeyExchanger = new KeyExchanger(this, _sessionID);
                _asyncKeyExchanger.AsyncProcessPacket(packet);
                return true;
            }
            else {
                _eventReceiver.OnUnknownMessage((byte)pt, r.Image);
                return false;
            }
        }
예제 #3
0
        //synchronous reception
        internal SSH2Packet ReceivePacket()
        {
            while(true) {
                SSH2Packet p = null;
                SynchronizedSSH2PacketHandler handler = (SynchronizedSSH2PacketHandler)_packetBuilder.Handler;
                if(!handler.HasPacket) {
                    handler.Wait();
                    if(handler.State==ReceiverState.Error)
                        throw new SSHException(handler.ErrorMessage);
                    else if(handler.State==ReceiverState.Closed)
                        throw new SSHException("socket closed");
                }
                p = handler.PopPacket();

                SSH2DataReader r = new SSH2DataReader(p.Data);
                PacketType pt = r.ReadPacketType();
                if(pt==PacketType.SSH_MSG_IGNORE) {
                    if(_eventReceiver!=null) _eventReceiver.OnIgnoreMessage(r.ReadString());
                }
                else if(pt==PacketType.SSH_MSG_DEBUG) {
                    bool f = r.ReadBool();
                    if(_eventReceiver!=null) _eventReceiver.OnDebugMessage(f, r.ReadString());
                }
                else
                    return p;
            }
        }
예제 #4
0
 private AuthenticationResult ProcessAuthenticationResponse()
 {
     do {
         SSH2DataReader response = new SSH2DataReader(ReceivePacket().Data);
         PacketType h = response.ReadPacketType();
         if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) {
             string msg = Encoding.ASCII.GetString(response.ReadString());
             return AuthenticationResult.Failure;
         }
         else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) {
             Debug.WriteLine("USERAUTH_BANNER");
         }
         else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) {
             _packetBuilder.Handler = new CallbackSSH2PacketHandler(this);
             return AuthenticationResult.Success; //successfully exit
         }
         else if(h==PacketType.SSH_MSG_USERAUTH_INFO_REQUEST) {
             string name = Encoding.ASCII.GetString(response.ReadString());
             string inst = Encoding.ASCII.GetString(response.ReadString());
             string lang = Encoding.ASCII.GetString(response.ReadString());
             int num = response.ReadInt32();
             string[] prompts = new string[num];
             for(int i=0; i<num; i++) {
                 prompts[i] = Encoding.ASCII.GetString(response.ReadString());
                 bool echo = response.ReadBool();
             }
             _eventReceiver.OnAuthenticationPrompt(prompts);
             return AuthenticationResult.Prompt;
         }
         else
             throw new SSHException("protocol error: unexpected packet type "+h);
     } while(true);
 }
예제 #5
0
        private bool ProcessKEXDHREPLY(SSH2Packet packet)
        {
            //Round2 receives response
            SSH2DataReader re = new SSH2DataReader(packet.Data);
            PacketType h = re.ReadPacketType();
            if(h!=PacketType.SSH_MSG_KEXDH_REPLY) throw new SSHException(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h));
            byte[] key_and_cert = re.ReadString();
            BigInteger f = re.ReadMPInt();
            byte[] signature = re.ReadString();
            Debug.Assert(re.Rest==0);

            //Round3 calc hash H
            SSH2DataWriter wr = new SSH2DataWriter();
            _k = f.modPow(_x, DH_PRIME);
            wr = new SSH2DataWriter();
            wr.Write(_cInfo._clientVersionString);
            wr.Write(_cInfo._serverVersionString);
            wr.WriteAsString(_clientKEXINITPayload);
            wr.WriteAsString(_serverKEXINITPayload);
            wr.WriteAsString(key_and_cert);
            wr.Write(_e);
            wr.Write(f);
            wr.Write(_k);
            _hash = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());

            if(!VerifyHostKey(key_and_cert, signature, _hash)) return false;

            //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash));
            if(_sessionID==null) _sessionID = _hash;
            return true;
        }