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 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); } }
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 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 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 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 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 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 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; } } }
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 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 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 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); } }