/// <summary> /// Connect to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { IpProxyToken iptoken = token as IpProxyToken; if ((iptoken != null) && IsFiltered(iptoken)) { return base.Connect(token, logger, meta, globalMeta, properties, credmgr); } else { token.Status = NetStatusCodes.Blocked; return null; } }
/// <summary> /// Apply the proxy filter to a token /// </summary> /// <param name="token">The tokeb</param> /// <param name="logger">A logger to log data to</param> public override void Apply(ProxyToken token, Logger logger) { base.Apply(token, logger); IpProxyToken t = token as IpProxyToken; if (t != null) { if (!String.IsNullOrWhiteSpace(RedirectAddress)) { t.Hostname = RedirectAddress; } if (RedirectPort != 0) { t.Port = RedirectPort; } } }
/// <summary> /// Bind to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public override IDataAdapter Bind(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { IDataAdapter adapter = null; IpProxyToken iptoken = token as IpProxyToken; if (iptoken != null) { if (iptoken.ClientType == IpProxyToken.IpClientType.Tcp) { adapter = BindTcp(iptoken, logger, properties); } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.IpProxyClient_InvalidTokenType); } } return adapter; }
public override CANAPE.DataAdapters.IDataAdapter Bind(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { throw new NotImplementedException(); }
private ProxyToken FilterToken(ProxyToken token) { if ((_filters != null) && (_filters.Length > 0)) { foreach (var filter in _filters) { if (!filter.Disabled && filter.Match(token)) { _logger.LogVerbose(CANAPE.Net.Properties.Resources.ProxyNetworkService_MatchedFilter, filter.ToString()); filter.Apply(token, _logger); break; } } return token; } return token; }
/// <summary> /// Check if the token matches this filter /// </summary> /// <param name="token">The token to match</param> /// <returns>True if it matches</returns> public override bool Match(ProxyToken token) { bool bMatch = base.Match(token); if (bMatch) { if (token is IpProxyToken) { IpProxyToken iptoken = (IpProxyToken)token; string hostName = iptoken.Hostname; string ipAddress = iptoken.Address != null ? iptoken.Address.ToString() : "0.0.0.0"; bMatch = Address.IsMatch(ipAddress); if (!bMatch) { bMatch = Address.IsMatch(hostName); } if (Port != 0) { if (iptoken.Port != Port) { bMatch = false; } } if (iptoken.ClientType != ClientType) { bMatch = false; } } else { bMatch = false; } } return bMatch; }
private ProxyToken HandleOtherRequest(HttpRequestHeader header, DataAdapterToStream stm, ProxyNetworkService service) { Uri url; if (Uri.TryCreate(header.Path, UriKind.Absolute, out url)) { // Use generic token so filters don't get used ProxyToken ret = new ProxyToken(); ret.State.Add("url", url); ret.State.Add("stm", stm); ret.State.Add("header", header); ret.Client = new HttpProxyDummyClient(this, service); ret.Graph = _factory; return ret; } else { _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidUrl, header.Path); // TODO: Put in some decent error codes ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm); return null; } }
// TODO: Should merge with implementation for the general connection so that it is 100% compatible /// <summary> /// /// </summary> /// <param name="graph"></param> /// <param name="token"></param> public void ReconnectClient(NetGraph graph, ProxyToken token) { IDataAdapter client = null; bool connected = false; PropertyBag networkService = graph.ConnectionProperties.GetRelativeBag("NetworkService"); PropertyBag clientProperties = graph.ConnectionProperties.GetRelativeBag("Client"); PropertyBag tokenProperties = graph.ConnectionProperties.GetRelativeBag("Token"); try { while(graph.Parent != null) { graph = graph.Parent; } if (token != null) { // If passed in a token we need to apply filters to it token = FilterToken(token); } else { // Use original post-filtered token = (ProxyToken)networkService.GetRelativeValue("Token"); } if (token.Status == NetStatusCodes.Success) { clientProperties.Clear(); if (token.Client == null) { client = _proxyClient.Connect(token, _logger, graph.Meta, _globalMeta, clientProperties, _credentialManager); } else { client = token.Client.Connect(token, _logger, graph.Meta, _globalMeta, clientProperties, _credentialManager); } tokenProperties.Clear(); token.PopulateBag(tokenProperties); // Negotiate SSL or other bespoke encryption mechanisms if (token.Layers != null) { // Bind but disabling server layer NetworkLayerBinding binding = DefaultBinding & ~NetworkLayerBinding.Server; foreach (INetworkLayer layer in token.Layers) { IDataAdapter server = null; layer.Negotiate(ref server, ref client, token, _logger, graph.Meta, _globalMeta, graph.ConnectionProperties, binding); } } graph.BindEndpoint((Guid)networkService.GetRelativeValue("ClientId"), client); IDataAdapter serverAdapter = networkService.GetRelativeValue("ServerAdapter"); if (token.NetworkDescription != null) { graph.NetworkDescription = token.NetworkDescription; } else { graph.NetworkDescription = String.Format("{0} <=> {1}", serverAdapter.Description, client.Description); } IDataAdapter oldClient = networkService.GetRelativeValue("ClientAdapter"); networkService.AddValue("ClientAdapter", client); networkService.AddValue("Token", token); oldClient.Close(); connected = true; } else { _logger.LogVerbose(CANAPE.Net.Properties.Resources.ProxyNetworkService_ConnectionFiltered); } } catch (Exception ex) { _logger.LogException(ex); } finally { if (!connected) { try { if (client != null) { client.Close(); } } catch (Exception ex) { Logger.GetSystemLogger().LogException(ex); } } } }
/// <summary> /// /// </summary> /// <param name="token"></param> /// <param name="client"></param> /// <param name="globalMeta"></param> /// <param name="meta"></param> /// <param name="service"></param> /// <returns></returns> public override IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client) { SocksProxyToken socksToken = (SocksProxyToken)token; if (IsSupported(socksToken.Version)) { if (socksToken.Version == 4) { return HandleSocksV4Response(socksToken); } else if (socksToken.Version == 5) { return HandleSocksV5Response(socksToken); } else { // We shouldn't get here throw new InvalidOperationException(CANAPE.Net.Properties.Resources.SocksProxyServer_IsSupportedError); } } else { _logger.LogError(CANAPE.Net.Properties.Resources.SocksProxyServer_UnsupportedTokenVersion, socksToken.Version); } return null; }
public override IDataAdapter Bind(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { return null; }
/// <summary> /// /// </summary> /// <param name="server"></param> /// <param name="client"></param> /// <param name="token"></param> /// <param name="logger"></param> /// <param name="meta"></param> /// <param name="globalMeta"></param> /// <param name="properties"></param> /// <param name="defaultBinding"></param> public void Negotiate(ref IDataAdapter server, ref IDataAdapter client, ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, NetworkLayerBinding defaultBinding) { if (defaultBinding == NetworkLayerBinding.Default) { defaultBinding = NetworkLayerBinding.ClientAndServer; } if (Binding != NetworkLayerBinding.Default) { defaultBinding = Binding; } if ((defaultBinding & NetworkLayerBinding.Server) == NetworkLayerBinding.Server) { server = new HttpRequestDataAdapter(server, logger, this); } if ((defaultBinding & NetworkLayerBinding.Client) == NetworkLayerBinding.Client) { client = new HttpResponseDataAdapter(client, logger, this); } }
/// <summary> /// Connect the client /// </summary> /// <param name="token">The proxy token</param> /// <param name="logger">The proxy logger instance</param> /// <param name="meta">The proxy meta data</param> /// <param name="globalMeta">The proxy global meta data</param> /// <param name="properties">The proxy property bag</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected adapter</returns> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { IDataAdapter ret = null; for (int i = 0; i < _clients.Length; ++i) { ret = _clients[i].Connect(token, logger, meta, globalMeta, properties, credmgr); if (ret != null) { break; } } if ((ret == null) && (token.Status == NetStatusCodes.Success)) { ret = new IpProxyClient().Connect(token, logger, meta, globalMeta, properties, credmgr); } return ret; }
public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { return new StreamDataAdapter(new NamedPipeClientStream(".", _pipeName, PipeDirection.InOut)); }
public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { return new HttpProxyClientDataAdapter(_server, _service, _server._logger); }
/// <summary> /// Complete the proxy connection by passing back the token and getting a new IDataAdapter /// </summary> /// <param name="token">The token returned from client</param> /// <param name="globalMeta">Global meta object</param> /// <param name="meta">Meta object</param> /// <param name="service">The service which contains this server</param> /// <param name="client">The client adapter which was created</param> /// <returns>The final data adapter, should be used for further work</returns> public abstract IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client);
private ProxyClient BuildProxyClient(ProxyToken token, Logger logger) { Uri url = null; if (token is HttpProxyToken) { url = ((HttpProxyToken)token).Url; } else if (token is IpProxyToken) { IpProxyToken iptoken = token as IpProxyToken; UriBuilder builder = new UriBuilder(); switch (iptoken.Port) { case 443: builder.Scheme = "https"; break; case 21: builder.Scheme = "ftp"; break; default: builder.Scheme = "http"; break; } builder.Port = iptoken.Port; builder.Host = iptoken.Hostname ?? iptoken.Address.ToString(); builder.Path = "/"; url = builder.Uri; } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.ScriptProxyClient_InvalidToken, "token"); } return CreateClient(url, logger); }
/// <summary> /// Connect to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { return BuildProxyClient(token, logger).Connect(token, logger, meta, globalMeta, properties, credmgr); }
/// <summary> /// Overridable method to determine if this token matches /// </summary> /// <param name="token"></param> /// <returns></returns> public virtual bool Match(ProxyToken token) { return token.Bind == Bound; }
/// <summary> /// /// </summary> /// <param name="token"></param> /// <param name="logger"></param> public virtual void Apply(ProxyToken token, Logger logger) { token.Status = Block ? NetStatusCodes.Blocked : NetStatusCodes.Success; token.Graph = Graph; token.Client = Client; List<INetworkLayer> layers = new List<INetworkLayer>(Layers.CreateLayers(logger)); if (token.Layers != null) { switch (MergePolicy) { case LayerMergePolicy.Prefix: layers.AddRange(token.Layers); break; case LayerMergePolicy.Suffix: layers.InsertRange(0, token.Layers); break; default: // Do nothing break; } } token.Layers = layers.ToArray(); }
/// <summary> /// Complete the client connection, just returns the original adapter /// </summary> /// <param name="token">The proxy token</param> /// <param name="client"></param> /// <param name="globalMeta"></param> /// <param name="meta"></param> /// <param name="service"></param> /// <returns>The data adapter</returns> public override IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client) { PassThroughToken passToken = (PassThroughToken)token; IDataAdapter adapter = passToken.Adapter; if (token.Status != NetStatusCodes.Success) { return null; } else { // Set to null to prevent Dispose being called passToken.Adapter = null; return adapter; } }
/// <summary> /// Connection to the socks server /// </summary> /// <param name="token">The proxy token</param> /// <param name="logger">Logger</param> /// <param name="globalMeta">Global meta</param> /// <param name="meta">Meta</param> /// <param name="credmgr">Credentials manager</param> /// <param name="properties">Property bag to populate</param> /// <returns>A connected data adapter, or null if not available</returns> /// <exception cref="SocketException">Throw if cannot connect</exception> /// <exception cref="ArgumentException">Throw if invalid operation occurs</exception> /// <exception cref="EndOfStreamException">Throw if stream ends before reading all data</exception> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { IDataAdapter ret = null; if (token is IpProxyToken) { IpProxyToken iptoken = token as IpProxyToken; TcpClient client = new TcpClient(); try { client.Connect(_hostname, _port); if (_version == SupportedVersion.Version4) { if (_sendHostName && !String.IsNullOrWhiteSpace(iptoken.Hostname)) { ConnectVersion4a(client.GetStream(), iptoken, logger); } else { ConnectVersion4(client.GetStream(), iptoken, logger); } } else { ConnectVersion5(client.GetStream(), iptoken, logger); } if (iptoken.Status == NetStatusCodes.Success) { NetUtils.PopulateBagFromSocket(client.Client, properties); ret = new TcpClientDataAdapter(client, IpProxyClient.GetDescription((IpProxyToken)token)); } } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } finally { if (ret == null) { client.Close(); } } } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidProxyToken3); } return ret; }
/// <summary> /// Connect to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public abstract IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr);
/// <summary> /// /// </summary> /// <param name="token"></param> /// <param name="client"></param> /// <param name="globalMeta"></param> /// <param name="meta"></param> /// <param name="service"></param> /// <returns></returns> public override IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client) { IDataAdapter ret = null; HttpProxyToken httpToken = (HttpProxyToken)token; DataAdapterToStream stm = httpToken.Adapter; if (httpToken.Status == NetStatusCodes.Success) { if (httpToken.IsHTTPProxyClient) { // We don't have to do anything as such, other than send back any smuggled data if it was a connect call if (httpToken.Response != null) { stm.Write(httpToken.Response, 0, httpToken.Response.Length); } httpToken.Adapter = null; if (httpToken.Connect) { // With CONNECT the data stream is transparent ret = new StreamDataAdapter(stm); } else { // For anything else, rebuild the original headers so it can flow through the graph StringBuilder builder = new StringBuilder(); foreach (string s in httpToken.Headers) { builder.Append(s); } ret = new PrefixedDataAdapter(new StreamDataAdapter(stm), GeneralUtils.MakeByteArray(builder.ToString())); } } else { if (httpToken.Connect) { ReturnResponse(200, "Connection established", stm); httpToken.Adapter = null; ret = new StreamDataAdapter(stm); } else { StringBuilder builder = new StringBuilder(); string[] reqValues = httpToken.Headers[0].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Downgrade to version 1.0 httpToken.Headers[0] = reqValues[0] + " " + httpToken.Url.PathAndQuery + " HTTP/1.0\r\n"; foreach (string s in httpToken.Headers) { // Remove proxy headers if (!s.StartsWith("proxy", StringComparison.OrdinalIgnoreCase)) { builder.Append(s); } } httpToken.Adapter = null; ret = new PrefixedDataAdapter(new StreamDataAdapter(stm), GeneralUtils.MakeByteArray(builder.ToString())); } } } else { ReturnResponse(404, "Not Found", stm); } return ret; }
public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { return new SerialPortDataAdapter(_config.Create()); }
/// <summary> /// /// </summary> /// <param name="server"></param> /// <param name="client"></param> /// <param name="token"></param> /// <param name="logger"></param> /// <param name="meta"></param> /// <param name="globalMeta"></param> /// <param name="properties"></param> /// <param name="defaultBinding"></param> public void Negotiate(ref IDataAdapter server, ref IDataAdapter client, ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, NetworkLayerBinding defaultBinding) { if (_config.Enabled) { if (defaultBinding == NetworkLayerBinding.Default) { defaultBinding = NetworkLayerBinding.ClientAndServer; } if (Binding != NetworkLayerBinding.Default) { defaultBinding = Binding; } if ((defaultBinding & NetworkLayerBinding.Client) == NetworkLayerBinding.Client) { if (_config.ClientProtocol != SslProtocols.None) { IpProxyToken iptoken = token as IpProxyToken; string serverName = null; if (iptoken != null) { if (!String.IsNullOrWhiteSpace(iptoken.Hostname)) { serverName = iptoken.Hostname; } else { serverName = iptoken.Address.ToString(); } } client = ConnectClient(client, logger, properties, serverName); } } if ((defaultBinding & NetworkLayerBinding.Server) == NetworkLayerBinding.Server) { if (_config.ServerProtocol != SslProtocols.None) { server = ConnectServer(server, logger, properties); } } } }
/// <summary> /// Connect to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { // Just use the underlying code to do it for us return base.Connect(new IpProxyToken(null, _hostname, _port, _clientType, _ipv6), logger, meta, globalMeta, properties, credmgr); }
/// <summary> /// /// </summary> /// <param name="token"></param> /// <param name="meta"></param> /// <param name="globalMeta"></param> /// <param name="service"></param> /// <param name="client"></param> /// <returns></returns> public override IDataAdapter Complete(ProxyToken token, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service, IDataAdapter client) { IDataAdapter ret = null; // An empty initial request indicates we are a full connection if (token.State.ContainsKey("header")) { HttpRequestHeader initialRequest = (HttpRequestHeader)token.State["header"]; DataAdapterToStream stm = (DataAdapterToStream)token.State["stm"]; if (token.Status == NetStatusCodes.Success) { if (initialRequest.IsConnect) { ReturnResponse(null, 200, "Connection established", initialRequest.Method, initialRequest.Version, stm); // Connect is transparent ret = new StreamDataAdapter(stm); } else { // Use a proxy adapter ret = new HttpProxyServerAdapter(stm, initialRequest, _logger); } } else { ReturnResponse(initialRequest, 404, "Not Found", initialRequest.Method, HttpVersion.Version11, stm); } } else { ret = (IDataAdapter)token.State["adapter"]; } token.State.Clear(); return ret; }
public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { return new DataEndpointAdapter(_factory.Create(logger, meta, globalMeta), logger); }
/// <summary> /// Connect to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { IDataAdapter ret = null; token.Status = NetStatusCodes.ConnectFailure; if ((token is IpProxyToken) && ((IpProxyToken)token).ClientType == IpProxyToken.IpClientType.Tcp) { TcpClient client = new TcpClient(); try { client.Connect(_hostname, _port); if (token is FullHttpProxyToken) { bool binary = false; if ((token.Layers != null) && (token.Layers.Length > 0)) { foreach (INetworkLayer layer in token.Layers) { // Find a binding layer if (layer.Binding == NetworkLayerBinding.Client || layer.Binding == NetworkLayerBinding.ClientAndServer || layer.Binding == NetworkLayerBinding.Default) { if (!(layer is HttpNetworkLayer)) { binary = true; } break; } } } if (!binary) { ret = new FullHttpProxyDataAdapter(client, (FullHttpProxyToken)token, IpProxyClient.GetDescription((IpProxyToken)token), logger); NetUtils.PopulateBagFromSocket(client.Client, properties); token.Status = NetStatusCodes.Success; } else { ConnectWithIpProxyToken(client.GetStream(), (IpProxyToken)token, logger); if (token.Status == NetStatusCodes.Success) { NetUtils.PopulateBagFromSocket(client.Client, properties); ret = new TcpClientDataAdapter(client, IpProxyClient.GetDescription((IpProxyToken)token)); } } } else { if (token is HttpProxyToken) { ConnectWithHttpProxyToken(client.GetStream(), (HttpProxyToken)token, logger); } else { ConnectWithIpProxyToken(client.GetStream(), (IpProxyToken)token, logger); } if (token.Status == NetStatusCodes.Success) { NetUtils.PopulateBagFromSocket(client.Client, properties); ret = new TcpClientDataAdapter(client, IpProxyClient.GetDescription((IpProxyToken)token)); } } } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } finally { if (ret == null) { client.Close(); } } } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.HttpProxyClient_InvalidProxyToken); } return ret; }