diff --git a/src/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj b/src/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj index 7fa26613b..7cb4068c5 100644 --- a/src/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj +++ b/src/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj @@ -288,6 +288,9 @@ HashInfo.cs + + HostResolutionMode.cs + IAuthenticationMethod.cs diff --git a/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj b/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj index 52ca2f2c2..d0ab9e620 100644 --- a/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj +++ b/src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj @@ -312,6 +312,9 @@ HashInfo.cs + + HostResolutionMode.cs + IAuthenticationMethod.cs diff --git a/src/Renci.SshNet.Tests/Classes/ConnectionInfoTest.cs b/src/Renci.SshNet.Tests/Classes/ConnectionInfoTest.cs index 5fc1cd832..af4e3f2fd 100644 --- a/src/Renci.SshNet.Tests/Classes/ConnectionInfoTest.cs +++ b/src/Renci.SshNet.Tests/Classes/ConnectionInfoTest.cs @@ -343,5 +343,74 @@ public void AuthenticateShouldThrowArgumentNullExceptionWhenServiceFactoryIsNull Assert.AreEqual("serviceFactory", ex.ParamName); } } - } + + [TestMethod] + [TestCategory("ConnectionInfo")] + public void ConstructorShouldThrowArgumentExceptionWhenUsingNoProxyAndNotResolvingHostLocally() + { + try + { + new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, + ProxyTypes.None, null, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD, + HostResolutionMode.ResolvedByProxy, + new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME)); + Assert.Fail(); + } + catch (ArgumentException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("hostResolutionMode", ex.ParamName); + } + } + + [TestMethod] + [TestCategory("ConnectionInfo")] + public void ConstructorShouldThrowArgumentExceptionWhenUsingHttproxyAndResolvingHostOnProxy() + { + try + { + new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, + ProxyTypes.Http, Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD, + HostResolutionMode.ResolvedByProxy, + new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME)); + Assert.Fail(); + } + catch (ArgumentException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("hostResolutionMode", ex.ParamName); + } + } + + [TestMethod] + [TestCategory("ConnectionInfo")] + public void ConstructorShouldThrowArgumentExceptionWhenUsingSocks4ProxyAndResolvingHostOnProxy() + { + try + { + new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, + ProxyTypes.Socks4, Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD, + HostResolutionMode.ResolvedByProxy, + new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME)); + Assert.Fail(); + } + catch (ArgumentException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("hostResolutionMode", ex.ParamName); + } + } + + [TestMethod] + [TestCategory("ConnectionInfo")] + public void ConstructorShouldNotThrowArgumentExceptionWhenUsingSocks5ProxyAndResolvingHostOnProxy() + { + var connectionInfo = new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, + ProxyTypes.Socks5, Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD, + HostResolutionMode.ResolvedByProxy, + new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME)); + + Assert.AreEqual(HostResolutionMode.ResolvedByProxy, connectionInfo.HostResolutionMode); + } + } } \ No newline at end of file diff --git a/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj b/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj index 3470b2be7..9a7e5652b 100644 --- a/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj +++ b/src/Renci.SshNet.UAP10/Renci.SshNet.UAP10.csproj @@ -351,6 +351,9 @@ HashInfo.cs + + HostResolutionMode.cs + IAuthenticationMethod.cs diff --git a/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj b/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj index 2349aebad..2aa883fc0 100644 --- a/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj +++ b/src/Renci.SshNet.WindowsPhone8/Renci.SshNet.WindowsPhone8.csproj @@ -337,6 +337,9 @@ HashInfo.cs + + HostResolutionMode.cs + IAuthenticationMethod.cs diff --git a/src/Renci.SshNet/ConnectionInfo.cs b/src/Renci.SshNet/ConnectionInfo.cs index ba8f38b93..b78539cec 100644 --- a/src/Renci.SshNet/ConnectionInfo.cs +++ b/src/Renci.SshNet/ConnectionInfo.cs @@ -115,6 +115,11 @@ public class ConnectionInfo : IConnectionInfoInternal /// public string ProxyPassword { get; private set; } + /// + /// Gets the host resolution mode. + /// + public HostResolutionMode? HostResolutionMode { get; private set; } + /// /// Gets or sets connection timeout. /// @@ -263,6 +268,32 @@ public ConnectionInfo(string host, int port, string username, params Authenticat /// is null. /// No specified. public ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params AuthenticationMethod[] authenticationMethods) + : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, SshNet.HostResolutionMode.ResolvedLocally, authenticationMethods) + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + /// The authentication methods. + /// is null. + /// is null, a zero-length string or contains only whitespace characters. + /// is not within and . + /// is not and is null. + /// is not and is not within and . + /// is null. + /// No specified. + public ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode, params AuthenticationMethod[] authenticationMethods) { if (host == null) throw new ArgumentNullException("host"); @@ -279,6 +310,17 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy throw new ArgumentNullException("proxyHost"); proxyPort.ValidatePort("proxyPort"); } + else + { + if (hostResolutionMode != SshNet.HostResolutionMode.ResolvedLocally) + throw new ArgumentException("HostResolutionMode.ResolvedLocally is the only supported value when using no proxy", "hostResolutionMode"); + } + + if (hostResolutionMode == SshNet.HostResolutionMode.ResolvedByProxy) + { + if (proxyType != ProxyTypes.Socks5) + throw new ArgumentException("HostResolutionMode.ResolvedByProxy is only supported by SOCKS5 proxies", "hostResolutionMode"); + } if (authenticationMethods == null) throw new ArgumentNullException("authenticationMethods"); @@ -393,6 +435,8 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy ProxyUsername = proxyUsername; ProxyPassword = proxyPassword; + HostResolutionMode = hostResolutionMode; + AuthenticationMethods = authenticationMethods; } diff --git a/src/Renci.SshNet/HostResolutionMode.cs b/src/Renci.SshNet/HostResolutionMode.cs new file mode 100644 index 000000000..e6f8d52c2 --- /dev/null +++ b/src/Renci.SshNet/HostResolutionMode.cs @@ -0,0 +1,14 @@ +namespace Renci.SshNet +{ + /// + /// Specifies the way host names will be resolved when conecting through a proxy. + /// + public enum HostResolutionMode + { + /// The host name is resolved by the client and the host IP is sent to the proxy. + ResolvedLocally, + + /// The host name is sent to the proxy and resolved later. + ResolvedByProxy + } +} \ No newline at end of file diff --git a/src/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs b/src/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs index fa14fc4a2..66e501fe0 100644 --- a/src/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs +++ b/src/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs @@ -30,7 +30,6 @@ public class KeyboardInteractiveConnectionInfo : ConnectionInfo, IDisposable public KeyboardInteractiveConnectionInfo(string host, string username) : this(host, DefaultPort, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty) { - } /// @@ -42,7 +41,6 @@ public KeyboardInteractiveConnectionInfo(string host, string username) public KeyboardInteractiveConnectionInfo(string host, int port, string username) : this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty) { - } /// @@ -59,6 +57,21 @@ public KeyboardInteractiveConnectionInfo(string host, int port, string username, { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + public KeyboardInteractiveConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode) + : this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -74,6 +87,22 @@ public KeyboardInteractiveConnectionInfo(string host, int port, string username, { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + public KeyboardInteractiveConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode) + : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -87,6 +116,20 @@ public KeyboardInteractiveConnectionInfo(string host, string username, ProxyType { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + public KeyboardInteractiveConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -101,6 +144,21 @@ public KeyboardInteractiveConnectionInfo(string host, string username, ProxyType { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + public KeyboardInteractiveConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -116,6 +174,22 @@ public KeyboardInteractiveConnectionInfo(string host, string username, ProxyType { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + public KeyboardInteractiveConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -137,6 +211,28 @@ public KeyboardInteractiveConnectionInfo(string host, int port, string username, } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + public KeyboardInteractiveConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode) + : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode, new KeyboardInteractiveAuthenticationMethod(username)) + { + foreach (var authenticationMethod in AuthenticationMethods.OfType()) + { + authenticationMethod.AuthenticationPrompt += AuthenticationMethod_AuthenticationPrompt; + } + + } + private void AuthenticationMethod_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e) { if (AuthenticationPrompt != null) diff --git a/src/Renci.SshNet/PasswordConnectionInfo.cs b/src/Renci.SshNet/PasswordConnectionInfo.cs index b97319d23..bec91206d 100644 --- a/src/Renci.SshNet/PasswordConnectionInfo.cs +++ b/src/Renci.SshNet/PasswordConnectionInfo.cs @@ -70,6 +70,22 @@ public PasswordConnectionInfo(string host, int port, string username, string pas { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode) + : this(host, port, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -86,6 +102,23 @@ public PasswordConnectionInfo(string host, int port, string username, string pas { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode) + : this(host, port, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -100,6 +133,21 @@ public PasswordConnectionInfo(string host, string username, string password, Pro { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -115,6 +163,22 @@ public PasswordConnectionInfo(string host, string username, string password, Pro { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -131,6 +195,23 @@ public PasswordConnectionInfo(string host, string username, string password, Pro { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -172,6 +253,22 @@ public PasswordConnectionInfo(string host, int port, string username, byte[] pas { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode) + : this(host, port, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -188,6 +285,23 @@ public PasswordConnectionInfo(string host, int port, string username, byte[] pas { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode) + : this(host, port, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -202,6 +316,21 @@ public PasswordConnectionInfo(string host, string username, byte[] password, Pro { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -217,6 +346,22 @@ public PasswordConnectionInfo(string host, string username, byte[] password, Pro { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -233,6 +378,23 @@ public PasswordConnectionInfo(string host, string username, byte[] password, Pro { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode) + : this(host, DefaultPort, username, password, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode) + { + } + /// /// Initializes a new instance of the class. /// @@ -254,6 +416,28 @@ public PasswordConnectionInfo(string host, int port, string username, byte[] pas } } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Connection password. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode) + : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode, new PasswordAuthenticationMethod(username, password)) + { + foreach (var authenticationMethod in AuthenticationMethods.OfType()) + { + authenticationMethod.PasswordExpired += AuthenticationMethod_PasswordExpired; + } + } + private void AuthenticationMethod_PasswordExpired(object sender, AuthenticationPasswordChangeEventArgs e) { if (PasswordExpired != null) diff --git a/src/Renci.SshNet/PrivateKeyConnectionInfo.cs b/src/Renci.SshNet/PrivateKeyConnectionInfo.cs index 217c902a1..001f38a99 100644 --- a/src/Renci.SshNet/PrivateKeyConnectionInfo.cs +++ b/src/Renci.SshNet/PrivateKeyConnectionInfo.cs @@ -61,6 +61,22 @@ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTyp { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + /// The key files. + public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode, params PrivateKeyFile[] keyFiles) + : this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode, keyFiles) + { + } + /// /// Initializes a new instance of the class. /// @@ -77,6 +93,23 @@ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTyp { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + /// The key files. + public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode, params PrivateKeyFile[] keyFiles) + : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode, keyFiles) + { + } + /// /// Initializes a new instance of the class. /// @@ -91,6 +124,21 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The host name resolution method when using the proxy. + /// The key files. + public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, HostResolutionMode hostResolutionMode, params PrivateKeyFile[] keyFiles) + : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, hostResolutionMode, keyFiles) + { + } + /// /// Initializes a new instance of the class. /// @@ -106,6 +154,22 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The host name resolution method when using the proxy. + /// The key files. + public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, HostResolutionMode hostResolutionMode, params PrivateKeyFile[] keyFiles) + : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, hostResolutionMode, keyFiles) + { + } + /// /// Initializes a new instance of the class. /// @@ -122,6 +186,23 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy { } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + /// The key files. + public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode, params PrivateKeyFile[] keyFiles) + : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode, keyFiles) + { + } + /// /// Initializes a new instance of the class. /// @@ -140,6 +221,25 @@ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTyp KeyFiles = new Collection(keyFiles); } + /// + /// Initializes a new instance of the class. + /// + /// Connection host. + /// The port. + /// Connection username. + /// Type of the proxy. + /// The proxy host. + /// The proxy port. + /// The proxy username. + /// The proxy password. + /// The host name resolution method when using the proxy. + /// The key files. + public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, HostResolutionMode hostResolutionMode, params PrivateKeyFile[] keyFiles) + : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, hostResolutionMode, new PrivateKeyAuthenticationMethod(username, keyFiles)) + { + KeyFiles = new Collection(keyFiles); + } + #region IDisposable Members private bool _isDisposed; diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 08de6f392..8e33b87e6 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -147,6 +147,7 @@ Code + diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index 68d92d81a..cf1a0bbcc 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -34,7 +34,7 @@ public partial class Session : ISession /// Specifies an infinite waiting period. /// /// - /// The value of this field is -1 millisecond. + /// The value of this field is -1 millisecond. /// internal static readonly TimeSpan InfiniteTimeSpan = new TimeSpan(0, 0, 0, 0, -1); @@ -1697,7 +1697,7 @@ private void SocketRead(int length, byte[] buffer) // 2012-09-11: Kenneth_aa // When Disconnect or Dispose is called, this throws SshConnectionException(), which... - // 1 - goes up to ReceiveMessage() + // 1 - goes up to ReceiveMessage() // 2 - up again to MessageListener() // which is where there is a catch-all exception block so it can notify event listeners. // 3 - MessageListener then again calls RaiseError(). @@ -1945,24 +1945,36 @@ private void ConnectSocks5() // Send reserved, must be 0x00 SocketWriteByte(0x00); - var ip = DnsAbstraction.GetHostAddresses(ConnectionInfo.Host)[0]; - - // Send address type and address - if (ip.AddressFamily == AddressFamily.InterNetwork) - { - SocketWriteByte(0x01); - var address = ip.GetAddressBytes(); - SocketAbstraction.Send(_socket, address); - } - else if (ip.AddressFamily == AddressFamily.InterNetworkV6) + if (ConnectionInfo.HostResolutionMode == HostResolutionMode.ResolvedByProxy) { - SocketWriteByte(0x04); - var address = ip.GetAddressBytes(); - SocketAbstraction.Send(_socket, address); + // Send the host name + SocketWriteByte(0x03); + + var hostNameBytes = SshData.Ascii.GetBytes(ConnectionInfo.Host); + SocketWriteByte((byte) hostNameBytes.Length); + SocketAbstraction.Send(_socket, hostNameBytes); } else { - throw new ProxyException(string.Format("SOCKS5: IP address '{0}' is not supported.", ip)); + var ip = DnsAbstraction.GetHostAddresses(ConnectionInfo.Host)[0]; + + // Send address type and address + if (ip.AddressFamily == AddressFamily.InterNetwork) + { + SocketWriteByte(0x01); + var address = ip.GetAddressBytes(); + SocketAbstraction.Send(_socket, address); + } + else if (ip.AddressFamily == AddressFamily.InterNetworkV6) + { + SocketWriteByte(0x04); + var address = ip.GetAddressBytes(); + SocketAbstraction.Send(_socket, address); + } + else + { + throw new ProxyException(string.Format("SOCKS5: IP address '{0}' is not supported.", ip)); + } } // Send port