Explorar el Código

Add SOCKS4 & SOCKS5 Proxy support when connecting to remote server.
For silverlight only IP address can be used for server address when using proxy.
Usage example:
var connectionInfo = new PasswordConnectionInfo("1.2.3.4", "username", "password", ProxyTypes.Socks4, "127.0.0.1", 8088);
using (var ssh = new SshClient(connectionInfo))
{
ssh.Connect();
var rrr = ssh.RunCommand("ls -l");
}

olegkap_cp hace 14 años
padre
commit
e435bd2300

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

@@ -133,6 +133,9 @@
     <Compile Include="..\Renci.SshNet\Common\PortForwardEventArgs.cs">
       <Link>Common\PortForwardEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Common\ProxyException.cs">
+      <Link>Common\ProxyException.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Common\ScpDownloadEventArgs.cs">
       <Link>Common\ScpDownloadEventArgs.cs</Link>
     </Compile>
@@ -448,6 +451,9 @@
     <Compile Include="..\Renci.SshNet\PrivateKeyFile.cs">
       <Link>PrivateKeyFile.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\ProxyTypes.cs">
+      <Link>ProxyTypes.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\ScpClient.cs">
       <Link>ScpClient.cs</Link>
     </Compile>
@@ -736,7 +742,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. 

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

@@ -141,6 +141,9 @@
     <Compile Include="..\Renci.SshNet\Common\PortForwardEventArgs.cs">
       <Link>Common\PortForwardEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Common\ProxyException.cs">
+      <Link>Common\ProxyException.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Common\ScpDownloadEventArgs.cs">
       <Link>Common\ScpDownloadEventArgs.cs</Link>
     </Compile>
@@ -426,6 +429,9 @@
     <Compile Include="..\Renci.SshNet\PrivateKeyFile.cs">
       <Link>PrivateKeyFile.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\ProxyTypes.cs">
+      <Link>ProxyTypes.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\ScpClient.cs">
       <Link>ScpClient.cs</Link>
     </Compile>
@@ -710,7 +716,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. 

+ 2 - 2
Renci.SshClient/Renci.SshNet.Silverlight/Session.SilverlightShared.cs

@@ -26,9 +26,9 @@ namespace Renci.SshNet
 
         private bool _isConnected = false;
 
-        partial void SocketConnect()
+        partial void SocketConnect(string host, int port)
         {
-            var ep = new DnsEndPoint(this.ConnectionInfo.Host, this.ConnectionInfo.Port);
+            var ep = new DnsEndPoint(host, port);
             this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
             SocketAsyncEventArgs args = new SocketAsyncEventArgs();

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

@@ -137,6 +137,9 @@
     <Compile Include="..\Renci.SshNet\Common\PortForwardEventArgs.cs">
       <Link>Common\PortForwardEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\Common\ProxyException.cs">
+      <Link>Common\ProxyException.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\Common\ScpDownloadEventArgs.cs">
       <Link>Common\ScpDownloadEventArgs.cs</Link>
     </Compile>
@@ -425,6 +428,9 @@
     <Compile Include="..\Renci.SshNet\PrivateKeyFile.cs">
       <Link>PrivateKeyFile.cs</Link>
     </Compile>
+    <Compile Include="..\Renci.SshNet\ProxyTypes.cs">
+      <Link>ProxyTypes.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet\ScpClient.cs">
       <Link>ScpClient.cs</Link>
     </Compile>
@@ -714,7 +720,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. 

+ 26 - 0
Renci.SshClient/Renci.SshNet/Common/ProxyException.NET40.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.Serialization;
+
+namespace Renci.SshNet.Common
+{
+    [Serializable]
+    public partial class ProxyException : SshException
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ProxyException"/> class.
+        /// </summary>
+        /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+        /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+        /// <exception cref="T:System.ArgumentNullException">The <paramref name="info"/> parameter is null. </exception>
+        ///   
+        /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
+        protected ProxyException(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
+    }
+
+}

+ 42 - 0
Renci.SshClient/Renci.SshNet/Common/ProxyException.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshNet.Common
+{
+    /// <summary>
+    /// The exception that is thrown when SCP error occurred.
+    /// </summary>
+    public partial class ProxyException : SshException
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ScpException"/> class.
+        /// </summary>
+        public ProxyException()
+        {
+
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ScpException"/> class.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        public ProxyException(string message)
+            : base(message)
+        {
+
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ScpException"/> class.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="innerException">The inner exception.</param>
+        public ProxyException(string message, Exception innerException) :
+            base(message, innerException)
+        {
+        }
+    }
+
+}

+ 3 - 2
Renci.SshClient/Renci.SshNet/Common/ScpException.NET40.cs

@@ -10,7 +10,7 @@ namespace Renci.SshNet.Common
     public partial class ScpException : SshException
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="SftpPathNotFoundException"/> class.
+        /// Initializes a new instance of the <see cref="ScpException"/> class.
         /// </summary>
         /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
         /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
@@ -21,4 +21,5 @@ namespace Renci.SshNet.Common
             : base(info, context)
         {
         }
-    }}
+    }
+}

+ 76 - 2
Renci.SshClient/Renci.SshNet/ConnectionInfo.cs

@@ -14,12 +14,14 @@ using Renci.SshNet.Security.Cryptography.Ciphers;
 using System.Security.Cryptography;
 using Renci.SshNet.Security.Cryptography;
 using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
+using System.Net.Sockets;
+using System.Text;
 namespace Renci.SshNet
 {
     /// <summary>
     /// Represents remote connection information base class.
     /// </summary>
-    public abstract class ConnectionInfo
+    public abstract partial class ConnectionInfo
     {
         /// <summary>
         /// Gets connection name
@@ -94,6 +96,34 @@ namespace Renci.SshNet
         /// </summary>
         public string Username { get; private set; }
 
+        /// <summary>
+        /// Gets proxy type.
+        /// </summary>
+        /// <value>
+        /// The type of the proxy.
+        /// </value>
+        public ProxyTypes ProxyType { get; private set; }
+
+        /// <summary>
+        /// Gets proxy connection host.
+        /// </summary>
+        public string ProxyHost { get; private set; }
+
+        /// <summary>
+        /// Gets proxy connection port.
+        /// </summary>
+        public int ProxyPort { get; private set; }
+
+        /// <summary>
+        /// Gets proxy connection username.
+        /// </summary>
+        public string ProxyUsername { get; private set; }
+
+        /// <summary>
+        /// Gets proxy connection password.
+        /// </summary>
+        public string ProxyPassword { get; private set; }
+
         /// <summary>
         /// Gets or sets connection timeout.
         /// </summary>
@@ -232,26 +262,70 @@ namespace Renci.SshNet
         /// <param name="host">Connection host.</param>
         /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</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>
         /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
+        ///   
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
+        ///   
         /// <exception cref="ArgumentException"><paramref name="username"/> is null or empty.</exception>
-        protected ConnectionInfo(string host, int port, string username)
+        protected ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
             : this()
         {
             if (!host.IsValidHost())
                 throw new ArgumentException("host");
 
+            if (!string.IsNullOrEmpty(proxyHost) && !proxyHost.IsValidHost())
+                throw new ArgumentException("proxyHost");
+
             if (!port.IsValidPort())
                 throw new ArgumentOutOfRangeException("port");
 
+            if (!proxyPort.IsValidPort())
+                throw new ArgumentOutOfRangeException("proxyPort");
+
             if (username.IsNullOrWhiteSpace())
                 throw new ArgumentException("username");
 
             this.Host = host;
             this.Port = port;
             this.Username = username;
+
+            this.ProxyType = proxyType;
+            this.ProxyHost = proxyHost;
+            this.ProxyPort = proxyPort;
+            this.ProxyUsername = proxyUsername;
+            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>

+ 91 - 3
Renci.SshClient/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs

@@ -42,7 +42,19 @@ namespace Renci.SshNet
         /// <param name="host">The host.</param>
         /// <param name="username">The username.</param>
         public KeyboardInteractiveConnectionInfo(string host, string username)
-            : this(host, 22, username)
+            : this(host, 22, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
+        {
+
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">The host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">The username.</param>
+        public KeyboardInteractiveConnectionInfo(string host, int port, string username)
+            : this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
         {
 
         }
@@ -53,8 +65,84 @@ namespace Renci.SshNet
         /// <param name="host">Connection host.</param>
         /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</param>
-        public KeyboardInteractiveConnectionInfo(string host, int port, string username)
-            : base(host, port, username)
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public KeyboardInteractiveConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">Connection port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public KeyboardInteractiveConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public KeyboardInteractiveConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public KeyboardInteractiveConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</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 KeyboardInteractiveConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">Connection port.</param>
+        /// <param name="username">Connection username.</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 KeyboardInteractiveConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {
             this._requestMessage = new RequestMessageKeyboardInteractive(ServiceName.Connection, username);
         }

+ 95 - 6
Renci.SshClient/Renci.SshNet/NoneConnectionInfo.cs

@@ -30,25 +30,114 @@ namespace Renci.SshNet
                 return "none";
             }
         }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">The host.</param>
+        /// <param name="username">The username.</param>
+        public NoneConnectionInfo(string host, string username)
+            : this(host, 22, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
+        {
+
+        }
+
         /// <summary>
-        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">The host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">The username.</param>
+        public NoneConnectionInfo(string host, int port, string username)
+            : this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
+        {
+
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
         /// </summary>
         /// <param name="host">Connection host.</param>
+        /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</param>
-        public NoneConnectionInfo(string host, string username)
-            : this(host, 22, username)
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public NoneConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">Connection port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public NoneConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
         {
+        }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public NoneConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
         }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public NoneConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</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 NoneConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
         /// </summary>
         /// <param name="host">Connection host.</param>
         /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</param>
-        public NoneConnectionInfo(string host, int port, string username)
-            : base(host, port, username)
+        /// <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 NoneConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {
         }
 

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

@@ -61,7 +61,99 @@ namespace Renci.SshNet
         /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="f:IPEndPoint.MinPort"/> and <see cref="f:IPEndPoint.MaxPort"/>.</exception>
         public PasswordConnectionInfo(string host, int port, string username, string password)
-            : base(host, port, username)
+            : this(host, port, username, password, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, port, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, port, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort)
+            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
+            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="password">Connection password.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="proxyUsername">The proxy username.</param>
+        public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
+            : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {
             if (password == null)
                 throw new ArgumentNullException("password");

+ 95 - 2
Renci.SshClient/Renci.SshNet/PrivateKeyConnectionInfo.cs

@@ -42,7 +42,7 @@ namespace Renci.SshNet
         /// <param name="username">Connection username.</param>
         /// <param name="keyFiles">Connection key files.</param>
         public PrivateKeyConnectionInfo(string host, string username, params PrivateKeyFile[] keyFiles)
-            : this(host, 22, username, keyFiles)
+            : this(host, 22, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
         {
 
         }
@@ -55,7 +55,100 @@ namespace Renci.SshNet
         /// <param name="username">Connection username.</param>
         /// <param name="keyFiles">Connection key files.</param>
         public PrivateKeyConnectionInfo(string host, int port, string username, params PrivateKeyFile[] keyFiles)
-            : base(host, port, username)
+            : this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="keyFiles">The key files.</param>
+        public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params PrivateKeyFile[] keyFiles)
+            : this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="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="keyFiles">The key files.</param>
+        public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles)
+            : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="proxyType">Type of the proxy.</param>
+        /// <param name="proxyHost">The proxy host.</param>
+        /// <param name="proxyPort">The proxy port.</param>
+        /// <param name="keyFiles">The key files.</param>
+        public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params PrivateKeyFile[] keyFiles)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="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="keyFiles">The key files.</param>
+        public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="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>
+        /// <param name="keyFiles">The key files.</param>
+        public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles)
+            : this(host, 22, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, keyFiles)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PasswordConnectionInfo"/> class.
+        /// </summary>
+        /// <param name="host">Connection host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="username">Connection username.</param>
+        /// <param name="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>
+        /// <param name="keyFiles">The key files.</param>
+        public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles)
+            : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
         {
             this.KeyFiles = new Collection<PrivateKeyFile>(keyFiles);
         }

+ 20 - 0
Renci.SshClient/Renci.SshNet/ProxyTypes.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshNet
+{
+    /// <summary>
+    /// Specifies the type of proxy client will use to connect to server.
+    /// </summary>
+    public enum ProxyTypes
+    {
+        /// <summary>No proxy server.</summary>
+        None,
+        /// <summary>A SOCKS4 proxy server.</summary>
+        Socks4,
+        /// <summary>A SOCKS5 proxy server.</summary>
+        Socks5
+    }
+}

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

@@ -69,6 +69,10 @@
     <Compile Include="Common\ChannelEventArgs.cs" />
     <Compile Include="Common\ChannelOpenFailedEventArgs.cs" />
     <Compile Include="Common\ChannelRequestEventArgs.cs" />
+    <Compile Include="Common\ProxyException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\ProxyException.NET40.cs" />
     <Compile Include="Common\HostKeyEventArgs.cs" />
     <Compile Include="Common\NetConfServerException.NET40.cs" />
     <Compile Include="Common\DerData.cs" />
@@ -125,6 +129,9 @@
     <Compile Include="ConnectionInfo.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="ProxyTypes.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="ScpClient.cs">
       <SubType>Code</SubType>
     </Compile>

+ 2 - 2
Renci.SshClient/Renci.SshNet/Session.NET.cs

@@ -20,9 +20,9 @@ namespace Renci.SshNet
             new TraceSource("SshNet.Logging");
 #endif
 
-        partial void SocketConnect()
+        partial void SocketConnect(string host, int port)
         {
-            var ep = new IPEndPoint(Dns.GetHostAddresses(this.ConnectionInfo.Host)[0], this.ConnectionInfo.Port);
+            var ep = new IPEndPoint(Dns.GetHostAddresses(host)[0], port);
             this._socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
 
             var socketBufferSize = 2 * MAXIMUM_PACKET_SIZE;

+ 261 - 2
Renci.SshClient/Renci.SshNet/Session.cs

@@ -431,7 +431,23 @@ namespace Renci.SshNet
                     //  Build list of available messages while connecting
                     this._messagesMetadata = GetMessagesMetadata();
 
-                    this.SocketConnect();
+                    switch (this.ConnectionInfo.ProxyType)
+                    {
+                        case ProxyTypes.None:
+                            this.SocketConnect(this.ConnectionInfo.Host, this.ConnectionInfo.Port);
+                            break;
+                        case ProxyTypes.Socks4:
+                            this.SocketConnect(this.ConnectionInfo.ProxyHost, this.ConnectionInfo.ProxyPort);
+                            this.ConnectSocks4(this._socket);
+                            break;
+                        case ProxyTypes.Socks5:
+                            this.SocketConnect(this.ConnectionInfo.ProxyHost, this.ConnectionInfo.ProxyPort);
+                            this.ConnectSocks5(this._socket);
+                            break;
+                        default:
+                            break;
+                    }
+
 
                     Match versionMatch = null;
 
@@ -1531,7 +1547,7 @@ namespace Renci.SshNet
 
         partial void ExecuteThread(Action action);
 
-        partial void SocketConnect();
+        partial void SocketConnect(string host, int port);
 
         partial void SocketDisconnect();
 
@@ -1572,6 +1588,249 @@ namespace Renci.SshNet
             }
         }
 
+        private byte SocketReadByte()
+        {
+            byte[] buffer = null;
+
+            this.SocketRead(1, ref buffer);
+
+            return buffer[0];
+        }
+
+        private void SocketWriteByte(byte data)
+        {
+            this.SocketWrite(new byte[] { data });
+        }
+
+        private void ConnectSocks4(Socket socket)
+        {
+            //  Send socks version number
+            this.SocketWriteByte(0x04);
+
+            //  Send command code
+            this.SocketWriteByte(0x01);
+
+            //  Send port
+            this.SocketWriteByte((byte)(this.ConnectionInfo.Port / 0xFF));
+            this.SocketWriteByte((byte)(this.ConnectionInfo.Port % 0xFF));
+
+            //  Send IP
+            IPAddress ipAddress;
+#if SILVERLIGHT
+            if (!IPAddress.TryParse(this.ConnectionInfo.Host, out ipAddress))
+            {
+                throw new ProxyException("SOCKS4: Silverlight supports only IP addresses.");
+            }
+#else
+            ipAddress = Dns.GetHostAddresses(this.ConnectionInfo.Host).First();
+#endif
+            this.SocketWrite(ipAddress.GetAddressBytes());
+
+            //  Send username
+            var username = new Renci.SshNet.Common.ASCIIEncoding().GetBytes(this.ConnectionInfo.ProxyUsername);
+            this.SocketWrite(username);
+            this.SocketWriteByte(0x00);
+
+            //  Read 0
+            if (this.SocketReadByte() != 0)
+            {
+                throw new ProxyException("SOCKS4: Null is expected.");
+            }
+
+            //  Read response code
+            var code = this.SocketReadByte();
+
+            switch (code)
+            {
+                case 0x5a:
+                    break;
+                case 0x5b:
+                    throw new ProxyException("SOCKS4: Connection rejected.");
+                case 0x5c:
+                    throw new ProxyException("SOCKS4: Client is not running identd or not reachable from the server.");
+                case 0x5d:
+                    throw new ProxyException("SOCKS4: Client's identd could not confirm the user ID string in the request.");
+                default:
+                    throw new ProxyException("SOCKS4: Not valid response.");
+            }
+
+            byte[] dummyBuffer = null;
+
+            //  Read 2 bytes to be ignored
+            this.SocketRead(2, ref dummyBuffer);
+
+            //  Read 4 bytes to be ignored
+            this.SocketRead(4, ref dummyBuffer);
+        }
+
+        private void ConnectSocks5(Socket socket)
+        {
+            //  Send socks version number
+            this.SocketWriteByte(0x05);
+
+            //  Send number of supported authentication methods
+            this.SocketWriteByte(0x02);
+
+            //  Send supported authentication methods
+            this.SocketWriteByte(0x00); //  No authentication
+            this.SocketWriteByte(0x02); //  Username/Password
+
+            var socksVersion = this.SocketReadByte();
+            if (socksVersion != 0x05)
+                throw new ProxyException(string.Format("SOCKS Version '{0}' is not supported.", socksVersion));
+
+            var authenticationMethod = this.SocketReadByte();
+            switch (authenticationMethod)
+            {
+                case 0x00:
+                    break;
+                case 0x02:
+
+                    //  Send version
+                    this.SocketWriteByte(0x01);
+
+                    var encoding = new Renci.SshNet.Common.ASCIIEncoding();
+
+                    var username = encoding.GetBytes(this.ConnectionInfo.ProxyUsername);
+
+                    if (username.Length > byte.MaxValue)
+                        throw new ProxyException("Proxy username is too long.");
+
+                    //  Send username length
+                    this.SocketWriteByte((byte)username.Length);
+
+                    //  Send username
+                    this.SocketWrite(username);
+
+                    var password = encoding.GetBytes(this.ConnectionInfo.ProxyPassword);
+
+                    if (password.Length > byte.MaxValue)
+                        throw new ProxyException("Proxy password is too long.");
+
+                    //  Send username length
+                    this.SocketWriteByte((byte)password.Length);
+
+                    //  Send username
+                    this.SocketWrite(password);
+
+                    var serverVersion = this.SocketReadByte();
+
+                    if (serverVersion != 1)
+                        throw new ProxyException("SOCKS5: Server authentication version is not valid.");
+
+                    var statusCode = this.SocketReadByte();
+                    if (statusCode != 0)
+                        throw new ProxyException("SOCKS5: Username/Password authentication failed.");
+
+                    break;
+                case 0xFF:
+                    throw new ProxyException("SOCKS5: No acceptable authentication methods were offered.");
+                default:
+                    break;
+            }
+
+            //  Send socks version number
+            this.SocketWriteByte(0x05);
+
+            //  Send command code
+            this.SocketWriteByte(0x01); //  establish a TCP/IP stream connection
+
+            //  Send reserved, must be 0x00
+            this.SocketWriteByte(0x00);
+
+            IPAddress ip;
+#if SILVERLIGHT
+            if (!IPAddress.TryParse(this.ConnectionInfo.Host, out ip))
+            {
+                throw new ProxyException("SOCKS4: Silverlight supports only IP addresses.");
+            }
+#else
+            ip = Dns.GetHostAddresses(this.ConnectionInfo.Host).First();
+#endif
+
+            //  Send address type and address
+            if (ip.AddressFamily == AddressFamily.InterNetwork)
+            {
+                this.SocketWriteByte(0x01);
+                var address = ip.GetAddressBytes();
+                this.SocketWrite(address);
+            }
+            else if (ip.AddressFamily == AddressFamily.InterNetworkV6)
+            {
+                this.SocketWriteByte(0x04);
+                var address = ip.GetAddressBytes();
+                this.SocketWrite(address);
+            }
+            else
+            {
+                throw new ProxyException(string.Format("SOCKS5: IP address '{0}' is not supported.", ip));
+            }
+
+            //  Send port
+            this.SocketWriteByte((byte)(this.ConnectionInfo.Port / 0xFF));
+            this.SocketWriteByte((byte)(this.ConnectionInfo.Port % 0xFF));
+
+            //  Read Server SOCKS5 version
+            if (this.SocketReadByte() != 5)
+            {
+                throw new ProxyException("SOCKS5: Version 5 is expected.");
+            }
+
+            //  Read response code
+            var status = this.SocketReadByte();
+
+            switch (status)
+            {
+                case 0x00:
+                    break;
+                case 0x01:
+                    throw new ProxyException("SOCKS5: General failure.");
+                case 0x02:
+                    throw new ProxyException("SOCKS5: Connection not allowed by ruleset.");
+                case 0x03:
+                    throw new ProxyException("SOCKS5: Network unreachable.");
+                case 0x04:
+                    throw new ProxyException("SOCKS5: Host unreachable.");
+                case 0x05:
+                    throw new ProxyException("SOCKS5: Connection refused by destination host.");
+                case 0x06:
+                    throw new ProxyException("SOCKS5: TTL expired.");
+                case 0x07:
+                    throw new ProxyException("SOCKS5: Command not supported or protocol error.");
+                case 0x08:
+                    throw new ProxyException("SOCKS5: Address type not supported.");
+                default:
+                    throw new ProxyException("SOCKS4: Not valid response.");
+            }
+
+            //  Read 0
+            if (this.SocketReadByte() != 0)
+            {
+                throw new ProxyException("SOCKS5: 0 byte is expected.");
+            }
+
+            var addressType = this.SocketReadByte();
+            byte[] responseIp = null;
+
+            switch (addressType)
+            {
+                case 0x01:
+                    this.SocketRead(4, ref responseIp);
+                    break;
+                case 0x04:
+                    this.SocketRead(16, ref responseIp);
+                    break;
+                default:
+                    throw new ProxyException(string.Format("Address type '{0}' is not supported.", addressType));
+            }
+
+            byte[] port = null;
+
+            //  Read 2 bytes to be ignored
+            this.SocketRead(2, ref port);
+
+        }
+
         /// <summary>
         /// Raises the <see cref="ErrorOccured"/> event.
         /// </summary>