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 Exception(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 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(wr.ToByteArray().AsBuffer()).ToArray(); if(!VerifyHostKey(key_and_cert, signature, _hash)) return false; //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash)); if(_sessionID==null) _sessionID = _hash; return true; }
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 Exception("service establishment failed "+t); } byte[] tmpdata = re.ReadString(); string s = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); if(servicename!=s) throw new Exception(resLoader.GetString("ProtocolError")); }
private AuthenticationResult ProcessAuthenticationResponse() { do { SSH2DataReader response = new SSH2DataReader(ReceivePacket().Data); PacketType h = response.ReadPacketType(); if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) { byte[] tmpdata = response.ReadString(); string msg = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); _eventReceiver.OnDebugMessage(true, tmpdata); bool partialSuccess = response.ReadBool(); return GranadosRT.Routrek.SSHC.AuthenticationResult.Failure; } else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) { //Debug.WriteLine("USERAUTH_BANNER"); byte[] tmpdata = response.ReadString(); _eventReceiver.OnDebugMessage(true, tmpdata); } else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) { _packetBuilder.Handler = new CallbackSSH2PacketHandler(this); return GranadosRT.Routrek.SSHC.AuthenticationResult.Success; //successfully exit } else if (h == PacketType.SSH_MSG_USERAUTH_INFO_REQUEST) { byte[] tmpdata = response.ReadString(); string name = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); tmpdata = response.ReadString(); string inst = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); tmpdata = response.ReadString(); string lang = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int num = response.ReadInt32(); string[] prompts = new string[num]; for (int i = 0; i < num; i++) { tmpdata = response.ReadString(); prompts[i] = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); bool echo = response.ReadBool(); } if (prompts.Length == 0) { //TODO 0 length response SSH2DataWriter re = new SSH2DataWriter(); re.WritePacketType(PacketType.SSH_MSG_USERAUTH_INFO_RESPONSE); re.Write(0); byte[] ba = re.ToByteArray(); TransmitPacket(ba); return ProcessAuthenticationResponse(); } else { _eventReceiver.OnAuthenticationPrompt(prompts); return GranadosRT.Routrek.SSHC.AuthenticationResult.Prompt; } } else { //throw new Exception(resLoader.GetString("ProtocolError") + resLoader.GetString("UnexpectedPacket") + h); } } while(true); }
private bool ProcessPacket(SSH2Packet packet) { //Debug.WriteLine("ProcessPacket pt="+pt); SSH2DataReader r = new SSH2DataReader(packet.Data); PacketType pt = r.ReadPacketType(); if(pt==PacketType.SSH_MSG_DISCONNECT) { int errorcode = r.ReadInt32(); byte[] tmpdata = r.ReadString(); string description = Encoding.UTF8.GetString(tmpdata, 0 ,tmpdata.Length); _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 Exception("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; } }
//synchronous reception internal SSH2Packet ReceivePacket() { while(true) { SSH2Packet p = null; SynchronizedSSH2PacketHandler handler = (SynchronizedSSH2PacketHandler)_packetBuilder.Handler; try { if (!handler.HasPacket) { handler.Wait(); if (handler.State == ReceiverState.Error) throw new Exception(handler.ErrorMessage); else if (handler.State == ReceiverState.Closed) throw new Exception(resLoader.GetString("SocketClosed")); } p = handler.PopPacket(); } catch (Exception e) { _eventReceiver.OnError(e, e.Message); return p; } 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; } }