/// <summary> /// Constructor /// </summary> /// <param name="hostname">The hostname to connect to</param> /// <param name="port">The port to connect to</param> /// <param name="clientType">The type of connection to make</param> /// <param name="ipv6">Indicates whether to use ipv6</param> public FixedIpProxyClient(string hostname, int port, IpProxyToken.IpClientType clientType, bool ipv6) { _hostname = hostname; _port = port; _ipv6 = ipv6; _clientType = clientType; }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="hostName"></param> /// <param name="port"></param> /// <param name="clientType"></param> /// <param name="ipv6"></param> /// <param name="layers"></param> public FixedProxyServer(Logger logger, string hostName, int port, IpProxyToken.IpClientType clientType, bool ipv6, INetworkLayerFactory[] layers) : base(logger) { _hostName = hostName; _port = port; _clientType = clientType; _ipv6 = ipv6; _layers = layers; if (!IPAddress.TryParse(_hostName, out _address)) { _address = null; } }
private bool IsFiltered(IpProxyToken token) { foreach (Regex re in _filters) { if (token.Hostname != null) { if (re.IsMatch(token.Hostname)) { return true; } } if (re.IsMatch(token.Address.ToString())) { return true; } } return false; }
private IDataAdapter ConnectUdp(IpProxyToken token, Logger logger, PropertyBag properties) { IDataAdapter adapter = null; try { UdpClient client = new UdpClient(IsTokenIpV6(token) ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork); if (token.Hostname == null) { client.Connect(token.Address, token.Port); } else { client.Connect(token.Hostname, token.Port); } NetUtils.PopulateBagFromSocket(client.Client, properties); adapter = new UdpClientDataAdapter(client, IpProxyClient.GetDescription(token)); } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } return adapter; }
private IDataAdapter BindTcp(IpProxyToken token, Logger logger, PropertyBag properties) { TcpListenerDataAdapter adapter = null; try { bool isIpv6 = IsTokenIpV6(token); adapter = new TcpListenerDataAdapter(new IPEndPoint(isIpv6 ? IPAddress.IPv6Any : IPAddress.Any, token.Port)); NetUtils.PopulateBagFromSocket(adapter.Listener.Server, properties); } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } return adapter; }
private static bool IsTokenIpV6(IpProxyToken token) { bool ret = false; if (NetUtils.OSSupportsIPv6) { if (token.Ipv6) { ret = true; } else if (token.Hostname == null) { ret = token.Address.AddressFamily == AddressFamily.InterNetworkV6; } else { IPAddress addr; if (IPAddress.TryParse(token.Hostname, out addr)) { ret = addr.AddressFamily == AddressFamily.InterNetworkV6; } } } return ret; }
/// <summary> /// Get a description of the token /// </summary> /// <param name="token">The token</param> /// <returns>The string description</returns> protected static string GetDescription(IpProxyToken token) { if (token.Hostname != null) { return String.Format("{0}:{1}", token.Hostname, token.Port); } return null; }
private ProxyToken HandleOtherRequest(HttpRequestHeader header, DataAdapterToStream stm, TcpClientDataAdapter tcpAdapter) { string host = null; foreach (KeyDataPair<string> pair in header.Headers) { if (pair.Name.Equals("host", StringComparison.OrdinalIgnoreCase)) { host = pair.Value; } } Uri url = GetUri(host, tcpAdapter); if (url != null) { // Use generic token so filters don't get used IpProxyToken ret = new IpProxyToken(null, url.Host, url.Port, IpProxyToken.IpClientType.Tcp, false); if(_config.SslConfig.Enabled) { ret.Layers = new INetworkLayer[1]; ret.Layers[0] = new SslNetworkLayer(new SslNetworkLayerConfig(false, true) { Enabled = true }); } ret.State.Add("url", url); ret.State.Add("stm", stm); ret.State.Add("header", header); return ret; } else { _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidUrl, header.Path); ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm); return null; } }
private void ConnectVersion5(Stream stm, IpProxyToken token, Logger logger) { byte[] req = new byte[3] { 5, 1, 0 }; stm.Write(req, 0, req.Length); byte[] resp = GeneralUtils.ReadBytes(stm, 2); if ((resp[0] == 5) && (resp[1] == 0)) { List<byte> connect = new List<byte>(); connect.Add(5); connect.Add(1); connect.Add(0); if (_sendHostName && !String.IsNullOrWhiteSpace(token.Hostname)) { connect.Add(3); connect.Add((byte)token.Hostname.Length); connect.AddRange(new BinaryEncoding().GetBytes(token.Hostname)); } else if(token.Address != null) { if (token.Address.AddressFamily == AddressFamily.InterNetwork) { connect.Add(1); } else if (token.Address.AddressFamily == AddressFamily.InterNetworkV6) { connect.Add(4); } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidProxyToken); } connect.AddRange(token.Address.GetAddressBytes()); } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidProxyToken2); } connect.Add((byte)(token.Port >> 8)); connect.Add((byte)(token.Port & 0xFF)); stm.Write(connect.ToArray(), 0, connect.Count); if (stm.ReadByte() != 5) { logger.LogError(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidV5Response); } int status = stm.ReadByte(); // Read out the rest of the data stm.ReadByte(); int addrType = stm.ReadByte(); switch (addrType) { case 1: GeneralUtils.ReadBytes(stm, 4); break; case 3: int len = stm.ReadByte(); if (len < 0) { throw new EndOfStreamException(CANAPE.Net.Properties.Resources.SocksProxyClient_EosInDomain); } GeneralUtils.ReadBytes(stm, len); break; case 4: GeneralUtils.ReadBytes(stm, 16); break; default: throw new ArgumentException(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidAddrType); } // Port GeneralUtils.ReadBytes(stm, 2); if (status == 0) { token.Status = NetStatusCodes.Success; } else { token.Status = NetStatusCodes.ConnectFailure; } } else { logger.LogError(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidV5Response2, resp[0], resp[1]); token.Status = NetStatusCodes.ConnectFailure; } }
private void ConnectVersion4a(Stream stm, IpProxyToken token, Logger logger) { byte[] req = new byte[9+token.Hostname.Length+1]; req[0] = 4; req[1] = 1; req[2] = (byte)(token.Port >> 8); req[3] = (byte)(token.Port & 0xFF); req[5] = 0; req[4] = 0; req[6] = 0; req[7] = 0x7F; Array.Copy(Encoding.ASCII.GetBytes(token.Hostname), 0, req, 9, token.Hostname.Length); stm.Write(req, 0, req.Length); byte[] resp = GeneralUtils.ReadBytes(stm, 8); if (resp[1] == 0x5A) { token.Status = NetStatusCodes.Success; } else { token.Status = NetStatusCodes.ConnectFailure; } }
////////////////////////////////// // Possible token permutations // Address set, no Hostname (use socks4 or socks5 with address) // Address set, Hostname set (use socks4a or socks5 with hostname if told to send, else resolve) // Address not set, Hostname set (use socks4a or socks5 with hostname if told to send, else resolve) private void ConnectVersion4(Stream stm, IpProxyToken token, Logger logger) { IPAddress address = token.Address; if (address == null) { address = GetAddressFromHost(token.Hostname, false); } byte[] req = new byte[9]; req[0] = 4; req[1] = 1; req[2] = (byte)(token.Port >> 8); req[3] = (byte)(token.Port & 0xFF); byte[] addrbytes = address.GetAddressBytes(); req[4] = addrbytes[0]; req[5] = addrbytes[1]; req[6] = addrbytes[2]; req[7] = addrbytes[3]; stm.Write(req, 0, req.Length); byte[] resp = GeneralUtils.ReadBytes(stm, 8); if (resp[1] == 0x5A) { token.Status = NetStatusCodes.Success; } else { token.Status = NetStatusCodes.ConnectFailure; } }
private IpProxyToken HandleConnect(HttpRequestHeader header, DataAdapterToStream stm) { string hostName = null; int port = 80; string[] connectHeader = header.Path.Split(':'); IpProxyToken ret = null; if (connectHeader.Length > 0) { hostName = connectHeader[0]; if (connectHeader.Length > 1) { if (!int.TryParse(connectHeader[1], out port)) { _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidConnect, connectHeader[1]); port = 0; } } if (port > 0) { ret = new IpProxyToken(null, hostName, port, IpProxyToken.IpClientType.Tcp, false); ret.State.Add("stm", stm); ret.State.Add("header", header); } else { ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm); } } return ret; }
public FixedProxyToken(IPAddress address, string hostname, int port, IpProxyToken.IpClientType clientType, bool ipv6, IDataAdapter adapter) : base(address, hostname, port, clientType, ipv6) { Adapter = adapter; }
private static void ConnectWithIpProxyToken(Stream stm, IpProxyToken token, Logger logger) { string hostname = token.Hostname != null ? token.Hostname : token.Address.ToString(); string req = String.Format("CONNECT {0}:{1} HTTP/1.0\r\n\r\n", hostname, token.Port); byte[] reqBytes = Encoding.ASCII.GetBytes(req); stm.Write(reqBytes, 0, reqBytes.Length); List<string> headers = new List<string>(); // Read out response headers while (true) { string nextLine = GeneralUtils.ReadLine(stm); headers.Add(nextLine); if (nextLine.Trim().Length == 0) { break; } } if (headers.Count > 0) { string[] vals = headers[0].Split(' '); int res = 0; if (vals.Length >= 2) { if (int.TryParse(vals[1], out res) && (res == 200)) { token.Status = NetStatusCodes.Success; } else { logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyClient_ErrorOnConnect, res, hostname, token.Port); } } else { logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyClient_InvalidResponse); } } else { logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyClient_NoResponse); } }