GTB: - LowLevelTools: - password repair

This commit is contained in:
Thomas Wiedebusch 2025-09-30 09:51:37 +02:00
parent 1c42253f3b
commit cdffeb10a7

View File

@ -57,6 +57,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
private MeterResetPsu _meterResetPsu;
private Boolean _meterResetProcessActive;
private Boolean _rebootSucceeded;
private Boolean _repairPasswordEnabled;
private Boolean _tryConnectPcb;
@ -178,6 +179,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
tbxFileToEraseDrive.Enabled = false;
btnUploadPWFile.Enabled = false;
btnReadStatus.Enabled = false;
btnRepairPassword.Enabled = false;
}
/// <summary>
@ -203,6 +205,8 @@ namespace Xylem.Common.Ui.GenesisToolBox
tbxFileToEraseDrive.Enabled = true;
btnUploadPWFile.Enabled = true;
btnReadStatus.Enabled = true;
if (_repairPasswordEnabled)
btnRepairPassword.Enabled = true;
}
/// <summary>
@ -266,7 +270,6 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
return;
}
btnRepairPassword.Enabled = false;
lblOverall.Text = @"Login to Cordonel...";
lblActualProcess.Text = @"Establish data base connection...";
@ -292,7 +295,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
_meterBatch.MetersLogin();
var retValPwdBuild = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.PcbId, out var pwdContainer);
// CASE 1: - Passwords are generated in database but password file is not installed or doesn't work.
// - The production password is the SkeletonKey as the login succeeded.
//
@ -301,7 +304,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
// file needs to be enabled!
if (retValPwdBuild && _currentGenesis.IsLoggedOn && pwdContainer.Skeleton.Equals(pwdContainer.Password))
{
ShowPasswordRepairMessage(@"Password exists on database but the SkeletonKey is valid - Password repair enabled");
ShowPasswordRepairMessage(@"Password exists on database but the SkeletonKey is valid - [Repair Password] enabled");
}
if (!_currentGenesis.IsLoggedOn)
@ -310,15 +313,15 @@ namespace Xylem.Common.Ui.GenesisToolBox
Thread.Sleep(2000);
// Try to log in with password level 8 which may not be published to the database
var retVal = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last()));
// CASE 2: - Passwords are generated in database and correctly installed. The login check will be done
// with the generated password, but the production password is still on SkeletonKey.
// - The production password is the SkeletonKey as login succeeded.
// - The database update of the production password went wrong!
if (_currentGenesis.IsLoggedOn && retVal)
{
ShowPasswordRepairMessage(@"Password file is installed, login Lvl8 works, password in database not updated" +
"- use password repair");
ShowPasswordRepairMessage(@"Password file is installed as login Lvl8 works, password in database not updated" +
"- [Repair Password] enabled");
}
else
{
@ -332,7 +335,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
// CASE 3: - The production password didn't work, so the SkeletonKey will be tried.
if (_currentGenesis.Login(pwdContainer.Skeleton))
{
ShowPasswordRepairMessage(@"Successfully logged in with SkeletonKey - Password repair enabled");
ShowPasswordRepairMessage(@"Successfully logged in with SkeletonKey - [Repair Password] enabled");
}
else
{
@ -352,7 +355,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
var retExport = JsonConvert.DeserializeObject<List<PwdExport>>(retStr);
if (retExport.Count == 0)
{
sb.AppendLine(@"Export entry hasn't be found [E1]");
sb.AppendLine(@"Export entry hasn't been found [E1]");
//request
sb.AppendLine(@"Export returns no password [E2]");
}
@ -463,9 +466,9 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
LogText(msg);
MessageBox.Show(msg);
Invoke(new Action(() => { btnRepairPassword.Enabled = true; }));
_repairPasswordEnabled = true;
}
/// <summary>
/// Wait for reboot is completed by polling of PcbId
/// </summary>
@ -2043,88 +2046,129 @@ namespace Xylem.Common.Ui.GenesisToolBox
}
}
/// <summary>
/// Read status
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2025-Mar-15" author="Roland Drabesch">
/// - Initial
/// </remarks>
/// <remarks date="2025-Sep-29..30" author="Thomas Wiedebusch">
/// - Check if new password is in the meter with login level 8 even if the file write wasn't successful,
/// - Set new password in production database,
/// - Check password level 3 as all applications need to use this,
/// - Validate production password.
/// </remarks>
private void btnRepairPassword_Click(Object sender, EventArgs e)
{
if (_currentGenesis == null)
{
return;
}
// Reset timer
_startTime = DateTimeOffset.UtcNow;
LowLevelActionControl(true);
var ret = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.GetPcbId(), out var pwdContainer);
if (pwdContainer?.ListOfHashes == null || pwdContainer.ListOfPasswords == null || !ret)
var msg = "Repair password";
LogText(msg);
lblOverall.Text = msg;
Task.Factory.StartNew(() =>
{
LogText(@"Password file from server corrupted [M3]!");
// Request password file and force generation
SetActualProcessAndLog("Request password files from database");
var ret = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.GetPcbId(), out var pwdContainer);
if (pwdContainer?.ListOfHashes == null || pwdContainer.ListOfPasswords == null || !ret)
{
LogText(@"Password file from server corrupted [M3]!");
LowLevelActionControl(false);
return;
}
// Build password file
SetActualProcessAndLog("Build password file");
var _meterPwdFile = new MeterPwdFile(_currentGenesis);
var retValBol = _meterPwdFile.BuildPwdFile(pwdContainer.ListOfPasswords, 1, pwdContainer.Skeleton);
if (!retValBol)
{
LogText(@"Unable to build password file [M3]!");
LowLevelActionControl(false);
return;
}
// Install password file and verify byte wise
SetActualProcessAndLog("Install and verify password file into meter");
_currentGenesis.ReLogin();
retValBol = _meterPwdFile.UnlockEraseWriteMeterPwdFile();
retValBol &= _meterPwdFile.WriteMeterPwdFile() && _meterPwdFile.VerifyMeterPwdFile();
if (!retValBol)
{
LogText(@"Installed password file check failed [M4]!");
return;
}
// Check if new password is in the meter with login level 8 even if the file write wasn't successful
SetActualProcessAndLog("Validate Lvl8 password from password file");
_currentGenesis.Logout();
retValBol = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last()));
if (!retValBol)
{
LogText(@"Login with new password failed [M4]!");
return;
}
LogText(@"Password was successfully installed.");
// Set new password in production database
SetActualProcessAndLog("Replace SkeletonKey with Lvl8 password as production password in database");
retValBol = MeterPwdHandlerDb.SetPwdFromSkeletonToLvl8inDd(_currentGenesis.PcbId, pwdContainer);
if (!retValBol)
{
LogText(@"Update of production password in database failed [E3]!");
return;
}
LogText(@"Production password successfully updated in database");
// Check password level 3 as all applications need to use this
SetActualProcessAndLog("Validate Lv3 as SkeletonKey in meter");
retValBol = _currentGenesis.WriteRegister("SYSTEM_ExitReason", new Byte[] { 21 });
var exitResult = RegisterConverter.ByteArrayToValue<Int16>(_currentGenesis.ReadRegister("SYSTEM_ExitReason"));
if (exitResult != 0 || !retValBol)
{
LogText(@"Meter reports wrong SkeletonKey at Lvl3 [M4]!");
return;
}
LogText(@"Meter reports correct SkeletonKey at Lvl3.");
// Clear intermediate stored password to force password collection from DB on simple login without
// given new password. Then the password will be taken from the DB or offline file.
SetActualProcessAndLog("Crosscheck production password with meter password Lvl8");
_currentGenesis.Logout();
_currentGenesis.ClearPassword();
// If the password is not set (Meter.ClearPassword) the actual valid production password will be
// requested from the DB in the GenesisMeter Login() without parameter.
Thread.Sleep(1000);
// Validate production password
retValBol = _currentGenesis.Login();
if (!retValBol)
{
LogText(@"Invalid password in production database [E3]!");
return;
}
LogText(@"Password Lvl8 successfully validated with production database.");
_repairPasswordEnabled = false;
}).ContinueWith(delegate
{
//add a blank line to separate next operation
LogText("");
_currentGenesis.Logout();
LowLevelActionControl(false);
return;
}
// Build password file
var _meterPwdFile = new MeterPwdFile(_currentGenesis);
var retValBol = _meterPwdFile.BuildPwdFile(pwdContainer.ListOfPasswords, 1, pwdContainer.Skeleton);
if (!retValBol)
{
LogText(@"Unable to build password file [M3]!");
LowLevelActionControl(false);
return;
}
});
_currentGenesis.ReLogin();
retValBol = _meterPwdFile.UnlockEraseWriteMeterPwdFile();
retValBol &= _meterPwdFile.WriteMeterPwdFile() && _meterPwdFile.VerifyMeterPwdFile();
if (!retValBol)
{
LogText(@"Installed password file check failed [M4]!");
LowLevelActionControl(false);
return;
}
// Check if new password is in the meter with login level 8... even if the file write wasn't successful
_currentGenesis.Logout();
retValBol = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last()));
if (!retValBol)
{
LogText(@"Login with new password failed [M4]!");
LowLevelActionControl(false);
return;
}
LogText(@"Password was successfully installed.");
// set new password in production database
retValBol = MeterPwdHandlerDb.SetPwdFromSkeletonToLvl8inDd(_currentGenesis.PcbId, pwdContainer);
if (!retValBol)
{
LogText(@"Update of production password in database failed [E3]!");
LowLevelActionControl(false);
return;
}
LogText(@"Production password successfully updated in database");
// Check password level 3 as all applications need to use this
retValBol = _currentGenesis.WriteRegister("SYSTEM_ExitReason", new Byte[] { 21 });
var exitResult = RegisterConverter.ByteArrayToValue<Int16>(_currentGenesis.ReadRegister("SYSTEM_ExitReason"));
_currentGenesis.Logout();
if (exitResult != 0 || !retValBol)
{
LogText(@"Meter reports wrong SkeletonKey at Lvl3 [M4]!");
LowLevelActionControl(false);
return;
}
LogText(@"Meter reports correct SkeletonKey at Lvl3.");
// Clear intermediate stored password to force password collection from DB on simple login without
// given new password. Then the password will be taken from the DB or offline file.
_currentGenesis.ClearPassword();
// If the password is not set (Meter.ClearPassword) the actual valid production password will be
// requested from the DB in the GenesisMeter Login() without parameter.
Thread.Sleep(1000);
retValBol = _currentGenesis.Login();
if (!retValBol)
{
LogText(@"Invalid password in production database [E3]!");
LowLevelActionControl(true);
return;
}
LogText(@"Password Lvl8 successfully validated with production database.");
Invoke(new Action(() => { btnRepairPassword.Enabled = false; }));
LowLevelActionControl(false);
}
private void btnConnectSkeleton_Click(Object sender, EventArgs e)