예제 #1
0
        public override bool Execute(IJob job, IAppConfiguration c)
        {
            job.UnwatchWebRequests();
            job.UnexceptionWebRequest();
            job.UnignoreWebRequest();

            if (!c.Enable || !job.Environment.Enable)
            {
                return(true);
            }

            if (!(c is ElmahConfiguration config))
            {
                job.WriteJournal(new JournalMessage("Error: Config passed into Elmah was not of the correct type"));
                return(false);
            }

            foreach (var error in _ipAccessControlService.InitIpAccessControl(config.IpAccessRules))
            {
                job.WriteJournal(new JournalMessage($"Error: Invalid IP Address {error}, unable to add to exception list"));
            }

            if (config.Unauthorized.TransferType != TransferTypes.PlayDead)
            {
                job.ExceptionWebRequest(config.Unauthorized.Url);
            }

            var regex = job.PathToRegex("elmah.axd");

            job.IgnoreWebRequest(regex);

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, regex, 300000, (count, httpApp) =>
            {
                if (_ipAccessControlService.IsValid(config.IpAccessRules, httpApp.Context.Request))
                {
                    httpApp.Context.Items.Add(_allowKey, true);
                }
                return(new WatchResponse(WatchResponse.Cycles.Continue));
            });

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, regex, 300500, (count, httpApp) =>
            {
                if ((bool?)httpApp.Context.Items[_allowKey] == true || (config.UmbracoUserEnable && AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp)))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                job.WriteJournal(new JournalMessage($"User with IP Address: {httpApp.Context.Request.UserHostAddress}; tried to access {httpApp.Context.Request.Url} Access was denied"));

                return(new WatchResponse(config.Unauthorized));
            });

            return(true);
        }
예제 #2
0
        private void AddHardWatch(IJob job, BackofficeAccessConfiguration config)
        {
            var hardLocationRegex = new Regex("^((" + ApplicationSettings.UmbracoPath.TrimEnd('/') + "(/)?)|(" + ApplicationSettings.UmbracoPath + "[\\w-/]+\\.[\\w.]{2,5}))$", RegexOptions.IgnoreCase);

            foreach (var error in _ipAccessControlService.InitIpAccessControl(config.IpAccessRules))
            {
                job.WriteJournal(new JournalMessage($"Error: Invalid IP Address {error}, unable to add to exception list"));
            }

            //Add watch on the on-disk UmbracoPath location to do the security checking of the user's ip
            job.ExceptionWebRequest(config.Unauthorized.Url);
            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, hardLocationRegex, 21000, (count, httpApp) =>
            {
                if (AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                if (_ipAccessControlService.IsValid(config.IpAccessRules, httpApp.Context.Request.UserHostAddress))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                var url = new UmbracoUrlService().Url(config.Unauthorized.Url);

                if (url == null)
                {
                    return(new WatchResponse(WatchResponse.Cycles.Stop));
                }

                if (!string.IsNullOrEmpty(httpApp.Context.Request.CurrentExecutionFilePathExtension) &&
                    (httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".css") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".map") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".js") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".png") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".jpg") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".jpeg") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".gif") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".woff") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".woff2") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".ttf") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".otf") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".eot") ||
                     httpApp.Context.Request.CurrentExecutionFilePathExtension.Equals(".svg")))
                {
                    httpApp.Context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    return(new WatchResponse(WatchResponse.Cycles.Stop));
                }

                job.WriteJournal(new JournalMessage($"User with IP Address: {httpApp.Context.Request.UserHostAddress}; tried to access the backoffice access url. Access was denied"));

                return(new WatchResponse(config.Unauthorized));
            });
        }
예제 #3
0
        /// <inheritdoc />
        public override bool Execute(IJob job, IConfiguration c)
        {
            job.UnwatchWebRequests();
            job.UnexceptionWebRequest();

            if (!c.Enable || !job.Environment.Enable)
            {
                return(true);
            }

            if (!(c is FrontendAccessConfiguration config))
            {
                job.WriteJournal(new JournalMessage("Error: Config passed into Frontend Access was not of the correct type"));
                return(false);
            }

            var hardUmbracoLocation = ApplicationSettings.UmbracoPath;
            var regex = new Regex("^/$|^(/(?!" + hardUmbracoLocation.Trim('/') + ")[\\w-/_]+?)$", RegexOptions.IgnoreCase);

            foreach (var error in new IpAccessControlService().InitIpAccessControl(config.IpAccessRules))
            {
                job.WriteJournal(new JournalMessage($"Error: Invalid IP Address {error}, unable to add to exception list"));
            }

            job.ExceptionWebRequest(config.Unauthorized.Url);

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, regex, 400000, (count, httpApp) =>
            {
                if (_ipAccessControlService.IsValid(config.IpAccessRules, httpApp.Context.Request.UserHostAddress))
                {
                    httpApp.Context.Items.Add(_allowKey, true);
                }
                return(new WatchResponse(WatchResponse.Cycles.Continue));
            });

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, regex, 10500, (count, httpApp) =>
            {
                if ((bool?)httpApp.Context.Items[_allowKey] == true ||
                    config.UmbracoUserEnable && AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                if (!httpApp.Context.Request.Url.LocalPath.Equals(config.Unauthorized.Url.Value))
                {
                    job.WriteJournal(new JournalMessage($"User with IP Address: {httpApp.Context.Request.UserHostAddress}; tried to access Page: {httpApp.Context.Request.Url}. Access was denied"));
                }

                return(new WatchResponse(config.Unauthorized));
            });

            return(true);
        }
예제 #4
0
        /// <inheritdoc />
        public override bool Execute(IJob job, IAppConfiguration c)
        {
            job.UnwatchWebRequests();
            job.UnexceptionWebRequest();

            if (!(c is FrontendAccessConfiguration config))
            {
                job.WriteJournal(new JournalMessage("Error: Config passed into Frontend Access was not of the correct type"));
                return(false);
            }

            if (!c.Enable || !job.Environment.Enable)
            {
                return(true);
            }

            foreach (var error in _ipAccessControlService.InitIpAccessControl(config.IpAccessRules))
            {
                job.WriteJournal(new JournalMessage($"Error: Invalid IP Address {error}, unable to add to exception list"));
            }

            if (config.Unauthorized.TransferType != TransferTypes.PlayDead)
            {
                job.ExceptionWebRequest(config.Unauthorized.Url);
            }

            //var ignores =

            //	umbracoReservedUrls



            var regex = new Regex(@"^/([a-z0-9-_~&\+%/])*(\?([^\?])*)?$", RegexOptions.IgnoreCase);

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, regex, 400000, (count, httpApp) =>
            {
                if (_ipAccessControlService.IsValid(config.IpAccessRules, httpApp.Context.Request))
                {
                    httpApp.Context.Items.Add(_allowKey, true);
                }
                return(new WatchResponse(WatchResponse.Cycles.Continue));
            });

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, regex, 400500, (count, httpApp) =>
            {
                if ((bool?)httpApp.Context.Items[_allowKey] == true ||
                    (config.UmbracoUserEnable && AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp)))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                var url = new UmbracoUrlService().Url(config.Unauthorized.Url);
                if (url == null)
                {
                    return(new WatchResponse(WatchResponse.Cycles.Error));
                }

                if (httpApp.Context.Request.Url.LocalPath.Equals(url))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                job.WriteJournal(new JournalMessage($"User with IP Address: {httpApp.Context.Request.UserHostAddress}; tried to access Page: {httpApp.Context.Request.Url}. Access was denied"));
                return(new WatchResponse(config.Unauthorized));
            });

            return(true);
        }
예제 #5
0
        /// <inheritdoc />
        /// <summary>
        /// </summary>
        /// <param name="job"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public override bool Execute(IJob job, IAppConfiguration c)
        {
            job.UnwatchWebRequests();
            job.UnexceptionWebRequest();

            _reSetterLock = 0;

            if (!(c is BackofficeAccessConfiguration config))
            {
                job.WriteJournal(new JournalMessage("Error: Config passed into Backoffice Access was not of the correct type"));
                return(false);
            }

            var defaultUmbracoLocation = ((BackofficeAccessConfiguration)DefaultConfiguration).BackendAccessUrl.EnsureStartsWith('/').EnsureEndsWith('/');
            var onDiscUmbracoLocation  = Configuration.UmbracoPath.EnsureStartsWith('/').EnsureEndsWith('/');
            var virtualUmbracoLocation = config.Enable && job.Environment.Enable
                ? config.BackendAccessUrl.EnsureStartsWith('/').EnsureEndsWith('/')
                : defaultUmbracoLocation;

            var defaultUmbracoRegex = job.PathToRegex(defaultUmbracoLocation);
            var onDiscUmbracoRegex  = job.PathToRegex(onDiscUmbracoLocation);
            var virtualUmbracoRegex = job.PathToRegex(virtualUmbracoLocation);

            job.IgnoreWebRequest(defaultUmbracoRegex);
            job.IgnoreWebRequest(onDiscUmbracoRegex);
            job.IgnoreWebRequest(virtualUmbracoRegex);

            if (!virtualUmbracoLocation.Equals(defaultUmbracoLocation, StringComparison.InvariantCultureIgnoreCase) &&
                !onDiscUmbracoLocation.Equals(defaultUmbracoLocation, StringComparison.InvariantCultureIgnoreCase))
            {
                SoftWatcher(job,
                            new Regex("^(" + defaultUmbracoLocation + "backoffice([\\w-/_]+))", RegexOptions.IgnoreCase),
                            20000,
                            onDiscUmbracoLocation,
                            virtualUmbracoLocation,
                            false);
            }

            if (config.Enable && job.Environment.Enable && config.Unauthorized.TransferType != TransferTypes.PlayDead)
            {
                job.ExceptionWebRequest(config.Unauthorized.Url);
            }

            if (!virtualUmbracoLocation.Equals(onDiscUmbracoLocation, StringComparison.InvariantCultureIgnoreCase))
            {
                if (Interlocked.CompareExchange(ref _reSetterLock, 0, 1) == 0)
                {
                    var path        = HttpRuntime.AppDomainAppPath;
                    var onDiscPath  = path + onDiscUmbracoLocation.Trim('/');
                    var virtualPath = path + virtualUmbracoLocation.Trim('/');

                    var reSetter = new HardResetFileHandler();

                    if (reSetter.HardLocation != onDiscPath || reSetter.SoftLocation != virtualPath)
                    {
                        reSetter.Delete();

                        reSetter.HardLocation = onDiscPath;
                        reSetter.SoftLocation = virtualPath;

                        reSetter.Save();
                    }
                }

                SoftWatcher(job,
                            virtualUmbracoRegex,
                            20100,
                            onDiscUmbracoLocation,
                            virtualUmbracoLocation,
                            true);

                job.WatchWebRequests(PipeLineStages.AuthenticateRequest, new Regex($"^(({onDiscUmbracoLocation})|({onDiscUmbracoLocation.TrimEnd('/')}))$"), 20200, (count, httpApp) =>
                {
                    if ((bool?)httpApp.Context.Items[_allowKey] == true ||
                        !string.IsNullOrEmpty(httpApp.Context.Request.CurrentExecutionFilePathExtension) ||
                        AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp))
                    {
                        return(new WatchResponse(WatchResponse.Cycles.Continue));
                    }

                    httpApp.Context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    return(new WatchResponse(WatchResponse.Cycles.Stop));
                });
            }

            if (!config.Enable || !job.Environment.Enable)
            {
                return(true);
            }

            foreach (var error in _ipAccessControlService.InitIpAccessControl(config.IpAccessRules))
            {
                job.WriteJournal(new JournalMessage($"Error: Invalid IP Address {error}, unable to add to exception list"));
            }

            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, onDiscUmbracoRegex, 20300, (count, httpApp) =>
            {
                if (AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp) ||
                    _ipAccessControlService.IsValid(config.IpAccessRules, httpApp.Context.Request))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                job.WriteJournal(new JournalMessage($"User with IP Address: {httpApp.Context.Request.UserHostAddress}; tried to access the backoffice access url. Access was denied"));

                return(new WatchResponse(config.Unauthorized));
            });

            return(true);
        }
예제 #6
0
        private void AddSoftWatches(IJob job, BackofficeAccessConfiguration config)
        {
            var umbracoLocation = ((BackofficeAccessConfiguration)DefaultConfiguration).BackendAccessUrl.EnsureStartsWith('/').EnsureEndsWith('/');
            var hardLocation    = ApplicationSettings.UmbracoPath;
            var softLocation    = (config.Enable && job.Environment.Enable)
                ? config.BackendAccessUrl.EnsureStartsWith('/').EnsureEndsWith('/')
                : umbracoLocation;

#if TRACE
            Debug.WriteLine($"AddSoftWatches({job.Environment.Name}): hardLocation = {hardLocation}, softLocation = {softLocation}");
#endif

            //Match Umbraco path for badly written Umbraco Packages, that only work with hardcoded /umbraco/backoffice
            if (!softLocation.Equals(umbracoLocation, StringComparison.InvariantCultureIgnoreCase) && !hardLocation.Equals(umbracoLocation, StringComparison.InvariantCultureIgnoreCase))
            {
                SoftWatcher(job,
                            new Regex("^((" + umbracoLocation + "backoffice([\\w-/_]+))|(" + umbracoLocation + "[\\w-/_]+\\.[\\w.]{2,5}))$", RegexOptions.IgnoreCase),
                            20015,
                            hardLocation,
                            umbracoLocation);
            }

            if (softLocation.Equals(hardLocation, StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }

            //A hard save is needed, so we need to hook up
            //the watches to route everything correctly

            //add watch on the soft location
            SoftWatcher(job,
                        new Regex("^((" + softLocation.TrimEnd('/') + "(/)?)|(" + softLocation + "[\\w-/_]+\\.[\\w.]{2,5}))$", RegexOptions.IgnoreCase),
                        20010,
                        hardLocation,
                        softLocation,
                        config.Unauthorized.TransferType.Equals(TransferTypes.Rewrite),
                        true);

            if (config.Enable && job.Environment.Enable)
            {
                job.ExceptionWebRequest(config.Unauthorized.Url);
            }

            //Add watch on the hard location
            job.WatchWebRequests(PipeLineStages.AuthenticateRequest, new Regex("^((" + hardLocation.TrimEnd('/') + "(/)?)|(" + hardLocation + "[\\w-/]+\\.[\\w.]{2,5}))$", RegexOptions.IgnoreCase), 20020, (count, httpApp) =>
            {
                //Check if request has our access token, if so, we're
                //rewriting the user to the hard location, so let
                //the request continue
                if ((bool?)httpApp.Context.Items[_allowKey] == true ||
                    !string.IsNullOrEmpty(httpApp.Context.Request.CurrentExecutionFilePathExtension))
                {
                    return(new WatchResponse(WatchResponse.Cycles.Continue));
                }

                //If the requests has an authenticated umbraco user,
                //we need to redirect the request back to the
                //softLocation - This is most likely due to
                //clicking a link (i.e. content breadcrumb)
                //which isn't handle by the angular single page app
                if (AccessHelper.IsRequestAuthenticatedUmbracoUser(httpApp))
                {
                    //request has a authenticated user, we want to
                    //redirect the user back to the soft location
                    return(new WatchResponse(new TransferUrl
                    {
                        TransferType = TransferTypes.Redirect,
                        Url = new UmbracoUrl
                        {
                            Type = UmbracoUrlTypes.Url,
                            Value = httpApp.Context.Request.Url.AbsolutePath.Length > hardLocation.Length
                                ? softLocation + httpApp.Context.Request.Url.AbsolutePath.Substring(hardLocation.Length)
                                : softLocation
                        }
                    }));
                }

                //if we're disabled, then we just want
                //to change the status code to 404
                if (!config.Enable || !job.Environment.Enable)
                {
                    httpApp.Context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    return(new WatchResponse(WatchResponse.Cycles.Stop));
                }

                //We're Enabled, so we need to transfer to the unauthorised Url
                return(new WatchResponse(config.Unauthorized));
            });
        }