protected void ProcessMsgUserAuthRequestNone(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserNoMethodEventArgs(_lastUserName); if (AuthenticateUserNoMethod != null) { AuthenticateUserNoMethod(this, authUserEventArgs); } // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.Failure: // Send list of supported auth methods. SendMsgUserAuthFailure(false); break; } }
protected void ProcessMsgGlobalRequest(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read request information. string requestName = msgReader.ReadString(); bool wantReply = msgReader.ReadBoolean(); switch (requestName) { case "tcpip-forward": throw new NotImplementedException(); //if (wantReply) SendMsgRequestSuccess(null); //return; default: // Unrecognised request type. break; } // Request has failed. if (wantReply) { SendMsgRequestFailure(); } }
protected List <TerminalMode> ReadTerminalModes(byte[] encodedModes) { var termModes = new List <TerminalMode>(); TerminalModeOpCode opCode; // Read modes from encoded byte stream. using (var streamReader = new SshStreamReader(new MemoryStream(encodedModes))) { while (true) { opCode = (TerminalModeOpCode)streamReader.ReadByte(); if (opCode == TerminalModeOpCode.TtyOpEnd) { break; } if ((byte)opCode >= 1 && (byte)opCode <= 160) { // Add mode to list. termModes.Add(new TerminalMode(opCode, streamReader.ReadUInt32())); } else { // Undefined op code. break; } } } return(termModes); }
protected void ProcessMsgRequestSuccess(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // }
protected void ProcessMsgChannelOpenFailure(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // }
protected void ProcessMsgUserInfoResponse(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read response info. int numResponses = msgReader.ReadInt32(); string[] responses = new string[numResponses]; for (int i = 0; i < numResponses; i++) { responses[i] = Encoding.UTF8.GetString(msgReader.ReadByteString()); } // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserKeyboardInteractiveEventArgs(_lastUserName, responses); if (AuthenticateUserKeyboardInteractive != null) { AuthenticateUserKeyboardInteractive(this, authUserEventArgs); } // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.FurtherAuthRequired: // Auth has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case AuthenticationResult.Failure: // Auth has failed. SendMsgUserAuthFailure(false); break; case AuthenticationResult.RequestMoreInfo: // Request more prompt info from client. RequestPromptInfo(null); break; } }
protected void ProcessMsgUserAuthRequest(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read auth information. string userName = Encoding.UTF8.GetString(msgReader.ReadByteString()); string serviceName = msgReader.ReadString(); string methodName = msgReader.ReadString(); // Store user name and service name used for this auth. _lastUserName = userName; _lastServiceName = serviceName; // Check if service with specified name exists. if (_client.Services.Count(item => item.Name == serviceName) == 0) { // Service was not found. _client.Disconnect(SshDisconnectReason.ServiceNotAvailable, string.Format( "The service with name {0} is not supported by this server.")); throw new DisconnectedException(); } // Check method of authentication. switch (methodName) { case "none": ProcessMsgUserAuthRequestNone(msgReader); break; case "publickey": ProcessMsgUserAuthRequestPublicKey(msgReader); break; case "password": ProcessMsgUserAuthRequestPassword(msgReader); break; case "hostbased": ProcessMsgUserAuthRequestHostBased(msgReader); break; case "keyboard-interactive": ProcessMsgUserAuthRequestKeyboardInteractive(msgReader); break; default: // Invalid auth method. _client.Disconnect(false); break; } }
internal override bool ProcessMessage(byte[] payload) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Check if banner message has not yet been set. if (!_bannerMsgSent) { // Send banner message if one has been specified. if (this.BannerMessage != null) { SendMsgUserAuthBanner(this.BannerMessage, this.BannerMessageLanguage); } _bannerMsgSent = true; } using (var msgReader = new SshStreamReader(new MemoryStream(payload))) { // Check message ID. SshAuthenticationMessage messageId = (SshAuthenticationMessage)msgReader.ReadByte(); #if DEBUG if (System.Enum.IsDefined(typeof(SshAuthenticationMessage), messageId)) { Debug.WriteLine(string.Format(">>> {0}", System.Enum.GetName( typeof(SshAuthenticationMessage), messageId))); } #endif switch (messageId) { // User auth messages case SshAuthenticationMessage.Request: ProcessMsgUserAuthRequest(msgReader); break; case SshAuthenticationMessage.InfoResponse: ProcessMsgUserInfoResponse(msgReader); break; // Unrecognised message default: return(false); } } // Message was recognised. return(true); }
protected void ProcessMsgChannelClose(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } channel.Close(); }
public byte[] GetSignature(byte[] signatureData) { using (var dataStream = new MemoryStream(signatureData)) { using (var dataReader = new SshStreamReader(dataStream)) { // Read signature from stream. if (dataReader.ReadString() != this.Name) { throw new CryptographicException( "Signature was not created with this algorithm."); } var signature = dataReader.ReadByteString(); return(signature); } } }
protected void ProcessMsgChannelExtendedData(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } // Let channel read extended data. var dataType = (SshExtendedDataType)msgReader.ReadUInt32(); var data = msgReader.ReadByteString(); channel.ProcessExtendedData(dataType, data); }
protected void ProcessMsgChannelRequest(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } string requestType = msgReader.ReadString(); bool wantReply = msgReader.ReadBoolean(); // Let channel process request. channel.ProcessRequest(requestType, wantReply, msgReader); }
protected void ProcessMsgUserAuthRequestKeyboardInteractive(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Raise event to specify requested auth method. if (AuthenticationMethodRequested != null) { AuthenticationMethodRequested(this, new AuthMethodRequestedEventArgs(AuthenticationMethod.KeyboardInteractive)); } // Read request information. string language = msgReader.ReadString(); string[] subMethods = Encoding.UTF8.GetString(msgReader.ReadByteString()).Split( new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); // Request prompt info from client. RequestPromptInfo(subMethods); }
protected void ProcessMsgUserAuthRequestPassword(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Raise event to specify requested auth method. if (AuthenticationMethodRequested != null) { AuthenticationMethodRequested(this, new AuthMethodRequestedEventArgs(AuthenticationMethod.Password)); } // Check whether client is changing password. bool changingPassword = msgReader.ReadBoolean(); if (changingPassword) { // Read old and new passwords (in plaintext). string oldPassword = Encoding.UTF8.GetString(msgReader.ReadByteString()); string newPassword = Encoding.UTF8.GetString(msgReader.ReadByteString()); // Raise event to get result of password change request. var changePasswordEventArgs = new ChangePasswordEventArgs(oldPassword, newPassword); if (ChangePassword != null) { ChangePassword(this, changePasswordEventArgs); } // Check result of password change request. switch (changePasswordEventArgs.Result) { case PasswordChangeResult.Success: // Password change and auth have succeeded. AuthenticateUser(_lastServiceName); break; case PasswordChangeResult.FurtherAuthRequired: // Password change has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case PasswordChangeResult.Failure: // Password change has failed. SendMsgUserAuthFailure(false); break; case PasswordChangeResult.NewPasswordUnacceptable: // Password was not changed. SendMsgUserAuthPasswdChangeReq(changePasswordEventArgs.ReplyPrompt, ""); break; } } else { // Read password (in plaintext). string password = Encoding.UTF8.GetString(msgReader.ReadByteString()); // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserPasswordEventArgs(_lastUserName, password); if (AuthenticateUserPassword != null) { AuthenticateUserPassword(this, authUserEventArgs); } // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.FurtherAuthRequired: // Auth has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case AuthenticationResult.Failure: // Increment number of failed auth attempts. _failedAuthAttempts++; if (_failedAuthAttempts < this.MaximumAuthAttempts) { // Auth has failed, but allow client to reattempt auth. SendMsgUserAuthFailure(false); } else { // Auth has failed too many times, disconnect. _client.Disconnect(false); throw new DisconnectedException(); } break; case AuthenticationResult.PasswordExpired: // Password change is required. SendMsgUserAuthPasswdChangeReq("The specified password has expired.", ""); break; } } }
protected void ProcessMsgChannelOpen(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Read channel information. string channelType = msgReader.ReadString(); uint senderChannel = msgReader.ReadUInt32(); uint initialWindowSize = msgReader.ReadUInt32(); uint maxPacketSize = msgReader.ReadUInt32(); // Check channel type. switch (channelType) { default: // Raise event to request channel. var channelRequestedEventArgs = new ChannelOpenRequestEventArgs(senderChannel, (uint)_channels.Count, channelType, initialWindowSize, maxPacketSize); if (ChannelOpenRequest != null) { ChannelOpenRequest(this, channelRequestedEventArgs); } var channel = channelRequestedEventArgs.Channel; // Check if channel was created. if (channel != null) { channel.Opened += new EventHandler <EventArgs>(channel_Opened); channel.Closed += new EventHandler <EventArgs>(channel_Closed); channel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( channel_PropertyChanged); channel.Open(this); _channels.Add(channel); // Send confirmation message. SendMsgChannelOpenConfirmation(channel); } else { string failureDescription = channelRequestedEventArgs.FailureDescription; if (failureDescription != null) { // Create description of failure from reason code. switch (channelRequestedEventArgs.FailureReason) { case SshChannelOpenFailureReason.AdministrativelyProhibited: failureDescription = "Administratively prohibited."; break; case SshChannelOpenFailureReason.ConnectFailed: failureDescription = "Connect attempt failed."; break; case SshChannelOpenFailureReason.UnknownChannelType: failureDescription = string.Format("Unknown channel type '{0}'.", channelType); break; case SshChannelOpenFailureReason.ResourceShortage: failureDescription = "Resource shortage on server."; break; } } // Channel open request has failed. SendMsgChannelOpenFailure(channel, channelRequestedEventArgs.FailureReason, failureDescription, ""); return; } break; } }
protected void ProcessMsgUserAuthRequestHostBased(SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Raise event to specify requested auth method. if (AuthenticationMethodRequested != null) { AuthenticationMethodRequested(this, new AuthMethodRequestedEventArgs(AuthenticationMethod.HostBased)); } // Read request information. string keyAlgName = msgReader.ReadString(); byte[] keyAndCertsData = msgReader.ReadByteString(); string clientHostName = msgReader.ReadString(); string clientUserName = msgReader.ReadString(); // Try to find public key algorithm. PublicKeyAlgorithm keyAlg = null; try { keyAlg = (PublicKeyAlgorithm)_client.PublicKeyAlgorithms.Single(item => item.Name == keyAlgName).Clone(); } catch (InvalidOperationException) { // Public key algorithm is not supported. SendMsgUserAuthFailure(false); } // Load key and certificats data for algorithm. keyAlg.LoadKeyAndCertificatesData(keyAndCertsData); // Read client signature. var signatureData = msgReader.ReadByteString(); var signature = keyAlg.GetSignature(signatureData); // Verify signature. var payloadData = ((MemoryStream)msgReader.BaseStream).ToArray(); if (VerifyPublicKeySignature(keyAlg, payloadData, 0, payloadData.Length - signatureData.Length - 4, signature)) { // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserHostBasedEventArgs(_lastUserName, clientHostName, clientUserName, keyAlg.ExportPublicKey()); if (AuthenticateUserHostBased != null) { AuthenticateUserHostBased(this, authUserEventArgs); } // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.FurtherAuthRequired: // Auth has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case AuthenticationResult.Failure: // Auth has failed. SendMsgUserAuthFailure(false); break; } } else { // Signature is invalid. SendMsgUserAuthFailure(false); } }
public byte[] GetSignature(byte[] signatureData) { using (var dataStream = new MemoryStream(signatureData)) { using (var dataReader = new SshStreamReader(dataStream)) { // Read signature from stream. if (dataReader.ReadString() != this.Name) throw new CryptographicException( "Signature was not created with this algorithm."); var signature = dataReader.ReadByteString(); return signature; } } }
internal override bool ProcessMessage(byte[] payload) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Create memory stream from payload data. using (var msgStream = new MemoryStream(payload)) using (var msgReader = new SshStreamReader(msgStream)) { // Check message ID. SshConnectionMessage messageId = (SshConnectionMessage)msgReader.ReadByte(); #if DEBUG if (System.Enum.IsDefined(typeof(SshConnectionMessage), messageId)) Debug.WriteLine(string.Format(">>> {0}", System.Enum.GetName( typeof(SshConnectionMessage), messageId))); #endif switch (messageId) { // Global request messages case SshConnectionMessage.GlobalRequest: ProcessMsgGlobalRequest(msgReader); break; case SshConnectionMessage.RequestSuccess: ProcessMsgRequestSuccess(msgReader); break; case SshConnectionMessage.RequestFailure: ProcessMsgRequestFailure(msgReader); break; // Channel messages case SshConnectionMessage.ChannelOpen: ProcessMsgChannelOpen(msgReader); break; case SshConnectionMessage.ChannelOpenConfirmation: ProcessMsgChannelOpenConfirmation(msgReader); break; case SshConnectionMessage.ChannelOpenFailure: ProcessMsgChannelOpenFailure(msgReader); break; case SshConnectionMessage.ChannelEof: ProcessMsgChannelEof(msgReader); break; case SshConnectionMessage.ChannelClose: ProcessMsgChannelClose(msgReader); break; case SshConnectionMessage.ChannelRequest: ProcessMsgChannelRequest(msgReader); break; case SshConnectionMessage.ChannelWindowAdjust: ProcessMsgChannelWindowAdjust(msgReader); break; case SshConnectionMessage.ChannelData: ProcessMsgChannelData(msgReader); break; case SshConnectionMessage.ChannelExtendedData: ProcessMsgChannelExtendedData(msgReader); break; // Unrecognised message default: return false; } } // Message was recognised. return true; }
protected void ProcessMsgUserInfoResponse(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read response info. int numResponses = msgReader.ReadInt32(); string[] responses = new string[numResponses]; for (int i = 0; i < numResponses; i++) responses[i] = Encoding.UTF8.GetString(msgReader.ReadByteString()); // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserKeyboardInteractiveEventArgs(_lastUserName, responses); if (AuthenticateUserKeyboardInteractive != null) AuthenticateUserKeyboardInteractive(this, authUserEventArgs); // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.FurtherAuthRequired: // Auth has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case AuthenticationResult.Failure: // Auth has failed. SendMsgUserAuthFailure(false); break; case AuthenticationResult.RequestMoreInfo: // Request more prompt info from client. RequestPromptInfo(null); break; } }
protected internal override void ProcessRequest(string requestType, bool wantReply, SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); switch (requestType) { case "pty-req": // Read information about pseudo-terminal. var termEnvVar = msgReader.ReadString(); var termCharsWidth = msgReader.ReadUInt32(); var termCharsHeight = msgReader.ReadUInt32(); var termPixelsWidth = msgReader.ReadUInt32(); var termPixelsHeight = msgReader.ReadUInt32(); var termModes = ReadTerminalModes(msgReader.ReadByteString()); // Raise event to request pseudo terminal. var pseudoTerminalRequestedEventArgs = new PseudoTerminalRequestedEventArgs(termEnvVar); OnPseudoTerminalRequested(pseudoTerminalRequestedEventArgs); // Check if request to allocate pseudo terminal failed. if (!pseudoTerminalRequestedEventArgs.Success) break; _termEnvVar = termEnvVar; _termCharsWidth = termCharsWidth; _termCharsHeight = termCharsHeight; _termPixelsWidth = termPixelsWidth; _termPixelsHeight = termPixelsHeight; _termModes = termModes; // Add TERM to list of environment variables. _envVars.Add("TERM", _termEnvVar); // Raise event, pseudo terminal has been allocated. OnPseudoTerminalAllocated(new EventArgs()); if (wantReply) _connService.SendMsgChannelSuccess(this); return; case "env": // Read name and value of environment variable. var varName = msgReader.ReadString(); var varValue = msgReader.ReadString(); // Add variable to list. _envVars.Add(varName, varValue); if (wantReply) _connService.SendMsgChannelSuccess(this); return; case "shell": // Start default shell. StartShell(); if (wantReply) _connService.SendMsgChannelSuccess(this); return; case "exec": // not implemented break; default: base.ProcessRequest(requestType, wantReply, msgReader); return; } // Request has failed. if (wantReply) _connService.SendMsgChannelFailure(this); }
protected void ProcessMsgUserAuthRequestKeyboardInteractive(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Raise event to specify requested auth method. if (AuthenticationMethodRequested != null) AuthenticationMethodRequested(this, new AuthMethodRequestedEventArgs(AuthenticationMethod.KeyboardInteractive)); // Read request information. string language = msgReader.ReadString(); string[] subMethods = Encoding.UTF8.GetString(msgReader.ReadByteString()).Split( new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); // Request prompt info from client. RequestPromptInfo(subMethods); }
protected void ProcessMsgUserAuthRequestPassword(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Raise event to specify requested auth method. if (AuthenticationMethodRequested != null) AuthenticationMethodRequested(this, new AuthMethodRequestedEventArgs(AuthenticationMethod.Password)); // Check whether client is changing password. bool changingPassword = msgReader.ReadBoolean(); if (changingPassword) { // Read old and new passwords (in plaintext). string oldPassword = Encoding.UTF8.GetString(msgReader.ReadByteString()); string newPassword = Encoding.UTF8.GetString(msgReader.ReadByteString()); // Raise event to get result of password change request. var changePasswordEventArgs = new ChangePasswordEventArgs(oldPassword, newPassword); if (ChangePassword != null) ChangePassword(this, changePasswordEventArgs); // Check result of password change request. switch (changePasswordEventArgs.Result) { case PasswordChangeResult.Success: // Password change and auth have succeeded. AuthenticateUser(_lastServiceName); break; case PasswordChangeResult.FurtherAuthRequired: // Password change has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case PasswordChangeResult.Failure: // Password change has failed. SendMsgUserAuthFailure(false); break; case PasswordChangeResult.NewPasswordUnacceptable: // Password was not changed. SendMsgUserAuthPasswdChangeReq(changePasswordEventArgs.ReplyPrompt, ""); break; } } else { // Read password (in plaintext). string password = Encoding.UTF8.GetString(msgReader.ReadByteString()); // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserPasswordEventArgs(_lastUserName, password); if (AuthenticateUserPassword != null) AuthenticateUserPassword(this, authUserEventArgs); // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.FurtherAuthRequired: // Auth has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case AuthenticationResult.Failure: // Increment number of failed auth attempts. _failedAuthAttempts++; if (_failedAuthAttempts < this.MaximumAuthAttempts) { // Auth has failed, but allow client to reattempt auth. SendMsgUserAuthFailure(false); } else { // Auth has failed too many times, disconnect. _client.Disconnect(false); throw new DisconnectedException(); } break; case AuthenticationResult.PasswordExpired: // Password change is required. SendMsgUserAuthPasswdChangeReq("The specified password has expired.", ""); break; } } }
internal override bool ProcessMessage(byte[] payload) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Check if banner message has not yet been set. if (!_bannerMsgSent) { // Send banner message if one has been specified. if (this.BannerMessage != null) SendMsgUserAuthBanner(this.BannerMessage, this.BannerMessageLanguage); _bannerMsgSent = true; } using (var msgReader = new SshStreamReader(new MemoryStream(payload))) { // Check message ID. SshAuthenticationMessage messageId = (SshAuthenticationMessage)msgReader.ReadByte(); #if DEBUG if (System.Enum.IsDefined(typeof(SshAuthenticationMessage), messageId)) Debug.WriteLine(string.Format(">>> {0}", System.Enum.GetName( typeof(SshAuthenticationMessage), messageId))); #endif switch (messageId) { // User auth messages case SshAuthenticationMessage.Request: ProcessMsgUserAuthRequest(msgReader); break; case SshAuthenticationMessage.InfoResponse: ProcessMsgUserInfoResponse(msgReader); break; // Unrecognised message default: return false; } } // Message was recognised. return true; }
protected void ProcessMsgChannelExtendedData(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } // Let channel read extended data. var dataType = (SshExtendedDataType)msgReader.ReadUInt32(); var data = msgReader.ReadByteString(); channel.ProcessExtendedData(dataType, data); }
protected void ProcessMsgChannelClose(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } channel.Close(); }
protected List<TerminalMode> ReadTerminalModes(byte[] encodedModes) { var termModes = new List<TerminalMode>(); TerminalModeOpCode opCode; // Read modes from encoded byte stream. using (var streamReader = new SshStreamReader(new MemoryStream(encodedModes))) { while (true) { opCode = (TerminalModeOpCode)streamReader.ReadByte(); if (opCode == TerminalModeOpCode.TtyOpEnd) break; if ((byte)opCode >= 1 && (byte)opCode <= 160) { // Add mode to list. termModes.Add(new TerminalMode(opCode, streamReader.ReadUInt32())); } else { // Undefined op code. break; } } } return termModes; }
protected void ProcessMsgRequestSuccess(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // }
internal override bool ProcessMessage(byte[] payload) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } // Create memory stream from payload data. using (var msgStream = new MemoryStream(payload)) using (var msgReader = new SshStreamReader(msgStream)) { // Check message ID. SshConnectionMessage messageId = (SshConnectionMessage)msgReader.ReadByte(); #if DEBUG if (System.Enum.IsDefined(typeof(SshConnectionMessage), messageId)) { Debug.WriteLine(string.Format(">>> {0}", System.Enum.GetName( typeof(SshConnectionMessage), messageId))); } #endif switch (messageId) { // Global request messages case SshConnectionMessage.GlobalRequest: ProcessMsgGlobalRequest(msgReader); break; case SshConnectionMessage.RequestSuccess: ProcessMsgRequestSuccess(msgReader); break; case SshConnectionMessage.RequestFailure: ProcessMsgRequestFailure(msgReader); break; // Channel messages case SshConnectionMessage.ChannelOpen: ProcessMsgChannelOpen(msgReader); break; case SshConnectionMessage.ChannelOpenConfirmation: ProcessMsgChannelOpenConfirmation(msgReader); break; case SshConnectionMessage.ChannelOpenFailure: ProcessMsgChannelOpenFailure(msgReader); break; case SshConnectionMessage.ChannelEof: ProcessMsgChannelEof(msgReader); break; case SshConnectionMessage.ChannelClose: ProcessMsgChannelClose(msgReader); break; case SshConnectionMessage.ChannelRequest: ProcessMsgChannelRequest(msgReader); break; case SshConnectionMessage.ChannelWindowAdjust: ProcessMsgChannelWindowAdjust(msgReader); break; case SshConnectionMessage.ChannelData: ProcessMsgChannelData(msgReader); break; case SshConnectionMessage.ChannelExtendedData: ProcessMsgChannelExtendedData(msgReader); break; // Unrecognised message default: return(false); } } // Message was recognised. return(true); }
protected internal virtual void ProcessRequest(string requestType, bool wantReply, SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); switch (requestType) { case "signal": // Process signal. ProcessSignal(msgReader.ReadString()); if (wantReply) _connService.SendMsgChannelSuccess(this); return; default: // Unrecognised request type. break; } // Request has failed. if (wantReply) _connService.SendMsgChannelFailure(this); }
protected void ProcessMsgChannelOpen(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read channel information. string channelType = msgReader.ReadString(); uint senderChannel = msgReader.ReadUInt32(); uint initialWindowSize = msgReader.ReadUInt32(); uint maxPacketSize = msgReader.ReadUInt32(); // Check channel type. switch (channelType) { default: // Raise event to request channel. var channelRequestedEventArgs = new ChannelOpenRequestEventArgs(senderChannel, (uint)_channels.Count, channelType, initialWindowSize, maxPacketSize); if (ChannelOpenRequest != null) ChannelOpenRequest(this, channelRequestedEventArgs); var channel = channelRequestedEventArgs.Channel; // Check if channel was created. if (channel != null) { channel.Opened += new EventHandler<EventArgs>(channel_Opened); channel.Closed += new EventHandler<EventArgs>(channel_Closed); channel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( channel_PropertyChanged); channel.Open(this); _channels.Add(channel); // Send confirmation message. SendMsgChannelOpenConfirmation(channel); } else { string failureDescription = channelRequestedEventArgs.FailureDescription; if (failureDescription != null) { // Create description of failure from reason code. switch (channelRequestedEventArgs.FailureReason) { case SshChannelOpenFailureReason.AdministrativelyProhibited: failureDescription = "Administratively prohibited."; break; case SshChannelOpenFailureReason.ConnectFailed: failureDescription = "Connect attempt failed."; break; case SshChannelOpenFailureReason.UnknownChannelType: failureDescription = string.Format("Unknown channel type '{0}'.", channelType); break; case SshChannelOpenFailureReason.ResourceShortage: failureDescription = "Resource shortage on server."; break; } } // Channel open request has failed. SendMsgChannelOpenFailure(channel, channelRequestedEventArgs.FailureReason, failureDescription, ""); return; } break; } }
protected internal override void ProcessRequest(string requestType, bool wantReply, SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } switch (requestType) { case "pty-req": // Read information about pseudo-terminal. var termEnvVar = msgReader.ReadString(); var termCharsWidth = msgReader.ReadUInt32(); var termCharsHeight = msgReader.ReadUInt32(); var termPixelsWidth = msgReader.ReadUInt32(); var termPixelsHeight = msgReader.ReadUInt32(); var termModes = ReadTerminalModes(msgReader.ReadByteString()); // Raise event to request pseudo terminal. var pseudoTerminalRequestedEventArgs = new PseudoTerminalRequestedEventArgs(termEnvVar); OnPseudoTerminalRequested(pseudoTerminalRequestedEventArgs); // Check if request to allocate pseudo terminal failed. if (!pseudoTerminalRequestedEventArgs.Success) { break; } _termEnvVar = termEnvVar; _termCharsWidth = termCharsWidth; _termCharsHeight = termCharsHeight; _termPixelsWidth = termPixelsWidth; _termPixelsHeight = termPixelsHeight; _termModes = termModes; // Add TERM to list of environment variables. _envVars.Add("TERM", _termEnvVar); // Raise event, pseudo terminal has been allocated. OnPseudoTerminalAllocated(new EventArgs()); if (wantReply) { _connService.SendMsgChannelSuccess(this); } return; case "env": // Read name and value of environment variable. var varName = msgReader.ReadString(); var varValue = msgReader.ReadString(); // Add variable to list. _envVars.Add(varName, varValue); if (wantReply) { _connService.SendMsgChannelSuccess(this); } return; case "shell": // Start default shell. StartShell(); if (wantReply) { _connService.SendMsgChannelSuccess(this); } return; case "exec": // not implemented break; default: base.ProcessRequest(requestType, wantReply, msgReader); return; } // Request has failed. if (wantReply) { _connService.SendMsgChannelFailure(this); } }
protected void ProcessMsgUserAuthRequest(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read auth information. string userName = Encoding.UTF8.GetString(msgReader.ReadByteString()); string serviceName = msgReader.ReadString(); string methodName = msgReader.ReadString(); // Store user name and service name used for this auth. _lastUserName = userName; _lastServiceName = serviceName; // Check if service with specified name exists. if (_client.Services.Count(item => item.Name == serviceName) == 0) { // Service was not found. _client.Disconnect(SshDisconnectReason.ServiceNotAvailable, string.Format( "The service with name {0} is not supported by this server.")); throw new DisconnectedException(); } // Check method of authentication. switch (methodName) { case "none": ProcessMsgUserAuthRequestNone(msgReader); break; case "publickey": ProcessMsgUserAuthRequestPublicKey(msgReader); break; case "password": ProcessMsgUserAuthRequestPassword(msgReader); break; case "hostbased": ProcessMsgUserAuthRequestHostBased(msgReader); break; case "keyboard-interactive": ProcessMsgUserAuthRequestKeyboardInteractive(msgReader); break; default: // Invalid auth method. _client.Disconnect(false); break; } }
protected void ProcessMsgChannelOpenFailure(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // }
protected void ProcessMsgUserAuthRequestNone(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserNoMethodEventArgs(_lastUserName); if (AuthenticateUserNoMethod != null) AuthenticateUserNoMethod(this, authUserEventArgs); // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.Failure: // Send list of supported auth methods. SendMsgUserAuthFailure(false); break; } }
protected void ProcessMsgChannelRequest(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } string requestType = msgReader.ReadString(); bool wantReply = msgReader.ReadBoolean(); // Let channel process request. channel.ProcessRequest(requestType, wantReply, msgReader); }
protected void ProcessMsgUserAuthRequestPublicKey(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Raise event to specify requested auth method. if (AuthenticationMethodRequested != null) AuthenticationMethodRequested(this, new AuthMethodRequestedEventArgs(AuthenticationMethod.PublicKey)); // Read request information. bool isAuthRequest = msgReader.ReadBoolean(); string keyAlgName = msgReader.ReadString(); byte[] keyAndCertsData = msgReader.ReadByteString(); // Try to find public key algorithm. PublicKeyAlgorithm keyAlg = null; try { keyAlg = (PublicKeyAlgorithm)_client.PublicKeyAlgorithms.Single(item => item.Name == keyAlgName).Clone(); } catch (InvalidOperationException) { // Public key algorithm is not supported. SendMsgUserAuthFailure(false); } // Load key and certificats data for algorithm. keyAlg.LoadKeyAndCertificatesData(keyAndCertsData); // Check if request is actual auth request or query of whether specified public key is // acceptable. if (isAuthRequest) { // Read client signature. var signatureData = msgReader.ReadByteString(); var signature = keyAlg.GetSignature(signatureData); // Verify signature. var payloadData = ((MemoryStream)msgReader.BaseStream).ToArray(); if (VerifyPublicKeySignature(keyAlg, payloadData, 0, payloadData.Length - signatureData.Length - 4, signature)) { // Raise event to get result of auth attempt. var authUserEventArgs = new AuthUserPublicKeyEventArgs(_lastUserName, keyAlg.ExportPublicKey()); AuthenticateUserPublicKey(this, authUserEventArgs); // Check result of auth attempt. switch (authUserEventArgs.Result) { case AuthenticationResult.Success: // Auth has succeeded. AuthenticateUser(_lastServiceName); break; case AuthenticationResult.FurtherAuthRequired: // Auth has succeeded, but further auth is required. SendMsgUserAuthFailure(true); break; case AuthenticationResult.Failure: // Auth has failed. SendMsgUserAuthFailure(false); break; } } else { // Signature is invalid. SendMsgUserAuthFailure(false); } } else { // Public key is acceptable. SendMsgUserAuthPkOk(keyAlgName, keyAndCertsData); } }
protected void ProcessMsgChannelWindowAdjust(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read channel number and get channel object. uint channelNum = msgReader.ReadUInt32(); SshChannel channel; try { channel = _channels.SingleOrDefault(item => item.ServerChannel == channelNum); } catch (InvalidOperationException) { return; } // Let channel adjust window size. var bytesToAdd = msgReader.ReadUInt32(); channel.ProcessWindowAdjust(bytesToAdd); }
protected void ProcessMsgGlobalRequest(SshStreamReader msgReader) { if (_isDisposed) throw new ObjectDisposedException(this.GetType().FullName); // Read request information. string requestName = msgReader.ReadString(); bool wantReply = msgReader.ReadBoolean(); switch (requestName) { case "tcpip-forward": throw new NotImplementedException(); //if (wantReply) SendMsgRequestSuccess(null); //return; default: // Unrecognised request type. break; } // Request has failed. if (wantReply) SendMsgRequestFailure(); }
protected internal virtual void ProcessRequest(string requestType, bool wantReply, SshStreamReader msgReader) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().FullName); } switch (requestType) { case "signal": // Process signal. ProcessSignal(msgReader.ReadString()); if (wantReply) { _connService.SendMsgChannelSuccess(this); } return; default: // Unrecognised request type. break; } // Request has failed. if (wantReply) { _connService.SendMsgChannelFailure(this); } }