internal static void SetNewPasswordHashAndSaltForUser(SUserRow AUserDR, string ANewPassword, string AClientComputerName, string AClientIPAddress, TDBTransaction ATransaction) { byte[] Salt; int PwdSchemeVersionUpTillNow = AUserDR.PwdSchemeVersion; int CurrentPwdSchemeVersion = TPasswordHelper.CurrentPasswordSchemeNumber; EnsurePasswordHashingSchemeChangeIsAllowed(AUserDR.UserId, PwdSchemeVersionUpTillNow); // Note: In this Method we deliberately ignore the present value of the PwdSchemeVersion Column of AUserDR // because we *always* want to save the new password with the password hash of the current (=newest) version! // We always assign a new 'Salt' with every password change (best practice)! Salt = TPasswordHelper.CurrentPasswordScheme.GetNewPasswordSalt(); AUserDR.PasswordSalt = Convert.ToBase64String(Salt); AUserDR.PasswordHash = TUserManagerWebConnector.CreateHashOfPassword(ANewPassword, Convert.ToBase64String(Salt), CurrentPwdSchemeVersion); if (PwdSchemeVersionUpTillNow != CurrentPwdSchemeVersion) { // Ensure AUserDR.PwdSchemeVersion gets set to the current (=newest) version! AUserDR.PwdSchemeVersion = CurrentPwdSchemeVersion; TUserAccountActivityLog.AddUserAccountActivityLogEntry(AUserDR.UserId, TUserAccountActivityLog.USER_ACTIVITY_PWD_HASHING_SCHEME_UPGRADED, String.Format(Catalog.GetString( "The Password Scheme of User {0} got upgraded to {1}; previously it was {2}. "), AUserDR.UserId, TPasswordHelper.CurrentPasswordSchemeNumber, PwdSchemeVersionUpTillNow) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), ATransaction); } }
public static bool PasswordAuthentication(String AUserID, String APassword) { TPetraPrincipal PetraPrincipal = null; SUserRow UserDR = TUserManagerWebConnector.LoadUser(AUserID, out PetraPrincipal); string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { if (TUserManagerWebConnector.CreateHashOfPassword(String.Concat(APassword, UserDR.PasswordSalt)) != UserDR.PasswordHash) { return(false); } } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); string ErrorMessage; if (!auth.AuthenticateUser(AUserID, APassword, out ErrorMessage)) { return(false); } } return(true); }
private void InitializeOtherControls() { // Load MethodOfContact List PMethodOfContactTable MethodOfContactTable = (PMethodOfContactTable)TDataCache.TMPartner.GetCacheableMailingTable( TCacheableMailingTablesEnum.MethodOfContactList); cmbContact.Items.Add("*"); foreach (PMethodOfContactRow Row in MethodOfContactTable.Rows) { cmbContact.Items.Add(Row.MethodOfContactCode); } cmbContact.SelectedIndex = 0; // Load User List SUserTable UserTable = (SUserTable)TDataCache.TMSysMan.GetCacheableSysManTable(TCacheableSysManTablesEnum.UserList); DataView dvActive = new DataView(UserTable); dvActive.RowFilter = string.Format("{0}=0 AND {1}=0", SUserTable.GetRetiredDBName(), SUserTable.GetAccountLockedDBName()); dvActive.Sort = string.Format("{0}", SUserTable.GetUserIdDBName()); cmbContactor.Items.Add("*"); foreach (DataRowView drv in dvActive) { SUserRow row = (SUserRow)drv.Row; cmbContactor.Items.Add(row.UserId); } cmbContactor.SelectedIndex = 0; }
private void CheckForCurrentUser(SUserRow ARow) { if ((ARow != null) && (ARow.UserId == UserInfo.GUserInfo.UserID)) { FChangesForCurrentUser = true; } }
private DataTable GetFoundationOwnerListTable(TDBTransaction AReadTransaction, string ATableName) { // Used in Foundation Details screen. SUserTable TmpUserTable = new SUserTable(); TmpUserTable = (SUserTable)DBAccess.GetDBAccessObj(AReadTransaction).SelectDT(TmpUserTable, "SELECT " + SUserTable.GetPartnerKeyDBName() + ',' + SUserTable.GetUserIdDBName() + ',' + SUserTable.GetFirstNameDBName() + ',' + SUserTable.GetLastNameDBName() + ' ' + "FROM PUB_" + SUserTable.GetTableDBName() + ' ' + "WHERE " + SUserTable.GetPartnerKeyDBName() + " <> 0 " + "AND " + SUserTable.GetUserIdDBName() + " IN (SELECT " + SUserModuleAccessPermissionTable.GetUserIdDBName() + ' ' + "FROM PUB_" + SUserModuleAccessPermissionTable.GetTableDBName() + ' ' + "WHERE " + SUserModuleAccessPermissionTable.GetModuleIdDBName() + " = 'DEVUSER')" + "AND " + SUserTable.GetRetiredDBName() + " = FALSE", AReadTransaction, null, -1, -1); SUserRow EmptyDR = TmpUserTable.NewRowTyped(false); EmptyDR.PartnerKey = 0; EmptyDR.UserId = ""; TmpUserTable.Rows.InsertAt(EmptyDR, 0); return(TmpUserTable); }
public static bool SetUserPassword(string AUsername, string APassword, bool APasswordNeedsChanged) { string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { TPetraPrincipal tempPrincipal; SUserRow UserDR = TUserManagerWebConnector.LoadUser(AUsername.ToUpper(), out tempPrincipal); SUserTable UserTable = (SUserTable)UserDR.Table; Random r = new Random(); UserDR.PasswordSalt = r.Next(1000000000).ToString(); UserDR.PasswordHash = TUserManagerWebConnector.CreateHashOfPassword(String.Concat(APassword, UserDR.PasswordSalt), "SHA1"); UserDR.PasswordNeedsChange = APasswordNeedsChanged; TDBTransaction Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable); SUserAccess.SubmitChanges(UserTable, Transaction); DBAccess.GDBAccessObj.CommitTransaction(); return(true); } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return(auth.SetPassword(AUsername, APassword)); } }
/// <summary> /// /// </summary> /// <remarks></remarks> /// <param name="ARow"></param> private void ShowDetailsManual(SUserRow ARow) { CheckForCurrentUser(ARow); string currentPermissions = String.Empty; if (ARow != null) { FMainDS.SUserModuleAccessPermission.DefaultView.RowFilter = String.Format("{0}='{1}'", SUserModuleAccessPermissionTable.GetUserIdDBName(), ARow.UserId); foreach (DataRowView rv in FMainDS.SUserModuleAccessPermission.DefaultView) { SUserModuleAccessPermissionRow permission = (SUserModuleAccessPermissionRow)rv.Row; if (permission.CanAccess) { currentPermissions = StringHelper.AddCSV(currentPermissions, permission.ModuleId); } } // If a password has been saved for a user it can be changed using btnResetPassword. // If a password has not been saved then it can be added using txtDetailPasswordHash. if (string.IsNullOrEmpty(ARow.PasswordHash) || (string.IsNullOrEmpty(ARow.PasswordSalt) && (ARow.RowState != DataRowState.Unchanged))) { btnResetPassword.Enabled = false; txtDetailPasswordHash.Enabled = true; if (FNewRecordBeingAdded) { FNewRecordBeingAdded = false; FTipPwd.Show(Catalog.GetString( "A 'random, secure' password got assigned.\r\nCopy it with the provided hyperlink!"), txtDetailPasswordHash, 0, 25, 5000); } else { FTipPwd.Hide(txtDetailPasswordHash); } llbCopyPassword.Visible = true; } else { btnResetPassword.Enabled = true; txtDetailPasswordHash.Enabled = false; llbCopyPassword.Visible = false; FTipPwd.Hide(txtDetailPasswordHash); } } clbUserGroup.SetCheckedStringList(currentPermissions); clbUserGroup.AutoResizeGrid(); }
private void ValidateDataDetailsManual(SUserRow ARow) { if (ARow == null) { return; } TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection; // validate bank account details TSharedSysManValidation.ValidateSUserDetails(this, ARow, ref VerificationResultCollection, FPetraUtilsObject.ValidationControlsDict); }
/// <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); }
internal static SUserRow LoadUser(String AUserID, out TPetraPrincipal APetraPrincipal, TDBTransaction ATransaction) { SUserRow ReturnValue = LoadUser(AUserID, ATransaction); APetraPrincipal = new TPetraPrincipal(AUserID, TGroupManager.LoadUserGroups( AUserID, ATransaction), TModuleAccessManager.LoadUserModules(AUserID, ATransaction)); if (!ReturnValue.IsPartnerKeyNull()) { APetraPrincipal.PartnerKey = ReturnValue.PartnerKey; } /* * TLogging.LogAtLevel (8, "APetraPrincipal.IsTableAccessOK(tapMODIFY, 'p_person'): " + * APetraPrincipal.IsTableAccessOK(TTableAccessPermission.tapMODIFY, "p_person").ToString()); */ return(ReturnValue); }
private void NewRowManual(ref SUserRow ARow) { string newName = Catalog.GetString("NEWUSER"); Int32 countNewDetail = 0; if (FMainDS.SUser.Rows.Find(new object[] { newName }) != null) { while (FMainDS.SUser.Rows.Find(new object[] { newName + countNewDetail.ToString() }) != null) { countNewDetail++; } newName += countNewDetail.ToString(); } ARow.UserId = newName; }
public static bool SetUserPassword(string AUsername, string APassword, bool APasswordNeedsChanged, bool AUnretireIfRetired) { string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { TDBTransaction SubmitChangesTransaction = null; bool SubmissionResult = false; TPetraPrincipal tempPrincipal; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { SUserRow UserDR = TUserManagerWebConnector.LoadUser(AUsername.ToUpper(), out tempPrincipal); SUserTable UserTable = (SUserTable)UserDR.Table; Random r = new Random(); UserDR.PasswordSalt = r.Next(1000000000).ToString(); UserDR.PasswordHash = TUserManagerWebConnector.CreateHashOfPassword(String.Concat(APassword, UserDR.PasswordSalt), "SHA1"); UserDR.PasswordNeedsChange = APasswordNeedsChanged; // unretire the user if it has been previously retired if (AUnretireIfRetired) { UserDR.Retired = false; } SUserAccess.SubmitChanges(UserTable, SubmitChangesTransaction); SubmissionResult = true; }); return(true); } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return(auth.SetPassword(AUsername, APassword)); } }
/// <summary> /// Compares the new password with existing password - are they the same? /// </summary> /// <param name="ANewPassword">New password.</param> /// <param name="AUserDR">DataRow of the user record in s_user DB Table whose password should be changed.</param> /// <param name="AVerificationResult">Will be null if the new password is not the same than the old password, /// otherwise it will be populated.</param> /// <returns>False if the new password is not the same than the old password, otherwise true.</returns> private static bool IsNewPasswordSameAsExistingPassword(string ANewPassword, SUserRow AUserDR, out TVerificationResult AVerificationResult) { string NewPasswordHashWithOldSalt = TUserManagerWebConnector.CreateHashOfPassword(ANewPassword, AUserDR.PasswordSalt, AUserDR.PwdSchemeVersion); if (TPasswordHelper.EqualsAntiTimingAttack(Convert.FromBase64String(AUserDR.PasswordHash), Convert.FromBase64String(NewPasswordHashWithOldSalt))) { AVerificationResult = new TVerificationResult("Password change", ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_NEW_PASSWORD_MUST_BE_DIFFERENT)); return(true); } AVerificationResult = null; return(false); }
private void GetDetailDataFromControlsManual(SUserRow ARow) { ARow.UserId = ARow.UserId.ToUpperInvariant(); FMainDS.SUserModuleAccessPermission.DefaultView.RowFilter = String.Format("{0}='{1}'", SUserModuleAccessPermissionTable.GetUserIdDBName(), ARow.UserId); string currentPermissions = clbUserGroup.GetCheckedStringList(); StringCollection CSVValues = StringHelper.StrSplit(currentPermissions, ","); foreach (DataRowView rv in FMainDS.SUserModuleAccessPermission.DefaultView) { SUserModuleAccessPermissionRow permission = (SUserModuleAccessPermissionRow)rv.Row; if (permission.CanAccess) { if (!CSVValues.Contains(permission.ModuleId)) { permission.CanAccess = false; } else { CSVValues.Remove(permission.ModuleId); } } else if (!permission.CanAccess && CSVValues.Contains(permission.ModuleId)) { permission.CanAccess = true; CSVValues.Remove(permission.ModuleId); } } // add new permissions foreach (string module in CSVValues) { SUserModuleAccessPermissionRow newRow = FMainDS.SUserModuleAccessPermission.NewRowTyped(); newRow.UserId = ARow.UserId; newRow.ModuleId = module; newRow.CanAccess = true; FMainDS.SUserModuleAccessPermission.Rows.Add(newRow); } }
private void NewRowManual(ref SUserRow ARow) { string newName = Catalog.GetString("NEWUSER"); Int32 countNewDetail = 0; if (FMainDS.SUser.Rows.Find(new object[] { newName }) != null) { while (FMainDS.SUser.Rows.Find(new object[] { newName + countNewDetail.ToString() }) != null) { countNewDetail++; } newName += countNewDetail.ToString(); } ARow.UserId = newName; ARow.PasswordHash = TPasswordHelper.GetRandomSecurePassword(); FNewRecordBeingAdded = true; }
/// <summary> /// Validates SUser Details /// </summary> /// <param name="AContext">Context that describes where the data validation failed.</param> /// <param name="ARow">The <see cref="DataRow" /> which holds the the data against which the validation is run.</param> /// <param name="AVerificationResultCollection">Will be filled with any <see cref="TVerificationResult" /> items if /// data validation errors occur.</param> /// <param name="AValidationControlsDict">A <see cref="TValidationControlsDict" /> containing the Controls that /// display data that is about to be validated.</param> public static void ValidateSUserDetails(object AContext, SUserRow ARow, ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict) { DataColumn ValidationColumn; TValidationControlsData ValidationControlsData; TVerificationResult VerificationResult = null; // Don't validate deleted DataRows if (ARow.RowState == DataRowState.Deleted) { return; } ValidationColumn = ARow.Table.Columns[SUserTable.ColumnPasswordHashId]; AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData); // PasswordHash must not be empty. if ((ARow.RowState != DataRowState.Unchanged) && string.IsNullOrEmpty(ARow.PasswordHash)) { VerificationResult = new TScreenVerificationResult(new TVerificationResult(AContext, ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_MISSING_PASSWORD, new string[] { ARow.UserId })), ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition to/removal from TVerificationResultCollection AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn); } // If this is a first password (no salt) check that the password is valid. if ((ARow.RowState != DataRowState.Unchanged) && string.IsNullOrEmpty(ARow.PasswordSalt) && !string.IsNullOrEmpty(ARow.PasswordHash)) { VerificationResult = null; if (!CheckPasswordQuality(ARow.PasswordHash, out VerificationResult)) { VerificationResult = new TScreenVerificationResult(VerificationResult, ValidationColumn, ValidationControlsData.ValidationControl); AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn); } } }
private void ShowDetailsManual(SUserRow ARow) { string currentPermissions = String.Empty; if (ARow != null) { FMainDS.SUserModuleAccessPermission.DefaultView.RowFilter = String.Format("{0}='{1}'", SUserModuleAccessPermissionTable.GetUserIdDBName(), ARow.UserId); foreach (DataRowView rv in FMainDS.SUserModuleAccessPermission.DefaultView) { SUserModuleAccessPermissionRow permission = (SUserModuleAccessPermissionRow)rv.Row; if (permission.CanAccess) { currentPermissions = StringHelper.AddCSV(currentPermissions, permission.ModuleId); } } // If a password has been saved for a user it can be changed using btnChangePassword. // If a password has not been saved then it can be added using txtDetailPasswordHash. if (string.IsNullOrEmpty(ARow.PasswordHash) || (string.IsNullOrEmpty(ARow.PasswordSalt) && (ARow.RowState != DataRowState.Unchanged))) { btnChangePassword.Enabled = false; txtDetailPasswordHash.Enabled = true; } else { btnChangePassword.Enabled = true; txtDetailPasswordHash.Enabled = false; } } clbUserGroup.SetCheckedStringList(currentPermissions); }
/// <summary> /// Implementation of the interface member /// </summary> /// <param name="AContext">The context that identifies the column for which an image is to be evaluated</param> /// <param name="ADataRowView">The data containing the column of interest. You will evaluate whether this column contains data that should have the image or not.</param> /// <returns>True if the image should be displayed in the current context</returns> public bool EvaluateBoundImage(BoundGridImage.AnnotationContextEnum AContext, DataRowView ADataRowView) { SUserRow row = (SUserRow)ADataRowView.Row; return(row.Retired); }
public static bool SetUserPassword(string AUserID, string ANewPassword, string ACurrentPassword, bool APasswordNeedsChanged, string AClientComputerName, string AClientIPAddress, out TVerificationResultCollection AVerification) { string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); TVerificationResult VerificationResult; TVerificationResultCollection VerificationResultColl = null; SUserRow UserDR = null; SUserTable UserTable = null; bool BogusPasswordChangeAttempt = false; AVerification = new TVerificationResultCollection(); // Security check: Is the user that is performing the password change request the current user? if (AUserID != UserInfo.GUserInfo.UserID) { throw new EOPAppException( "The setting of a User's Password must only be done by the user itself, but this isn't the case here and therefore the request gets denied"); } // Password quality check if (!TSharedSysManValidation.CheckPasswordQuality(ANewPassword, out VerificationResult)) { AVerification.Add(VerificationResult); return(false); } if (UserAuthenticationMethod == "OpenPetraDBSUser") { TPetraPrincipal tempPrincipal; TDBTransaction SubmitChangesTransaction = null; bool SubmissionResult = false; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { try { UserDR = TUserManagerWebConnector.LoadUser(AUserID.ToUpper(), out tempPrincipal, SubmitChangesTransaction); } catch (EUserNotExistantException) { // Because this cannot happen when a password change gets effected through normal OpenPetra // operation this is treated as a bogus operation that an attacker launches! BogusPasswordChangeAttempt = true; // Logging TUserAccountActivityLog.AddUserAccountActivityLogEntry(AUserID, TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_ATTEMPT_BY_USER_FOR_NONEXISTING_USER, String.Format(Catalog.GetString( "User {0} tried to make an attempt to change a User's password for UserID {1} " + "but that user doesn't exist! "), UserInfo.GUserInfo.UserID, AUserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); SubmissionResult = true; // Need to set this so that the DB Transaction gets committed! // Simulate that time is spent on 'authenticating' a user (although the user doesn't exist)...! Reason for that: see Method // SimulatePasswordAuthenticationForNonExistingUser! TUserManagerWebConnector.SimulatePasswordAuthenticationForNonExistingUser(); return; } UserTable = (SUserTable)UserDR.Table; // Security check: Is the supplied current password correct? if (TUserManagerWebConnector.CreateHashOfPassword(ACurrentPassword, UserDR.PasswordSalt, UserDR.PwdSchemeVersion) != UserDR.PasswordHash) { VerificationResultColl = new TVerificationResultCollection(); VerificationResultColl.Add(new TVerificationResult("Password Verification", Catalog.GetString( "The current password was entered incorrectly! The password did not get changed."), TResultSeverity.Resv_Critical)); try { SUserAccess.SubmitChanges(UserTable, SubmitChangesTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId, TUserAccountActivityLog.USER_ACTIVITY_PWD_WRONG_WHILE_PWD_CHANGE, String.Format(Catalog.GetString( "User {0} supplied the wrong current password while attempting to change " + "his/her password! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), UserInfo.GUserInfo.UserID), SubmitChangesTransaction); SubmissionResult = true; } catch (Exception Exc) { TLogging.Log(String.Format( "An Exception occured during the changing of the User Password by user '{0}' (Situation 1):", AUserID) + Environment.NewLine + Exc.ToString()); throw; } } }); if (BogusPasswordChangeAttempt) { // Note: VerificationResultColl will be null in this case because we don't want to disclose to an attackeer // why the password change attempt was denied!!! return(false); } if (VerificationResultColl != null) { AVerification = VerificationResultColl; return(false); } // Security check: Is the supplied new password the same than the current password? if (IsNewPasswordSameAsExistingPassword(ANewPassword, UserDR, out VerificationResult)) { AVerification.Add(VerificationResult); return(false); } // // All checks passed: We go aheand and change the user's password! // SetNewPasswordHashAndSaltForUser(UserDR, ANewPassword, AClientComputerName, AClientIPAddress, SubmitChangesTransaction); UserDR.PasswordNeedsChange = false; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { try { SUserAccess.SubmitChanges(UserTable, SubmitChangesTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId, (APasswordNeedsChanged ? TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_BY_USER_ENFORCED : TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_BY_USER), String.Format(Catalog.GetString("User {0} changed his/her password{1}"), UserInfo.GUserInfo.UserID, (APasswordNeedsChanged ? Catalog.GetString(" (enforced password change.) ") : ". ")) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); SubmissionResult = true; } catch (Exception Exc) { TLogging.Log(String.Format("An Exception occured during the changing of the User Password by user '{0}' (Situation 2):", AUserID) + Environment.NewLine + Exc.ToString()); throw; } }); return(true); } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return(auth.SetPassword(AUserID, ANewPassword, ACurrentPassword)); } }
public static bool CreateUser(string AUsername, string APassword, string AFirstName, string AFamilyName, string AModulePermissions, string AClientComputerName, string AClientIPAddress, TDBTransaction ATransaction = null) { TDataBase DBConnectionObj = DBAccess.GetDBAccessObj(ATransaction); TDBTransaction ReadWriteTransaction = null; bool SeparateDBConnectionEstablished = false; bool NewTransaction; bool SubmissionOK = false; // TODO: check permissions. is the current user allowed to create other users? SUserTable userTable = new SUserTable(); SUserRow newUser = userTable.NewRowTyped(); newUser.UserId = AUsername; newUser.FirstName = AFirstName; newUser.LastName = AFamilyName; if (AUsername.Contains("@")) { newUser.EmailAddress = AUsername; newUser.UserId = AUsername.Substring(0, AUsername.IndexOf("@")). Replace(".", string.Empty). Replace("_", string.Empty).ToUpper(); } if (DBConnectionObj == null) { // ATransaction was null and GDBAccess is also null: we need to establish a DB Connection manually here! DBConnectionObj = DBAccess.SimpleEstablishDBConnection("CreateUser"); SeparateDBConnectionEstablished = true; } ReadWriteTransaction = DBConnectionObj.GetNewOrExistingTransaction( IsolationLevel.Serializable, out NewTransaction, "CreateUser"); try { // Check whether the user that we are asked to create already exists if (SUserAccess.Exists(newUser.UserId, ReadWriteTransaction)) { TLogging.Log("Cannot create new user because a user with User Name '" + newUser.UserId + "' already exists!"); return(false); } newUser.PwdSchemeVersion = TPasswordHelper.CurrentPasswordSchemeNumber; userTable.Rows.Add(newUser); string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { if (APassword.Length > 0) { SetNewPasswordHashAndSaltForUser(newUser, APassword, AClientComputerName, AClientIPAddress, ReadWriteTransaction); if (AModulePermissions != TMaintenanceWebConnector.DEMOMODULEPERMISSIONS) { newUser.PasswordNeedsChange = true; } } } else { try { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); if (!auth.CreateUser(AUsername, APassword, AFirstName, AFamilyName)) { newUser = null; } } catch (Exception e) { TLogging.Log("Problem loading user authentication method " + UserAuthenticationMethod + ": " + e.ToString()); return(false); } } if (newUser != null) { SUserAccess.SubmitChanges(userTable, ReadWriteTransaction); List <string> modules = new List <string>(); if (AModulePermissions == DEMOMODULEPERMISSIONS) { modules.Add("PTNRUSER"); modules.Add("FINANCE-1"); ALedgerTable theLedgers = ALedgerAccess.LoadAll(ReadWriteTransaction); foreach (ALedgerRow ledger in theLedgers.Rows) { modules.Add("LEDGER" + ledger.LedgerNumber.ToString("0000")); } } else { string[] modulePermissions = AModulePermissions.Split(new char[] { ',' }); foreach (string s in modulePermissions) { if (s.Trim().Length > 0) { modules.Add(s.Trim()); } } } SUserModuleAccessPermissionTable moduleAccessPermissionTable = new SUserModuleAccessPermissionTable(); foreach (string module in modules) { SUserModuleAccessPermissionRow moduleAccessPermissionRow = moduleAccessPermissionTable.NewRowTyped(); moduleAccessPermissionRow.UserId = newUser.UserId; moduleAccessPermissionRow.ModuleId = module; moduleAccessPermissionRow.CanAccess = true; moduleAccessPermissionTable.Rows.Add(moduleAccessPermissionRow); } SUserModuleAccessPermissionAccess.SubmitChanges(moduleAccessPermissionTable, ReadWriteTransaction); // TODO: table permissions should be set by the module list // TODO: add p_data_label... tables here so user can generally have access string[] tables = new string[] { "p_bank", "p_church", "p_family", "p_location", "p_organisation", "p_partner", "p_partner_location", "p_partner_type", "p_person", "p_unit", "p_venue", "p_data_label", "p_data_label_lookup", "p_data_label_lookup_category", "p_data_label_use", "p_data_label_value_partner", }; SUserTableAccessPermissionTable tableAccessPermissionTable = new SUserTableAccessPermissionTable(); foreach (string table in tables) { SUserTableAccessPermissionRow tableAccessPermissionRow = tableAccessPermissionTable.NewRowTyped(); tableAccessPermissionRow.UserId = newUser.UserId; tableAccessPermissionRow.TableName = table; tableAccessPermissionTable.Rows.Add(tableAccessPermissionRow); } SUserTableAccessPermissionAccess.SubmitChanges(tableAccessPermissionTable, ReadWriteTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(newUser.UserId, TUserAccountActivityLog.USER_ACTIVITY_USER_RECORD_CREATED, String.Format(Catalog.GetString("The user record for the new user {0} got created by user {1}. "), newUser.UserId, UserInfo.GUserInfo.UserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), ReadWriteTransaction); SubmissionOK = true; return(true); } } finally { if (NewTransaction) { if (SubmissionOK) { ReadWriteTransaction.DataBaseObj.CommitTransaction(); } else { ReadWriteTransaction.DataBaseObj.RollbackTransaction(); } if (SeparateDBConnectionEstablished) { DBConnectionObj.CloseDBConnection(); } } } return(false); }
public static bool CreateUser(string AUsername, string APassword, string AFirstName, string AFamilyName, string AModulePermissions) { TDBTransaction ReadTransaction = null; TDBTransaction SubmitChangesTransaction = null; bool UserExists = false; bool SubmissionOK = false; // TODO: check permissions. is the current user allowed to create other users? SUserTable userTable = new SUserTable(); SUserRow newUser = userTable.NewRowTyped(); newUser.UserId = AUsername; newUser.FirstName = AFirstName; newUser.LastName = AFamilyName; if (AUsername.Contains("@")) { newUser.EmailAddress = AUsername; newUser.UserId = AUsername.Substring(0, AUsername.IndexOf("@")). Replace(".", string.Empty). Replace("_", string.Empty).ToUpper(); } // Check whether the user that we are asked to create already exists DBAccess.GDBAccessObj.BeginAutoReadTransaction(IsolationLevel.ReadCommitted, ref ReadTransaction, delegate { if (SUserAccess.Exists(newUser.UserId, ReadTransaction)) { TLogging.Log("Cannot create new user as a user with User Name '" + newUser.UserId + "' already exists!"); UserExists = true; } }); if (UserExists) { return(false); } userTable.Rows.Add(newUser); string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { if (APassword.Length > 0) { newUser.PasswordSalt = PasswordHelper.GetNewPasswordSalt(); newUser.PasswordHash = PasswordHelper.GetPasswordHash(APassword, newUser.PasswordSalt); newUser.PasswordNeedsChange = true; } } else { try { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); if (!auth.CreateUser(AUsername, APassword, AFirstName, AFamilyName)) { newUser = null; } } catch (Exception e) { TLogging.Log("Problem loading user authentication method " + UserAuthenticationMethod + ": " + e.ToString()); return(false); } } if (newUser != null) { DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionOK, delegate { SUserAccess.SubmitChanges(userTable, SubmitChangesTransaction); List <string> modules = new List <string>(); if (AModulePermissions == DEMOMODULEPERMISSIONS) { modules.Add("PTNRUSER"); modules.Add("FINANCE-1"); ALedgerTable theLedgers = ALedgerAccess.LoadAll(SubmitChangesTransaction); foreach (ALedgerRow ledger in theLedgers.Rows) { modules.Add("LEDGER" + ledger.LedgerNumber.ToString("0000")); } } else { string[] modulePermissions = AModulePermissions.Split(new char[] { ',' }); foreach (string s in modulePermissions) { if (s.Trim().Length > 0) { modules.Add(s.Trim()); } } } SUserModuleAccessPermissionTable moduleAccessPermissionTable = new SUserModuleAccessPermissionTable(); foreach (string module in modules) { SUserModuleAccessPermissionRow moduleAccessPermissionRow = moduleAccessPermissionTable.NewRowTyped(); moduleAccessPermissionRow.UserId = newUser.UserId; moduleAccessPermissionRow.ModuleId = module; moduleAccessPermissionRow.CanAccess = true; moduleAccessPermissionTable.Rows.Add(moduleAccessPermissionRow); } SUserModuleAccessPermissionAccess.SubmitChanges(moduleAccessPermissionTable, SubmitChangesTransaction); // TODO: table permissions should be set by the module list // TODO: add p_data_label... tables here so user can generally have access string[] tables = new string[] { "p_bank", "p_church", "p_family", "p_location", "p_organisation", "p_partner", "p_partner_location", "p_partner_type", "p_person", "p_unit", "p_venue", "p_data_label", "p_data_label_lookup", "p_data_label_lookup_category", "p_data_label_use", "p_data_label_value_partner", }; SUserTableAccessPermissionTable tableAccessPermissionTable = new SUserTableAccessPermissionTable(); foreach (string table in tables) { SUserTableAccessPermissionRow tableAccessPermissionRow = tableAccessPermissionTable.NewRowTyped(); tableAccessPermissionRow.UserId = newUser.UserId; tableAccessPermissionRow.TableName = table; tableAccessPermissionTable.Rows.Add(tableAccessPermissionRow); } SUserTableAccessPermissionAccess.SubmitChanges(tableAccessPermissionTable, SubmitChangesTransaction); SubmissionOK = true; }); return(true); } return(false); }
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 = Convert.ToInt32( TSystemDefaults.GetSystemDefault(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 = Catalog.GetString("You need to change your password immediately."); } } finally { DBAccess.GDBAccessObj.RollbackTransaction(); } return(PetraPrincipal); }
public static bool SetUserPassword(string AUsername, string APassword, string AOldPassword, bool APasswordNeedsChanged, out TVerificationResultCollection AVerification) { TDBTransaction Transaction; string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); TVerificationResult VerificationResult; AVerification = new TVerificationResultCollection(); if (!TSharedSysManValidation.CheckPasswordQuality(APassword, out VerificationResult)) { return(false); } if (APasswordNeedsChanged && APassword == AOldPassword) { AVerification = new TVerificationResultCollection(); AVerification.Add(new TVerificationResult("\nPassword check.", Catalog.GetString( "Password not changed as the old password was reused. Please use a new password."), TResultSeverity.Resv_Critical)); return(false); } if (UserAuthenticationMethod == "OpenPetraDBSUser") { TPetraPrincipal tempPrincipal; SUserRow UserDR = TUserManagerWebConnector.LoadUser(AUsername.ToUpper(), out tempPrincipal); if (TUserManagerWebConnector.CreateHashOfPassword(String.Concat(AOldPassword, UserDR.PasswordSalt)) != UserDR.PasswordHash) { AVerification = new TVerificationResultCollection(); AVerification.Add(new TVerificationResult("\nPassword quality check.", String.Format( Catalog.GetString( "Old password entered incorrectly. Password not changed.")), TResultSeverity.Resv_Critical)); return(false); } SUserTable UserTable = (SUserTable)UserDR.Table; UserDR.PasswordHash = TUserManagerWebConnector.CreateHashOfPassword(String.Concat(APassword, UserDR.PasswordSalt)); UserDR.PasswordNeedsChange = false; Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable); try { SUserAccess.SubmitChanges(UserTable, Transaction); DBAccess.GDBAccessObj.CommitTransaction(); } catch (Exception Exc) { TLogging.Log("An Exception occured during the setting of the User Password:" + Environment.NewLine + Exc.ToString()); DBAccess.GDBAccessObj.RollbackTransaction(); throw; } return(true); } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return(auth.SetPassword(AUsername, APassword, AOldPassword)); } }
private static void SendEmailForUser(TDataBase ADataBaseObj, string AUserId, DataTable AErrors) { TDBTransaction ReadTransaction = new TDBTransaction(); SUserRow userrow = null; // get the email address of the user ADataBaseObj.ReadTransaction(ref ReadTransaction, delegate { userrow = SUserAccess.LoadByPrimaryKey(AUserId, ReadTransaction)[0]; }); string excelfile = TAppSettingsManager.GetValue("DataChecks.TempPath") + "/errors" + AUserId + ".xlsx"; DateTime Errors_SinceDate = DateTime.Today.AddDays(-1 * SENDREPORTFORDAYS_TOUSERS); DataView v = new DataView(AErrors, "(CreatedBy='" + AUserId + "' AND ModifiedBy IS NULL AND DateCreated > #" + Errors_SinceDate.ToString("MM/dd/yyyy") + "#) " + "OR (ModifiedBy='" + AUserId + "' AND DateModified > #" + Errors_SinceDate.ToString("MM/dd/yyyy") + "#)", string.Empty, DataViewRowState.CurrentRows); try { using (StreamWriter sw = new StreamWriter(excelfile)) { using (MemoryStream m = new MemoryStream()) { if (!TCsv2Xml.DataTable2ExcelStream(v.ToTable(), m)) { return; } m.WriteTo(sw.BaseStream); m.Close(); sw.Close(); } } } catch (Exception e) { TLogging.Log("Problems writing to file " + excelfile); TLogging.Log(e.ToString()); return; } string recipientEmail = string.Empty; if (!userrow.IsEmailAddressNull()) { recipientEmail = userrow.EmailAddress; } else if (TAppSettingsManager.HasValue("DataChecks.Email.Recipient.UserDomain")) { recipientEmail = userrow.FirstName + "." + userrow.LastName + "@" + TAppSettingsManager.GetValue( "DataChecks.Email.Recipient.UserDomain"); } else if (TAppSettingsManager.HasValue("DataChecks.Email.Recipient")) { recipientEmail = TAppSettingsManager.GetValue("DataChecks.Email.Recipient"); } if (recipientEmail.Length > 0) { new TSmtpSender().SendEmail("<" + TAppSettingsManager.GetValue("DataChecks.Email.Sender") + ">", "OpenPetra DataCheck Robot", recipientEmail, "Data Check for " + AUserId, "there are " + v.Count.ToString() + " errors. Please see attachment!", new string[] { excelfile }); } else { TLogging.Log("no email can be sent to " + AUserId); } }