Example #1
0
        /// <summary>
        /// Save a failed user login attempt. If the number of permitted failed logins in a row gets exceeded then the
        /// user account gets Locked, too!
        /// </summary>
        /// <param name="AUserID">User ID.</param>
        /// <param name="UserDR">s_user DataRow of the user.</param>
        /// <param name="AClientComputerName">Name of the Client Computer that the authentication request came from.</param>
        /// <param name="AClientIPAddress">IP Address of the Client Computer that the authentication request came from.</param>
        /// <param name="ATransaction">Instantiated DB Transaction.</param>
        private static void SaveFailedLogin(string AUserID, SUserRow UserDR,
                                            string AClientComputerName, string AClientIPAddress, TDBTransaction ATransaction)
        {
            int AProcessID;
            int FailedLoginsUntilAccountGetsLocked =
                TSystemDefaults.GetInt32Default(SharedConstants.SYSDEFAULT_FAILEDLOGINS_UNTIL_ACCOUNT_GETS_LOCKED, 10);
            bool AccountLockedAtThisAttempt = false;

            // Console.WriteLine('PetraPrincipal.PetraIdentity.FailedLogins: ' + PetraPrincipal.PetraIdentity.FailedLogins.ToString +
            // '; PetraPrincipal.PetraIdentity.AccountLocked: ' + PetraPrincipal.PetraIdentity.AccountLocked.ToString);

            UserDR.FailedLogins++;
            UserDR.FailedLoginDate = DateTime.Now;
            UserDR.FailedLoginTime = Conversions.DateTimeToInt32Time(UserDR.FailedLoginDate.Value);

            // Check if User Account should be Locked due to too many successive failed log-in attempts
            if ((UserDR.FailedLogins >= FailedLoginsUntilAccountGetsLocked) &&
                ((!UserDR.AccountLocked)))
            {
                // Lock User Account (this user will no longer be able to log in until a Sysadmin resets this flag!)
                UserDR.AccountLocked       = true;
                AccountLockedAtThisAttempt = true;

                TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId,
                                                                       TUserAccountActivityLog.USER_ACTIVITY_PERMITTED_FAILED_LOGINS_EXCEEDED,
                                                                       String.Format(Catalog.GetString(
                                                                                         "The permitted number of failed logins in a row got exceeded and the user account for the user {0} got locked! ") +
                                                                                     String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress),
                                                                                     UserDR.UserId), ATransaction);
            }

            // Logging
            TLoginLog.AddLoginLogEntry(AUserID,
                                       AccountLockedAtThisAttempt ? TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_PWD_WRONG_ACCOUNT_GOT_LOCKED :
                                       TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_PWD_WRONG,
                                       String.Format(Catalog.GetString("User supplied wrong password{0}!  (Failed Logins: now {1}; " +
                                                                       "Account Locked: now {2}, User Retired: {3}) "),
                                                     (AccountLockedAtThisAttempt ?
                                                      Catalog.GetString("; because the permitted number of failed logins in a row got exceeded the user account " +
                                                                        "for the user got locked! ") : String.Empty),
                                                     UserDR.FailedLogins, UserDR.AccountLocked, UserDR.Retired) +
                                       String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress),
                                       out AProcessID, ATransaction);

            SaveUser(AUserID, (SUserTable)UserDR.Table, ATransaction);
        }
Example #2
0
        public static TPetraPrincipal PerformUserAuthentication(String AUserID, String APassword, out Boolean ASystemEnabled)
        {
            DateTime        LoginDateTime;
            TPetraPrincipal PetraPrincipal = null;

            Int32 AProcessID = -1;

            ASystemEnabled = true;

            string EmailAddress = AUserID;

            if (AUserID.Contains("@"))
            {
                AUserID = AUserID.Substring(0, AUserID.IndexOf("@")).
                          Replace(".", string.Empty).
                          Replace("_", string.Empty).ToUpper();
            }

            try
            {
                SUserRow UserDR = LoadUser(AUserID, out PetraPrincipal);

                // Already assign the global variable here, because it is needed for SUserAccess.SubmitChanges later in this function
                UserInfo.GUserInfo = PetraPrincipal;

                // Check if user is retired
                if (PetraPrincipal.PetraIdentity.Retired)
                {
                    throw new EUserRetiredException(StrInvalidUserIDPassword);
                }

                int FailedLoginsUntilRetire =
                    TSystemDefaults.GetInt32Default(SharedConstants.SYSDEFAULT_FAILEDLOGINS_UNTIL_RETIRE, 10);

                // Console.WriteLine('PetraPrincipal.PetraIdentity.FailedLogins: ' + PetraPrincipal.PetraIdentity.FailedLogins.ToString +
                // '; PetraPrincipal.PetraIdentity.Retired: ' + PetraPrincipal.PetraIdentity.Retired.ToString);
                // Check if user should be autoretired
                if ((PetraPrincipal.PetraIdentity.FailedLogins >= FailedLoginsUntilRetire) && ((!PetraPrincipal.PetraIdentity.Retired)))
                {
                    UserDR.Retired      = true;
                    UserDR.FailedLogins = 0;

                    SaveUser(AUserID, (SUserTable)UserDR.Table);

                    throw new EAccessDeniedException(StrInvalidUserIDPassword);
                }

                // Check SystemLoginStatus (Petra enabled/disabled) in the SystemStatus table (always holds only one record)
                Boolean            NewTransaction = false;
                SSystemStatusTable SystemStatusDT;

                TDBTransaction ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted,
                                                                                                   TEnforceIsolationLevel.eilMinimum,
                                                                                                   out NewTransaction);

                try
                {
                    SystemStatusDT = SSystemStatusAccess.LoadAll(ReadTransaction);
                }
                finally
                {
                    if (NewTransaction)
                    {
                        DBAccess.GDBAccessObj.CommitTransaction();
                        TLogging.LogAtLevel(7, "TUserManager.PerformUserAuthentication: committed own transaction.");
                    }
                }

                if (SystemStatusDT[0].SystemLoginStatus)
                {
                    ASystemEnabled = true;
                }
                else
                {
                    ASystemEnabled = false;

                    if (PetraPrincipal.IsInGroup("SYSADMIN"))
                    {
                        PetraPrincipal.LoginMessage =
                            String.Format(StrSystemDisabled1,
                                          SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine + StrSystemDisabled2Admin;
                    }
                    else
                    {
                        TLoginLog.AddLoginLogEntry(AUserID, "System disabled", true, out AProcessID);

                        throw new ESystemDisabledException(String.Format(StrSystemDisabled1,
                                                                         SystemStatusDT[0].SystemDisabledReason) + Environment.NewLine + Environment.NewLine +
                                                           String.Format(StrSystemDisabled2, StringHelper.DateToLocalizedString(SystemStatusDT[0].SystemAvailableDate.Value),
                                                                         SystemStatusDT[0].SystemAvailableDate.Value.AddSeconds(SystemStatusDT[0].SystemAvailableTime).ToShortTimeString()));
                    }
                }

                if ((AUserID == "SYSADMIN") && TSession.HasVariable("ServerAdminToken"))
                {
                    // Login via server admin console authenticated by file token
                }
                else
                {
                    string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false);

                    if (UserAuthenticationMethod == "OpenPetraDBSUser")
                    {
                        // TODO 1 oChristianK cSecurity : Perform user authentication by verifying password hash in the DB
                        // see also ICTPetraWiki: Todo_Petra.NET#Implement_Security_.7B2.7D_.5BChristian.5D
                        if (CreateHashOfPassword(String.Concat(APassword,
                                                               UserDR.PasswordSalt)) != UserDR.PasswordHash)
                        {
                            // increase failed logins
                            UserDR.FailedLogins++;
                            LoginDateTime          = DateTime.Now;
                            UserDR.FailedLoginDate = LoginDateTime;
                            UserDR.FailedLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime);
                            SaveUser(AUserID, (SUserTable)UserDR.Table);

                            throw new EPasswordWrongException(StrInvalidUserIDPassword);
                        }
                    }
                    else
                    {
                        IUserAuthentication auth = LoadAuthAssembly(UserAuthenticationMethod);

                        string ErrorMessage;

                        if (!auth.AuthenticateUser(EmailAddress, APassword, out ErrorMessage))
                        {
                            UserDR.FailedLogins++;
                            LoginDateTime          = DateTime.Now;
                            UserDR.FailedLoginDate = LoginDateTime;
                            UserDR.FailedLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime);
                            SaveUser(AUserID, (SUserTable)UserDR.Table);

                            throw new EPasswordWrongException(ErrorMessage);
                        }
                    }
                }

                // Save successful login
                LoginDateTime        = DateTime.Now;
                UserDR.LastLoginDate = LoginDateTime;
                UserDR.LastLoginTime = Conversions.DateTimeToInt32Time(LoginDateTime);
                UserDR.FailedLogins  = 0;

                SaveUser(AUserID, (SUserTable)UserDR.Table);

                PetraPrincipal.PetraIdentity.CurrentLogin = LoginDateTime;

                // PetraPrincipal.PetraIdentity.FailedLogins := 0;

                if (PetraPrincipal.IsInGroup("SYSADMIN"))
                {
                    TLoginLog.AddLoginLogEntry(AUserID, "Successful  SYSADMIN", out AProcessID);
                }
                else
                {
                    TLoginLog.AddLoginLogEntry(AUserID, "Successful", out AProcessID);
                }

                PetraPrincipal.ProcessID = AProcessID;
                AProcessID = 0;

                if (UserDR.PasswordNeedsChange)
                {
                    // The user needs to change their password before they can use OpenPetra
                    PetraPrincipal.LoginMessage = SharedConstants.LOGINMUSTCHANGEPASSWORD;
                }
            }
            finally
            {
                DBAccess.GDBAccessObj.RollbackTransaction();
            }

            return(PetraPrincipal);
        }