/// <summary> /// Queries the SOCKS5 proxy for its desired authentication mechanism /// </summary> private Socks5AuthType GetSocks5AuthMethod() { Socks5AuthType retval = Socks5AuthType.AuthMethodRejected; int reqlength = 4, sent = 0; byte[] request = new byte[reqlength]; request[0] = 0x05; request[1] = 0x02; request[2] = 0x00; request[3] = 0x02; try { while (sent < reqlength) { sent += socket.Write(request, sent, reqlength - sent); } int replength = 2, received = 0; byte[] reply = new byte[replength]; while (received < replength) { received += socket.Read(reply, received, replength - received); } retval = (Socks5AuthType)reply[1]; } catch (Exception sockex) { Logging.WriteString("Caught exception in GetSocks5AuthMethod: {0}", sockex); } return(retval); }
/// <summary> /// Ends the host connection phase and negotiates the proxied connection /// </summary> private void EndConnectToIPAddress(IAsyncResult res) { try { socket.EndConnect(res); if (destinationSsl) { socket.AuthenticateAsClient(destinationServer); } } catch (Exception sockex) { OnConnectionFailed("Can't connect to server: {0}", sockex); return; } if (parent.Connections.LocalInternalIP == null) { parent.Connections.LocalInternalIP = ((IPEndPoint)socket.LocalEndPoint).Address; } if (parent.ServerSettings.ProxySetting == ProxyType.None) { OnConnectionComplete(); return; } if (parent.ServerSettings.ProxySetting == ProxyType.Socks5) { Socks5AuthType auth = GetSocks5AuthMethod(); if (auth == Socks5AuthType.AuthMethodRejected) { socket.Close(); OnConnectionFailed("SOCKS5 authentication mechanism unsupported"); return; } else if (auth != Socks5AuthType.None) { if (SendSocks5Authentication() == false) { socket.Close(); OnConnectionFailed("SOCK5 authentication failed, bad username/password"); return; } } if (SendSocks5ConnectRequest() == false) { socket.Close(); OnConnectionFailed("SOCKS5 connect failed, proxy server failure"); return; } } // Done! OnConnectionComplete(); }