Răsfoiți Sursa

Refactor out use of dynamic types, and reflection for processing received SSH messages.

drieseng 9 ani în urmă
părinte
comite
f9773a6786
49 a modificat fișierele cu 398 adăugiri și 579 ștergeri
  1. 3 3
      src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj
  2. 8 8
      src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj
  3. 10 9
      src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs
  4. 5 0
      src/Renci.SshNet/Messages/Authentication/BannerMessage.cs
  5. 5 0
      src/Renci.SshNet/Messages/Authentication/FailureMessage.cs
  6. 5 0
      src/Renci.SshNet/Messages/Authentication/InformationRequestMessage.cs
  7. 6 1
      src/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs
  8. 5 0
      src/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs
  9. 5 0
      src/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs
  10. 5 0
      src/Renci.SshNet/Messages/Authentication/RequestMessage.cs
  11. 5 0
      src/Renci.SshNet/Messages/Authentication/SuccessMessage.cs
  12. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelCloseMessage.cs
  13. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs
  14. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelEofMessage.cs
  15. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelExtendedDataMessage.cs
  16. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelFailureMessage.cs
  17. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs
  18. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelOpenConfirmationMessage.cs
  19. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelOpenFailureMessage.cs
  20. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelRequest/ChannelRequestMessage.cs
  21. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelSuccessMessage.cs
  22. 5 0
      src/Renci.SshNet/Messages/Connection/ChannelWindowAdjustMessage.cs
  23. 5 0
      src/Renci.SshNet/Messages/Connection/GlobalRequestMessage.cs
  24. 5 0
      src/Renci.SshNet/Messages/Connection/RequestFailureMessage.cs
  25. 5 0
      src/Renci.SshNet/Messages/Connection/RequestSuccessMessage.cs
  26. 8 2
      src/Renci.SshNet/Messages/Message.cs
  27. 5 0
      src/Renci.SshNet/Messages/Transport/DebugMessage.cs
  28. 5 0
      src/Renci.SshNet/Messages/Transport/DisconnectMessage.cs
  29. 5 0
      src/Renci.SshNet/Messages/Transport/IgnoreMessage.cs
  30. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeGroup.cs
  31. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeInit.cs
  32. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeReply.cs
  33. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeRequest.cs
  34. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeDhInitMessage.cs
  35. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeDhReplyMessage.cs
  36. 5 1
      src/Renci.SshNet/Messages/Transport/KeyExchangeEcdhInitMessage.cs
  37. 5 1
      src/Renci.SshNet/Messages/Transport/KeyExchangeEcdhReplyMessage.cs
  38. 5 0
      src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs
  39. 5 0
      src/Renci.SshNet/Messages/Transport/NewKeysMessage.cs
  40. 5 0
      src/Renci.SshNet/Messages/Transport/ServiceAcceptMessage.cs
  41. 5 0
      src/Renci.SshNet/Messages/Transport/ServiceRequestMessage.cs
  42. 5 0
      src/Renci.SshNet/Messages/Transport/UnimplementedMessage.cs
  43. 21 24
      src/Renci.SshNet/PasswordAuthenticationMethod.cs
  44. 5 9
      src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs
  45. 2 2
      src/Renci.SshNet/Renci.SshNet.csproj
  46. 33 28
      src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeShaBase.cs
  47. 10 12
      src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs
  48. 107 474
      src/Renci.SshNet/Session.cs
  49. 0 5
      src/Renci.SshNet/Sftp/SftpSession.cs

+ 3 - 3
src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj

@@ -29,7 +29,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>Bin\Debug</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1_MANAGED;FEATURE_HASH_SHA256_MANAGED;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1_MANAGED;FEATURE_HASH_SHA256_MANAGED;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
     <NoStdLib>true</NoStdLib>
     <NoConfig>true</NoConfig>
     <ErrorReport>prompt</ErrorReport>
@@ -42,7 +42,7 @@
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
     <OutputPath>Bin\Release</OutputPath>
-    <DefineConstants>TRACE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1_MANAGED;FEATURE_HASH_SHA256_MANAGED;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1_MANAGED;FEATURE_HASH_SHA256_MANAGED;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
     <NoStdLib>true</NoStdLib>
     <NoConfig>true</NoConfig>
     <ErrorReport>prompt</ErrorReport>
@@ -923,7 +923,7 @@
       <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
         <SilverlightProjectProperties />
       </FlavorProperties>
-      <UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
+      <UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
     </VisualStudio>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 8 - 8
src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj

@@ -23,7 +23,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Debug\Renci.SshNet.xml</DocumentationFile>
@@ -34,7 +34,7 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
     <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
@@ -44,7 +44,7 @@
     <PlatformTarget>x86</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <OutputPath>bin\x86\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <NoWarn>;2008</NoWarn>
     <DebugType>full</DebugType>
     <PlatformTarget>x86</PlatformTarget>
@@ -54,7 +54,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
     <PlatformTarget>x86</PlatformTarget>
     <OutputPath>bin\x86\Release\</OutputPath>
-    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <Optimize>true</Optimize>
     <NoWarn>;2008</NoWarn>
     <DebugType>pdbonly</DebugType>
@@ -66,7 +66,7 @@
     <PlatformTarget>ARM</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <OutputPath>bin\ARM\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <NoWarn>;2008</NoWarn>
     <DebugType>full</DebugType>
     <PlatformTarget>ARM</PlatformTarget>
@@ -76,7 +76,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
     <PlatformTarget>ARM</PlatformTarget>
     <OutputPath>bin\ARM\Release\</OutputPath>
-    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <Optimize>true</Optimize>
     <NoWarn>;2008</NoWarn>
     <DebugType>pdbonly</DebugType>
@@ -88,7 +88,7 @@
     <PlatformTarget>x64</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <OutputPath>bin\x64\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <NoWarn>;2008</NoWarn>
     <DebugType>full</DebugType>
     <PlatformTarget>x64</PlatformTarget>
@@ -98,7 +98,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
     <PlatformTarget>x64</PlatformTarget>
     <OutputPath>bin\x64\Release\</OutputPath>
-    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;FEATURE_DATAGRAMSOCKET;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_ENCODING_ASCII</DefineConstants>
     <Optimize>true</Optimize>
     <NoWarn>;2008</NoWarn>
     <DebugType>pdbonly</DebugType>

+ 10 - 9
src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs

@@ -55,7 +55,7 @@ namespace Renci.SshNet
 
             session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived;
             session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
-            session.MessageReceived += Session_MessageReceived;
+            session.UserAuthenticationInformationRequestReceived += Session_UserAuthenticationInformationRequestReceived;
 
             session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
 
@@ -69,7 +69,7 @@ namespace Renci.SshNet
                 session.UnRegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
                 session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
                 session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
-                session.MessageReceived -= Session_MessageReceived;
+                session.UserAuthenticationInformationRequestReceived -= Session_UserAuthenticationInformationRequestReceived;
             }
 
             if (_exception != null)
@@ -97,14 +97,16 @@ namespace Renci.SshNet
             _authenticationCompleted.Set();
         }
 
-        private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        private void Session_UserAuthenticationInformationRequestReceived(object sender, MessageEventArgs<InformationRequestMessage> e)
         {
-            var informationRequestMessage = e.Message as InformationRequestMessage;
-            if (informationRequestMessage != null)
-            {
-                var eventArgs = new AuthenticationPromptEventArgs(Username, informationRequestMessage.Instruction, informationRequestMessage.Language, informationRequestMessage.Prompts);
+            var informationRequestMessage = e.Message;
+
+            var eventArgs = new AuthenticationPromptEventArgs(Username,
+                                                              informationRequestMessage.Instruction,
+                                                              informationRequestMessage.Language,
+                                                              informationRequestMessage.Prompts);
 
-                ThreadAbstraction.ExecuteThread(() =>
+            ThreadAbstraction.ExecuteThread(() =>
                 {
                     try
                     {
@@ -129,7 +131,6 @@ namespace Renci.SshNet
                         _authenticationCompleted.Set();
                     }
                 });
-            }
         }
 
         #region IDisposable Members

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/BannerMessage.cs

@@ -44,6 +44,11 @@
             }
         }
 
+        internal override void Process(Session session)
+        {
+            session.OnUserAuthenticationBannerReceived(this);
+        }
+
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// </summary>

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/FailureMessage.cs

@@ -49,5 +49,10 @@ namespace Renci.SshNet.Messages.Authentication
         {
             throw new NotImplementedException();
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnUserAuthenticationFailureReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/InformationRequestMessage.cs

@@ -63,5 +63,10 @@ namespace Renci.SshNet.Messages.Authentication
         {
             throw new NotImplementedException();
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnUserAuthenticationInformationRequestReceived(this);
+        }
     }
 }

+ 6 - 1
src/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs

@@ -47,11 +47,16 @@ namespace Renci.SshNet.Messages.Authentication
         /// </summary>
         protected override void SaveData()
         {
-            Write((UInt32)Responses.Count);
+            Write((uint) Responses.Count);
             foreach (var response in Responses)
             {
                 Write(response);
             }
         }
+
+        internal override void Process(Session session)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs

@@ -52,5 +52,10 @@
             WriteBinaryString(Message);
             WriteBinaryString(Language);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnUserAuthenticationPasswordChangeRequiredReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs

@@ -38,6 +38,11 @@
             }
         }
 
+        internal override void Process(Session session)
+        {
+            session.OnUserAuthenticationPublicKeyReceived(this);
+        }
+
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// </summary>

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/RequestMessage.cs

@@ -100,6 +100,11 @@ namespace Renci.SshNet.Messages.Authentication
             WriteBinaryString(_serviceName);
             WriteBinaryString(_methodNameBytes);
         }
+
+        internal override void Process(Session session)
+        {
+            throw new NotImplementedException();
+        }
     }
 }
 

+ 5 - 0
src/Renci.SshNet/Messages/Authentication/SuccessMessage.cs

@@ -19,5 +19,10 @@
         protected override void SaveData()
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnUserAuthenticationSuccessReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelCloseMessage.cs

@@ -22,5 +22,10 @@
             : base(localChannelNumber)
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelCloseReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs

@@ -54,6 +54,11 @@ namespace Renci.SshNet.Messages.Connection
             }
         }
 
+        internal override void Process(Session session)
+        {
+            session.OnChannelDataReceived(this);
+        }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="ChannelDataMessage"/> class.
         /// </summary>

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelEofMessage.cs

@@ -22,5 +22,10 @@
             : base(localChannelNumber)
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelEofReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelExtendedDataMessage.cs

@@ -73,5 +73,10 @@
             Write(DataTypeCode);
             WriteBinaryString(Data);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelExtendedDataReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelFailureMessage.cs

@@ -22,5 +22,10 @@
             : base(localChannelNumber)
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelFailureReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs

@@ -143,5 +143,10 @@ namespace Renci.SshNet.Messages.Connection
             Write(MaximumPacketSize);
             Write(_infoBytes);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelOpenReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelOpenConfirmationMessage.cs

@@ -88,5 +88,10 @@
             Write(InitialWindowSize);
             Write(MaximumPacketSize);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelOpenConfirmationReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelOpenFailureMessage.cs

@@ -112,5 +112,10 @@
             WriteBinaryString(_description);
             WriteBinaryString(_language);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelOpenFailureReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelRequest/ChannelRequestMessage.cs

@@ -90,5 +90,10 @@
             WriteBinaryString(_requestNameBytes);
             Write(RequestData);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelRequestReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelSuccessMessage.cs

@@ -22,5 +22,10 @@
             : base(localChannelNumber)
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelSuccessReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/ChannelWindowAdjustMessage.cs

@@ -63,5 +63,10 @@
             base.SaveData();
             Write(BytesToAdd);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnChannelWindowAdjustReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/GlobalRequestMessage.cs

@@ -80,5 +80,10 @@
             WriteBinaryString(_requestName);
             Write(WantReply);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnGlobalRequestReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/RequestFailureMessage.cs

@@ -20,5 +20,10 @@ namespace Renci.SshNet.Messages.Connection
         protected override void SaveData()
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnRequestFailureReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Connection/RequestSuccessMessage.cs

@@ -62,5 +62,10 @@
             if (BoundPort.HasValue)
                 Write(BoundPort.Value);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnRequestSuccessReceived(this);
+        }
     }
 }

+ 8 - 2
src/Renci.SshNet/Messages/Message.cs

@@ -148,10 +148,10 @@ namespace Renci.SshNet.Messages
         }
 
         /// <summary>
-        /// Returns a <see cref="System.String"/> that represents this instance.
+        /// Returns a <see cref="string"/> that represents this instance.
         /// </summary>
         /// <returns>
-        /// A <see cref="System.String"/> that represents this instance.
+        /// A <see cref="string"/> that represents this instance.
         /// </returns>
         public override string ToString()
         {
@@ -162,5 +162,11 @@ namespace Renci.SshNet.Messages
 
             return messageAttribute.Name;
         }
+
+        /// <summary>
+        /// Process the current message for the specified <see cref="Session"/>.
+        /// </summary>
+        /// <param name="session">The <see cref="Session"/> for which to process the current message.</param>
+        internal abstract void Process(Session session);
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/DebugMessage.cs

@@ -72,5 +72,10 @@
             WriteBinaryString(_message);
             WriteBinaryString(_language);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnDebugReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/DisconnectMessage.cs

@@ -90,5 +90,10 @@
             WriteBinaryString(_description);
             WriteBinaryString(_language);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnDisconnectReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/IgnoreMessage.cs

@@ -84,5 +84,10 @@ namespace Renci.SshNet.Messages.Transport
         {
             WriteBinaryString(Data);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnIgnoreReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeGroup.cs

@@ -72,5 +72,10 @@ namespace Renci.SshNet.Messages.Transport
             WriteBinaryString(_safePrime);
             WriteBinaryString(_subGroup);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnKeyExchangeDhGroupExchangeGroupReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeInit.cs

@@ -59,5 +59,10 @@ namespace Renci.SshNet.Messages.Transport
         {
             WriteBinaryString(_eBytes);
         }
+
+        internal override void Process(Session session)
+        {
+            throw new System.NotImplementedException();
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeReply.cs

@@ -72,5 +72,10 @@ namespace Renci.SshNet.Messages.Transport
             WriteBinaryString(_fBytes);
             WriteBinaryString(Signature);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnKeyExchangeDhGroupExchangeReplyReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeRequest.cs

@@ -82,5 +82,10 @@
             Write(Preferred);
             Write(Maximum);
         }
+
+        internal override void Process(Session session)
+        {
+            throw new System.NotImplementedException();
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeDhInitMessage.cs

@@ -59,5 +59,10 @@ namespace Renci.SshNet.Messages.Transport
         {
             WriteBinaryString(_eBytes);
         }
+
+        internal override void Process(Session session)
+        {
+            throw new System.NotImplementedException();
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeDhReplyMessage.cs

@@ -70,5 +70,10 @@ namespace Renci.SshNet.Messages.Transport
             WriteBinaryString(_fBytes);
             WriteBinaryString(Signature);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnKeyExchangeDhReplyMessageReceived(this);
+        }
     }
 }

+ 5 - 1
src/Renci.SshNet/Messages/Transport/KeyExchangeEcdhInitMessage.cs

@@ -1,4 +1,6 @@
-using System;
+#if false
+
+using System;
 using Renci.SshNet.Common;
 
 namespace Renci.SshNet.Messages.Transport
@@ -63,3 +65,5 @@ namespace Renci.SshNet.Messages.Transport
         }
     }
 }
+
+#endif // false

+ 5 - 1
src/Renci.SshNet/Messages/Transport/KeyExchangeEcdhReplyMessage.cs

@@ -1,4 +1,6 @@
-namespace Renci.SshNet.Messages.Transport
+#if false
+
+namespace Renci.SshNet.Messages.Transport
 {
     /// <summary>
     /// Represents SSH_MSG_KEXECDH_REPLY message.
@@ -65,3 +67,5 @@
         }
     }
 }
+
+#endif // false

+ 5 - 0
src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs

@@ -174,5 +174,10 @@ namespace Renci.SshNet.Messages.Transport
             Write(FirstKexPacketFollows);
             Write(Reserved);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnKeyExchangeInitReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/NewKeysMessage.cs

@@ -19,5 +19,10 @@
         protected override void SaveData()
         {
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnNewKeysReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/ServiceAcceptMessage.cs

@@ -33,5 +33,10 @@ namespace Renci.SshNet.Messages.Transport
         {
             throw new NotImplementedException();
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnServiceAcceptReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/ServiceRequestMessage.cs

@@ -62,5 +62,10 @@ namespace Renci.SshNet.Messages.Transport
         {
             WriteBinaryString(_serviceName);
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnServiceRequestReceived(this);
+        }
     }
 }

+ 5 - 0
src/Renci.SshNet/Messages/Transport/UnimplementedMessage.cs

@@ -22,5 +22,10 @@ namespace Renci.SshNet.Messages.Transport
         {
             throw new NotImplementedException();
         }
+
+        internal override void Process(Session session)
+        {
+            session.OnUnimplementedReceived(this);
+        }
     }
 }

+ 21 - 24
src/Renci.SshNet/PasswordAuthenticationMethod.cs

@@ -79,7 +79,7 @@ namespace Renci.SshNet
 
             session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived;
             session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
-            session.MessageReceived += Session_MessageReceived;
+            session.UserAuthenticationPasswordChangeRequiredReceived += Session_UserAuthenticationPasswordChangeRequiredReceived;
 
             try
             {
@@ -92,7 +92,7 @@ namespace Renci.SshNet
                 session.UnRegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
                 session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
                 session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
-                session.MessageReceived -= Session_MessageReceived;
+                session.UserAuthenticationPasswordChangeRequiredReceived -= Session_UserAuthenticationPasswordChangeRequiredReceived;
             }
 
             if (_exception != null)
@@ -121,34 +121,31 @@ namespace Renci.SshNet
             _authenticationCompleted.Set();
         }
 
-        private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        private void Session_UserAuthenticationPasswordChangeRequiredReceived(object sender, MessageEventArgs<PasswordChangeRequiredMessage> e)
         {
-            if (e.Message is PasswordChangeRequiredMessage)
-            {
-                _session.UnRegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
+            _session.UnRegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
 
-                ThreadAbstraction.ExecuteThread(() =>
+            ThreadAbstraction.ExecuteThread(() =>
+            {
+                try
                 {
-                    try
-                    {
-                        var eventArgs = new AuthenticationPasswordChangeEventArgs(Username);
+                    var eventArgs = new AuthenticationPasswordChangeEventArgs(Username);
 
-                        //  Raise an event to allow user to supply a new password
-                        if (PasswordExpired != null)
-                        {
-                            PasswordExpired(this, eventArgs);
-                        }
-
-                        //  Send new authentication request with new password
-                        _session.SendMessage(new RequestMessagePassword(ServiceName.Connection, Username, _password, eventArgs.NewPassword));
-                    }
-                    catch (Exception exp)
+                    //  Raise an event to allow user to supply a new password
+                    if (PasswordExpired != null)
                     {
-                        _exception = exp;
-                        _authenticationCompleted.Set();
+                        PasswordExpired(this, eventArgs);
                     }
-                });
-            }
+
+                    //  Send new authentication request with new password
+                    _session.SendMessage(new RequestMessagePassword(ServiceName.Connection, Username, _password, eventArgs.NewPassword));
+                }
+                catch (Exception exp)
+                {
+                    _exception = exp;
+                    _authenticationCompleted.Set();
+                }
+            });
         }
 
         #region IDisposable Members

+ 5 - 9
src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs

@@ -56,7 +56,7 @@ namespace Renci.SshNet
         {
             session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived;
             session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
-            session.MessageReceived += Session_MessageReceived;
+            session.UserAuthenticationPublicKeyReceived += Session_UserAuthenticationPublicKeyReceived;
 
             session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK");
 
@@ -116,7 +116,7 @@ namespace Renci.SshNet
             {
                 session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
                 session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
-                session.MessageReceived -= Session_MessageReceived;
+                session.UserAuthenticationPublicKeyReceived -= Session_UserAuthenticationPublicKeyReceived;
                 session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK");
             }
         }
@@ -141,14 +141,10 @@ namespace Renci.SshNet
             _authenticationCompleted.Set();
         }
 
-        private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        private void Session_UserAuthenticationPublicKeyReceived(object sender, MessageEventArgs<PublicKeyMessage> e)
         {
-            var publicKeyMessage = e.Message as PublicKeyMessage;
-            if (publicKeyMessage != null)
-            {
-                _isSignatureRequired = true;
-                _authenticationCompleted.Set();
-            }
+            _isSignatureRequired = true;
+            _authenticationCompleted.Set();
         }
 
         #region IDisposable Members

+ 2 - 2
src/Renci.SshNet/Renci.SshNet.csproj

@@ -18,7 +18,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Debug\Renci.SshNet.xml</DocumentationFile>
@@ -29,7 +29,7 @@
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
     <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_DYNAMIC_TYPE</DefineConstants>
+    <DefineConstants>FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>

+ 33 - 28
src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeShaBase.cs

@@ -49,9 +49,10 @@ namespace Renci.SshNet.Security
         {
             base.Start(session, message);
 
+            // Register SSH_MSG_KEX_DH_GEX_GROUP message
             Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
-
-            Session.MessageReceived += Session_MessageReceived;
+            // Subscribe to KeyExchangeDhGroupExchangeGroupReceived events
+            Session.KeyExchangeDhGroupExchangeGroupReceived += Session_KeyExchangeDhGroupExchangeGroupReceived;
 
             // 1. client sends SSH_MSG_KEY_DH_GEX_REQUEST
             SendMessage(new KeyExchangeDhGroupExchangeRequest(MinimumGroupSize, PreferredGroupSize,
@@ -65,44 +66,48 @@ namespace Renci.SshNet.Security
         {
             base.Finish();
 
-            Session.MessageReceived -= Session_MessageReceived;
+            Session.KeyExchangeDhGroupExchangeGroupReceived -= Session_KeyExchangeDhGroupExchangeGroupReceived;
+            Session.KeyExchangeDhGroupExchangeReplyReceived -= Session_KeyExchangeDhGroupExchangeReplyReceived;
         }
 
-        private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        private void Session_KeyExchangeDhGroupExchangeGroupReceived(object sender, MessageEventArgs<KeyExchangeDhGroupExchangeGroup> e)
         {
             // 2. server sends SSH_MSG_KEX_DH_GEX_GROUP
-            var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
-            if (groupMessage != null)
-            {
-                // Unregister SSH_MSG_KEX_DH_GEX_GROUP message once received
-                Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
-                // Register in order to be able to receive SSH_MSG_KEX_DH_GEX_REPLY message
-                Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
+            var groupMessage = e.Message;
+
+            // Unregister SSH_MSG_KEX_DH_GEX_GROUP message once received
+            Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
+            // Unsubscribe from KeyExchangeDhGroupExchangeGroupReceived events
+            Session.KeyExchangeDhGroupExchangeGroupReceived -= Session_KeyExchangeDhGroupExchangeGroupReceived;
 
-                _prime = groupMessage.SafePrime;
-                _group = groupMessage.SubGroup;
+            // Register in order to be able to receive SSH_MSG_KEX_DH_GEX_REPLY message
+            Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
+            // Subscribe to KeyExchangeDhGroupExchangeReplyReceived events
+            Session.KeyExchangeDhGroupExchangeReplyReceived += Session_KeyExchangeDhGroupExchangeReplyReceived;
 
-                PopulateClientExchangeValue();
+            _prime = groupMessage.SafePrime;
+            _group = groupMessage.SubGroup;
 
-                // 3. client sends SSH_MSG_KEX_DH_GEX_INIT
-                SendMessage(new KeyExchangeDhGroupExchangeInit(_clientExchangeValue));
+            PopulateClientExchangeValue();
 
-                // Skip further execution as we'll be waiting for the SSH_MSG_KEX_DH_GEX_REPLY message
-                return;
-            }
+            // 3. client sends SSH_MSG_KEX_DH_GEX_INIT
+            SendMessage(new KeyExchangeDhGroupExchangeInit(_clientExchangeValue));
+        }
 
+        private void Session_KeyExchangeDhGroupExchangeReplyReceived(object sender, MessageEventArgs<KeyExchangeDhGroupExchangeReply> e)
+        {
             // 4. server sends SSH_MSG_KEX_DH_GEX_REPLY
-            var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
-            if (replyMessage != null)
-            {
-                // Unregister SSH_MSG_KEX_DH_GEX_REPLY message once received
-                Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
+            var replyMessage = e.Message;
+
+            // Unregister SSH_MSG_KEX_DH_GEX_REPLY message once received
+            Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
+            // Unsubscribe from KeyExchangeDhGroupExchangeReplyReceived events
+            Session.KeyExchangeDhGroupExchangeReplyReceived -= Session_KeyExchangeDhGroupExchangeReplyReceived;
 
-                HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
+            HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
 
-                // When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
-                Finish();
-            }
+            // When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
+            Finish();
         }
     }
 }

+ 10 - 12
src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs

@@ -52,7 +52,7 @@ namespace Renci.SshNet.Security
 
             Session.RegisterMessage("SSH_MSG_KEXDH_REPLY");
 
-            Session.MessageReceived += Session_MessageReceived;
+            Session.KeyExchangeDhReplyMessageReceived += Session_KeyExchangeDhReplyMessageReceived;
 
             _prime = GroupPrime;
             _group = new BigInteger(new byte[] { 2 });
@@ -69,22 +69,20 @@ namespace Renci.SshNet.Security
         {
             base.Finish();
 
-            Session.MessageReceived -= Session_MessageReceived;
+            Session.KeyExchangeDhReplyMessageReceived -= Session_KeyExchangeDhReplyMessageReceived;
         }
 
-        private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        private void Session_KeyExchangeDhReplyMessageReceived(object sender, MessageEventArgs<KeyExchangeDhReplyMessage> e)
         {
-            var message = e.Message as KeyExchangeDhReplyMessage;
-            if (message != null)
-            {
-                //  Unregister message once received
-                Session.UnRegisterMessage("SSH_MSG_KEXDH_REPLY");
+            var message = e.Message;
 
-                HandleServerDhReply(message.HostKey, message.F, message.Signature);
+            //  Unregister message once received
+            Session.UnRegisterMessage("SSH_MSG_KEXDH_REPLY");
 
-                //  When SSH_MSG_KEXDH_REPLY received key exchange is completed
-                Finish();
-            }
+            HandleServerDhReply(message.HostKey, message.F, message.Signature);
+
+            //  When SSH_MSG_KEXDH_REPLY received key exchange is completed
+            Finish();
         }
 
         private class _ExchangeHashData : SshData

+ 107 - 474
src/Renci.SshNet/Session.cs

@@ -357,6 +357,31 @@ namespace Renci.SshNet
         /// </summary>
         public event EventHandler<MessageEventArgs<BannerMessage>> UserAuthenticationBannerReceived;
 
+        /// <summary>
+        /// Occurs when <see cref="InformationRequestMessage"/> message is received from the server.
+        /// </summary>
+        internal event EventHandler<MessageEventArgs<InformationRequestMessage>> UserAuthenticationInformationRequestReceived;
+
+        /// <summary>
+        /// Occurs when <see cref="PasswordChangeRequiredMessage"/> message is received from the server.
+        /// </summary>
+        internal event EventHandler<MessageEventArgs<PasswordChangeRequiredMessage>> UserAuthenticationPasswordChangeRequiredReceived;
+
+        /// <summary>
+        /// Occurs when <see cref="PublicKeyMessage"/> message is received from the server.
+        /// </summary>
+        internal event EventHandler<MessageEventArgs<PublicKeyMessage>> UserAuthenticationPublicKeyReceived;
+
+        /// <summary>
+        /// Occurs when <see cref="KeyExchangeDhGroupExchangeGroup"/> message is received from the server.
+        /// </summary>
+        internal event EventHandler<MessageEventArgs<KeyExchangeDhGroupExchangeGroup>> KeyExchangeDhGroupExchangeGroupReceived;
+
+        /// <summary>
+        /// Occurs when <see cref="KeyExchangeDhGroupExchangeReply"/> message is received from the server.
+        /// </summary>
+        internal event EventHandler<MessageEventArgs<KeyExchangeDhGroupExchangeReply>> KeyExchangeDhGroupExchangeReplyReceived;
+
         #region Message events
 
         /// <summary>
@@ -394,6 +419,11 @@ namespace Renci.SshNet
         /// </summary>
         internal event EventHandler<MessageEventArgs<KeyExchangeInitMessage>> KeyExchangeInitReceived;
 
+        /// <summary>
+        /// Occurs when a <see cref="KeyExchangeDhReplyMessage"/> message is received from the SSH server.
+        /// </summary>
+        internal event EventHandler<MessageEventArgs<KeyExchangeDhReplyMessage>> KeyExchangeDhReplyMessageReceived;
+
         /// <summary>
         /// Occurs when <see cref="NewKeysMessage"/> message received
         /// </summary>
@@ -484,11 +514,6 @@ namespace Renci.SshNet
         /// </summary>
         public event EventHandler<MessageEventArgs<ChannelFailureMessage>> ChannelFailureReceived;
 
-        /// <summary>
-        /// Occurs when message received and is not handled by any of the event handlers
-        /// </summary>
-        internal event EventHandler<MessageEventArgs<Message>> MessageReceived;
-
         #endregion
 
         /// <summary>
@@ -1063,444 +1088,13 @@ namespace Renci.SshNet
             _isDisconnectMessageSent = true;
         }
 
-        void HandleMessageCore(Message message)
-        {
-            if (message == null)
-                throw new ArgumentNullException("message");
-
-#if FEATURE_DYNAMIC_TYPE
-            HandleMessage((dynamic) message);
-#else
-            var disconnectMessage = message as DisconnectMessage;
-            if (disconnectMessage != null)
-            {
-                HandleMessage(disconnectMessage);
-                return;
-            }
-
-            var serviceRequestMessage = message as ServiceRequestMessage;
-            if (serviceRequestMessage != null)
-            {
-                HandleMessage(serviceRequestMessage);
-                return;
-            }
-
-            var serviceAcceptMessage = message as ServiceAcceptMessage;
-            if (serviceAcceptMessage != null)
-            {
-                HandleMessage(serviceAcceptMessage);
-                return;
-            }
-
-            var keyExchangeInitMessage = message as KeyExchangeInitMessage;
-            if (keyExchangeInitMessage != null)
-            {
-                HandleMessage(keyExchangeInitMessage);
-                return;
-            }
-
-            var newKeysMessage = message as NewKeysMessage;
-            if (newKeysMessage != null)
-            {
-                HandleMessage(newKeysMessage);
-                return;
-            }
-
-            var requestMessage = message as RequestMessage;
-            if (requestMessage != null)
-            {
-                HandleMessage(requestMessage);
-                return;
-            }
-
-            var failureMessage = message as FailureMessage;
-            if (failureMessage != null)
-            {
-                HandleMessage(failureMessage);
-                return;
-            }
-
-            var successMessage = message as SuccessMessage;
-            if (successMessage != null)
-            {
-                HandleMessage(successMessage);
-                return;
-            }
-
-            var bannerMessage = message as BannerMessage;
-            if (bannerMessage != null)
-            {
-                HandleMessage(bannerMessage);
-                return;
-            }
-
-            var globalRequestMessage = message as GlobalRequestMessage;
-            if (globalRequestMessage != null)
-            {
-                HandleMessage(globalRequestMessage);
-                return;
-            }
-
-            var requestSuccessMessage = message as RequestSuccessMessage;
-            if (requestSuccessMessage != null)
-            {
-                HandleMessage(requestSuccessMessage);
-                return;
-            }
-
-            var requestFailureMessage = message as RequestFailureMessage;
-            if (requestFailureMessage != null)
-            {
-                HandleMessage(requestFailureMessage);
-                return;
-            }
-
-            var channelOpenMessage = message as ChannelOpenMessage;
-            if (channelOpenMessage != null)
-            {
-                HandleMessage(channelOpenMessage);
-                return;
-            }
-
-            var channelOpenConfirmationMessage = message as ChannelOpenConfirmationMessage;
-            if (channelOpenConfirmationMessage != null)
-            {
-                HandleMessage(channelOpenConfirmationMessage);
-                return;
-            }
-
-            var channelOpenFailureMessage = message as ChannelOpenFailureMessage;
-            if (channelOpenFailureMessage != null)
-            {
-                HandleMessage(channelOpenFailureMessage);
-                return;
-            }
-
-            var channelWindowAdjustMessage = message as ChannelWindowAdjustMessage;
-            if (channelWindowAdjustMessage != null)
-            {
-                HandleMessage(channelWindowAdjustMessage);
-                return;
-            }
-
-            var channelDataMessage = message as ChannelDataMessage;
-            if (channelDataMessage != null)
-            {
-                HandleMessage(channelDataMessage);
-                return;
-            }
-
-            var channelExtendedDataMessage = message as ChannelExtendedDataMessage;
-            if (channelExtendedDataMessage != null)
-            {
-                HandleMessage(channelExtendedDataMessage);
-                return;
-            }
-
-            var channelEofMessage = message as ChannelEofMessage;
-            if (channelEofMessage != null)
-            {
-                HandleMessage(channelEofMessage);
-                return;
-            }
-
-            var channelCloseMessage = message as ChannelCloseMessage;
-            if (channelCloseMessage != null)
-            {
-                HandleMessage(channelCloseMessage);
-                return;
-            }
-
-            var channelRequestMessage = message as ChannelRequestMessage;
-            if (channelRequestMessage != null)
-            {
-                HandleMessage(channelRequestMessage);
-                return;
-            }
-
-            var channelSuccessMessage = message as ChannelSuccessMessage;
-            if (channelSuccessMessage != null)
-            {
-                HandleMessage(channelSuccessMessage);
-                return;
-            }
-
-            var channelFailureMessage = message as ChannelFailureMessage;
-            if (channelFailureMessage != null)
-            {
-                HandleMessage(channelFailureMessage);
-                return;
-            }
-
-            var ignoreMessage = message as IgnoreMessage;
-            if (ignoreMessage != null)
-            {
-                HandleMessage(ignoreMessage);
-                return;
-            }
-
-            var unimplementedMessage = message as UnimplementedMessage;
-            if (unimplementedMessage != null)
-            {
-                HandleMessage(unimplementedMessage);
-                return;
-            }
-
-            var debugMessage = message as DebugMessage;
-            if (debugMessage != null)
-            {
-                HandleMessage(debugMessage);
-                return;
-            }
-
-            throw new NotImplementedException("Message type '{0}' is not implemented. Please submit an issue.", message.GetType().FullName);
-        }
-
-        #error FUCK
-#endif
-        }
-
-        /// <summary>
-        /// Handles the message.
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="message">The message.</param>
-        private void HandleMessage<T>(T message) where T : Message
-        {
-            DiagnosticAbstraction.Log(string.Format("[{0}] Message<{1}> received", ToHex(SessionId), typeof(T).FullName));
-            OnMessageReceived(message);
-        }
-
-#region Handle transport messages
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(DisconnectMessage message)
-        {
-            OnDisconnectReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(IgnoreMessage message)
-        {
-            OnIgnoreReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(UnimplementedMessage message)
-        {
-            OnUnimplementedReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(DebugMessage message)
-        {
-            OnDebugReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ServiceRequestMessage message)
-        {
-            OnServiceRequestReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ServiceAcceptMessage message)
-        {
-            //  TODO:   Refactor to avoid this method here
-            OnServiceAcceptReceived(message);
-
-            _serviceAccepted.Set();
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(KeyExchangeInitMessage message)
-        {
-            OnKeyExchangeInitReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(NewKeysMessage message)
-        {
-            OnNewKeysReceived(message);
-        }
-
-#endregion
-
-#region Handle User Authentication messages
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(RequestMessage message)
-        {
-            OnUserAuthenticationRequestReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(FailureMessage message)
-        {
-            OnUserAuthenticationFailureReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(SuccessMessage message)
-        {
-            OnUserAuthenticationSuccessReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(BannerMessage message)
-        {
-            OnUserAuthenticationBannerReceived(message);
-        }
-
-#endregion
-
-#region Handle connection messages
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(GlobalRequestMessage message)
-        {
-            OnGlobalRequestReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(RequestSuccessMessage message)
-        {
-            OnRequestSuccessReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(RequestFailureMessage message)
-        {
-            OnRequestFailureReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelOpenMessage message)
-        {
-            OnChannelOpenReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelOpenConfirmationMessage message)
-        {
-            OnChannelOpenConfirmationReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelOpenFailureMessage message)
-        {
-            OnChannelOpenFailureReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelWindowAdjustMessage message)
-        {
-            OnChannelWindowAdjustReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelDataMessage message)
-        {
-            OnChannelDataReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelExtendedDataMessage message)
-        {
-            OnChannelExtendedDataReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelEofMessage message)
-        {
-            OnChannelEofReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelCloseMessage message)
-        {
-            OnChannelCloseReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelRequestMessage message)
-        {
-            OnChannelRequestReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelSuccessMessage message)
-        {
-            OnChannelSuccessReceived(message);
-        }
-
-        /// <summary>
-        /// Invoked via reflection.
-        /// </summary>
-        private void HandleMessage(ChannelFailureMessage message)
-        {
-            OnChannelFailureReceived(message);
-        }
-
-#endregion
-
 #region Handle received message events
 
         /// <summary>
         /// Called when <see cref="DisconnectMessage"/> received.
         /// </summary>
         /// <param name="message"><see cref="DisconnectMessage"/> message.</param>
-        protected virtual void OnDisconnectReceived(DisconnectMessage message)
+        internal void OnDisconnectReceived(DisconnectMessage message)
         {
             DiagnosticAbstraction.Log(string.Format("[{0}] {1} Disconnect received: {2} {3}", ToHex(SessionId), DateTime.Now.Ticks, message.ReasonCode, message.Description));
 
@@ -1528,7 +1122,7 @@ namespace Renci.SshNet
         /// Called when <see cref="IgnoreMessage"/> received.
         /// </summary>
         /// <param name="message"><see cref="IgnoreMessage"/> message.</param>
-        protected virtual void OnIgnoreReceived(IgnoreMessage message)
+        internal void OnIgnoreReceived(IgnoreMessage message)
         {
             var handlers = IgnoreReceived;
             if (handlers != null)
@@ -1539,7 +1133,7 @@ namespace Renci.SshNet
         /// Called when <see cref="UnimplementedMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="UnimplementedMessage"/> message.</param>
-        protected virtual void OnUnimplementedReceived(UnimplementedMessage message)
+        internal void OnUnimplementedReceived(UnimplementedMessage message)
         {
             var handlers = UnimplementedReceived;
             if (handlers != null)
@@ -1550,7 +1144,7 @@ namespace Renci.SshNet
         /// Called when <see cref="DebugMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="DebugMessage"/> message.</param>
-        protected virtual void OnDebugReceived(DebugMessage message)
+        internal void OnDebugReceived(DebugMessage message)
         {
             var handlers = DebugReceived;
             if (handlers != null)
@@ -1561,7 +1155,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ServiceRequestMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ServiceRequestMessage"/> message.</param>
-        protected virtual void OnServiceRequestReceived(ServiceRequestMessage message)
+        internal void OnServiceRequestReceived(ServiceRequestMessage message)
         {
             var handlers = ServiceRequestReceived;
             if (handlers != null)
@@ -1572,18 +1166,34 @@ namespace Renci.SshNet
         /// Called when <see cref="ServiceAcceptMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ServiceAcceptMessage"/> message.</param>
-        protected virtual void OnServiceAcceptReceived(ServiceAcceptMessage message)
+        internal void OnServiceAcceptReceived(ServiceAcceptMessage message)
         {
             var handlers = ServiceAcceptReceived;
             if (handlers != null)
                 handlers(this, new MessageEventArgs<ServiceAcceptMessage>(message));
+
+            _serviceAccepted.Set();
+        }
+
+        internal void OnKeyExchangeDhGroupExchangeGroupReceived(KeyExchangeDhGroupExchangeGroup message)
+        {
+            var handlers = KeyExchangeDhGroupExchangeGroupReceived;
+            if (handlers != null)
+                handlers(this, new MessageEventArgs<KeyExchangeDhGroupExchangeGroup>(message));
+        }
+
+        internal void OnKeyExchangeDhGroupExchangeReplyReceived(KeyExchangeDhGroupExchangeReply message)
+        {
+            var handlers = KeyExchangeDhGroupExchangeReplyReceived;
+            if (handlers != null)
+                handlers(this, new MessageEventArgs<KeyExchangeDhGroupExchangeReply>(message));
         }
 
         /// <summary>
         /// Called when <see cref="KeyExchangeInitMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="KeyExchangeInitMessage"/> message.</param>
-        protected virtual void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
+        internal void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
         {
             _keyExchangeInProgress = true;
 
@@ -1607,11 +1217,18 @@ namespace Renci.SshNet
                 keyExchangeInitReceived(this, new MessageEventArgs<KeyExchangeInitMessage>(message));
         }
 
+        internal void OnKeyExchangeDhReplyMessageReceived(KeyExchangeDhReplyMessage message)
+        {
+            var handlers = KeyExchangeDhReplyMessageReceived;
+            if (handlers != null)
+                handlers(this, new MessageEventArgs<KeyExchangeDhReplyMessage>(message));
+        }
+
         /// <summary>
         /// Called when <see cref="NewKeysMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="NewKeysMessage"/> message.</param>
-        protected virtual void OnNewKeysReceived(NewKeysMessage message)
+        internal void OnNewKeysReceived(NewKeysMessage message)
         {
             //  Update sessionId
             if (SessionId == null)
@@ -1673,7 +1290,7 @@ namespace Renci.SshNet
         /// Called when <see cref="RequestMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="RequestMessage"/> message.</param>
-        protected virtual void OnUserAuthenticationRequestReceived(RequestMessage message)
+        internal void OnUserAuthenticationRequestReceived(RequestMessage message)
         {
             var handlers = UserAuthenticationRequestReceived;
             if (handlers != null)
@@ -1684,7 +1301,7 @@ namespace Renci.SshNet
         /// Called when <see cref="FailureMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="FailureMessage"/> message.</param>
-        protected virtual void OnUserAuthenticationFailureReceived(FailureMessage message)
+        internal void OnUserAuthenticationFailureReceived(FailureMessage message)
         {
             var handlers = UserAuthenticationFailureReceived;
             if (handlers != null)
@@ -1695,7 +1312,7 @@ namespace Renci.SshNet
         /// Called when <see cref="SuccessMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="SuccessMessage"/> message.</param>
-        protected virtual void OnUserAuthenticationSuccessReceived(SuccessMessage message)
+        internal void OnUserAuthenticationSuccessReceived(SuccessMessage message)
         {
             var handlers = UserAuthenticationSuccessReceived;
             if (handlers != null)
@@ -1706,18 +1323,44 @@ namespace Renci.SshNet
         /// Called when <see cref="BannerMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="BannerMessage"/> message.</param>
-        protected virtual void OnUserAuthenticationBannerReceived(BannerMessage message)
+        internal void OnUserAuthenticationBannerReceived(BannerMessage message)
         {
             var handlers = UserAuthenticationBannerReceived;
             if (handlers != null)
                 handlers(this, new MessageEventArgs<BannerMessage>(message));
         }
 
+
+        /// <summary>
+        /// Called when <see cref="InformationRequestMessage"/> message received.
+        /// </summary>
+        /// <param name="message"><see cref="InformationRequestMessage"/> message.</param>
+        internal void OnUserAuthenticationInformationRequestReceived(InformationRequestMessage message)
+        {
+            var handlers = UserAuthenticationInformationRequestReceived;
+            if (handlers != null)
+                handlers(this, new MessageEventArgs<InformationRequestMessage>(message));
+        }
+
+        internal void OnUserAuthenticationPasswordChangeRequiredReceived(PasswordChangeRequiredMessage message)
+        {
+            var handlers = UserAuthenticationPasswordChangeRequiredReceived;
+            if (handlers != null)
+                handlers(this, new MessageEventArgs<PasswordChangeRequiredMessage>(message));
+        }
+
+        internal void OnUserAuthenticationPublicKeyReceived(PublicKeyMessage message)
+        {
+            var handlers = UserAuthenticationPublicKeyReceived;
+            if (handlers != null)
+                handlers(this, new MessageEventArgs<PublicKeyMessage>(message));
+        }
+
         /// <summary>
         /// Called when <see cref="GlobalRequestMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="GlobalRequestMessage"/> message.</param>
-        protected virtual void OnGlobalRequestReceived(GlobalRequestMessage message)
+        internal void OnGlobalRequestReceived(GlobalRequestMessage message)
         {
             var handlers = GlobalRequestReceived;
             if (handlers != null)
@@ -1728,7 +1371,7 @@ namespace Renci.SshNet
         /// Called when <see cref="RequestSuccessMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="RequestSuccessMessage"/> message.</param>
-        protected virtual void OnRequestSuccessReceived(RequestSuccessMessage message)
+        internal void OnRequestSuccessReceived(RequestSuccessMessage message)
         {
             var handlers = RequestSuccessReceived;
             if (handlers != null)
@@ -1739,7 +1382,7 @@ namespace Renci.SshNet
         /// Called when <see cref="RequestFailureMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="RequestFailureMessage"/> message.</param>
-        protected virtual void OnRequestFailureReceived(RequestFailureMessage message)
+        internal void OnRequestFailureReceived(RequestFailureMessage message)
         {
             var handlers = RequestFailureReceived;
             if (handlers != null)
@@ -1750,7 +1393,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelOpenMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelOpenMessage"/> message.</param>
-        protected virtual void OnChannelOpenReceived(ChannelOpenMessage message)
+        internal void OnChannelOpenReceived(ChannelOpenMessage message)
         {
             var handlers = ChannelOpenReceived;
             if (handlers != null)
@@ -1761,7 +1404,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelOpenConfirmationMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelOpenConfirmationMessage"/> message.</param>
-        protected virtual void OnChannelOpenConfirmationReceived(ChannelOpenConfirmationMessage message)
+        internal void OnChannelOpenConfirmationReceived(ChannelOpenConfirmationMessage message)
         {
             var handlers = ChannelOpenConfirmationReceived;
             if (handlers != null)
@@ -1772,7 +1415,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelOpenFailureMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelOpenFailureMessage"/> message.</param>
-        protected virtual void OnChannelOpenFailureReceived(ChannelOpenFailureMessage message)
+        internal void OnChannelOpenFailureReceived(ChannelOpenFailureMessage message)
         {
             var handlers = ChannelOpenFailureReceived;
             if (handlers != null)
@@ -1783,7 +1426,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelWindowAdjustMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelWindowAdjustMessage"/> message.</param>
-        protected virtual void OnChannelWindowAdjustReceived(ChannelWindowAdjustMessage message)
+        internal void OnChannelWindowAdjustReceived(ChannelWindowAdjustMessage message)
         {
             var handlers = ChannelWindowAdjustReceived;
             if (handlers != null)
@@ -1794,7 +1437,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelDataMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelDataMessage"/> message.</param>
-        protected virtual void OnChannelDataReceived(ChannelDataMessage message)
+        internal void OnChannelDataReceived(ChannelDataMessage message)
         {
             var handlers = ChannelDataReceived;
             if (handlers != null)
@@ -1805,7 +1448,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelExtendedDataMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelExtendedDataMessage"/> message.</param>
-        protected virtual void OnChannelExtendedDataReceived(ChannelExtendedDataMessage message)
+        internal void OnChannelExtendedDataReceived(ChannelExtendedDataMessage message)
         {
             var handlers = ChannelExtendedDataReceived;
             if (handlers != null)
@@ -1816,7 +1459,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelCloseMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelCloseMessage"/> message.</param>
-        protected virtual void OnChannelEofReceived(ChannelEofMessage message)
+        internal void OnChannelEofReceived(ChannelEofMessage message)
         {
             var handlers = ChannelEofReceived;
             if (handlers != null)
@@ -1827,7 +1470,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelCloseMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelCloseMessage"/> message.</param>
-        protected virtual void OnChannelCloseReceived(ChannelCloseMessage message)
+        internal void OnChannelCloseReceived(ChannelCloseMessage message)
         {
             var handlers = ChannelCloseReceived;
             if (handlers != null)
@@ -1838,7 +1481,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelRequestMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelRequestMessage"/> message.</param>
-        protected virtual void OnChannelRequestReceived(ChannelRequestMessage message)
+        internal void OnChannelRequestReceived(ChannelRequestMessage message)
         {
             var handlers = ChannelRequestReceived;
             if (handlers != null)
@@ -1849,7 +1492,7 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelSuccessMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelSuccessMessage"/> message.</param>
-        protected virtual void OnChannelSuccessReceived(ChannelSuccessMessage message)
+        internal void OnChannelSuccessReceived(ChannelSuccessMessage message)
         {
             var handlers = ChannelSuccessReceived;
             if (handlers != null)
@@ -1860,24 +1503,13 @@ namespace Renci.SshNet
         /// Called when <see cref="ChannelFailureMessage"/> message received.
         /// </summary>
         /// <param name="message"><see cref="ChannelFailureMessage"/> message.</param>
-        protected virtual void OnChannelFailureReceived(ChannelFailureMessage message)
+        internal void OnChannelFailureReceived(ChannelFailureMessage message)
         {
             var handlers = ChannelFailureReceived;
             if (handlers != null)
                 handlers(this, new MessageEventArgs<ChannelFailureMessage>(message));
         }
 
-        /// <summary>
-        /// Called when <see cref="Message"/> message received.
-        /// </summary>
-        /// <param name="message"><see cref="Message"/> message.</param>
-        protected virtual void OnMessageReceived(Message message)
-        {
-            var handlers = MessageReceived;
-            if (handlers != null)
-                handlers(this, new MessageEventArgs<Message>(message));
-        }
-
 #endregion
 
         private void KeyExchange_HostKeyReceived(object sender, HostKeyEventArgs e)
@@ -2233,7 +1865,8 @@ namespace Renci.SshNet
                         break;
                     }
 
-                    HandleMessageCore(message);
+                    // process message
+                    message.Process(this);
                 }
 
                 // connection with SSH server was closed

+ 0 - 5
src/Renci.SshNet/Sftp/SftpSession.cs

@@ -240,11 +240,6 @@ namespace Renci.SshNet.Sftp
                 // extract packet length
                 var packetDataLength = _data[0] << 24 | _data[1] << 16 | _data[2] << 8 | _data[3];
 
-#if DEBUG_GERT
-                if (packetDataLength > 32 * 1024)
-                    Console.WriteLine("BIG PACKAGE: " + packetDataLength + " | " + data.Length);
-#endif // DEBUG_GERT
-
                 var packetTotalLength = packetDataLength + packetLengthByteCount;
 
                 // check if complete packet data is available