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");
            }
This commit is contained in:
olegkap_cp
2012-01-04 14:56:58 +00:00
parent 746b4796fa
commit e435bd2300
16 changed files with 835 additions and 26 deletions
@@ -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.
@@ -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.
@@ -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();
@@ -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.
@@ -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)
{
}
}
}
@@ -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)
{
}
}
}
@@ -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
View File
@@ -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>
@@ -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);
}
@@ -30,25 +30,114 @@ namespace Renci.SshNet
return "none";
}
}
/// <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="host">The host.</param>
/// <param name="username">The username.</param>
public NoneConnectionInfo(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="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, 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 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="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>
/// <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)
{
}
@@ -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");
@@ -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);
}
@@ -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
}
}
@@ -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
View File
@@ -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
View File
@@ -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>