Master password change can silently fail to save: root node raises no PropertyChanged, and default SaveConnectionsFrequency skips the exit save
Summary
Setting or clearing the connection file's master password ("Password Protect" on the root node) can fail to reach disk with no indication to the user. Two independent gaps combine: the root node's password properties raise no PropertyChanged, so the save-on-edit path never fires; and on a default profile SaveConnectionsFrequency is Unassigned, so the shutdown path returns without saving either.
The consequence is security-relevant rather than merely inconvenient. A user who sets a master password and closes mRemoteNG can be left with a connection file still encrypted under the built-in mR3m constant, while the UI gave every indication the change was applied.
This is from reading the code on v1.78.2-dev, not from a runtime repro — flagging that up front so it can be confirmed before anyone acts on it.
Cause 1 — root node password properties raise no change notification
RootNodeInfo declares Password as a plain auto-property that hides the base implementation:
https://github.com/mRemoteNG/mRemoteNG/blob/v1.78.2-dev/mRemoteNG/Tree/Root/RootNodeInfo.cs#L41
public new bool Password { get; set; }The hidden base property does notify (mRemoteNG/Connection/AbstractConnectionRecord.cs:260-263):
public virtual string Password
{
get => GetPropertyValue("Password", _password);
set => SetField(ref _password, value, "Password");
}PasswordString / _customPassword (RootNodeInfo.cs:44-52) likewise assign fields directly and raise nothing.
So editing the master password raises no PropertyChanged on the tree model, and SaveConnectionsOnEdit never runs:
Ordinary edits are unaffected — SaveConnectionsAfterEveryEdit defaults to True and drives that path normally. The master password change simply never reaches it.
Cause 2 — default settings produce no save on exit
SaveConnectionsFrequency defaults to 0, which is ConnectionsBackupFrequencyEnum.Unassigned (mRemoteNG/Properties/OptionsBackupPage.settings:17-19). Shutdown.SaveConnections has no case for it:
https://github.com/mRemoteNG/mRemoteNG/blob/v1.78.2-dev/mRemoteNG/App/Shutdown.cs#L64-L93
switch (Properties.OptionsBackupPage.Default.SaveConnectionsFrequency)
{
case (int)ConnectionsBackupFrequencyEnum.Daily: ...
case (int)ConnectionsBackupFrequencyEnum.Weekly: ...
default:
return; // Unassigned lands here — no save
}The migration off Unassigned runs only when the options page is loaded:
so a profile where the user has never opened Tools → Options → Connections stays at Unassigned indefinitely. Note also that the legacy SaveConsOnExit setting still defaults to True but is no longer consulted at shutdown — only that migration reads it. A user who has that box ticked reasonably expects an exit save and does not get one.
Steps to reproduce (expected, unverified)
On a profile that has never opened Tools → Options → Connections:
- Set a master password on the connection file via the root node's "Password Protect" property.
- File → Save Connections.
- Close mRemoteNG.
- Reopen — the password is not in effect, and
confCons.xmlis still readable under the default key.
Suggested fix
- Make
RootNodeInfo.PasswordandPasswordStringraisePropertyChangedlike every other connection property, rather than hiding the notifying base member with silent auto-properties. - Give
Shutdown.SaveConnectionsa defined behaviour forUnassigned— treating it asOnExitmatches the legacySaveConsOnExitdefault and preserves the user's existing expectation.
More broadly, SaveConnectionsFrequency governs how often to save periodically; it should not be able to decide whether an edit the user has already made is written at all.
Related, lower severity
SaveConnectionsOnEdit.cs:52 drops any edit made while the main form is closing:
if (FrmMain.Default.IsClosing)
return;With cause 2 in play there is then no exit save to catch it. Separate from the above, but the same class of silent loss.
Environment
- Branch:
v1.78.2-dev(atc6018d9d) - Windows 11 Pro 23H2
Source: mRemoteNG/mRemoteNG