<PackageReference Include="SSH.NET" Version="2023.0.1" />

Socks4Connector

Establishes a tunnel via a SOCKS4 proxy server.
using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using System; using System.Net; using System.Net.Sockets; using System.Text; namespace Renci.SshNet.Connection { internal sealed class Socks4Connector : ProxyConnector { public Socks4Connector(ISocketFactory socketFactory) : base(socketFactory) { } protected override void HandleProxyConnect(IConnectionInfo connectionInfo, Socket socket) { byte[] data = CreateSocks4ConnectionRequest(connectionInfo.Host, (ushort)connectionInfo.Port, connectionInfo.ProxyUsername); SocketAbstraction.Send(socket, data); if (ConnectorBase.SocketReadByte(socket, connectionInfo.Timeout) != 0) throw new ProxyException("SOCKS4: Null is expected."); switch (ConnectorBase.SocketReadByte(socket, connectionInfo.Timeout)) { case 91: throw new ProxyException("SOCKS4: Connection rejected."); case 92: throw new ProxyException("SOCKS4: Client is not running identd or not reachable from the server."); case 93: 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."); case 90: { byte[] array = new byte[6]; ConnectorBase.SocketRead(socket, array, 0, array.Length, connectionInfo.Timeout); break; } } } private static byte[] CreateSocks4ConnectionRequest(string hostname, ushort port, string username) { byte[] socks4DestinationAddress = GetSocks4DestinationAddress(hostname); byte[] proxyUserBytes = GetProxyUserBytes(username); byte[] array = new byte[4 + socks4DestinationAddress.Length + proxyUserBytes.Length + 1]; int num = 0; array[num++] = 4; array[num++] = 1; Pack.UInt16ToBigEndian(port, array, num); num += 2; Buffer.BlockCopy(socks4DestinationAddress, 0, array, num, socks4DestinationAddress.Length); num += socks4DestinationAddress.Length; Buffer.BlockCopy(proxyUserBytes, 0, array, num, proxyUserBytes.Length); num += proxyUserBytes.Length; array[num] = 0; return array; } private static byte[] GetSocks4DestinationAddress(string hostname) { IPAddress[] hostAddresses = DnsAbstraction.GetHostAddresses(hostname); foreach (IPAddress iPAddress in hostAddresses) { if (iPAddress.AddressFamily == AddressFamily.InterNetwork) return iPAddress.GetAddressBytes(); } throw new ProxyException($"""{hostname}"""); } private static byte[] GetProxyUserBytes(string proxyUser) { if (proxyUser == null) return Array.Empty<byte>(); return Encoding.ASCII.GetBytes(proxyUser); } } }