Browse Source

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 years ago
parent
commit
f8faabddda
32 changed files with 165 additions and 74 deletions
  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">
     <Compile Include="..\Renci.SshNet\Messages\Transport\IgnoreMessage.cs">
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Messages\Transport\IKeyExchangedAllowed.cs">
+      <Link>Messages\Transport\IKeyExchangedAllowed.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
     </Compile>
     </Compile>
@@ -752,7 +755,7 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <ProjectExtensions>
   <ProjectExtensions>
     <VisualStudio>
     <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>
     </VisualStudio>
   </ProjectExtensions>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- 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">
     <Compile Include="..\Renci.SshNet\Messages\Transport\IgnoreMessage.cs">
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Messages\Transport\IKeyExchangedAllowed.cs">
+      <Link>Messages\Transport\IKeyExchangedAllowed.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
     </Compile>
     </Compile>
@@ -719,7 +722,7 @@
       <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
       <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
         <SilverlightProjectProperties />
         <SilverlightProjectProperties />
       </FlavorProperties>
       </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>
     </VisualStudio>
   </ProjectExtensions>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- 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">
     <Compile Include="..\Renci.SshNet\Messages\Transport\IgnoreMessage.cs">
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
       <Link>Messages\Transport\IgnoreMessage.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Messages\Transport\IKeyExchangedAllowed.cs">
+      <Link>Messages\Transport\IKeyExchangedAllowed.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
     <Compile Include="..\Renci.SshNet\Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs">
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
       <Link>Messages\Transport\KeyExchangeDhGroupExchangeGroup.cs</Link>
     </Compile>
     </Compile>
@@ -723,7 +726,7 @@
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
   <ProjectExtensions>
   <ProjectExtensions>
     <VisualStudio>
     <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>
     </VisualStudio>
   </ProjectExtensions>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- 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));
             this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
         }
         }
 
 
+        internal void SendData(byte[] buffer)
+        {
+            this.SendMessage(new ChannelDataMessage(this.RemoteChannelNumber, buffer));
+        }
+
         /// <summary>
         /// <summary>
         /// Closes the channel.
         /// Closes the channel.
         /// </summary>
         /// </summary>
@@ -215,8 +220,6 @@ namespace Renci.SshNet.Channels
 
 
             //  Wait for channel to be closed
             //  Wait for channel to be closed
             this._session.WaitHandle(this._channelClosedWaitHandle);
             this._session.WaitHandle(this._channelClosedWaitHandle);
-
-            //this.Dispose();
         }
         }
 
 
         #region Channel virtual methods
         #region Channel virtual methods

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

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

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

@@ -153,6 +153,46 @@ namespace Renci.SshNet
         /// </summary>
         /// </summary>
         public event EventHandler<AuthenticationBannerEventArgs> AuthenticationBanner;
         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>
         /// <summary>
         /// Prevents a default instance of the <see cref="ConnectionInfo"/> class from being created.
         /// Prevents a default instance of the <see cref="ConnectionInfo"/> class from being created.
         /// </summary>
         /// </summary>
@@ -301,31 +341,6 @@ namespace Renci.SshNet
             this.ProxyPassword = proxyPassword;
             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>
         /// <summary>
         /// Authenticates the specified session.
         /// Authenticates the specified session.
         /// </summary>
         /// </summary>

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

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

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

@@ -6,7 +6,10 @@ using System.Threading;
 
 
 namespace Renci.SshNet
 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;
         private EventWaitHandle _listenerTaskCompleted;
 
 
@@ -63,7 +66,7 @@ namespace Renci.SshNet
         partial void InternalStop();
         partial void InternalStop();
 
 
         partial void ExecuteThread(Action action);
         partial void ExecuteThread(Action action);
-    
+
         #region IDisposable Members
         #region IDisposable Members
 
 
         private bool _isDisposed = false;
         private bool _isDisposed = false;
@@ -117,5 +120,5 @@ namespace Renci.SshNet
         }
         }
 
 
         #endregion
         #endregion
-}
+    }
 }
 }

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

@@ -37,6 +37,12 @@ namespace Renci.SshNet
         /// </summary>
         /// </summary>
         public uint Port { get; protected set; }
         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)
         public ForwardedPortRemote(uint boundPort, string host, uint port)
             : this(string.Empty, boundPort, host, 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.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
 
 
-            this.Session.SendMessage(this._requestMessage);
+            this.SendMessage(this._requestMessage);
 
 
             this.WaitHandle(this._authenticationCompleted);
             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.
     /// Represents SSH_MSG_DISCONNECT message.
     /// </summary>
     /// </summary>
     [Message("SSH_MSG_DISCONNECT", 1)]
     [Message("SSH_MSG_DISCONNECT", 1)]
-    public class DisconnectMessage : Message
+    public class DisconnectMessage : Message, IKeyExchangedAllowed
     {
     {
         /// <summary>
         /// <summary>
         /// Gets disconnect reason code.
         /// 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.
     /// Represents SSH_MSG_KEX_DH_GEX_INIT message.
     /// </summary>
     /// </summary>
     [Message("SSH_MSG_KEX_DH_GEX_INIT", 32)]
     [Message("SSH_MSG_KEX_DH_GEX_INIT", 32)]
-    internal class KeyExchangeDhGroupExchangeInit : Message
+    internal class KeyExchangeDhGroupExchangeInit : Message, IKeyExchangedAllowed
     {
     {
         /// <summary>
         /// <summary>
         /// Gets the E value.
         /// 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.
     /// Represents SSH_MSG_KEX_DH_GEX_REQUEST message.
     /// </summary>
     /// </summary>
     [Message("SSH_MSG_KEX_DH_GEX_REQUEST", 34)]
     [Message("SSH_MSG_KEX_DH_GEX_REQUEST", 34)]
-    internal class KeyExchangeDhGroupExchangeRequest : Message
+    internal class KeyExchangeDhGroupExchangeRequest : Message, IKeyExchangedAllowed
     {
     {
         /// <summary>
         /// <summary>
         /// Gets or sets the minimal size in bits of an acceptable group.
         /// 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.
     /// Represents SSH_MSG_KEXDH_INIT message.
     /// </summary>
     /// </summary>
     [Message("SSH_MSG_KEXDH_INIT", 30)]
     [Message("SSH_MSG_KEXDH_INIT", 30)]
-    internal class KeyExchangeDhInitMessage : Message
+    internal class KeyExchangeDhInitMessage : Message, IKeyExchangedAllowed
     {
     {
         /// <summary>
         /// <summary>
         /// Gets the E value.
         /// 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.
     /// Represents SSH_MSG_KEXINIT message.
     /// </summary>
     /// </summary>
     [Message("SSH_MSG_KEXINIT", 20)]
     [Message("SSH_MSG_KEXINIT", 20)]
-    public class KeyExchangeInitMessage : Message
+    public class KeyExchangeInitMessage : Message, IKeyExchangedAllowed
     {
     {
         private static RNGCryptoServiceProvider _randomizer = new System.Security.Cryptography.RNGCryptoServiceProvider();
         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.
     /// Represents SSH_MSG_KEXINIT message.
     /// </summary>
     /// </summary>
     [Message("SSH_MSG_NEWKEYS", 21)]
     [Message("SSH_MSG_NEWKEYS", 21)]
-    public class NewKeysMessage : Message
+    public class NewKeysMessage : Message, IKeyExchangedAllowed
     {
     {
         /// <summary>
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// 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.AppendFormat("\n#{0}\n", rpc.InnerXml.Length);
                 command.Append(rpc.InnerXml);
                 command.Append(rpc.InnerXml);
                 command.Append("\n##\n");
                 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);
                 this.WaitHandle(this._rpcReplyReceived, this._operationTimeout);
                 reply.LoadXml(_rpcReply.ToString());
                 reply.LoadXml(_rpcReply.ToString());
             }
             }
             else
             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);
                 this.WaitHandle(this._rpcReplyReceived, this._operationTimeout);
                 reply.LoadXml(_rpcReply.ToString());
                 reply.LoadXml(_rpcReply.ToString());
             }
             }
@@ -108,7 +109,7 @@ namespace Renci.SshNet.NetConf
         {            
         {            
             string message = string.Format("{0}{1}", this.ClientCapabilities.InnerXml, _prompt);
             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);
             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.
         /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
         /// </summary>
         /// </summary>
         /// <param name="host">Connection host.</param>
         /// <param name="host">Connection host.</param>
-        /// <param name="port">The port.</param>
         /// <param name="username">Connection username.</param>
         /// <param name="username">Connection username.</param>
         /// <param name="password">Connection password.</param>
         /// <param name="password">Connection password.</param>
         /// <param name="proxyType">Type of the proxy.</param>
         /// <param name="proxyType">Type of the proxy.</param>
         /// <param name="proxyHost">The proxy host.</param>
         /// <param name="proxyHost">The proxy host.</param>
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</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)
         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)
             : 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="proxyHost">The proxy host.</param>
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyPort">The proxy port.</param>
         /// <param name="proxyUsername">The proxy username.</param>
         /// <param name="proxyUsername">The proxy username.</param>
+        /// <param name="proxyPassword">The proxy password.</param>
         public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
         public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
             : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, 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>
       <SubType>Code</SubType>
     </Compile>
     </Compile>
     <Compile Include="ForwardedPortLocal.NET.cs" />
     <Compile Include="ForwardedPortLocal.NET.cs" />
+    <Compile Include="Messages\Transport\IKeyExchangedAllowed.cs" />
     <Compile Include="ProxyTypes.cs">
     <Compile Include="ProxyTypes.cs">
       <SubType>Code</SubType>
       <SubType>Code</SubType>
     </Compile>
     </Compile>

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

@@ -270,7 +270,7 @@ namespace Renci.SshNet
 
 
         partial void SendData(ChannelSession channel, string command)
         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)
             if (length == buffer.Length)
             {
             {
-                this.Session.SendMessage(new ChannelDataMessage(channel.RemoteChannelNumber, buffer));
+                channel.SendData(buffer);
             }
             }
             else
             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)
         private void SendData(ChannelSession channel, byte[] buffer)
         {
         {
-            this.Session.SendMessage(new ChannelDataMessage(channel.RemoteChannelNumber, buffer));
+            channel.SendData(buffer);
         }
         }
 
 
         private static int ReadByte(Stream stream)
         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);
                 throw new SshConnectionException("Client encryption algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
             }
 
 
+            session.ConnectionInfo.CurrentClientEncryption = clientEncryptionAlgorithmName;
+
             //  Determine encryption algorithm
             //  Determine encryption algorithm
             var serverDecryptionAlgorithmName = (from b in session.ConnectionInfo.Encryptions.Keys
             var serverDecryptionAlgorithmName = (from b in session.ConnectionInfo.Encryptions.Keys
                                                  from a in message.EncryptionAlgorithmsServerToClient
                                                  from a in message.EncryptionAlgorithmsServerToClient
@@ -98,6 +100,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Server decryption algorithm not found", DisconnectReason.KeyExchangeFailed);
                 throw new SshConnectionException("Server decryption algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
             }
 
 
+            session.ConnectionInfo.CurrentServerEncryption = serverDecryptionAlgorithmName;
+
             //  Determine client hmac algorithm
             //  Determine client hmac algorithm
             var clientHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys
             var clientHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys
                                            from a in message.MacAlgorithmsClientToServer
                                            from a in message.MacAlgorithmsClientToServer
@@ -108,6 +112,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Server HMAC algorithm not found", DisconnectReason.KeyExchangeFailed);
                 throw new SshConnectionException("Server HMAC algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
             }
 
 
+            session.ConnectionInfo.CurrentClientHmacAlgorithm = clientHmacAlgorithmName;
+
             //  Determine server hmac algorithm
             //  Determine server hmac algorithm
             var serverHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys
             var serverHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys
                                            from a in message.MacAlgorithmsServerToClient
                                            from a in message.MacAlgorithmsServerToClient
@@ -118,6 +124,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Server HMAC algorithm not found", DisconnectReason.KeyExchangeFailed);
                 throw new SshConnectionException("Server HMAC algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
             }
 
 
+            session.ConnectionInfo.CurrentServerHmacAlgorithm = serverHmacAlgorithmName;
+
             //  Determine compression algorithm
             //  Determine compression algorithm
             var compressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
             var compressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
                                             from a in message.CompressionAlgorithmsClientToServer
                                             from a in message.CompressionAlgorithmsClientToServer
@@ -128,6 +136,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Compression algorithm not found", DisconnectReason.KeyExchangeFailed);
                 throw new SshConnectionException("Compression algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
             }
 
 
+            session.ConnectionInfo.CurrentClientCompressionAlgorithm = compressionAlgorithmName;
+
             //  Determine decompression algorithm
             //  Determine decompression algorithm
             var decompressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
             var decompressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
                                               from a in message.CompressionAlgorithmsServerToClient
                                               from a in message.CompressionAlgorithmsServerToClient
@@ -138,6 +148,8 @@ namespace Renci.SshNet.Security
                 throw new SshConnectionException("Decompression algorithm not found", DisconnectReason.KeyExchangeFailed);
                 throw new SshConnectionException("Decompression algorithm not found", DisconnectReason.KeyExchangeFailed);
             }
             }
 
 
+            session.ConnectionInfo.CurrentServerCompressionAlgorithm = decompressionAlgorithmName;
+
             this._clientCipherInfo = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName];
             this._clientCipherInfo = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName];
             this._serverCipherInfo = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName];
             this._serverCipherInfo = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName];
             this._cientHmacAlgorithmType = session.ConnectionInfo.HmacAlgorithms[clientHmacAlgorithmName];
             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);
                 var key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](this._hostKey);
 
 
+                this.Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName;
+
                 return key.VerifySignature(exchangeHash, this._signature);
                 return key.VerifySignature(exchangeHash, this._signature);
             }
             }
             else
             else

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

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

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

@@ -12,7 +12,7 @@ namespace Renci.SshNet.Security
     /// <summary>
     /// <summary>
     /// Represents "diffie-hellman-group1-sha1" algorithm implementation.
     /// Represents "diffie-hellman-group1-sha1" algorithm implementation.
     /// </summary>
     /// </summary>
-    internal class KeyExchangeDiffieHellmanGroup1Sha1 : KeyExchangeDiffieHellman
+    public class KeyExchangeDiffieHellmanGroup1Sha1 : KeyExchangeDiffieHellman
     {
     {
         /// <summary>
         /// <summary>
         /// Gets algorithm name.
         /// Gets algorithm name.
@@ -68,7 +68,7 @@ namespace Renci.SshNet.Security
 
 
             this.PopulateClientExchangeValue();
             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;
             this.Session.MessageReceived += Session_MessageReceived;
 
 
             //  1. send SSH_MSG_KEY_DH_GEX_REQUEST
             //  1. send SSH_MSG_KEY_DH_GEX_REQUEST
-            this.Session.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024, 1024, 1024));
+            this.SendMessage(new KeyExchangeDhGroupExchangeRequest(1024, 1024, 1024));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -95,7 +95,7 @@ namespace Renci.SshNet.Security
                 this.PopulateClientExchangeValue();
                 this.PopulateClientExchangeValue();
 
 
                 //  3. Send SSH_MSG_KEX_DH_GEX_INIT
                 //  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;
             var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;

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

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

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

@@ -93,6 +93,11 @@ namespace Renci.SshNet
         /// </summary>
         /// </summary>
         private EventWaitHandle _keyExchangeCompletedWaitHandle = new ManualResetEvent(false);
         private EventWaitHandle _keyExchangeCompletedWaitHandle = new ManualResetEvent(false);
 
 
+        /// <summary>
+        /// WaitHandle to signal that key exchange is in progress.
+        /// </summary>
+        private bool _keyExchangeInProgress = false;
+
         /// <summary>
         /// <summary>
         /// Exception that need to be thrown by waiting thread
         /// Exception that need to be thrown by waiting thread
         /// </summary>
         /// </summary>
@@ -657,6 +662,12 @@ namespace Renci.SshNet
             if (this._socket == null || !this._socket.Connected)
             if (this._socket == null || !this._socket.Connected)
                 return;
                 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()));
             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            
             //  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>
         /// <param name="message"><see cref="KeyExchangeInitMessage"/> message.</param>
         protected virtual void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
         protected virtual void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
         {
         {
+            this._keyExchangeInProgress = true;
+
             this._keyExchangeCompletedWaitHandle.Reset();
             this._keyExchangeCompletedWaitHandle.Reset();
 
 
             //  Disable all registered messages except key exchange related
             //  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
             //  Create instance of key exchange algorithm that will be used
             this._keyExchange = this.ConnectionInfo.KeyExchangeAlgorithms[keyExchangeAlgorithmName].CreateInstance<KeyExchange>();
             this._keyExchange = this.ConnectionInfo.KeyExchangeAlgorithms[keyExchangeAlgorithmName].CreateInstance<KeyExchange>();
 
 
+            this.ConnectionInfo.CurrentKeyExchangeAlgorithm = keyExchangeAlgorithmName;
+
             this._keyExchange.HostKeyReceived += KeyExchange_HostKeyReceived;
             this._keyExchange.HostKeyReceived += KeyExchange_HostKeyReceived;
 
 
             //  Start the algorithm implementation
             //  Start the algorithm implementation
@@ -1243,6 +1258,8 @@ namespace Renci.SshNet
 
 
             //  Signal that key exchange completed
             //  Signal that key exchange completed
             this._keyExchangeCompletedWaitHandle.Set();
             this._keyExchangeCompletedWaitHandle.Set();
+
+            this._keyExchangeInProgress = false;
         }
         }
 
 
         /// <summary>
         /// <summary>

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

@@ -70,7 +70,14 @@ namespace Renci.SshNet.Sftp
 
 
         internal void SendMessage(SftpMessage sftpMessage)
         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>
         /// <summary>
@@ -245,7 +252,18 @@ namespace Renci.SshNet.Sftp
                 this._requests.Add(request.RequestId, request);
                 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
         #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);
                             var read = this._input.EndRead(result);
                             if (read > 0)
                             if (read > 0)
                             {
                             {
-                                this._session.SendMessage(new ChannelDataMessage(this._channel.RemoteChannelNumber, buffer.Take(read).ToArray()));
+                                this._channel.SendData(buffer.Take(read).ToArray());
                             }
                             }
 
 
                         }, null);
                         }, null);

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

@@ -98,10 +98,10 @@ namespace Renci.SshNet.Sftp
         /// <summary>
         /// <summary>
         /// Sends data to the subsystem.
         /// Sends data to the subsystem.
         /// </summary>
         /// </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>
         /// <summary>