/// <summary> /// Process a global message. /// </summary> /// <param name="packet"></param> /// <returns></returns> protected internal override bool ProcessGlobalMessage(SSHPacket packet) { // We need to filter for any messages that require a response from the // connection protocol such as channel open or global requests. These // are not handled anywhere else within this implementation because // doing so would require a thread to wait. try { switch (packet.MessageID) { case SSH_MSG_CHANNEL_OPEN: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_CHANNEL_OPEN"); #endif // Attempt to open the channel System.String type = packet.ReadString(); int remoteid = (int)packet.ReadUINT32(); int remotewindow = (int)packet.ReadUINT32(); int remotepacket = (int)packet.ReadUINT32(); byte[] requestdata = packet.Available > 0 ? new byte[packet.Available] : null; if (requestdata != null) { packet.ReadBytes(requestdata); } ProcessChannelOpenRequest(type, remoteid, remotewindow, remotepacket, requestdata); return(true); } case SSH_MSG_GLOBAL_REQUEST: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_GLOBAL_REQUEST"); #endif // Attempt to process the global request System.String requestname = packet.ReadString(); bool wantreply = packet.ReadBool(); byte[] requestdata = new byte[packet.Available]; packet.ReadBytes(requestdata); // Process the request ProcessGlobalRequest(requestname, wantreply, requestdata); return(true); } default: return(false); } } catch (System.IO.IOException ex) { throw new SSHException(ex.Message, SSHException.INTERNAL_ERROR); } }
internal bool ProcessMessage(SSHPacket packet) { try { switch (packet.MessageID) { case SSH_MSG_USERAUTH_FAILURE: { String auths = packet.ReadString(); throw new SSH2AuthenticationResult( packet.ReadBool() ? AuthenticationResult.FURTHER_AUTHENTICATION_REQUIRED : AuthenticationResult.FAILED, auths); } case SSH_MSG_USERAUTH_SUCCESS: { connection.Start(); throw new SSH2AuthenticationResult(AuthenticationResult.COMPLETE, ""); } case SSH_MSG_USERAUTH_BANNER: { if (((SSH2Context)transport.Context).Banner != null) { ((SSH2Context)transport.Context).Banner.DisplayBanner(packet.ReadString()); } return(true); } default: return(false); } } catch (IOException ex) { throw new SSHException(ex.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); } } }