Finalize Credentials Options Page

This commit finalizes the Credentials Options Page with the following changes:
- Updated and added comments to improve code readability and understanding.
- Enabled the password storing ability, making it functional but not yet usable.
- Applied some code optimizations for improved efficiency.
This commit is contained in:
xRushG
2024-06-11 09:44:20 +02:00
parent ca62502499
commit 9687ccd01d
6 changed files with 204 additions and 101 deletions

View File

@@ -3399,9 +3399,9 @@ namespace mRemoteNG.Resources.Language {
/// <summary>
/// Looks up a localized string similar to *Some settings are determined by your company. For further information, please contact your administrator.
/// </summary>
internal static string OptionsAdminInfo {
internal static string OptionsCompanyPolicyMessage {
get {
return ResourceManager.GetString("OptionsAdminInfo", resourceCulture);
return ResourceManager.GetString("OptionsCompanyPolicyMessage", resourceCulture);
}
}

View File

@@ -2047,7 +2047,7 @@ Nightly umfasst Alphas, Betas und Release Candidates.</value>
<value>Maximale Anmeldeversuche erreicht. Verbindung erneut initiieren.</value>
<comment>C# to Powershell transfer issue with encoding possible</comment>
</data>
<data name="OptionsAdminInfo" xml:space="preserve">
<data name="OptionsCompanyPolicyMessage" xml:space="preserve">
<value>*Einige Einstellungen werden von Ihrem Unternehmen festgelegt. Für weitere Informationen wenden Sie sich an Ihren Systemadministrator.</value>
</data>
</root>

View File

@@ -2365,7 +2365,7 @@ Nightly Channel includes Alphas, Betas &amp; Release Candidates.</value>
<data name="FilterSecureCRT" xml:space="preserve">
<value>SecureCRT (*.xml)</value>
</data>
<data name="OptionsAdminInfo" xml:space="preserve">
<data name="OptionsCompanyPolicyMessage" xml:space="preserve">
<value>*Some settings are determined by your company. For further information, please contact your administrator</value>
</data>
</root>

View File

@@ -43,7 +43,7 @@
lblCredentialsDomain = new Controls.MrngLabel();
radCredentialsNoInfo = new Controls.MrngRadioButton();
radCredentialsCustom = new Controls.MrngRadioButton();
lblCredentialsAdminInfo = new System.Windows.Forms.Label();
lblRegistrySettingsUsedInfo = new System.Windows.Forms.Label();
lblCredentialsGeneratorHelp = new Controls.MrngLabel();
btnCredentialsGenerator = new System.Windows.Forms.Button();
lblCredentialsGenerator = new Controls.MrngLabel();
@@ -56,7 +56,7 @@
// pnlDefaultCredentials
//
pnlDefaultCredentials.Controls.Add(pnlCredentialsSettingsPanel);
pnlDefaultCredentials.Controls.Add(lblCredentialsAdminInfo);
pnlDefaultCredentials.Controls.Add(lblRegistrySettingsUsedInfo);
pnlDefaultCredentials.Dock = System.Windows.Forms.DockStyle.Top;
pnlDefaultCredentials.Location = new System.Drawing.Point(0, 0);
pnlDefaultCredentials.Name = "pnlDefaultCredentials";
@@ -149,6 +149,7 @@
txtCredentialsPassword.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
txtCredentialsPassword.Location = new System.Drawing.Point(163, 55);
txtCredentialsPassword.Name = "txtCredentialsPassword";
txtCredentialsPassword.PasswordChar = '*';
txtCredentialsPassword.Size = new System.Drawing.Size(166, 22);
txtCredentialsPassword.TabIndex = 7;
//
@@ -232,18 +233,18 @@
radCredentialsCustom.UseVisualStyleBackColor = false;
radCredentialsCustom.CheckedChanged += radCredentialsCustom_CheckedChanged;
//
// lblCredentialsAdminInfo
// lblRegistrySettingsUsedInfo
//
lblCredentialsAdminInfo.BackColor = System.Drawing.SystemColors.ControlLight;
lblCredentialsAdminInfo.Dock = System.Windows.Forms.DockStyle.Top;
lblCredentialsAdminInfo.ForeColor = System.Drawing.SystemColors.ControlText;
lblCredentialsAdminInfo.Location = new System.Drawing.Point(0, 0);
lblCredentialsAdminInfo.Name = "lblCredentialsAdminInfo";
lblCredentialsAdminInfo.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
lblCredentialsAdminInfo.Size = new System.Drawing.Size(610, 30);
lblCredentialsAdminInfo.TabIndex = 0;
lblCredentialsAdminInfo.Text = "Some settings are configured by your Administrator. Please contact your administrator for more information.";
lblCredentialsAdminInfo.Visible = false;
lblRegistrySettingsUsedInfo.BackColor = System.Drawing.SystemColors.ControlLight;
lblRegistrySettingsUsedInfo.Dock = System.Windows.Forms.DockStyle.Top;
lblRegistrySettingsUsedInfo.ForeColor = System.Drawing.SystemColors.ControlText;
lblRegistrySettingsUsedInfo.Location = new System.Drawing.Point(0, 0);
lblRegistrySettingsUsedInfo.Name = "lblRegistrySettingsUsedInfo";
lblRegistrySettingsUsedInfo.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
lblRegistrySettingsUsedInfo.Size = new System.Drawing.Size(610, 30);
lblRegistrySettingsUsedInfo.TabIndex = 0;
lblRegistrySettingsUsedInfo.Text = "Some settings are configured by your Administrator. Please contact your administrator for more information.";
lblRegistrySettingsUsedInfo.Visible = false;
//
// lblCredentialsGeneratorHelp
//
@@ -304,7 +305,7 @@
internal Controls.MrngTextBox txtCredentialsUsername;
internal Controls.MrngLabel lblCredentialsDomain;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
internal System.Windows.Forms.Label lblCredentialsAdminInfo;
internal System.Windows.Forms.Label lblRegistrySettingsUsedInfo;
internal System.Windows.Forms.Panel pnlCredentialsSettingsPanel;
internal Controls.MrngLabel lblCredentialsGenerator;
internal System.Windows.Forms.TextBox txtCredentialsGeneratorPsswd;

View File

@@ -5,6 +5,7 @@ using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
using mRemoteNG.Config.Settings.Registry;
using System.DirectoryServices;
namespace mRemoteNG.UI.Forms.OptionsPages
{
@@ -13,8 +14,6 @@ namespace mRemoteNG.UI.Forms.OptionsPages
{
#region Private Fields
private readonly OptRegistryCredentialsPage _RegistrySettings = new();
private bool _pageEnabled = true;
#endregion
public CredentialsPage()
@@ -40,12 +39,13 @@ namespace mRemoteNG.UI.Forms.OptionsPages
lblCredentialsUsername.Text = Language.Username;
lblCredentialsPassword.Text = Language.Password;
lblCredentialsDomain.Text = Language.Domain;
lblCredentialsAdminInfo.Text = Language.OptionsAdminInfo;
lblRegistrySettingsUsedInfo.Text = Language.OptionsCompanyPolicyMessage;
}
public override void LoadSettings()
{
if (!_pageEnabled) { return; }
if (!_RegistrySettings.CredentialPageEnabled)
return;
// ReSharper disable once SwitchStatementMissingSomeCases
switch (Properties.OptionsCredentialsPage.Default.EmptyCredentials)
@@ -92,13 +92,19 @@ namespace mRemoteNG.UI.Forms.OptionsPages
public override void LoadRegistrySettings()
{
if (!CommonRegistrySettings.AllowModifyCredentialSettings)
// CredentialPageEnabled reg setting: enabled/default: true; Disabled: false.
if (!_RegistrySettings.CredentialPageEnabled)
{
DisablePage();
return;
}
if (_RegistrySettings.UseCredentials.IsKeyPresent)
// UseCredentials reg setting with validation:
// 1. Is not set or valid, stop processing.
// 2. Set the 'EmptyCredentials' option based on value
// 3. Only proceed when "custom"
if (!_RegistrySettings.UseCredentials.IsValid) { return; }
else if (_RegistrySettings.UseCredentials.IsValid)
{
Properties.OptionsCredentialsPage.Default.EmptyCredentials = _RegistrySettings.UseCredentials.Value;
@@ -107,11 +113,13 @@ namespace mRemoteNG.UI.Forms.OptionsPages
case "noinfo":
DisableControl(radCredentialsWindows);
DisableControl(radCredentialsCustom);
break;
SetVisibilitySettingsUsedInfo();
return;
case "windows":
DisableControl(radCredentialsNoInfo);
DisableControl(radCredentialsCustom);
break;
SetVisibilitySettingsUsedInfo();
return;
case "custom":
DisableControl(radCredentialsNoInfo);
DisableControl(radCredentialsWindows);
@@ -119,95 +127,87 @@ namespace mRemoteNG.UI.Forms.OptionsPages
}
}
if (_RegistrySettings.UseCredentials.Value != "custom") { return; }
// ***
// The following is only used when set to custom!
if (!CommonRegistrySettings.AllowSaveUsernames)
{
Properties.OptionsCredentialsPage.Default.DefaultUsername = "";
DisableControl(txtCredentialsUsername);
}
else if (_RegistrySettings.DefaultUsername.IsKeyPresent)
// DefaultUsername reg setting: set DefaultUsername option based on value
if (_RegistrySettings.DefaultUsername.IsSet)
{
Properties.OptionsCredentialsPage.Default.DefaultUsername = _RegistrySettings.DefaultUsername.Value;
DisableControl(txtCredentialsUsername);
}
if (!CommonRegistrySettings.AllowSavePasswords)
// DefaultPassword reg setting:
// 1. Test decription works to prevents potential issues
// 2. Set DefaultPassword option based on value
// 3. Clears reg setting if fails
if (_RegistrySettings.DefaultPassword.IsSet)
{
Properties.OptionsCredentialsPage.Default.DefaultPassword = "";
try
{
LegacyRijndaelCryptographyProvider cryptographyProvider = new();
string decryptedPassword;
string defaultPassword = _RegistrySettings.DefaultPassword.Value;
decryptedPassword = cryptographyProvider.Decrypt(defaultPassword, Runtime.EncryptionKey);
Properties.OptionsCredentialsPage.Default.DefaultPassword = defaultPassword;
DisableControl(txtCredentialsPassword);
}
//else if (_RegistrySettings.DefaultPassword.IsKeyPresent)
//{
// Properties.OptionsCredentialsPage.Default.DefaultPassword = _RegistrySettings.DefaultPassword.Value;
// DisableControl(txtCredentialsPassword);
//}
catch
{
// Fire-and-forget: The DefaultPassword in the registry is not encrypted.
_RegistrySettings.DefaultPassword.Clear();
}
}
if (_RegistrySettings.DefaultDomain.IsKeyPresent)
// DefaultDomain reg setting: set DefaultDomain option based on value
if (_RegistrySettings.DefaultDomain.IsSet)
{
Properties.OptionsCredentialsPage.Default.DefaultDomain = _RegistrySettings.DefaultDomain.Value;
DisableControl(txtCredentialsDomain);
}
if (!CommonRegistrySettings.AllowSaveUsernames)
{
Properties.OptionsCredentialsPage.Default.UserViaAPIDefault = "";
DisableControl(txtCredentialsUserViaAPI);
}
else if (_RegistrySettings.UserViaAPIDefault.IsKeyPresent)
// UserViaAPIDefault reg setting: set UserViaAPIDefault option based on value
if (_RegistrySettings.UserViaAPIDefault.IsSet)
{
Properties.OptionsCredentialsPage.Default.UserViaAPIDefault = _RegistrySettings.UserViaAPIDefault.Value;
DisableControl(txtCredentialsUserViaAPI);
}
lblCredentialsAdminInfo.Visible = ShowAdministratorInfo();
SetVisibilitySettingsUsedInfo();
}
public override bool ShowAdministratorInfo()
/// <summary>
/// Checks if any credantil registry settings are being used.
/// </summary>
/// <returns>
/// True if any relevant registry settings are used; otherwise, false.
/// </returns>
public override bool ShowRegistrySettingsUsedInfo()
{
return !CommonRegistrySettings.AllowModifyCredentialSettings
|| !CommonRegistrySettings.AllowExportPasswords
return !CommonRegistrySettings.AllowExportPasswords
|| !CommonRegistrySettings.AllowExportUsernames
|| !CommonRegistrySettings.AllowSavePasswords
|| !CommonRegistrySettings.AllowSaveUsernames
|| _RegistrySettings.DefaultUsername.IsKeyPresent
//|| _RegistrySettings.DefaultPassword.IsKeyPresent
|| _RegistrySettings.DefaultDomain.IsKeyPresent
|| _RegistrySettings.UserViaAPIDefault.IsKeyPresent;
}
private void radCredentialsCustom_CheckedChanged(object sender, EventArgs e)
{
if (!_RegistrySettings.DefaultUsername.IsKeyPresent && CommonRegistrySettings.AllowSaveUsernames)
{
lblCredentialsUsername.Enabled = radCredentialsCustom.Checked;
txtCredentialsUsername.Enabled = radCredentialsCustom.Checked;
}
if (/*!_RegistrySettings.DefaultPassword.IsKeyPresent &&*/ CommonRegistrySettings.AllowSavePasswords)
{
lblCredentialsPassword.Enabled = radCredentialsCustom.Checked;
txtCredentialsPassword.Enabled = radCredentialsCustom.Checked;
}
if (!_RegistrySettings.DefaultDomain.IsKeyPresent)
{
lblCredentialsDomain.Enabled = radCredentialsCustom.Checked;
txtCredentialsDomain.Enabled = radCredentialsCustom.Checked;
}
if (!_RegistrySettings.UserViaAPIDefault.IsKeyPresent)
{
lblCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
txtCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
}
|| !_RegistrySettings.CredentialPageEnabled
|| _RegistrySettings.UseCredentials.IsValid;
/*
* Checking these values is unnecessary because UseCredentials must be valid and set to Custom.
*
||_RegistrySettings.DefaultUsername.IsSet
|| _RegistrySettings.DefaultPassword.IsSet
|| _RegistrySettings.DefaultDomain.IsSet
|| _RegistrySettings.UserViaAPIDefault.IsSet;
*/
}
/// <summary>
/// Disables the page by setting default values and disabling controls.
/// </summary>
public override void DisablePage()
{
Properties.OptionsCredentialsPage.Default.EmptyCredentials = "noinfo";
//radCredentialsNoInfo.Enabled = false;
radCredentialsWindows.Enabled = false;
radCredentialsCustom.Enabled = false;
@@ -216,8 +216,50 @@ namespace mRemoteNG.UI.Forms.OptionsPages
txtCredentialsDomain.Enabled = false;
txtCredentialsUserViaAPI.Enabled = false;
lblCredentialsAdminInfo.Visible = true;
_pageEnabled = false;
SetVisibilitySettingsUsedInfo();
}
#region Event Handlers
private void radCredentialsCustom_CheckedChanged(object sender, EventArgs e)
{
if (!_RegistrySettings.DefaultUsername.IsSet && CommonRegistrySettings.AllowSaveUsernames)
{
lblCredentialsUsername.Enabled = radCredentialsCustom.Checked;
txtCredentialsUsername.Enabled = radCredentialsCustom.Checked;
}
if (!_RegistrySettings.DefaultPassword.IsSet && CommonRegistrySettings.AllowSavePasswords)
{
lblCredentialsPassword.Enabled = radCredentialsCustom.Checked;
txtCredentialsPassword.Enabled = radCredentialsCustom.Checked;
}
if (!_RegistrySettings.DefaultDomain.IsSet)
{
lblCredentialsDomain.Enabled = radCredentialsCustom.Checked;
txtCredentialsDomain.Enabled = radCredentialsCustom.Checked;
}
if (!_RegistrySettings.UserViaAPIDefault.IsSet && CommonRegistrySettings.AllowSaveUsernames)
{
lblCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
txtCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
}
}
#endregion
#region Private Methods
/// <summary>
/// Updates the visibility of the information label indicating whether registry settings are used.
/// </summary>
private void SetVisibilitySettingsUsedInfo()
{
lblRegistrySettingsUsedInfo.Visible = ShowRegistrySettingsUsedInfo();
}
#endregion
}
}

View File

@@ -1,4 +1,64 @@
<root>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">