Explorar o código

Refactor WaitAny handle
Add ability to specify password as byte array which can be cleaned up later for security reasons

olegkap_cp %!s(int64=13) %!d(string=hai) anos
pai
achega
9125534cff

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/AuthenticationMethodDerivativesTest.cs

@@ -67,7 +67,7 @@ namespace Renci.SshNet.Tests
         [ExpectedException(typeof(ArgumentNullException))]
         public void Password_Test_Pass_Null_Password()
         {
-            new PasswordAuthenticationMethod("valid", null);
+            new PasswordAuthenticationMethod("valid", (string)null);
         }
 
         [TestMethod]

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/ConnectionTest.cs

@@ -163,7 +163,7 @@ namespace Renci.SshNet.Tests
         [ExpectedException(typeof(ArgumentNullException))]
         public void Test_ConnectionInfo_Password_Is_Null()
         {
-            var connectionInfo = new PasswordConnectionInfo(Resources.HOST, Resources.USERNAME, null);
+            var connectionInfo = new PasswordConnectionInfo(Resources.HOST, Resources.USERNAME, (string)null);
         }
 
         [TestMethod]

+ 1 - 1
Renci.SshClient/Renci.SshNet/Common/AuthenticationPasswordChangeEventArgs.cs

@@ -16,7 +16,7 @@ namespace Renci.SshNet.Common
         /// <value>
         /// The new password.
         /// </value>
-        public string NewPassword { get; set; }
+        public byte[] NewPassword { get; set; }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="AuthenticationPasswordChangeEventArgs"/> class.

+ 10 - 8
Renci.SshClient/Renci.SshNet/Messages/Authentication/RequestMessagePassword.cs

@@ -24,12 +24,12 @@ namespace Renci.SshNet.Messages.Authentication
         /// <summary>
         /// Gets authentication password.
         /// </summary>
-        public string Password { get; private set; }
+        public byte[] Password { get; private set; }
 
         /// <summary>
         /// Gets new authentication password.
         /// </summary>
-        public string NewPassword { get; private set; }
+        public byte[] NewPassword { get; private set; }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="RequestMessagePassword"/> class.
@@ -37,10 +37,10 @@ namespace Renci.SshNet.Messages.Authentication
         /// <param name="serviceName">Name of the service.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
-        public RequestMessagePassword(ServiceName serviceName, string username, string password)
+        public RequestMessagePassword(ServiceName serviceName, string username, byte[] password)
             : base(serviceName, username)
         {
-            this.Password = password ?? string.Empty;
+            this.Password = password;
         }
 
         /// <summary>
@@ -50,10 +50,10 @@ namespace Renci.SshNet.Messages.Authentication
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
         /// <param name="newPassword">New authentication password.</param>
-        public RequestMessagePassword(ServiceName serviceName, string username, string password, string newPassword)
+        public RequestMessagePassword(ServiceName serviceName, string username, byte[] password, byte[] newPassword)
             : this(serviceName, username, password)
         {
-            this.NewPassword = newPassword ?? string.Empty;
+            this.NewPassword = newPassword;
         }
 
         /// <summary>
@@ -63,12 +63,14 @@ namespace Renci.SshNet.Messages.Authentication
         {
             base.SaveData();
 
-            this.Write(!string.IsNullOrEmpty(this.NewPassword));
+            this.Write(this.NewPassword != null);
 
+            this.Write((uint)this.Password.Length);
             this.Write(this.Password);
 
-            if (!string.IsNullOrEmpty(this.NewPassword))
+            if (this.NewPassword != null)
             {
+                this.Write((uint)this.NewPassword.Length);
                 this.Write(this.NewPassword);
             }
         }

+ 15 - 3
Renci.SshClient/Renci.SshNet/PasswordAuthenticationMethod.cs

@@ -24,7 +24,7 @@ namespace Renci.SshNet
 
         private RequestMessage _requestMessage;
 
-        private string _password;
+        private byte[] _password;
 
         /// <summary>
         /// Gets authentication method name
@@ -47,6 +47,18 @@ namespace Renci.SshNet
         /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
         /// <exception cref="ArgumentException"><paramref name="password"/> is null.</exception>
         public PasswordAuthenticationMethod(string username, string password)
+            : this(username, Encoding.UTF8.GetBytes(password))
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordAuthenticationMethod"/> class.
+        /// </summary>
+        /// <param name="username">The username.</param>
+        /// <param name="password">The password.</param>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="password"/> is null.</exception>
+        public PasswordAuthenticationMethod(string username, byte[] password)
             : base(username)
         {
             if (password == null)
@@ -54,7 +66,7 @@ namespace Renci.SshNet
 
             this._password = password;
 
-            this._requestMessage = new RequestMessagePassword(ServiceName.Connection, this.Username, password);
+            this._requestMessage = new RequestMessagePassword(ServiceName.Connection, this.Username, this._password);
         }
 
         /// <summary>
@@ -75,7 +87,7 @@ namespace Renci.SshNet
             session.SendMessage(this._requestMessage);
 
             session.WaitHandle(this._authenticationCompleted);
-
+            
             session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
             session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
             session.MessageReceived -= Session_MessageReceived;

+ 110 - 7
Renci.SshClient/Renci.SshNet/PasswordConnectionInfo.cs

@@ -23,7 +23,7 @@ namespace Renci.SshNet
         /// <param name="username">Connection username.</param>
         /// <param name="password">Connection password.</param>
         public PasswordConnectionInfo(string host, string username, string password)
-            : this(host, 22, username, password)
+            : this(host, 22, username, Encoding.UTF8.GetBytes(password))
         {
 
         }
@@ -39,7 +39,7 @@ namespace Renci.SshNet
         /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="f:IPEndPoint.MinPort"/> and <see cref="f:IPEndPoint.MaxPort"/>.</exception>
         public PasswordConnectionInfo(string host, int port, string username, string password)
-            : this(host, port, username, password, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
+            : this(host, port, username, Encoding.UTF8.GetBytes(password), ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
         {
         }
 
@@ -54,7 +54,7 @@ namespace Renci.SshNet
         /// <param name="proxyHost">The proxy host.</param>
         /// <param name="proxyPort">The proxy port.</param>
         public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort)
-            : this(host, port, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+            : this(host, port, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
         {
         }
 
@@ -70,7 +70,7 @@ namespace Renci.SshNet
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</param>
         public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
-            : this(host, port, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+            : this(host, port, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
         {
         }
 
@@ -84,7 +84,7 @@ namespace Renci.SshNet
         /// <param name="proxyHost">The proxy host.</param>
         /// <param name="proxyPort">The proxy port.</param>
         public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort)
-            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+            : this(host, 22, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
         {
         }
 
@@ -99,7 +99,7 @@ namespace Renci.SshNet
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</param>
         public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
-            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+            : this(host, 22, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
         {
         }
 
@@ -115,6 +115,109 @@ namespace Renci.SshNet
         /// <param name="proxyUsername">The proxy username.</param>
         /// <param name="proxyPassword">The proxy password.</param>
         public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : this(host, 22, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        public PasswordConnectionInfo(string host, string username, byte[] password)
+            : this(host, 22, username, password)
+        {
+
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">Connection port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="f:IPEndPoint.MinPort"/> and <see cref="f:IPEndPoint.MaxPort"/>.</exception>
+        public PasswordConnectionInfo(string host, int port, string username, byte[] password)
+            : this(host, port, username, password, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, port, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, port, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        /// <param name="proxyPassword">The proxy password.</param>
+        public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
             : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {
         }
@@ -131,7 +234,7 @@ namespace Renci.SshNet
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</param>
         /// <param name="proxyPassword">The proxy password.</param>
-        public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+        public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
             : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, new PasswordAuthenticationMethod(username, password))
         {
             foreach (var authenticationMethod in this.AuthenticationMethods.OfType<PasswordAuthenticationMethod>())

+ 1 - 1
Renci.SshClient/Renci.SshNet/Session.cs

@@ -640,7 +640,7 @@ namespace Renci.SshNet
             {
                 throw this._exception;
             }
-            else if (index > 1)
+            else if (index == System.Threading.WaitHandle.WaitTimeout)
             {
                 this.SendDisconnect(DisconnectReason.ByApplication, "Operation timeout");
 

+ 1 - 1
Renci.SshClient/Renci.SshNet/SshCommand.cs

@@ -417,7 +417,7 @@ namespace Renci.SshNet
             {
                 throw this._exception;
             }
-            else if (index > 1)
+            else if (index == System.Threading.WaitHandle.WaitTimeout)
             {
                 //  throw time out error
                 throw new SshOperationTimeoutException(string.Format(CultureInfo.CurrentCulture, "Command '{0}' has timed out.", this.CommandText));

+ 1 - 1
Renci.SshClient/Renci.SshNet/SubsystemSession.cs

@@ -157,7 +157,7 @@ namespace Renci.SshNet.Sftp
             {
                 throw this._exception;
             }
-            else if (index > 1)
+            else if (index == System.Threading.WaitHandle.WaitTimeout)
             {
                 //  throw time out error
                 throw new SshOperationTimeoutException(string.Format(CultureInfo.CurrentCulture, "Sftp operation has timed out."));