public static IHandlerBuilder Create()
        {
            var proxy = ReverseProxy.Create()
                        .Upstream("https://genhttp.org/");

            return(Layout.Create()
                   .Add("exceptions", new ExceptionProviderBuilder())
                   .Add("proxy", proxy));
        }
Exemple #2
0
        /// <summary>
        ///     if the DocData is less then 2083 characters long (that is internet explorer's address bar limit), inline the actual
        ///     data to the URL. When that can't be achieved the document will be stored in MemoryCache and a quazi-ticket-number
        ///     will URL parameter will be used guaranteeing availability of anything that requests it within 10 minutes of this
        ///     method being called.
        /// </summary>
        /// <param name="BaseDoc"></param>
        /// <param name="RelayUrl"></param>
        /// <returns></returns>
        public static string ToUrl(BaseDoc BaseDoc, string RelayUrl = null)
        {
            if (string.IsNullOrWhiteSpace(RelayUrl))
            {
                RelayUrl = ReverseProxy.GetRelayUrl();
            }

            string DocTypeName = BaseDoc.DocTypeName;

            string _Url = string.IsNullOrWhiteSpace(RelayUrl)
                              ? string.Format("{0}/DocDataHandler.ashx?DocTypeName={1}&{2}={3}",
                                              RequestPaths.ApplicationPath,
                                              DocTypeName,
                                              Parm.DocBin,
                                              HttpUtility.UrlEncode(Compressor.CompressToBase64String(BaseDoc.ToBytes())))
                              : string.Format("{0}/DocDataHandler.ashx?DocTypeName={1}&{2}={3}&{4}={5}",
                                              RelayUrl,
                                              DocTypeName,
                                              Parm.DocBin,
                                              HttpUtility.UrlEncode(Compressor.CompressToBase64String(BaseDoc.ToBytes())),
                                              Parm.RelayUrl,
                                              HttpUtility.UrlEncode(RelayUrl)
                                              );

            //REF:http://support.microsoft.com/kb/208427
            if (_Url.Length > 2083)
            {
                string _CacheKey = HttpUtility.UrlEncode(string.Format("{0}.{1}", DocTypeName, _Url.GetHashCode()));

                if (HttpRuntime.Cache[_CacheKey] == null)
                {
                    HttpRuntime.Cache.Insert(_CacheKey,
                                             BaseDoc,
                                             null,
                                             Cache.NoAbsoluteExpiration,
                                             TimeSpan.FromMinutes(10));
                }

                _Url = string.IsNullOrWhiteSpace(RelayUrl)
                           ? string.Format("{0}/DocDataHandler.ashx?DocTypeName={1}&{2}={3}",
                                           RequestPaths.ApplicationPath,
                                           DocTypeName,
                                           Parm.DocCache,
                                           _CacheKey)
                           : string.Format("{0}/DocDataHandler.ashx?DocTypeName={1}&{2}={3}&{4}={5}",
                                           RelayUrl,
                                           DocTypeName,
                                           Parm.DocCache,
                                           _CacheKey,
                                           Parm.RelayUrl,
                                           HttpUtility.UrlEncode(RelayUrl));
            }
            return(_Url);
        }
        public void TestBadGateway()
        {
            var proxy = ReverseProxy.Create()
                        .Upstream("http://127.0.0.2");

            var layout = Layout.Create().Fallback(proxy);

            using var runner = TestRunner.Run(layout);

            using var response = runner.GetResponse();

            Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);
        }
Exemple #4
0
            public ProxyTestFixture()
            {
                server = new MockHttpServer($"http://localhost:{remotePort}/", OnRequestAsync);
                client = new HttpClient()
                {
                    BaseAddress = new Uri($"http://localhost:{localPort}/"),
                    Timeout     = TimeSpan.FromSeconds(2)
                };

                // Start the proxy.

                proxy = new ReverseProxy(localPort, remotePort);
            }
            public static TestSetup Create(Func <IRequest, IResponseBuilder?> response)
            {
                // server hosting the actuall web app
                var testServer = TestRunner.Run(new ProxiedRouter(response));

                // proxying server
                var proxy = ReverseProxy.Create()
                            .ConnectTimeout(TimeSpan.FromSeconds(2))
                            .ReadTimeout(TimeSpan.FromSeconds(5))
                            .Upstream("http://localhost:" + testServer.Port);

                var layout = Layout.Create().Fallback(proxy);

                var runner = TestRunner.Run(layout);

                return(new TestSetup(runner, testServer));
            }
        public override IReadOnlyCollection <ConfigurationValidationError> Validate(string?prefix = null)
        {
            var errors = new ConfigurationValidationErrorCollection(prefix);

            errors.AddErrors(base.Validate(prefix));
            if (ReverseProxy != null)
            {
                errors.AddErrors(ReverseProxy.Validate(nameof(ReverseProxy)));
            }

            errors.AddErrors(ExternalUrls.Validate(nameof(ExternalUrls)));
            errors.AddErrors(DbOptions.Validate(nameof(DbOptions)));
            errors.AddErrors(MigrationOptions.Validate(nameof(MigrationOptions)));
            errors.AddErrors(AuthOptions.Validate(nameof(AuthOptions)));
            errors.AddErrors(SmtpEMailOptions.Validate(nameof(SmtpEMailOptions)));
            errors.AddErrors(TempFiles.Validate(nameof(TempFiles)));

            return(errors);
        }
Exemple #7
0
            public void Dispose()
            {
                if (server != null)
                {
                    server.Dispose();
                    server = null;
                }

                if (client != null)
                {
                    client.Dispose();
                    client = null;
                }

                if (proxy != null)
                {
                    proxy.Dispose();
                    proxy = null;
                }
            }
Exemple #8
0
        public static string ToUrl(string DocTypeName, string DocId, string RelayUrl = "~", long LogSequenceNumber = 0)
        {
            if (string.IsNullOrWhiteSpace(RelayUrl))
            {
                RelayUrl = ReverseProxy.GetRelayUrl();
            }

            return(string.IsNullOrWhiteSpace(RelayUrl)
                       ? string.Format("{0}/DocDataHandler.ashx?&DocTypeName={1}&{2}={3}&LogSequenceNumber={4}",
                                       RelayUrl, DocTypeName,
                                       Parm.DocId,
                                       DocId,
                                       LogSequenceNumber)
                       : string.Format("{0}/DocDataHandler.ashx?{6}={4}&DocTypeName={1}&{2}={3}&LogSequenceNumber={5}",
                                       RelayUrl,
                                       DocTypeName,
                                       Parm.DocId,
                                       DocId,
                                       HttpUtility.UrlEncode(RelayUrl),
                                       LogSequenceNumber,
                                       Parm.RelayUrl));
        }
Exemple #9
0
        /// <summary>
        /// Updates the running proxies to match the current cluster
        /// (if there is one).  This may only be called on the UI thread.
        /// </summary>
        private async Task UpdateProxiesAsync()
        {
            if (InvokeRequired)
            {
                throw new InvalidOperationException($"[{nameof(UpdateProxiesAsync)}()] may only be called on the UI thread.");
            }

            if (KubeHelper.CurrentContext == null)
            {
                StopProxies();
                StopPortForwards();
            }
            else
            {
                var cluster = Program.GetCluster();

                // We're going to use the current Kubenetes context name and cluster ID
                // to determine whether we're still connected to the same cluster.

                if (proxiedContext != null)
                {
                    if (proxiedContext.Name == KubeHelper.CurrentContext.Name &&
                        proxiedContext.Extension.ClusterId == KubeHelper.CurrentContext.Extension.ClusterId)
                    {
                        // We're still proxying the same cluster so no changes
                        // are required.

                        return;
                    }
                }

                StopProxies();
                StopPortForwards();

                if (KubeHelper.CurrentContext == null)
                {
                    // Wr're not logged into a cluster so don't start any proxies.

                    return;
                }

                try
                {
                    // Start the connecting animation if we're not already in the error state.

                    if (!InErrorState)
                    {
                        StartNotifyAnimation(connectingAnimation, $"{KubeHelper.CurrentContextName}: Connecting...", isTransient: true);
                    }

                    //-------------------------------------------------------------
                    // The Kubernetes dashboard reverse proxy.

                    // Setup a callback that transparently adds an [Authentication] header
                    // to all requests with the correct bearer token.  We'll need to
                    // obtain the token secret via two steps:
                    //
                    //      1. Identify the dashboard token secret by listing all secrets
                    //         in the [kube-system] namespace looking for one named like
                    //         [root-user-token-*].
                    //
                    //      2. Reading that secret and extracting the value.

                    var response       = (ExecuteResponse)null;
                    var secretName     = string.Empty;
                    var dashboardToken = string.Empty;

                    await Task.Run(
                        async() =>
                    {
                        response = KubeHelper.Kubectl("--namespace", "kube-system", "get", "secrets", "-o=name");
                        await Task.CompletedTask;
                    });

                    if (response.ExitCode != 0)
                    {
                        try
                        {
                            response.EnsureSuccess();
                        }
                        catch (Exception e)
                        {
                            Program.LogError(e);
                            SetErrorState($"{KubeHelper.CurrentContextName}: Kubernetes API failure");
                            return;
                        }
                    }

                    // Step 1: Determine the secret name.

                    using (var reader = new StringReader(response.OutputText))
                    {
                        const string secretPrefix = "secret/";

                        secretName = reader.Lines().FirstOrDefault(line => line.StartsWith($"{secretPrefix}root-user-token-"));

                        Covenant.Assert(!string.IsNullOrEmpty(secretName));

                        secretName = secretName.Substring(secretPrefix.Length);
                    }

                    // Step 2: Describe the secret and extract the token value.  This
                    //         is a bit of a hack because I'm making assumptions about
                    //         the output format.

                    await Task.Run(
                        async() =>
                    {
                        response = KubeHelper.Kubectl("--namespace", "kube-system", "describe", "secret", secretName);
                        await Task.CompletedTask;
                    });

                    if (response.ExitCode != 0)
                    {
                        try
                        {
                            response.EnsureSuccess();
                        }
                        catch (Exception e)
                        {
                            Program.LogError(e);
                            SetErrorState($"{KubeHelper.CurrentContextName}: Kubernetes API failure");
                            return;
                        }
                    }

                    using (var reader = new StringReader(response.OutputText))
                    {
                        var tokenLine = reader.Lines().FirstOrDefault(line => line.StartsWith("token:"));

                        Covenant.Assert(!string.IsNullOrEmpty(tokenLine));

                        dashboardToken = tokenLine.Split(new char[] { ' ' }, 2).Skip(1).First().Trim();
                    }

                    Action <RequestContext> dashboardRequestHandler =
                        context =>
                    {
                        context.Request.Headers.Add("Authorization", $"Bearer {dashboardToken}");
                    };

                    // Start the proxy.

                    var userContext   = KubeHelper.Config.GetUser(KubeHelper.CurrentContext.Properties.User);
                    var certPem       = Encoding.UTF8.GetString(Convert.FromBase64String(userContext.Properties.ClientCertificateData));
                    var keyPem        = Encoding.UTF8.GetString(Convert.FromBase64String(userContext.Properties.ClientKeyData));
                    var dashboardCert = TlsCertificate.Parse(KubeHelper.CurrentContext.Extension.KubernetesDashboardCertificate).ToX509(publicOnly: true);

                    var kubeDashboardProxy =
                        new ReverseProxy(
                            localPort: KubeHelper.ClientConfig.KubeDashboardProxyPort,
                            remotePort: KubeHostPorts.KubeDashboard,
                            remoteHost: cluster.GetReachableMaster().PrivateAddress.ToString(),
                            validCertificate: dashboardCert,
                            requestHandler: dashboardRequestHandler);

                    proxies.Add(kubeDashboardProxy);

                    var kibanaDashboardProxy =
                        new PortForward(
                            serviceName: "kibana-kibana",
                            localPort: KubeConst.KibanaDashboardProxyPort,
                            remotePort: KubeConst.KibanaDashboardProxyPort,
                            @namespace: "logging");

                    portForwards.Add(kibanaDashboardProxy);

                    var prometheusDashboardProxy =
                        new PortForward(
                            serviceName: "prometheus",
                            localPort: KubeConst.PrometheusDashboardProxyPort,
                            remotePort: KubeConst.PrometheusDashboardProxyPort,
                            @namespace: "istio-system");

                    portForwards.Add(prometheusDashboardProxy);

                    var kialiDashboardProxy =
                        new PortForward(
                            serviceName: "kiali",
                            localPort: KubeConst.KialiDashboardProxyPort,
                            remotePort: KubeConst.KialiDashboardProxyPort,
                            @namespace: "istio-system");

                    portForwards.Add(kialiDashboardProxy);

                    var grafanaDashboardProxy =
                        new PortForward(
                            serviceName: "grafana",
                            localPort: KubeConst.GrafanaDashboardProxyPort,
                            remotePort: KubeConst.GrafanaDashboardProxyPort,
                            @namespace: "istio-system");

                    portForwards.Add(grafanaDashboardProxy);

                    //-------------------------------------------------------------
                    // Remember which cluster context we're proxying.

                    proxiedContext = KubeHelper.CurrentContext;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                finally
                {
                    // Stop any non-error transient animation on the top of the notify stack.

                    if (notifyStack.Count > 0 && notifyStack.Peek().IsTransient&& !notifyStack.Peek().IsError)
                    {
                        StopNotifyAnimation();
                    }
                }
            }
        }
        public IHttpProxy MakeProxy(string type)
        {
            HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Created proxy '{0}'", type);
            string host       = TrafficViewerOptions.Instance.TrafficServerIp;
            int    port       = TrafficViewerOptions.Instance.TrafficServerPort;
            int    securePort = TrafficViewerOptions.Instance.TrafficServerPortSecure;
            ITrafficDataAccessor dataStore = TrafficViewer.Instance.TrafficViewerFile;
            var        exploiter           = new CustomTestsExploiter();
            IHttpProxy result = null;

            if (type.Equals(Resources.CaptureProxy))
            {
                result = new AdvancedExploreProxy(host, port, dataStore);
            }
            else if (type.Equals(Resources.DriveByAttackProxy))
            {
                result = new DriveByAttackProxy(exploiter, dataStore, host, port);
            }
            else if (type.Equals(Resources.SequentialAttackProxy))
            {
                result = new SequentialAttackProxy(exploiter, dataStore, host, port);
            }
            else if (type.Equals(Resources.ReverseProxy))
            {
                result = new ReverseProxy(host, port, securePort, dataStore);
            }
            else if (type.Equals(Resources.TrafficFileProxy))
            {
                result = new TrafficStoreProxy(dataStore, dataStore, host, port, securePort);
            }
            else if (type.Equals(Resources.BinaryReverseProxy))
            {
                result = new BinaryReverseProxy(host, port, securePort, dataStore);
            }
            else if (type.Equals(Resources.TrackingProxy))
            {
                result = new TrackingReverseProxy(host, port, securePort, dataStore);
            }


            if (result != null)
            {
                if (!(result is TrafficStoreProxy))
                {
                    if (TrafficViewerOptions.Instance.UseProxy)
                    {
                        WebProxy proxy = new WebProxy(TrafficViewerOptions.Instance.HttpProxyServer, TrafficViewerOptions.Instance.HttpProxyPort);
                        result.NetworkSettings.WebProxy = proxy;
                    }
                    result.NetworkSettings.CertificateValidationCallback = new RemoteCertificateValidationCallback(SSLValidationCallback.ValidateRemoteCertificate);
                }


                if (result is BaseAttackProxy)
                {
                    result.ExtraOptions[BaseAttackProxy.TEST_FILE_PATH] = Path.Combine(TrafficViewerOptions.TrafficViewerAppDataDir, "CustomTests.xml");
                }

                if (result is ReverseProxy || result is BinaryReverseProxy)
                {
                    result.ExtraOptions[ReverseProxy.FORWARDING_HOST_OPT] = TrafficViewerOptions.Instance.ForwardingHost;
                    result.ExtraOptions[ReverseProxy.FORWARDING_PORT_OPT] = TrafficViewerOptions.Instance.ForwardingPort.ToString();
                }
            }
            return(result);
        }
Exemple #11
0
        //[TestMethod]
        public void Test_ReverseProxy()
        {
            string testRequest   = "GET / HTTP/1.1\r\n";
            string site1Response = "HTTP/1.1 200 OK\r\n\r\nThis is site1";
            string site2Response = "HTTP/1.1 200 OK\r\n\r\nThis is site2";
            //create two mock sites each on a different port and a http client that send a request to the first but in fact gets redirected to the other
            TrafficViewerFile site1Source = new TrafficViewerFile();

            site1Source.AddRequestResponse(testRequest, site1Response);
            TrafficViewerFile site2Source = new TrafficViewerFile();

            site2Source.AddRequestResponse(testRequest, site2Response);

            TrafficStoreProxy mockSite1 = new TrafficStoreProxy(
                site1Source, null, "127.0.0.1", 0, 0);

            mockSite1.Start();

            TrafficStoreProxy mockSite2 = new TrafficStoreProxy(
                site2Source, null, "127.0.0.1", 0, 0);

            mockSite2.Start();

            HttpRequestInfo reqInfo = new HttpRequestInfo(testRequest);

            //request will be sent to site 1
            reqInfo.Host = mockSite1.Host;
            reqInfo.Port = mockSite1.Port;

            ReverseProxy revProxy = new ReverseProxy("127.0.0.1", 0, 0, null);

            revProxy.ExtraOptions[ReverseProxy.FORWARDING_HOST_OPT] = mockSite2.Host;
            revProxy.ExtraOptions[ReverseProxy.FORWARDING_PORT_OPT] = mockSite2.Port.ToString();
            revProxy.Start();

            //make an http client
            IHttpClient            client   = new WebRequestClient();
            DefaultNetworkSettings settings = new DefaultNetworkSettings();

            settings.WebProxy = new WebProxy(revProxy.Host, revProxy.Port);

            client.SetNetworkSettings(settings);

            //send the request Http and verify the target site received it

            HttpResponseInfo respInfo = client.SendRequest(reqInfo);
            string           respBody = respInfo.ResponseBody.ToString();


            Assert.IsTrue(respBody.Contains("This is site2"));

            //check over ssl

            reqInfo.IsSecure = true;
            respInfo         = client.SendRequest(reqInfo);
            respBody         = respInfo.ResponseBody.ToString();
            Assert.IsTrue(respBody.Contains("This is site2"));

            mockSite1.Stop();
            mockSite2.Stop();
            revProxy.Stop();
        }