Преглед на файлове

Fix WindowAdjusment for SCP and SFTP
Fix Key regeneration
Minor comments and other fixes
Add Current* properties to ConnectionInfo object to specify parameters that currently by the connection

olegkap_cp преди 13 години
родител
ревизия
f8faabddda
променени са 32 файла, в които са добавени 165 реда и са изтрити 74 реда
  1. 4 1
      Renci.SshClient/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj
  2. 4 1
      Renci.SshClient/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj
  3. 4 1
      Renci.SshClient/Renci.SshNet.WindowsPhone/Renci.SshNet.WindowsPhone.csproj
  4. 5 2
      Renci.SshClient/Renci.SshNet/Channels/Channel.cs
  5. 1 4
      Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs
  6. 40 25
      Renci.SshClient/Renci.SshNet/ConnectionInfo.cs
  7. 0 8
      Renci.SshClient/Renci.SshNet/ForwardedPort.cs
  8. 6 3
      Renci.SshClient/Renci.SshNet/ForwardedPortDynamic.cs
  9. 6 0
      Renci.SshClient/Renci.SshNet/ForwardedPortRemote.cs
  10. 1 1
      Renci.SshClient/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs
  11. 1 1
      Renci.SshClient/Renci.SshNet/Messages/Transport/DisconnectMessage.cs
  12. 14 0
      Renci.SshClient/Renci.SshNet/Messages/Transport/IKeyExchangedAllowed.cs
  13. 1 1
      Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeInit.cs
  14. 1 1
      Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeRequest.cs
  15. 1 1
      Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeDhInitMessage.cs
  16. 1 1
      Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs
  17. 1 1
      Renci.SshClient/Renci.SshNet/Messages/Transport/NewKeysMessage.cs
  18. 4 3
      Renci.SshClient/Renci.SshNet/Netconf/NetConfSession.cs
  19. 2 1
      Renci.SshClient/Renci.SshNet/PasswordConnectionInfo.cs
  20. 1 0
      Renci.SshClient/Renci.SshNet/Renci.SshNet.csproj
  21. 1 1
      Renci.SshClient/Renci.SshNet/ScpClient.NET.cs
  22. 3 3
      Renci.SshClient/Renci.SshNet/ScpClient.cs
  23. 12 0
      Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs
  24. 2 0
      Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs
  25. 1 1
      Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroup14Sha1.cs
  26. 2 2
      Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroup1Sha1.cs
  27. 2 2
      Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs
  28. 3 3
      Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs
  29. 17 0
      Renci.SshClient/Renci.SshNet/Session.cs
  30. 20 2
      Renci.SshClient/Renci.SshNet/Sftp/SftpSession.cs
  31. 1 1
      Renci.SshClient/Renci.SshNet/Shell.cs
  32. 3 3
      Renci.SshClient/Renci.SshNet/SubsystemSession.cs

+ 4 - 1
Renci.SshClient/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj

@@ -409,6 +409,9 @@
     <Compile Include="..\Renci.SshNet\Messages\Transport\IgnoreMessage.cs">
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Messages\Transport\IKeyExchangedAllowed.cs">
+      <Link>Messages\Transport\IKeyExchangedAllowed.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
     </Compile>
@@ -752,7 +755,7 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <ProjectExtensions>
     <VisualStudio>
-      <UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
+      <UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
     </VisualStudio>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 4 - 1
Renci.SshClient/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj

@@ -387,6 +387,9 @@
     <Compile Include="..\Renci.SshNet\Messages\Transport\IgnoreMessage.cs">
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Messages\Transport\IKeyExchangedAllowed.cs">
+      <Link>Messages\Transport\IKeyExchangedAllowed.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
     </Compile>
@@ -719,7 +722,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. 

+ 4 - 1
Renci.SshClient/Renci.SshNet.WindowsPhone/Renci.SshNet.WindowsPhone.csproj

@@ -383,6 +383,9 @@
     <Compile Include="..\Renci.SshNet\Messages\Transport\IgnoreMessage.cs">
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Messages\Transport\IKeyExchangedAllowed.cs">
+      <Link>Messages\Transport\IKeyExchangedAllowed.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
     </Compile>
@@ -723,7 +726,7 @@
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
   <ProjectExtensions>
     <VisualStudio>
-      <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. 

+ 5 - 2
Renci.SshClient/Renci.SshNet/Channels/Channel.cs

@@ -205,6 +205,11 @@ namespace Renci.SshNet.Channels
             this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
         }
 
+        internal void SendData(byte[] buffer)
+        {
+            this.SendMessage(new ChannelDataMessage(this.RemoteChannelNumber, buffer));
+        }
+
         /// <summary>
         /// Closes the channel.
         /// </summary>
@@ -215,8 +220,6 @@ namespace Renci.SshNet.Channels
 
             //  Wait for channel to be closed
             this._session.WaitHandle(this._channelClosedWaitHandle);
-
-            //this.Dispose();
         }
 
         #region Channel virtual methods

+ 1 - 4
Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs

@@ -62,11 +62,8 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Binds channel to specified remote host.
+        /// Binds channel to remote host.
         /// </summary>
-        /// <param name="remoteHost">The remote host.</param>
-        /// <param name="port">The port.</param>
-        /// <param name="socket">The socket.</param>
         public void Bind()
         {
             //  Cannot bind if channel is not open

+ 40 - 25
Renci.SshClient/Renci.SshNet/ConnectionInfo.cs

@@ -153,6 +153,46 @@ namespace Renci.SshNet
         /// </summary>
         public event EventHandler<AuthenticationBannerEventArgs> AuthenticationBanner;
 
+        /// <summary>
+        /// Gets the current key exchange algorithm.
+        /// </summary>
+        public string CurrentKeyExchangeAlgorithm { get; internal set; }
+
+        /// <summary>
+        /// Gets the current server encryption.
+        /// </summary>
+        public string CurrentServerEncryption { get; internal set; }
+
+        /// <summary>
+        /// Gets the current client encryption.
+        /// </summary>
+        public string CurrentClientEncryption { get; internal set; }
+
+        /// <summary>
+        /// Gets the current server hash algorithm.
+        /// </summary>
+        public string CurrentServerHmacAlgorithm { get; internal set; }
+
+        /// <summary>
+        /// Gets the current client hash algorithm.
+        /// </summary>
+        public string CurrentClientHmacAlgorithm { get; internal set; }
+
+        /// <summary>
+        /// Gets the current host key algorithm.
+        /// </summary>
+        public string CurrentHostKeyAlgorithm { get; internal set; }
+
+        /// <summary>
+        /// Gets the current server compression algorithm.
+        /// </summary>
+        public string CurrentServerCompressionAlgorithm { get; internal set; }
+
+        /// <summary>
+        /// Gets the current client compression algorithm.
+        /// </summary>
+        public string CurrentClientCompressionAlgorithm { get; internal set; }
+
         /// <summary>
         /// Prevents a default instance of the <see cref="ConnectionInfo"/> class from being created.
         /// </summary>
@@ -301,31 +341,6 @@ namespace Renci.SshNet
             this.ProxyPassword = proxyPassword;
         }
 
-        //internal Socket CreateSocket()
-        //{
-        //    Socket socket = null;
-
-        //    CreateSocket(ref socket);
-
-        //    switch (this.ProxyType)
-        //    {
-        //        case ProxyTypes.None:
-        //            break;
-        //        case ProxyTypes.Socks4:
-        //            ConnectSocks4(socket);
-        //            break;
-        //        case ProxyTypes.Socks5:
-        //            ConnectSocks5(socket);
-        //            break;
-        //        default:
-        //            break;
-        //    }
-
-        //    return socket;
-        //}
-
-        //partial void CreateSocket(ref Socket socket);
-
         /// <summary>
         /// Authenticates the specified session.
         /// </summary>

+ 0 - 8
Renci.SshClient/Renci.SshNet/ForwardedPort.cs

@@ -34,14 +34,6 @@ namespace Renci.SshNet
         /// </summary>
         public event EventHandler<PortForwardEventArgs> RequestReceived;
 
-        /// <summary>
-        /// Initializes a new instance of the <see cref="Port"/> class.
-        /// </summary>
-        internal ForwardedPort()
-        {
-
-        }
-
         /// <summary>
         /// Starts port forwarding.
         /// </summary>

+ 6 - 3
Renci.SshClient/Renci.SshNet/ForwardedPortDynamic.cs

@@ -6,7 +6,10 @@ using System.Threading;
 
 namespace Renci.SshNet
 {
-    public partial class ForwardedPortDynamic : ForwardedPort
+    /// <summary>
+    /// Provides functionality for dynamic port forwarding
+    /// </summary>
+    public partial class ForwardedPortDynamic : ForwardedPort, IDisposable
     {
         private EventWaitHandle _listenerTaskCompleted;
 
@@ -63,7 +66,7 @@ namespace Renci.SshNet
         partial void InternalStop();
 
         partial void ExecuteThread(Action action);
-    
+
         #region IDisposable Members
 
         private bool _isDisposed = false;
@@ -117,5 +120,5 @@ namespace Renci.SshNet
         }
 
         #endregion
-}
+    }
 }

+ 6 - 0
Renci.SshClient/Renci.SshNet/ForwardedPortRemote.cs

@@ -37,6 +37,12 @@ namespace Renci.SshNet
         /// </summary>
         public uint Port { get; protected set; }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ForwardedPortRemote"/> class.
+        /// </summary>
+        /// <param name="boundPort">The bound port.</param>
+        /// <param name="host">The host.</param>
+        /// <param name="port">The port.</param>
         public ForwardedPortRemote(uint boundPort, string host, uint port)
             : this(string.Empty, boundPort, host, port)
         {

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

@@ -154,7 +154,7 @@ namespace Renci.SshNet
         {
             this.Session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
 
-            this.Session.SendMessage(this._requestMessage);
+            this.SendMessage(this._requestMessage);
 
             this.WaitHandle(this._authenticationCompleted);
 

+ 1 - 1
Renci.SshClient/Renci.SshNet/Messages/Transport/DisconnectMessage.cs

@@ -6,7 +6,7 @@ namespace Renci.SshNet.Messages.Transport
     /// Represents SSH_MSG_DISCONNECT message.
     /// </summary>
     [Message("SSH_MSG_DISCONNECT", 1)]
-    public class DisconnectMessage : Message
+    public class DisconnectMessage : Message, IKeyExchangedAllowed
     {
         /// <summary>
         /// Gets disconnect reason code.

+ 14 - 0
Renci.SshClient/Renci.SshNet/Messages/Transport/IKeyExchangedAllowed.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshNet.Messages.Transport
+{
+    /// <summary>
+    /// Indicates that message that implement this interface is allowed during key exchange phase
+    /// </summary>
+    public interface IKeyExchangedAllowed
+    {
+    }
+}

+ 1 - 1
Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeInit.cs

@@ -10,7 +10,7 @@ namespace Renci.SshNet.Messages.Transport
     /// Represents SSH_MSG_KEX_DH_GEX_INIT message.
     /// </summary>
     [Message("SSH_MSG_KEX_DH_GEX_INIT", 32)]
-    internal class KeyExchangeDhGroupExchangeInit : Message
+    internal class KeyExchangeDhGroupExchangeInit : Message, IKeyExchangedAllowed
     {
         /// <summary>
         /// Gets the E value.

+ 1 - 1
Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeDhGroupExchangeRequest.cs

@@ -9,7 +9,7 @@ namespace Renci.SshNet.Messages.Transport
     /// Represents SSH_MSG_KEX_DH_GEX_REQUEST message.
     /// </summary>
     [Message("SSH_MSG_KEX_DH_GEX_REQUEST", 34)]
-    internal class KeyExchangeDhGroupExchangeRequest : Message
+    internal class KeyExchangeDhGroupExchangeRequest : Message, IKeyExchangedAllowed
     {
         /// <summary>
         /// Gets or sets the minimal size in bits of an acceptable group.

+ 1 - 1
Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeDhInitMessage.cs

@@ -6,7 +6,7 @@ namespace Renci.SshNet.Messages.Transport
     /// Represents SSH_MSG_KEXDH_INIT message.
     /// </summary>
     [Message("SSH_MSG_KEXDH_INIT", 30)]
-    internal class KeyExchangeDhInitMessage : Message
+    internal class KeyExchangeDhInitMessage : Message, IKeyExchangedAllowed
     {
         /// <summary>
         /// Gets the E value.

+ 1 - 1
Renci.SshClient/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs

@@ -8,7 +8,7 @@ namespace Renci.SshNet.Messages.Transport
     /// Represents SSH_MSG_KEXINIT message.
     /// </summary>
     [Message("SSH_MSG_KEXINIT", 20)]
-    public class KeyExchangeInitMessage : Message
+    public class KeyExchangeInitMessage : Message, IKeyExchangedAllowed
     {
         private static RNGCryptoServiceProvider _randomizer = new System.Security.Cryptography.RNGCryptoServiceProvider();
 

+ 1 - 1
Renci.SshClient/Renci.SshNet/Messages/Transport/NewKeysMessage.cs

@@ -4,7 +4,7 @@
     /// Represents SSH_MSG_KEXINIT message.
     /// </summary>
     [Message("SSH_MSG_NEWKEYS", 21)]
-    public class NewKeysMessage : Message
+    public class NewKeysMessage : Message, IKeyExchangedAllowed
     {
         /// <summary>
         /// Called when type specific data need to be loaded.

+ 4 - 3
Renci.SshClient/Renci.SshNet/Netconf/NetConfSession.cs

@@ -82,13 +82,14 @@ namespace Renci.SshNet.NetConf
                 command.AppendFormat("\n#{0}\n", rpc.InnerXml.Length);
                 command.Append(rpc.InnerXml);
                 command.Append("\n##\n");
-                SendData(new ChannelDataMessage(this.ChannelNumber, Encoding.UTF8.GetBytes(command.ToString())));
+                this.SendData(Encoding.UTF8.GetBytes(command.ToString()));
+
                 this.WaitHandle(this._rpcReplyReceived, this._operationTimeout);
                 reply.LoadXml(_rpcReply.ToString());
             }
             else
             {
-                SendData(new ChannelDataMessage(this.ChannelNumber, Encoding.UTF8.GetBytes(rpc.InnerXml + _prompt)));
+                this.SendData(Encoding.UTF8.GetBytes(rpc.InnerXml + _prompt));
                 this.WaitHandle(this._rpcReplyReceived, this._operationTimeout);
                 reply.LoadXml(_rpcReply.ToString());
             }
@@ -108,7 +109,7 @@ namespace Renci.SshNet.NetConf
         {            
             string message = string.Format("{0}{1}", this.ClientCapabilities.InnerXml, _prompt);
 
-            this.SendData(new ChannelDataMessage(this.ChannelNumber, Encoding.UTF8.GetBytes(message)));
+            this.SendData(Encoding.UTF8.GetBytes(message));
 
             this.WaitHandle(this._serverCapabilitiesConfirmed, this._operationTimeout);
         }

+ 2 - 1
Renci.SshClient/Renci.SshNet/PasswordConnectionInfo.cs

@@ -129,13 +129,13 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
         /// </summary>
         /// <param name="host">Connection host.</param>
-        /// <param name="port">The port.</param>
         /// <param name="username">Connection username.</param>
         /// <param name="password">Connection password.</param>
         /// <param name="proxyType">Type of the proxy.</param>
         /// <param name="proxyHost">The proxy host.</param>
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</param>
+        /// <param name="proxyPassword">The proxy password.</param>
         public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
             : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {
@@ -152,6 +152,7 @@ namespace Renci.SshNet
         /// <param name="proxyHost">The proxy host.</param>
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</param>
+        /// <param name="proxyPassword">The proxy password.</param>
         public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
             : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {

+ 1 - 0
Renci.SshClient/Renci.SshNet/Renci.SshNet.csproj

@@ -137,6 +137,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="ForwardedPortLocal.NET.cs" />
+    <Compile Include="Messages\Transport\IKeyExchangedAllowed.cs" />
     <Compile Include="ProxyTypes.cs">
       <SubType>Code</SubType>
     </Compile>

+ 1 - 1
Renci.SshClient/Renci.SshNet/ScpClient.NET.cs

@@ -270,7 +270,7 @@ namespace Renci.SshNet
 
         partial void SendData(ChannelSession channel, string command)
         {
-            this.Session.SendMessage(new ChannelDataMessage(channel.RemoteChannelNumber, System.Text.Encoding.Default.GetBytes(command)));
+            channel.SendData(System.Text.Encoding.Default.GetBytes(command));
         }
     }
 }

+ 3 - 3
Renci.SshClient/Renci.SshNet/ScpClient.cs

@@ -323,17 +323,17 @@ namespace Renci.SshNet
         {
             if (length == buffer.Length)
             {
-                this.Session.SendMessage(new ChannelDataMessage(channel.RemoteChannelNumber, buffer));
+                channel.SendData(buffer);
             }
             else
             {
-                this.Session.SendMessage(new ChannelDataMessage(channel.RemoteChannelNumber, buffer.Take(length).ToArray()));
+                channel.SendData(buffer.Take(length).ToArray());
             }
         }
 
         private void SendData(ChannelSession channel, byte[] buffer)
         {
-            this.Session.SendMessage(new ChannelDataMessage(channel.RemoteChannelNumber, buffer));
+            channel.SendData(buffer);
         }
 
         private static int ReadByte(Stream stream)

+ 12 - 0
Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs

@@ -88,6 +88,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Client encryption algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
 
+            session.ConnectionInfo.CurrentClientEncryption = clientEncryptionAlgorithmName;
+
             //  Determine encryption algorithm
             var serverDecryptionAlgorithmName = (from b in session.ConnectionInfo.Encryptions.Keys
                                                  from a in message.EncryptionAlgorithmsServerToClient
@@ -98,6 +100,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Server decryption algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
 
+            session.ConnectionInfo.CurrentServerEncryption = serverDecryptionAlgorithmName;
+
             //  Determine client hmac algorithm
             var clientHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys
                                            from a in message.MacAlgorithmsClientToServer
@@ -108,6 +112,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Server HMAC algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
 
+            session.ConnectionInfo.CurrentClientHmacAlgorithm = clientHmacAlgorithmName;
+
             //  Determine server hmac algorithm
             var serverHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys
                                            from a in message.MacAlgorithmsServerToClient
@@ -118,6 +124,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Server HMAC algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
 
+            session.ConnectionInfo.CurrentServerHmacAlgorithm = serverHmacAlgorithmName;
+
             //  Determine compression algorithm
             var compressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
                                             from a in message.CompressionAlgorithmsClientToServer
@@ -128,6 +136,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Compression algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
 
+            session.ConnectionInfo.CurrentClientCompressionAlgorithm = compressionAlgorithmName;
+
             //  Determine decompression algorithm
             var decompressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
                                               from a in message.CompressionAlgorithmsServerToClient
@@ -138,6 +148,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Decompression algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
 
+            session.ConnectionInfo.CurrentServerCompressionAlgorithm = decompressionAlgorithmName;
+
             this._clientCipherInfo = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName];
             this._serverCipherInfo = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName];
             this._cientHmacAlgorithmType = session.ConnectionInfo.HmacAlgorithms[clientHmacAlgorithmName];

+ 2 - 0
Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs

@@ -81,6 +81,8 @@ namespace Renci.SshNet.Security
 
                 var key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](this._hostKey);
 
+                this.Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName;
+
                 return key.VerifySignature(exchangeHash, this._signature);
             }
             else

+ 1 - 1
Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroup14Sha1.cs

@@ -68,7 +68,7 @@ namespace Renci.SshNet.Security
 
             this.PopulateClientExchangeValue();
 
-            this.Session.SendMessage(new KeyExchangeDhInitMessage(this._clientExchangeValue));
+            this.SendMessage(new KeyExchangeDhInitMessage(this._clientExchangeValue));
         }
 
         /// <summary>

+ 2 - 2
Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroup1Sha1.cs

@@ -12,7 +12,7 @@ namespace Renci.SshNet.Security
     /// <summary>
     /// Represents "diffie-hellman-group1-sha1" algorithm implementation.
     /// </summary>
-    internal class KeyExchangeDiffieHellmanGroup1Sha1 : KeyExchangeDiffieHellman
+    public class KeyExchangeDiffieHellmanGroup1Sha1 : KeyExchangeDiffieHellman
     {
         /// <summary>
         /// Gets algorithm name.
@@ -68,7 +68,7 @@ namespace Renci.SshNet.Security
 
             this.PopulateClientExchangeValue();
 
-            this.Session.SendMessage(new KeyExchangeDhInitMessage(this._clientExchangeValue));
+            this.SendMessage(new KeyExchangeDhInitMessage(this._clientExchangeValue));
 
         }
 

+ 2 - 2
Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs

@@ -66,7 +66,7 @@ namespace Renci.SshNet.Security
             this.Session.MessageReceived += Session_MessageReceived;
 
             //  1. send SSH_MSG_KEY_DH_GEX_REQUEST
-            this.Session.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024, 1024, 1024));
+            this.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024, 1024, 1024));
         }
 
         /// <summary>
@@ -95,7 +95,7 @@ namespace Renci.SshNet.Security
                 this.PopulateClientExchangeValue();
 
                 //  3. Send SSH_MSG_KEX_DH_GEX_INIT
-                this.Session.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
+                this.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
 
             }
             var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;

+ 3 - 3
Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs

@@ -21,7 +21,7 @@ namespace Renci.SshNet.Security
         /// </summary>
         public override string Name
         {
-            get { return "diffie-hellman-group-exchange-sha1"; }
+            get { return "diffie-hellman-group-exchange-sha256"; }
         }
 
         /// <summary>
@@ -39,7 +39,7 @@ namespace Renci.SshNet.Security
             this.Session.MessageReceived += Session_MessageReceived;
 
             //  1. send SSH_MSG_KEY_DH_GEX_REQUEST
-            this.Session.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024,1024,1024));
+            this.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024,1024,1024));
             
         }
 
@@ -112,7 +112,7 @@ namespace Renci.SshNet.Security
                 this.PopulateClientExchangeValue();
 
                 //  3. Send SSH_MSG_KEX_DH_GEX_INIT
-                this.Session.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
+                this.SendMessage(new KeyExchangeDhGroupExchangeInit(this._clientExchangeValue));
             }
             var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
 

+ 17 - 0
Renci.SshClient/Renci.SshNet/Session.cs

@@ -93,6 +93,11 @@ namespace Renci.SshNet
         /// </summary>
         private EventWaitHandle _keyExchangeCompletedWaitHandle = new ManualResetEvent(false);
 
+        /// <summary>
+        /// WaitHandle to signal that key exchange is in progress.
+        /// </summary>
+        private bool _keyExchangeInProgress = false;
+
         /// <summary>
         /// Exception that need to be thrown by waiting thread
         /// </summary>
@@ -657,6 +662,12 @@ namespace Renci.SshNet
             if (this._socket == null || !this._socket.Connected)
                 return;
 
+            if (this._keyExchangeInProgress && !(message is IKeyExchangedAllowed))
+            { 
+                //  Wait for key exchange to be completed
+                this.WaitHandle(this._keyExchangeCompletedWaitHandle);
+            }
+
             this.Log(string.Format("SendMessage to server '{0}': '{1}'.", message.GetType().Name, message.ToString()));
 
             //  Messages can be sent by different thread so we need to synchronize it            
@@ -1155,6 +1166,8 @@ namespace Renci.SshNet
         /// <param name="message"><see cref="KeyExchangeInitMessage"/> message.</param>
         protected virtual void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
         {
+            this._keyExchangeInProgress = true;
+
             this._keyExchangeCompletedWaitHandle.Reset();
 
             //  Disable all registered messages except key exchange related
@@ -1177,6 +1190,8 @@ namespace Renci.SshNet
             //  Create instance of key exchange algorithm that will be used
             this._keyExchange = this.ConnectionInfo.KeyExchangeAlgorithms[keyExchangeAlgorithmName].CreateInstance<KeyExchange>();
 
+            this.ConnectionInfo.CurrentKeyExchangeAlgorithm = keyExchangeAlgorithmName;
+
             this._keyExchange.HostKeyReceived += KeyExchange_HostKeyReceived;
 
             //  Start the algorithm implementation
@@ -1243,6 +1258,8 @@ namespace Renci.SshNet
 
             //  Signal that key exchange completed
             this._keyExchangeCompletedWaitHandle.Set();
+
+            this._keyExchangeInProgress = false;
         }
 
         /// <summary>

+ 20 - 2
Renci.SshClient/Renci.SshNet/Sftp/SftpSession.cs

@@ -70,7 +70,14 @@ namespace Renci.SshNet.Sftp
 
         internal void SendMessage(SftpMessage sftpMessage)
         {
-            this.SendData(new SftpDataMessage(this.ChannelNumber, sftpMessage));
+            var messageData = sftpMessage.GetBytes();
+
+            var data = new byte[4 + messageData.Length];
+
+            ((uint)messageData.Length).GetBytes().CopyTo(data, 0);
+            messageData.CopyTo(data, 4);
+
+            this.SendData(data);
         }
 
         /// <summary>
@@ -245,7 +252,18 @@ namespace Renci.SshNet.Sftp
                 this._requests.Add(request.RequestId, request);
             }
 
-            this.SendData(new SftpDataMessage(this.ChannelNumber, request));
+            this.SendMessage(request);
+            //this.SendData(new SftpDataMessage(this.ChannelNumber, request));
+
+            //var messageData = request.GetBytes();
+
+            //var data = new byte[4 + messageData.Length];
+
+            //((uint)messageData.Length).GetBytes().CopyTo(data, 0);
+            //messageData.CopyTo(data, 4);
+
+            //this.SendData(data);
+
         }
 
         #region SFTP API functions

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

@@ -153,7 +153,7 @@ namespace Renci.SshNet
                             var read = this._input.EndRead(result);
                             if (read > 0)
                             {
-                                this._session.SendMessage(new ChannelDataMessage(this._channel.RemoteChannelNumber, buffer.Take(read).ToArray()));
+                                this._channel.SendData(buffer.Take(read).ToArray());
                             }
 
                         }, null);

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

@@ -98,10 +98,10 @@ namespace Renci.SshNet.Sftp
         /// <summary>
         /// Sends data to the subsystem.
         /// </summary>
-        /// <param name="message">The message.</param>
-        public void SendData(ChannelDataMessage message)
+        /// <param name="data">The data to be sent.</param>
+        public void SendData(byte[] data)
         {
-            this._session.SendMessage(message);
+            this._channel.SendData(data);
         }
 
         /// <summary>