private void ProcessKEXINIT(SSH2Packet packet) { _serverKEXINITPayload = packet.Data; SSH2DataReader re = new SSH2DataReader(_serverKEXINITPayload); byte[] head = re.Read(17); //Type and cookie if(head[0]!=(byte)PacketType.SSH_MSG_KEXINIT) throw new Exception(String.Format("Server response is not SSH_MSG_KEXINIT but {0}", head[0])); Encoding enc = Encoding.UTF8; byte[] tmpdata; tmpdata = re.ReadString(); string kex = enc.GetString(tmpdata,0,tmpdata.Length); _cInfo._supportedKEXAlgorithms = kex; CheckAlgorithmSupport("keyexchange", kex, "diffie-hellman-group1-sha1"); tmpdata = re.ReadString(); string host_key = enc.GetString(tmpdata, 0, tmpdata.Length); _cInfo._supportedHostKeyAlgorithms = host_key; _cInfo._algorithmForHostKeyVerification = DecideHostKeyAlgorithm(host_key); tmpdata = re.ReadString(); string enc_cs = enc.GetString(tmpdata, 0, tmpdata.Length); _cInfo._supportedCipherAlgorithms = enc_cs; _cInfo._algorithmForTransmittion = DecideCipherAlgorithm(enc_cs); tmpdata = re.ReadString(); string enc_sc = enc.GetString(tmpdata, 0, tmpdata.Length); _cInfo._algorithmForReception = DecideCipherAlgorithm(enc_sc); tmpdata = re.ReadString(); string mac_cs = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("mac", mac_cs, "hmac-sha1"); tmpdata = re.ReadString(); string mac_sc = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("mac", mac_sc, "hmac-sha1"); tmpdata = re.ReadString(); string comp_cs = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("compression", comp_cs, "none"); tmpdata = re.ReadString(); string comp_sc = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("compression", comp_sc, "none"); tmpdata = re.ReadString(); string lang_cs = enc.GetString(tmpdata, 0, tmpdata.Length); tmpdata = re.ReadString(); string lang_sc = enc.GetString(tmpdata, 0, tmpdata.Length); bool flag = re.ReadBool(); int reserved = re.ReadInt32(); Debug.Assert(re.Rest==0); if(flag) throw new Exception(resLoader.GetString("AlgNegotiationFailed")); }
//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; } }
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); }
internal void ProcessPacket(ISSHChannelEventReceiver receiver, PacketType pt, int data_length, SSH2DataReader re) { //NOTE: the offset of 're' is next to 'receipiant channel' field _leftWindowSize -= data_length; if (_negotiationStatus < 1) { while (_leftWindowSize <= _windowSize) { SSH2DataWriter adj = new SSH2DataWriter(); adj.WritePacketType(PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST); adj.Write(_remoteID); adj.Write(_windowSize); TransmitPacket(adj.ToByteArray()); _leftWindowSize += _windowSize; Debug.WriteLine("Window size is adjusted to " + _leftWindowSize); } } if(pt==PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST) { int w = re.ReadInt32(); //Debug.WriteLine(String.Format("Window Adjust +={0}",w)); } else if(_negotiationStatus!=0) { //when the negotiation is not completed if(_type==ChannelType.Shell) OpenShell(receiver, pt, re); else if(_type==ChannelType.ForwardedLocalToRemote) ReceivePortForwardingResponse(receiver, pt, re); else if(_type==ChannelType.Session) EstablishSession(receiver, pt, re); } else { switch(pt) { case PacketType.SSH_MSG_CHANNEL_DATA: { int len = re.ReadInt32(); //await receiver.OnData(re.Image, re.Offset, len); receiver.OnData(re.Image, re.Offset, len); } break; case PacketType.SSH_MSG_CHANNEL_EXTENDED_DATA: { int t = re.ReadInt32(); byte[] data = re.ReadString(); receiver.OnExtendedData(t, data); } break; case PacketType.SSH_MSG_CHANNEL_REQUEST: { byte[] tmpdata = re.ReadString(); string request = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); bool reply = re.ReadBool(); if(request=="exit-status") { int status = re.ReadInt32(); } } break; case PacketType.SSH_MSG_CHANNEL_EOF: receiver.OnChannelEOF(); break; case PacketType.SSH_MSG_CHANNEL_CLOSE: _connection.UnregisterChannelEventReceiver(_localID); receiver.OnChannelClosed(); break; case PacketType.SSH_MSG_CHANNEL_FAILURE: case PacketType.SSH_MSG_CHANNEL_SUCCESS: receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest); break; default: receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest); Debug.WriteLine(resLoader.GetString("UnexpectedPacket")+pt); break; } } }