Bläddra i källkod

Avoid event-based memory leak in case of exception in Authenticate.
Simplify Dispose(bool).

drieseng 9 år sedan
förälder
incheckning
9334312d04

+ 17 - 21
src/Renci.SshNet/NoneAuthenticationMethod.cs

@@ -12,7 +12,6 @@ namespace Renci.SshNet
     public class NoneAuthenticationMethod : AuthenticationMethod, IDisposable
     {
         private AuthenticationResult _authenticationResult = AuthenticationResult.Failure;
-
         private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
 
         /// <summary>
@@ -31,7 +30,6 @@ namespace Renci.SshNet
         public NoneAuthenticationMethod(string username)
             : base(username)
         {
-
         }
 
         /// <summary>
@@ -50,12 +48,16 @@ namespace Renci.SshNet
             session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived;
             session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
 
-            session.SendMessage(new RequestMessageNone(ServiceName.Connection, Username));
-
-            session.WaitOnHandle(_authenticationCompleted);
-
-            session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
-            session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
+            try
+            {
+                session.SendMessage(new RequestMessageNone(ServiceName.Connection, Username));
+                session.WaitOnHandle(_authenticationCompleted);
+            }
+            finally
+            {
+                session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
+                session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
+            }
 
             return _authenticationResult;
         }
@@ -90,7 +92,6 @@ namespace Renci.SshNet
         public void Dispose()
         {
             Dispose(true);
-
             GC.SuppressFinalize(this);
         }
 
@@ -100,22 +101,17 @@ namespace Renci.SshNet
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
-            // Check to see if Dispose has already been called.
-            if (!_isDisposed)
+            if (_isDisposed)
+                return;
+
+            if (disposing)
             {
-                // If disposing equals true, dispose all managed
-                // and unmanaged resources.
-                if (disposing)
+                if (_authenticationCompleted != null)
                 {
-                    // Dispose managed resources.
-                    if (_authenticationCompleted != null)
-                    {
-                        _authenticationCompleted.Dispose();
-                        _authenticationCompleted = null;
-                    }
+                    _authenticationCompleted.Dispose();
+                    _authenticationCompleted = null;
                 }
 
-                // Note disposing has been done.
                 _isDisposed = true;
             }
         }

+ 20 - 32
src/Renci.SshNet/PasswordAuthenticationMethod.cs

@@ -12,18 +12,13 @@ namespace Renci.SshNet
     /// <summary>
     /// Provides functionality to perform password authentication.
     /// </summary>
-    public partial class PasswordAuthenticationMethod : AuthenticationMethod, IDisposable
+    public class PasswordAuthenticationMethod : AuthenticationMethod, IDisposable
     {
         private AuthenticationResult _authenticationResult = AuthenticationResult.Failure;
-
         private Session _session;
-
         private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
-
         private Exception _exception;
-
         private readonly RequestMessage _requestMessage;
-
         private readonly byte[] _password;
 
         /// <summary>
@@ -65,7 +60,6 @@ namespace Renci.SshNet
                 throw new ArgumentNullException("password");
 
             _password = password;
-
             _requestMessage = new RequestMessagePassword(ServiceName.Connection, Username, _password);
         }
 
@@ -88,21 +82,21 @@ namespace Renci.SshNet
             session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
             session.MessageReceived += Session_MessageReceived;
 
-            session.RegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
-
-            session.SendMessage(_requestMessage);
-
-            session.WaitOnHandle(_authenticationCompleted);
-            
-            session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
-            session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
-            session.MessageReceived -= Session_MessageReceived;
-
+            try
+            {
+                session.RegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
+                session.SendMessage(_requestMessage);
+                session.WaitOnHandle(_authenticationCompleted);
+            }
+            finally 
+            {
+                session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
+                session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
+                session.MessageReceived -= Session_MessageReceived;
+            }
 
             if (_exception != null)
-            {
                 throw _exception;
-            }
 
             return _authenticationResult;
         }
@@ -167,7 +161,6 @@ namespace Renci.SshNet
         public void Dispose()
         {
             Dispose(true);
-
             GC.SuppressFinalize(this);
         }
 
@@ -177,22 +170,17 @@ namespace Renci.SshNet
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
-            // Check to see if Dispose has already been called.
-            if (!_isDisposed)
+            if (_isDisposed)
+                return;
+           
+            if (disposing)
             {
-                // If disposing equals true, dispose all managed
-                // and unmanaged resources.
-                if (disposing)
+                if (_authenticationCompleted != null)
                 {
-                    // Dispose managed resources.
-                    if (_authenticationCompleted != null)
-                    {
-                        _authenticationCompleted.Dispose();
-                        _authenticationCompleted = null;
-                    }
+                    _authenticationCompleted.Dispose();
+                    _authenticationCompleted = null;
                 }
 
-                // Note disposing has been done.
                 _isDisposed = true;
             }
         }

+ 7 - 15
src/Renci.SshNet/PasswordConnectionInfo.cs

@@ -37,7 +37,6 @@ namespace Renci.SshNet
         public PasswordConnectionInfo(string host, string username, string password)
             : this(host, DefaultPort, username, Encoding.UTF8.GetBytes(password))
         {
-
         }
 
         /// <summary>
@@ -140,7 +139,6 @@ namespace Renci.SshNet
         public PasswordConnectionInfo(string host, string username, byte[] password)
             : this(host, DefaultPort, username, password)
         {
-
         }
 
         /// <summary>
@@ -273,7 +271,6 @@ namespace Renci.SshNet
         public void Dispose()
         {
             Dispose(true);
-
             GC.SuppressFinalize(this);
         }
 
@@ -283,24 +280,19 @@ namespace Renci.SshNet
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
-            // Check to see if Dispose has already been called.
-            if (!_isDisposed)
+            if (_isDisposed)
+                return;
+
+            if (disposing)
             {
-                // If disposing equals true, dispose all managed
-                // and unmanaged resources.
-                if (disposing)
+                if (AuthenticationMethods != null)
                 {
-                    // Dispose managed resources.
-                    if (AuthenticationMethods != null)
+                    foreach (var authenticationMethods in AuthenticationMethods.OfType<IDisposable>())
                     {
-                        foreach (var authenticationMethods in AuthenticationMethods.OfType<IDisposable>())
-                        {
-                            authenticationMethods.Dispose();
-                        }
+                        authenticationMethods.Dispose();
                     }
                 }
 
-                // Note disposing has been done.
                 _isDisposed = true;
             }
         }

+ 7 - 15
src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs

@@ -15,9 +15,7 @@ namespace Renci.SshNet
     public class PrivateKeyAuthenticationMethod : AuthenticationMethod, IDisposable
     {
         private AuthenticationResult _authenticationResult = AuthenticationResult.Failure;
-
         private EventWaitHandle _authenticationCompleted = new ManualResetEvent(false);
-
         private bool _isSignatureRequired;
 
         /// <summary>
@@ -154,7 +152,6 @@ namespace Renci.SshNet
         public void Dispose()
         {
             Dispose(true);
-
             GC.SuppressFinalize(this);
         }
 
@@ -164,22 +161,17 @@ namespace Renci.SshNet
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
-            // Check to see if Dispose has already been called.
-            if (!_isDisposed)
+            if (_isDisposed)
+                return;
+
+            if (disposing)
             {
-                // If disposing equals true, dispose all managed
-                // and unmanaged resources.
-                if (disposing)
+                if (_authenticationCompleted != null)
                 {
-                    // Dispose managed resources.
-                    if (_authenticationCompleted != null)
-                    {
-                        _authenticationCompleted.Dispose();
-                        _authenticationCompleted = null;
-                    }
+                    _authenticationCompleted.Dispose();
+                    _authenticationCompleted = null;
                 }
 
-                // Note disposing has been done.
                 _isDisposed = true;
             }
         }

+ 13 - 18
src/Renci.SshNet/PrivateKeyConnectionInfo.cs

@@ -29,7 +29,7 @@ namespace Renci.SshNet
         ///     <code source="..\..\Renci.SshNet.Tests\Classes\PrivateKeyConnectionInfoTest.cs" region="Example PrivateKeyConnectionInfo PrivateKeyFile Multiple" language="C#" title="Connect using multiple private key" />
         /// </example>
         public PrivateKeyConnectionInfo(string host, string username, params PrivateKeyFile[] keyFiles)
-            : this(host, ConnectionInfo.DefaultPort, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
+            : this(host, DefaultPort, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
         {
 
         }
@@ -87,7 +87,7 @@ namespace Renci.SshNet
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="keyFiles">The key files.</param>
         public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params PrivateKeyFile[] keyFiles)
-            : this(host, ConnectionInfo.DefaultPort, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
+            : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
         {
         }
 
@@ -102,7 +102,7 @@ namespace Renci.SshNet
         /// <param name="proxyUsername">The proxy username.</param>
         /// <param name="keyFiles">The key files.</param>
         public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles)
-            : this(host, ConnectionInfo.DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
+            : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
         {
         }
 
@@ -118,7 +118,7 @@ namespace Renci.SshNet
         /// <param name="proxyPassword">The proxy password.</param>
         /// <param name="keyFiles">The key files.</param>
         public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles)
-            : this(host, ConnectionInfo.DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, keyFiles)
+            : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, keyFiles)
         {
         }
 
@@ -137,7 +137,7 @@ namespace Renci.SshNet
         public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles)
             : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, new PrivateKeyAuthenticationMethod(username, keyFiles))
         {
-            this.KeyFiles = new Collection<PrivateKeyFile>(keyFiles);
+            KeyFiles = new Collection<PrivateKeyFile>(keyFiles);
         }
 
         #region IDisposable Members
@@ -150,7 +150,6 @@ namespace Renci.SshNet
         public void Dispose()
         {
             Dispose(true);
-
             GC.SuppressFinalize(this);
         }
 
@@ -160,24 +159,20 @@ namespace Renci.SshNet
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
-            // Check to see if Dispose has already been called.
-            if (!this._isDisposed)
+            if (_isDisposed)
+                return;
+
+            if (disposing)
             {
-                // If disposing equals true, dispose all managed
-                // and unmanaged resources.
-                if (disposing)
+                // Dispose managed resources.
+                if (AuthenticationMethods != null)
                 {
-                    // Dispose managed resources.
-                    if (this.AuthenticationMethods != null)
+                    foreach (var authenticationMethods in AuthenticationMethods.OfType<IDisposable>())
                     {
-                        foreach (var authenticationMethods in this.AuthenticationMethods.OfType<IDisposable>())
-                        {
-                            authenticationMethods.Dispose();
-                        }
+                        authenticationMethods.Dispose();
                     }
                 }
 
-                // Note disposing has been done.
                 _isDisposed = true;
             }
         }