コード例 #1
0
ファイル: Reporting.cs プロジェクト: zjorz/laps-web
        public static void PerformAuditSuccessActions(LapRequestModel model, TargetElement target, ReaderElement reader, UserPrincipal user, ComputerPrincipal computer, SearchResult searchResult)
        {
            Dictionary <string, string> tokens = BuildTokenDictionary(target, reader, user, computer, searchResult, model.ComputerName);
            string logSuccessMessage           = Reporting.LogSuccessTemplate ?? LogMessages.DefaultAuditSuccessText;
            string emailSuccessMessage         = Reporting.EmailSuccessTemplate ?? $"<html><head/><body><pre>{LogMessages.DefaultAuditSuccessText}</pre></body></html>";

            LogEventInfo logEvent = new LogEventInfo(LogLevel.Info, Reporting.Logger.Name, ReplaceTokens(tokens, logSuccessMessage, false));

            logEvent.Properties.Add("EventID", EventIDs.PasswordAccessed);
            Reporting.Logger.Log(logEvent);

            try
            {
                ICollection <string> recipients = Reporting.BuildRecipientList(target, reader, true, user);

                if (recipients.Count > 0)
                {
                    string subject = ReplaceTokens(tokens, LogMessages.AuditEmailSubjectSuccess, false);
                    Reporting.SendEmail(recipients, subject, ReplaceTokens(tokens, emailSuccessMessage, true));
                }
            }
            catch (Exception iex)
            {
                Reporting.LogErrorEvent(EventIDs.AuditErrorCannotSendSuccessEmail, "An error occurred sending the success audit email", iex);
            }
        }
コード例 #2
0
ファイル: RateLimiter.cs プロジェクト: zjorz/laps-web
        private static bool IsUserThresholdExceeded(LapRequestModel model, UserPrincipal p, HttpRequestBase r, int threshold, int duration)
        {
            if (RateLimiter.IsThresholdExceeded(p, threshold, duration))
            {
                Reporting.PerformAuditFailureActions(model, UIMessages.RateLimitError, EventIDs.RateLimitExceededUser,
                                                     string.Format(LogMessages.RateLimitExceededUser, p.SamAccountName, r.UserHostAddress, threshold, duration), null, null, null, p, null);
                return(true);
            }

            return(false);
        }
コード例 #3
0
ファイル: RateLimiter.cs プロジェクト: zjorz/laps-web
        public static bool IsRateLimitExceeded(LapRequestModel model, UserPrincipal p, HttpRequestBase r)
        {
            if (LapsConfigSection.Configuration.RateLimitIP.Enabled)
            {
                if (RateLimiter.IsIpThresholdExceeded(model, p, r, LapsConfigSection.Configuration.RateLimitIP.ReqPerMinute, 60) ||
                    RateLimiter.IsIpThresholdExceeded(model, p, r, LapsConfigSection.Configuration.RateLimitIP.ReqPerHour, 3600) ||
                    RateLimiter.IsIpThresholdExceeded(model, p, r, LapsConfigSection.Configuration.RateLimitIP.ReqPerDay, 86400))
                {
                    return(true);
                }
            }

            if (LapsConfigSection.Configuration.RateLimitUser.Enabled)
            {
                if (RateLimiter.IsUserThresholdExceeded(model, p, r, LapsConfigSection.Configuration.RateLimitUser.ReqPerMinute, 60) ||
                    RateLimiter.IsUserThresholdExceeded(model, p, r, LapsConfigSection.Configuration.RateLimitUser.ReqPerHour, 3600) ||
                    RateLimiter.IsUserThresholdExceeded(model, p, r, LapsConfigSection.Configuration.RateLimitUser.ReqPerDay, 86400))
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #4
0
ファイル: Reporting.cs プロジェクト: zjorz/laps-web
        public static void PerformAuditFailureActions(LapRequestModel model, string userMessage, int eventID, string logMessage, Exception ex, TargetElement target, ReaderElement reader, UserPrincipal user, ComputerPrincipal computer)
        {
            Dictionary <string, string> tokens = BuildTokenDictionary(target, reader, user, computer, null, model.ComputerName, logMessage ?? userMessage);
            string logFailureMessage           = Reporting.LogFailureTemplate ?? LogMessages.DefaultAuditFailureText;
            string emailFailureMessage         = Reporting.EmailFailureTemplate ?? $"<html><head/><body><pre>{LogMessages.DefaultAuditFailureText}</pre></body></html>";

            Reporting.LogErrorEvent(eventID, ReplaceTokens(tokens, logFailureMessage, false), ex);

            try
            {
                ICollection <string> recipients = Reporting.BuildRecipientList(target, reader, false);

                if (recipients.Count > 0)
                {
                    string subject = ReplaceTokens(tokens, LogMessages.AuditEmailSubjectFailure, false);
                    Reporting.SendEmail(recipients, subject, ReplaceTokens(tokens, emailFailureMessage, true));
                }
            }
            catch (Exception iex)
            {
                Reporting.LogErrorEvent(EventIDs.AuditErrorCannotSendFailureEmail, "An error occurred sending the failure audit email", iex);
            }
        }
コード例 #5
0
ファイル: LapController.cs プロジェクト: zaeja/laps-web
        public ActionResult Get(LapRequestModel model)
        {
            if (!this.ModelState.IsValid)
            {
                return(this.View());
            }

            UserPrincipal user = null;

            try
            {
                model.FailureReason = null;

                try
                {
                    user = this.GetCurrentUser();

                    if (user == null)
                    {
                        throw new NoMatchingPrincipalException();
                    }
                }
                catch (NoMatchingPrincipalException ex)
                {
                    return(this.LogAndReturnErrorResponse(model, UIMessages.SsoIdentityNotFound, EventIDs.SsoIdentityNotFound, null, ex));
                }

                if (RateLimiter.IsRateLimitExceeded(model, user, this.Request))
                {
                    return(this.View("RateLimitExceeded"));
                }

                Reporting.LogSuccessEvent(EventIDs.UserRequestedPassword, string.Format(LogMessages.UserHasRequestedPassword, user.SamAccountName, model.ComputerName));

                ComputerPrincipal computer = Directory.GetComputerPrincipal(model.ComputerName);

                if (computer == null)
                {
                    return(this.LogAndReturnErrorResponse(model, UIMessages.ComputerNotFoundInDirectory, EventIDs.ComputerNotFound, string.Format(LogMessages.ComputerNotFoundInDirectory, user.SamAccountName, model.ComputerName)));
                }

                TargetElement target = this.GetMatchingTargetOrNull(computer);
                if (target == null)
                {
                    return(this.AuditAndReturnErrorResponse(
                               model: model,
                               userMessage: UIMessages.NotAuthorized,
                               eventID: EventIDs.AuthZFailedNoTargetMatch,
                               logMessage: string.Format(LogMessages.NoTargetsExist, user.SamAccountName, computer.SamAccountName),
                               user: user,
                               computer: computer));
                }

                foreach (ReaderElement reader in target.Readers.OfType <ReaderElement>())
                {
                    if (this.IsReaderAuthorized(reader, user))
                    {
                        logger.Trace($"User {user.SamAccountName} matches reader principal {reader.Principal} is authorized to read passwords from target {target.Name}");

                        SearchResult searchResult = Directory.GetDirectoryEntry(computer, Directory.AttrSamAccountName, Directory.AttrMsMcsAdmPwd, Directory.AttrMsMcsAdmPwdExpirationTime);

                        if (!searchResult.Properties.Contains(Directory.AttrMsMcsAdmPwd))
                        {
                            return(this.LogAndReturnErrorResponse(model, UIMessages.NoLapsPassword, EventIDs.LapsPasswordNotPresent, string.Format(LogMessages.NoLapsPassword, computer.SamAccountName, user.SamAccountName)));
                        }

                        if (target.ExpireAfter != null)
                        {
                            LapController.UpdateTargetPasswordExpiry(target, computer);
                            searchResult = Directory.GetDirectoryEntry(computer, Directory.AttrSamAccountName, Directory.AttrMsMcsAdmPwd, Directory.AttrMsMcsAdmPwdExpirationTime);
                        }

                        Reporting.PerformAuditSuccessActions(model, target, reader, user, computer, searchResult);

                        return(this.View("Show", LapController.CreateLapEntryModel(searchResult)));
                    }
                }

                return(this.AuditAndReturnErrorResponse(
                           model: model,
                           userMessage: UIMessages.NotAuthorized,
                           eventID: EventIDs.AuthZFailedNoReaderPrincipalMatch,
                           logMessage: string.Format(LogMessages.AuthZFailedNoReaderPrincipalMatch, user.SamAccountName, computer.SamAccountName),
                           target: target,
                           user: user,
                           computer: computer));
            }
            catch (Exception ex)
            {
                return(this.LogAndReturnErrorResponse(model, UIMessages.UnexpectedError, EventIDs.UnexpectedError, string.Format(LogMessages.UnhandledError, model.ComputerName, user?.SamAccountName ?? LogMessages.UnknownComputerPlaceholder), ex));
            }
        }
コード例 #6
0
ファイル: LapController.cs プロジェクト: zaeja/laps-web
 private ViewResult LogAndReturnErrorResponse(LapRequestModel model, string userMessage, int eventID, string logMessage = null, Exception ex = null)
 {
     Reporting.LogErrorEvent(eventID, logMessage ?? userMessage, ex);
     model.FailureReason = userMessage;
     return(this.View("Get", model));
 }
コード例 #7
0
ファイル: LapController.cs プロジェクト: zaeja/laps-web
 private ViewResult AuditAndReturnErrorResponse(LapRequestModel model, string userMessage, int eventID, string logMessage = null, Exception ex = null, TargetElement target = null, ReaderElement reader = null, UserPrincipal user = null, ComputerPrincipal computer = null)
 {
     Reporting.PerformAuditFailureActions(model, userMessage, eventID, logMessage, ex, target, reader, user, computer);
     model.FailureReason = userMessage;
     return(this.View("Get", model));
 }