Browse Source

On SOCKS5 proxy: set hostname, not always IP (#1072)

* On SOCKS5 proxy:
The library always resolves the hostname to the IP. Some SOCKS5 proxies don't allow you to specify the IP, they want to resolve the hostname themselves.

The patch sends the proxy the same specified value, IP, or hostname.

* refactor

---------

Co-authored-by: Jordi Vaca <jjvaca@indra.es>
Co-authored-by: Rob Hague <rob.hague00@gmail.com>
Jordi Vaca 1 năm trước cách đây
mục cha
commit
27fad71353
1 tập tin đã thay đổi với 21 bổ sung15 xóa
  1. 21 15
      src/Renci.SshNet/Connection/Socks5Connector.cs

+ 21 - 15
src/Renci.SshNet/Connection/Socks5Connector.cs

@@ -1,6 +1,8 @@
 using System;
+using System.Diagnostics;
 using System.Net;
 using System.Net.Sockets;
+using System.Text;
 
 using Renci.SshNet.Abstractions;
 using Renci.SshNet.Common;
@@ -244,25 +246,29 @@ namespace Renci.SshNet.Connection
 
         private static byte[] GetSocks5DestinationAddress(string hostname, out byte addressType)
         {
-            var ip = Dns.GetHostAddresses(hostname)[0];
+            if (IPAddress.TryParse(hostname, out var ipAddress))
+            {
+                Debug.Assert(ipAddress.AddressFamily is AddressFamily.InterNetwork or AddressFamily.InterNetworkV6);
+
+                addressType = ipAddress.AddressFamily == AddressFamily.InterNetwork
+                    ? (byte)0x01 // IPv4
+                    : (byte)0x04; // IPv6
+
+                return ipAddress.GetAddressBytes();
+            }
+
+            addressType = 0x03; // Domain name
 
-            byte[] address;
+            var byteCount = Encoding.UTF8.GetByteCount(hostname);
 
-#pragma warning disable IDE0010 // Add missing cases
-            switch (ip.AddressFamily)
+            if (byteCount > byte.MaxValue)
             {
-                case AddressFamily.InterNetwork:
-                    addressType = 0x01; // IPv4
-                    address = ip.GetAddressBytes();
-                    break;
-                case AddressFamily.InterNetworkV6:
-                    addressType = 0x04; // IPv6
-                    address = ip.GetAddressBytes();
-                    break;
-                default:
-                    throw new ProxyException(string.Format("SOCKS5: IP address '{0}' is not supported.", ip));
+                throw new ProxyException(string.Format("SOCKS5: SOCKS 5 cannot support host names longer than 255 chars ('{0}').", hostname));
             }
-#pragma warning restore IDE0010 // Add missing cases
+
+            var address = new byte[1 + byteCount];
+            address[0] = (byte)byteCount;
+            _ = Encoding.UTF8.GetBytes(hostname, 0, hostname.Length, address, 1);
 
             return address;
         }