/// <summary> /// Processes a channel message. /// </summary> /// <param name="msg"></param> /// <returns></returns> protected internal override bool ProcessChannelMessage(SSHChannelMessage msg) { try { #if DEBUG LogMessage(msg); #endif switch (msg.MessageID) { case SSH_MSG_CHANNEL_REQUEST: { String requesttype = msg.ReadString(); bool wantreply = msg.ReadBool(); byte[] requestdata = new byte[msg.Available]; msg.ReadBytes(requestdata); ChannelRequest(requesttype, wantreply, requestdata); return(true); } case SSH_MSG_CHANNEL_DATA: { int count = (int)SSHPacket.ReadInt(msg.Payload, 5); if (autoConsumeInput) { localwindow.consume(count); if (localwindow.available() <= stream.buffer.Length / 2 && !IsClosed) { AdjustWindow(stream.buffer.Length - localwindow.available()); } } // Fire the input listener event FireInputListenerEvent(msg.Payload, 9, count); return(autoConsumeInput); } case SSH_MSG_CHANNEL_EXTENDED_DATA: { int type = (int)SSHPacket.ReadInt(msg.Payload, 5); int count = (int)SSHPacket.ReadInt(msg.Payload, 9); if (autoConsumeInput) { localwindow.consume(count); if (localwindow.available() <= stream.buffer.Length / 2 && !IsClosed) { AdjustWindow(stream.buffer.Length - localwindow.available()); } } FireErrorStreamListenerEvent(type, msg.Payload, 13, count); return(autoConsumeInput); } case SSH_MSG_CHANNEL_CLOSE: { remoteClosed = true; CheckCloseStatus(true); return(false); } case SSH_MSG_CHANNEL_EOF: { FireEvent(this, ChannelState.REMOTE_EOF); ChannelEOF(); return(false); } default: return(false); } } catch (System.IO.IOException ex) { throw new SSHException(ex.Message, SSHException.INTERNAL_ERROR); } }
internal bool ProcessMessage(SSHPacket packet) { try { if (packet.Length < 1) { Disconnect("Invalid message received", DisconnectionReason.PROTOCOL_ERROR); throw new SSHException("Invalid transport protocol message", SSHException.INTERNAL_ERROR); } switch (packet.MessageID) { case SSH_MSG_DISCONNECT: { packet.ReadInt(); #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_DISCONNECT: " + packet.ReadString()); #endif InternalDisconnect(); throw new SSHException(packet.ReadString(), SSHException.REMOTE_HOST_DISCONNECTED); } case SSH_MSG_IGNORE: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_IGNORE"); #endif return(true); } case SSH_MSG_DEBUG: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_DEBUG"); packet.Skip(1); System.Diagnostics.Trace.WriteLine(packet.ReadString()); #endif return(true); } case SSH_MSG_NEWKEYS: { // This lightweight implemention ignores these messages #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_NEWKEYS"); #endif return(true); } case SSH_MSG_KEX_INIT: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_KEX_INIT"); #endif if (remotekex != null) { Disconnect("Key exchange already in progress!", DisconnectionReason.PROTOCOL_ERROR); throw new SSHException("Key exchange already in progress!", SSHException.PROTOCOL_VIOLATION); } PerformKeyExchange(packet); return(true); } default: { // Not a transport protocol message return(false); } } } catch (System.IO.IOException ex1) { throw new SSHException(ex1.Message, SSHException.INTERNAL_ERROR); } }
/// <summary> /// Start the authentication request. /// </summary> /// <param name="authentication">The authentication protocol instance.</param> /// <param name="serviceName">The name of the service to start upon a successful authentication.</param> public void Authenticate(AuthenticationProtocol authentication, String serviceName) { if (InteractivePrompt == null) { throw new SSHException("An interactive prompt event must be set!", SSHException.BAD_API_USAGE); } ByteBuffer baw = new ByteBuffer(); baw.WriteString(""); baw.WriteString(""); authentication.SendRequest(username, serviceName, "keyboard-interactive", baw.ToByteArray()); while (true) { SSHPacket msg = authentication.ReadMessage(); if (msg.MessageID != SSH_MSG_USERAUTH_INFO_REQUEST) { authentication.transport.Disconnect("Unexpected authentication message received!", DisconnectionReason.PROTOCOL_ERROR); throw new SSHException("Unexpected authentication message received!", SSHException.PROTOCOL_VIOLATION); } String name = msg.ReadString(); String instruction = msg.ReadString(); String langtag = msg.ReadString(); int num = (int)msg.ReadInt(); String prompt; bool echo; KBIPrompt[] prompts = new KBIPrompt[num]; for (int i = 0; i < num; i++) { prompt = msg.ReadString(); echo = (msg.ReadBool()); prompts[i] = new KBIPrompt(prompt, echo); } if (InteractivePrompt(name, instruction, prompts)) { msg = authentication.transport.GetSSHPacket(true); msg.WriteByte(SSH_MSG_USERAUTH_INFO_RESPONSE); msg.WriteInt(prompts.Length); for (int i = 0; i < prompts.Length; i++) { msg.WriteString(prompts[i].Response); } authentication.transport.SendMessage(msg); } else { throw new SSHException("User cancelled during authentication", SSHException.USER_CANCELATION); } } }