From 3522e2980d187837634bc045257e4ce73bc7dee3 Mon Sep 17 00:00:00 2001 From: Frezzle Date: Wed, 12 Oct 2016 19:09:35 +0100 Subject: [PATCH 1/2] [CP-19111] Added ability to choose Basic or Digest authentication for proxy server 2 new radio buttons in Connection Options page, for Basic and Digest; Digest is the default as it's the most secure. New proxy authentication method setting, which is used to configure XenAPI's HTTP class and the .NET AuthenticationManager (which handles which authentication schemes can be used by the .NET web classes). The new setting is also transferred and used by the Health Check service. The bug noted in CA-214653 also occurs here, but the work-around on PR#1201 for that bug will also work for this. Signed-off-by: Frezzle --- .../ConnectionOptionsPage.Designer.cs | 54 +++++- .../OptionsPages/ConnectionOptionsPage.cs | 74 ++++++-- .../OptionsPages/ConnectionOptionsPage.resx | 159 ++++++++++++++++-- XenAdmin/MainWindow.cs | 20 ++- XenAdmin/Program.cs | 60 ++++++- XenAdmin/Properties/Settings.Designer.cs | 12 ++ XenAdmin/Properties/Settings.settings | 3 + XenAdmin/app.config | 3 + .../TransferProxySettingsAction.cs | 7 +- XenModel/Network/HTTPHelper.cs | 7 + XenModel/XenAPI/HTTP.cs | 20 ++- .../Properties/Settings.Designer.cs | 12 ++ .../Properties/Settings.settings | 3 + XenServerHealthCheck/ServerListHelper.cs | 1 + .../XenServerHealthCheckService.cs | 2 + XenServerHealthCheck/app.config | 3 + 16 files changed, 385 insertions(+), 55 deletions(-) diff --git a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs index a0e3664ff..8dd682977 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs @@ -52,12 +52,17 @@ namespace XenAdmin.Dialogs.OptionsPages this.ProxyAddressTextBox = new System.Windows.Forms.TextBox(); this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); this.ProxyPortLabel = new System.Windows.Forms.Label(); + this.AuthenticationMethodLabel = new System.Windows.Forms.Label(); + this.AuthenticationMethodPanel = new System.Windows.Forms.Panel(); + this.DigestRadioButton = new System.Windows.Forms.RadioButton(); + this.BasicRadioButton = new System.Windows.Forms.RadioButton(); this.ConnectionTableLayoutPanel.SuspendLayout(); this.TimeoutGroupBox.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.ConnectionTimeoutNud)).BeginInit(); this.ProxyGroupBox.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); + this.AuthenticationMethodPanel.SuspendLayout(); this.SuspendLayout(); // // ConnectionTableLayoutPanel @@ -135,18 +140,20 @@ namespace XenAdmin.Dialogs.OptionsPages // resources.ApplyResources(this.tableLayoutPanel1, "tableLayoutPanel1"); this.tableLayoutPanel1.Controls.Add(this.BypassForServersCheckbox, 1, 4); - this.tableLayoutPanel1.Controls.Add(this.ProxyPasswordTextBox, 6, 6); + this.tableLayoutPanel1.Controls.Add(this.ProxyPasswordTextBox, 7, 6); this.tableLayoutPanel1.Controls.Add(this.ProxyUsernameLabel, 2, 6); - this.tableLayoutPanel1.Controls.Add(this.ProxyUsernameTextBox, 4, 6); - this.tableLayoutPanel1.Controls.Add(this.ProxyPasswordLabel, 5, 6); + this.tableLayoutPanel1.Controls.Add(this.ProxyUsernameTextBox, 3, 6); + this.tableLayoutPanel1.Controls.Add(this.ProxyPasswordLabel, 6, 6); this.tableLayoutPanel1.Controls.Add(this.AuthenticationCheckBox, 1, 5); this.tableLayoutPanel1.Controls.Add(this.ProxyAddressLabel, 1, 3); this.tableLayoutPanel1.Controls.Add(this.UseProxyRadioButton, 0, 2); this.tableLayoutPanel1.Controls.Add(this.DirectConnectionRadioButton, 0, 0); this.tableLayoutPanel1.Controls.Add(this.UseIERadioButton, 0, 1); this.tableLayoutPanel1.Controls.Add(this.ProxyAddressTextBox, 3, 3); - this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 5, 3); - this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 4, 3); + this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 7, 3); + this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 6, 3); + this.tableLayoutPanel1.Controls.Add(this.AuthenticationMethodLabel, 2, 8); + this.tableLayoutPanel1.Controls.Add(this.AuthenticationMethodPanel, 5, 8); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; // // BypassForServersCheckbox @@ -172,6 +179,7 @@ namespace XenAdmin.Dialogs.OptionsPages // // ProxyUsernameTextBox // + this.tableLayoutPanel1.SetColumnSpan(this.ProxyUsernameTextBox, 2); resources.ApplyResources(this.ProxyUsernameTextBox, "ProxyUsernameTextBox"); this.ProxyUsernameTextBox.Name = "ProxyUsernameTextBox"; this.ProxyUsernameTextBox.TextChanged += new System.EventHandler(this.ProxyUsernameTextBox_TextChanged); @@ -222,7 +230,7 @@ namespace XenAdmin.Dialogs.OptionsPages // // ProxyAddressTextBox // - this.tableLayoutPanel1.SetColumnSpan(this.ProxyAddressTextBox, 2); + this.tableLayoutPanel1.SetColumnSpan(this.ProxyAddressTextBox, 3); resources.ApplyResources(this.ProxyAddressTextBox, "ProxyAddressTextBox"); this.ProxyAddressTextBox.Name = "ProxyAddressTextBox"; this.ProxyAddressTextBox.TextChanged += new System.EventHandler(this.ProxyAddressTextBox_TextChanged); @@ -238,6 +246,34 @@ namespace XenAdmin.Dialogs.OptionsPages resources.ApplyResources(this.ProxyPortLabel, "ProxyPortLabel"); this.ProxyPortLabel.Name = "ProxyPortLabel"; // + // AuthenticationMethodLabel + // + resources.ApplyResources(this.AuthenticationMethodLabel, "AuthenticationMethodLabel"); + this.tableLayoutPanel1.SetColumnSpan(this.AuthenticationMethodLabel, 3); + this.AuthenticationMethodLabel.Name = "AuthenticationMethodLabel"; + // + // AuthenticationMethodPanel + // + this.tableLayoutPanel1.SetColumnSpan(this.AuthenticationMethodPanel, 2); + this.AuthenticationMethodPanel.Controls.Add(this.DigestRadioButton); + this.AuthenticationMethodPanel.Controls.Add(this.BasicRadioButton); + resources.ApplyResources(this.AuthenticationMethodPanel, "AuthenticationMethodPanel"); + this.AuthenticationMethodPanel.Name = "AuthenticationMethodPanel"; + // + // DigestRadioButton + // + resources.ApplyResources(this.DigestRadioButton, "DigestRadioButton"); + this.DigestRadioButton.Name = "DigestRadioButton"; + this.DigestRadioButton.UseVisualStyleBackColor = true; + this.DigestRadioButton.CheckedChanged += new System.EventHandler(this.DigestRadioButton_CheckedChanged); + // + // BasicRadioButton + // + resources.ApplyResources(this.BasicRadioButton, "BasicRadioButton"); + this.BasicRadioButton.Name = "BasicRadioButton"; + this.BasicRadioButton.UseVisualStyleBackColor = true; + this.BasicRadioButton.CheckedChanged += new System.EventHandler(this.BasicRadioButton_CheckedChanged); + // // ConnectionOptionsPage // resources.ApplyResources(this, "$this"); @@ -255,6 +291,8 @@ namespace XenAdmin.Dialogs.OptionsPages this.ProxyGroupBox.PerformLayout(); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); + this.AuthenticationMethodPanel.ResumeLayout(false); + this.AuthenticationMethodPanel.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -285,5 +323,9 @@ namespace XenAdmin.Dialogs.OptionsPages private System.Windows.Forms.Label ProxyUsernameLabel; private System.Windows.Forms.TextBox ProxyUsernameTextBox; private System.Windows.Forms.Label ProxyPasswordLabel; + private System.Windows.Forms.RadioButton BasicRadioButton; + private System.Windows.Forms.Label AuthenticationMethodLabel; + private System.Windows.Forms.RadioButton DigestRadioButton; + private System.Windows.Forms.Panel AuthenticationMethodPanel; } } diff --git a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs index 6f77155c2..0382caace 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs @@ -30,16 +30,11 @@ */ using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Drawing; -using System.Data; -using System.Text; using System.Windows.Forms; using XenAdmin.Properties; using XenAdmin.Actions; using XenAPI; -using System.Text.RegularExpressions; using XenAdmin.Core; @@ -69,15 +64,15 @@ namespace XenAdmin.Dialogs.OptionsPages private void build() { // Proxy server - switch (Properties.Settings.Default.ProxySetting) + switch ((HTTPHelper.ProxyStyle)Properties.Settings.Default.ProxySetting) { - case 0: + case HTTPHelper.ProxyStyle.DirectConnection: DirectConnectionRadioButton.Checked = true; break; - case 1: + case HTTPHelper.ProxyStyle.SystemProxy: UseIERadioButton.Checked = true; break; - case 2: + case HTTPHelper.ProxyStyle.SpecifiedProxy: UseProxyRadioButton.Checked = true; break; default: @@ -92,6 +87,19 @@ namespace XenAdmin.Dialogs.OptionsPages if (Registry.ProxyAuthenticationEnabled) { AuthenticationCheckBox.Checked = Properties.Settings.Default.ProvideProxyAuthentication; + + switch ((HTTPHelper.ProxyAuthenticationMethod)Properties.Settings.Default.ProxyAuthenticationMethod) + { + case HTTPHelper.ProxyAuthenticationMethod.Basic: + BasicRadioButton.Checked = true; + break; + case HTTPHelper.ProxyAuthenticationMethod.Digest: + DigestRadioButton.Checked = true; + break; + default: + DigestRadioButton.Checked = true; + break; + } // checks for empty default username/password which starts out unencrypted string protectedUsername = Properties.Settings.Default.ProxyUsername; @@ -107,6 +115,8 @@ namespace XenAdmin.Dialogs.OptionsPages ProxyUsernameTextBox.Visible = false; ProxyPasswordLabel.Visible = false; ProxyPasswordTextBox.Visible = false; + AuthenticationMethodPanel.Visible = false; + AuthenticationMethodLabel.Visible = false; } ConnectionTimeoutNud.Value = Properties.Settings.Default.ConnectionTimeout / 1000; @@ -191,6 +201,26 @@ namespace XenAdmin.Dialogs.OptionsPages enableOK(); } + private void BasicRadioButton_CheckedChanged(object sender, EventArgs e) + { + if (eventsDisabled) + return; + + SelectProvideCredentials(); + + enableOK(); + } + + private void DigestRadioButton_CheckedChanged(object sender, EventArgs e) + { + if (eventsDisabled) + return; + + SelectProvideCredentials(); + + enableOK(); + } + private void SelectUseThisProxyServer() { UseProxyRadioButton.Checked = true; @@ -246,6 +276,7 @@ namespace XenAdmin.Dialogs.OptionsPages log.Info("=== ProxyPort: " + Properties.Settings.Default.ProxyPort.ToString()); log.Info("=== ByPassProxyForServers: " + Properties.Settings.Default.BypassProxyForServers.ToString()); log.Info("=== ProvideProxyAuthentication: " + Properties.Settings.Default.ProvideProxyAuthentication.ToString()); + log.Info("=== ProxyAuthenticationMethod: " + Properties.Settings.Default.ProxyAuthenticationMethod.ToString()); log.Info("=== ConnectionTimeout: " + Properties.Settings.Default.ConnectionTimeout.ToString()); } @@ -270,6 +301,11 @@ namespace XenAdmin.Dialogs.OptionsPages Properties.Settings.Default.ProxyUsername = EncryptionUtils.Protect(ProxyUsernameTextBox.Text); Properties.Settings.Default.ProxyPassword = EncryptionUtils.Protect(ProxyPasswordTextBox.Text); Properties.Settings.Default.ProvideProxyAuthentication = AuthenticationCheckBox.Checked; + + HTTPHelper.ProxyAuthenticationMethod new_auth_method = BasicRadioButton.Checked ? + HTTPHelper.ProxyAuthenticationMethod.Basic : HTTPHelper.ProxyAuthenticationMethod.Digest; + if (Properties.Settings.Default.ProxyAuthenticationMethod != (int)new_auth_method) + Properties.Settings.Default.ProxyAuthenticationMethod = (int)new_auth_method; } try @@ -294,15 +330,17 @@ namespace XenAdmin.Dialogs.OptionsPages } Program.ReconfigureConnectionSettings(); - new TransferProxySettingsAction((HTTPHelper.ProxyStyle)Properties.Settings.Default.ProxySetting, - Properties.Settings.Default.ProxyAddress, - Properties.Settings.Default.ProxyPort, - Properties.Settings.Default.ConnectionTimeout, - false, - Properties.Settings.Default.BypassProxyForServers, - Properties.Settings.Default.ProvideProxyAuthentication, - Properties.Settings.Default.ProxyUsername, - Properties.Settings.Default.ProxyPassword).RunAsync(); + new TransferProxySettingsAction( + (HTTPHelper.ProxyStyle)Properties.Settings.Default.ProxySetting, + Properties.Settings.Default.ProxyAddress, + Properties.Settings.Default.ProxyPort, + Properties.Settings.Default.ConnectionTimeout, + false, + Properties.Settings.Default.BypassProxyForServers, + Properties.Settings.Default.ProvideProxyAuthentication, + Properties.Settings.Default.ProxyUsername, + Properties.Settings.Default.ProxyPassword, + (HTTPHelper.ProxyAuthenticationMethod)Properties.Settings.Default.ProxyAuthenticationMethod).RunAsync(); } #endregion diff --git a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.resx b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.resx index 72ce4bea8..f086030f4 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.resx +++ b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.resx @@ -319,7 +319,7 @@ Tahoma, 8pt - 3, 241 + 3, 267 3, 3, 3, 0 @@ -403,13 +403,13 @@ Tahoma, 8pt - 355, 139 + 365, 139 0, 3, 3, 0 - 140, 20 + 137, 20 13 @@ -475,13 +475,13 @@ Tahoma, 8pt - 99, 139 + 105, 139 0, 3, 3, 0 - 193, 20 + 192, 20 11 @@ -511,7 +511,7 @@ NoControl - 298, 136 + 308, 136 3, 0, 0, 0 @@ -598,7 +598,7 @@ 0, 0, 0, 0 - 50, 23 + 55, 23 3 @@ -727,7 +727,7 @@ Tahoma, 8pt - 70, 72 + 75, 72 0, 3, 3, 0 @@ -757,7 +757,7 @@ Tahoma, 8pt - 355, 72 + 365, 72 0, 3, 3, 0 @@ -766,7 +766,7 @@ 5 - 140, 20 + 137, 20 6 @@ -796,7 +796,7 @@ NoControl - 324, 74 + 334, 74 3, 0, 0, 0 @@ -825,14 +825,143 @@ 12 + + True + + + Tahoma, 8pt + + + NoControl + + + 40, 159 + + + 0, 0, 0, 0 + + + 0, 5, 0, 0 + + + 120, 18 + + + 14 + + + Authentication method: + + + MiddleLeft + + + AuthenticationMethodLabel + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 13 + + + True + + + Tahoma, 8pt + + + NoControl + + + 60, 0 + + + 55, 17 + + + 17 + + + Di&gest + + + DigestRadioButton + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + AuthenticationMethodPanel + + + 0 + + + True + + + Tahoma, 8pt + + + NoControl + + + 0, 0 + + + 49, 17 + + + 16 + + + Ba&sic + + + BasicRadioButton + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + AuthenticationMethodPanel + + + 1 + + + 183, 162 + + + 122, 20 + + + 15 + + + AuthenticationMethodPanel + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 14 + 12, 19 - 7 + 9 - 498, 159 + 505, 185 8 @@ -850,7 +979,7 @@ 0 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="BypassForServersCheckbox" Row="4" RowSpan="1" Column="1" ColumnSpan="6" /><Control Name="ProxyPasswordTextBox" Row="6" RowSpan="1" Column="6" ColumnSpan="1" /><Control Name="ProxyUsernameLabel" Row="6" RowSpan="1" Column="2" ColumnSpan="2" /><Control Name="ProxyUsernameTextBox" Row="6" RowSpan="1" Column="4" ColumnSpan="1" /><Control Name="ProxyPasswordLabel" Row="6" RowSpan="1" Column="5" ColumnSpan="1" /><Control Name="AuthenticationCheckBox" Row="5" RowSpan="1" Column="1" ColumnSpan="6" /><Control Name="ProxyAddressLabel" Row="3" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="UseProxyRadioButton" Row="2" RowSpan="1" Column="0" ColumnSpan="6" /><Control Name="DirectConnectionRadioButton" Row="0" RowSpan="1" Column="0" ColumnSpan="6" /><Control Name="UseIERadioButton" Row="1" RowSpan="1" Column="0" ColumnSpan="6" /><Control Name="ProxyAddressTextBox" Row="3" RowSpan="1" Column="3" ColumnSpan="2" /><Control Name="ProxyPortTextBox" Row="3" RowSpan="1" Column="5" ColumnSpan="1" /><Control Name="ProxyPortLabel" Row="3" RowSpan="1" Column="4" ColumnSpan="1" /></Controls><Columns Styles="Absolute,20,Absolute,20,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="BypassForServersCheckbox" Row="4" RowSpan="1" Column="1" ColumnSpan="6" /><Control Name="ProxyPasswordTextBox" Row="6" RowSpan="1" Column="7" ColumnSpan="1" /><Control Name="ProxyUsernameLabel" Row="6" RowSpan="1" Column="2" ColumnSpan="2" /><Control Name="ProxyUsernameTextBox" Row="6" RowSpan="1" Column="3" ColumnSpan="2" /><Control Name="ProxyPasswordLabel" Row="6" RowSpan="1" Column="6" ColumnSpan="1" /><Control Name="AuthenticationCheckBox" Row="5" RowSpan="1" Column="1" ColumnSpan="6" /><Control Name="ProxyAddressLabel" Row="3" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="UseProxyRadioButton" Row="2" RowSpan="1" Column="0" ColumnSpan="6" /><Control Name="DirectConnectionRadioButton" Row="0" RowSpan="1" Column="0" ColumnSpan="6" /><Control Name="UseIERadioButton" Row="1" RowSpan="1" Column="0" ColumnSpan="6" /><Control Name="ProxyAddressTextBox" Row="3" RowSpan="1" Column="3" ColumnSpan="3" /><Control Name="ProxyPortTextBox" Row="3" RowSpan="1" Column="7" ColumnSpan="1" /><Control Name="ProxyPortLabel" Row="3" RowSpan="1" Column="6" ColumnSpan="1" /><Control Name="AuthenticationMethodLabel" Row="8" RowSpan="1" Column="2" ColumnSpan="3" /><Control Name="AuthenticationMethodPanel" Row="8" RowSpan="1" Column="5" ColumnSpan="2" /></Controls><Columns Styles="Absolute,20,Absolute,20,Absolute,35,Absolute,30,Absolute,75,Absolute,120,Absolute,65,Absolute,140" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings> Fill @@ -865,7 +994,7 @@ 3, 3, 3, 0 - 584, 194 + 584, 220 0 diff --git a/XenAdmin/MainWindow.cs b/XenAdmin/MainWindow.cs index 767853abd..5b51df6c8 100644 --- a/XenAdmin/MainWindow.cs +++ b/XenAdmin/MainWindow.cs @@ -503,15 +503,17 @@ namespace XenAdmin try { Settings.RestoreSession(); - new TransferProxySettingsAction((HTTPHelper.ProxyStyle)Properties.Settings.Default.ProxySetting, - Properties.Settings.Default.ProxyAddress, - Properties.Settings.Default.ProxyPort, - Properties.Settings.Default.ConnectionTimeout, - true, - Properties.Settings.Default.BypassProxyForServers, - Properties.Settings.Default.ProvideProxyAuthentication, - Properties.Settings.Default.ProxyUsername, - Properties.Settings.Default.ProxyPassword).RunAsync(); + new TransferProxySettingsAction( + (HTTPHelper.ProxyStyle)Properties.Settings.Default.ProxySetting, + Properties.Settings.Default.ProxyAddress, + Properties.Settings.Default.ProxyPort, + Properties.Settings.Default.ConnectionTimeout, + true, + Properties.Settings.Default.BypassProxyForServers, + Properties.Settings.Default.ProvideProxyAuthentication, + Properties.Settings.Default.ProxyUsername, + Properties.Settings.Default.ProxyPassword, + (HTTPHelper.ProxyAuthenticationMethod)Properties.Settings.Default.ProxyAuthenticationMethod).RunAsync(); } catch (ConfigurationErrorsException ex) { diff --git a/XenAdmin/Program.cs b/XenAdmin/Program.cs index 86b1c02c1..6ee9a06f5 100644 --- a/XenAdmin/Program.cs +++ b/XenAdmin/Program.cs @@ -56,7 +56,14 @@ namespace XenAdmin { public const int DEFAULT_WLB_PORT = 8012; - + /// + /// Module for authenticating with proxy server using the Basic authentication scheme. + /// + private static IAuthenticationModule BasicAuthenticationModule = null; + /// + /// Module for authenticating with proxy server using the Digest authentication scheme. + /// + private static IAuthenticationModule DigestAuthenticationModule = null; /// /// A UUID for the current instance of XenCenter. Used to identify our own task instances. @@ -303,6 +310,7 @@ namespace XenAdmin ServicePointManager.ServerCertificateValidationCallback = SSL.ValidateServerCertificate; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; XenAPI.Session.UserAgent = string.Format("XenCenter/{0}", ClientVersion()); + RememberProxyAuthenticationModules(); ReconfigureConnectionSettings(); log.Info("Application started"); @@ -990,9 +998,59 @@ namespace XenAdmin Properties.Settings.Default.ProvideProxyAuthentication = false; Properties.Settings.Default.Save(); } + else + { + ReconfigureProxyAuthenticationSettings(); + } XenAPI.Session.Proxy = XenAdminConfigManager.Provider.GetProxyFromSettings(null); } + /// + /// Stores the Basic and Digest authentication modules, used for proxy server authentication, + /// for later use; this is needed because we cannot create new instances of them and it + /// saves us needing to create our own custom authentication modules. + /// + private static void RememberProxyAuthenticationModules() + { + var authModules = AuthenticationManager.RegisteredModules; + while (authModules.MoveNext()) + { + var module = (IAuthenticationModule)authModules.Current; + if (module.AuthenticationType == "Basic") + BasicAuthenticationModule = module; + else if (module.AuthenticationType == "Digest") + DigestAuthenticationModule = module; + } + } + + /// + /// Configures .NET's AuthenticationManager to only use the authentication module that is + /// specified in the ProxyAuthenticationMethod setting. Also sets XenAPI's HTTP class to + /// use the same authentication method. + /// + private static void ReconfigureProxyAuthenticationSettings() + { + var authModules = AuthenticationManager.RegisteredModules; + var modulesToUnregister = new List(); + + while (authModules.MoveNext()) + { + var module = (IAuthenticationModule)authModules.Current; + modulesToUnregister.Add(module); + } + + foreach (var module in modulesToUnregister) + AuthenticationManager.Unregister(module); + + var authSetting = (HTTPHelper.ProxyAuthenticationMethod)Properties.Settings.Default.ProxyAuthenticationMethod; + if (authSetting == HTTPHelper.ProxyAuthenticationMethod.Basic) + AuthenticationManager.Register(BasicAuthenticationModule); + else + AuthenticationManager.Register(DigestAuthenticationModule); + + XenAPI.HTTP.ProxyAuthenticationMethod = authSetting; + } + private const string SplashWindowClass = "XenCenterSplash0001"; internal static void CloseSplash() diff --git a/XenAdmin/Properties/Settings.Designer.cs b/XenAdmin/Properties/Settings.Designer.cs index 6a316fe0c..6de7d2ce7 100644 --- a/XenAdmin/Properties/Settings.Designer.cs +++ b/XenAdmin/Properties/Settings.Designer.cs @@ -743,5 +743,17 @@ namespace XenAdmin.Properties { this["BypassProxyForServers"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("1")] + public int ProxyAuthenticationMethod { + get { + return ((int)(this["ProxyAuthenticationMethod"])); + } + set { + this["ProxyAuthenticationMethod"] = value; + } + } } } diff --git a/XenAdmin/Properties/Settings.settings b/XenAdmin/Properties/Settings.settings index f077948ce..8921fd061 100644 --- a/XenAdmin/Properties/Settings.settings +++ b/XenAdmin/Properties/Settings.settings @@ -173,5 +173,8 @@ False + + 1 + \ No newline at end of file diff --git a/XenAdmin/app.config b/XenAdmin/app.config index 1779ab75b..b7d7ff25d 100644 --- a/XenAdmin/app.config +++ b/XenAdmin/app.config @@ -168,6 +168,9 @@ False + + 1 + diff --git a/XenModel/Actions/HealthCheck/TransferProxySettingsAction.cs b/XenModel/Actions/HealthCheck/TransferProxySettingsAction.cs index 048c5769e..467d6c5ac 100644 --- a/XenModel/Actions/HealthCheck/TransferProxySettingsAction.cs +++ b/XenModel/Actions/HealthCheck/TransferProxySettingsAction.cs @@ -48,9 +48,10 @@ namespace XenAdmin.Actions private bool provideProxyCredentials; private string proxyUsername; private string proxyPassword; + private HTTPHelper.ProxyAuthenticationMethod proxyAuthenticationMethod; public TransferProxySettingsAction(HTTPHelper.ProxyStyle style, string address, int port, int timeout, - bool suppressHistory, bool bypassForServer, bool provideCredentials, string username, string password) + bool suppressHistory, bool bypassForServer, bool provideCredentials, string username, string password, HTTPHelper.ProxyAuthenticationMethod proxyAuthMethod) : base(null, Messages.ACTION_TRANSFER_HEALTHCHECK_SETTINGS, Messages.ACTION_TRANSFER_HEALTHCHECK_SETTINGS, suppressHistory) { proxyStyle = style; @@ -61,6 +62,7 @@ namespace XenAdmin.Actions provideProxyCredentials = provideCredentials; proxyUsername = username; proxyPassword = password; + proxyAuthenticationMethod = proxyAuthMethod; } private const string HEALTHCHECKSERVICENAME = "XenServerHealthCheck"; @@ -81,7 +83,8 @@ namespace XenAdmin.Actions bypassProxyForServers.ToString(), provideProxyCredentials.ToString(), proxyUsername.ToString(), - proxyPassword.ToString()}); + proxyPassword.ToString(), + ((Int32)proxyAuthenticationMethod).ToString()}); return proxySettings; case HTTPHelper.ProxyStyle.SystemProxy: diff --git a/XenModel/Network/HTTPHelper.cs b/XenModel/Network/HTTPHelper.cs index 3df61d62b..090aa6bdc 100644 --- a/XenModel/Network/HTTPHelper.cs +++ b/XenModel/Network/HTTPHelper.cs @@ -52,6 +52,13 @@ namespace XenAPI SpecifiedProxy = 2 } + public enum ProxyAuthenticationMethod + { + // Note that these numbers make it into user settings files, so need to be preserved. + Basic = 0, + Digest = 1 + } + private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); diff --git a/XenModel/XenAPI/HTTP.cs b/XenModel/XenAPI/HTTP.cs index f984c4584..f647baf96 100644 --- a/XenModel/XenAPI/HTTP.cs +++ b/XenModel/XenAPI/HTTP.cs @@ -130,6 +130,12 @@ namespace XenAPI public const int DEFAULT_HTTPS_PORT = 443; + /// + /// The authentication scheme to use for authenticating XenCenter to a proxy server. + /// Defaults to Digest. + /// + public static HTTPHelper.ProxyAuthenticationMethod ProxyAuthenticationMethod = HTTPHelper.ProxyAuthenticationMethod.Digest; + #region Helper functions private static void WriteLine(String txt, Stream stream) @@ -464,7 +470,7 @@ namespace XenAPI if (fields.Count > 0) { // clean up (if initial server response specifies "Proxy-Connection: Close" then stream cannot be re-used) - string field = initialResponse.Find(str => str.StartsWith("Proxy-Connection: Close")); + string field = initialResponse.Find(str => str.StartsWith("Proxy-Connection: Close", StringComparison.CurrentCultureIgnoreCase)); if (!string.IsNullOrEmpty(field)) { stream.Close(); @@ -478,16 +484,22 @@ namespace XenAPI string basicField = fields.Find(str => str.StartsWith("Proxy-Authenticate: Basic")); string digestField = fields.Find(str => str.StartsWith("Proxy-Authenticate: Digest")); - if (!string.IsNullOrEmpty(basicField)) + if (ProxyAuthenticationMethod == HTTPHelper.ProxyAuthenticationMethod.Basic) { - string authenticationFieldReply = String.Format("Proxy-Authorization: Basic {0}", + if (string.IsNullOrEmpty(basicField)) + throw new ProxyServerAuthenticationException("Basic authentication scheme is not supported/enabled by the proxy server."); + + string authenticationFieldReply = string.Format("Proxy-Authorization: Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials.UserName + ":" + credentials.Password))); WriteLine(header, stream); WriteLine(authenticationFieldReply, stream); WriteLine(stream); } - else if (!string.IsNullOrEmpty(digestField)) + else if (ProxyAuthenticationMethod == HTTPHelper.ProxyAuthenticationMethod.Digest) { + if (string.IsNullOrEmpty(digestField)) + throw new ProxyServerAuthenticationException("Digest authentication scheme is not supported/enabled by the proxy server."); + string authenticationFieldReply = string.Format( "Proxy-Authorization: Digest username=\"{0}\", uri=\"{1}:{2}\"", credentials.UserName, uri.Host, uri.Port); diff --git a/XenServerHealthCheck/Properties/Settings.Designer.cs b/XenServerHealthCheck/Properties/Settings.Designer.cs index 02ed27357..2552498c3 100644 --- a/XenServerHealthCheck/Properties/Settings.Designer.cs +++ b/XenServerHealthCheck/Properties/Settings.Designer.cs @@ -163,5 +163,17 @@ namespace XenServerHealthCheck.Properties { this["ProxyPassword"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("1")] + public int ProxyAuthenticationMethod { + get { + return ((int)(this["ProxyAuthenticationMethod"])); + } + set { + this["ProxyAuthenticationMethod"] = value; + } + } } } diff --git a/XenServerHealthCheck/Properties/Settings.settings b/XenServerHealthCheck/Properties/Settings.settings index 12b6419a8..db0288aad 100644 --- a/XenServerHealthCheck/Properties/Settings.settings +++ b/XenServerHealthCheck/Properties/Settings.settings @@ -36,5 +36,8 @@ + + 1 + \ No newline at end of file diff --git a/XenServerHealthCheck/ServerListHelper.cs b/XenServerHealthCheck/ServerListHelper.cs index aeac66af3..6e8234e9b 100755 --- a/XenServerHealthCheck/ServerListHelper.cs +++ b/XenServerHealthCheck/ServerListHelper.cs @@ -232,6 +232,7 @@ namespace XenServerHealthCheck Properties.Settings.Default.ProvideProxyAuthentication = bool.Parse(proxySettings[6]); Properties.Settings.Default.ProxyUsername = proxySettings[7]; Properties.Settings.Default.ProxyPassword = proxySettings[8]; + Properties.Settings.Default.ProxyAuthenticationMethod = Int32.Parse(proxySettings[9]); break; case HTTPHelper.ProxyStyle.SystemProxy: diff --git a/XenServerHealthCheck/XenServerHealthCheckService.cs b/XenServerHealthCheck/XenServerHealthCheckService.cs index 1d1e6c89e..98439ca28 100755 --- a/XenServerHealthCheck/XenServerHealthCheckService.cs +++ b/XenServerHealthCheck/XenServerHealthCheckService.cs @@ -76,6 +76,8 @@ namespace XenServerHealthCheck public static void ReconfigureConnectionSettings() { XenAPI.Session.Proxy = XenAdminConfigManager.Provider.GetProxyFromSettings(null); + XenAPI.HTTP.ProxyAuthenticationMethod = + (HTTPHelper.ProxyAuthenticationMethod)Properties.Settings.Default.ProxyAuthenticationMethod; } protected override void OnStart(string[] args) diff --git a/XenServerHealthCheck/app.config b/XenServerHealthCheck/app.config index 47737a0d3..e3eb8d0d9 100755 --- a/XenServerHealthCheck/app.config +++ b/XenServerHealthCheck/app.config @@ -81,6 +81,9 @@ + + 1 + From c96911aac5a1fbf569a64e157eef61b8ecaa1c7f Mon Sep 17 00:00:00 2001 From: Frezzle Date: Thu, 13 Oct 2016 15:28:17 +0100 Subject: [PATCH 2/2] [CP-19111] Removed duplicated code for functions registered to UI controls Signed-off-by: Frezzle --- .../ConnectionOptionsPage.Designer.cs | 14 ++--- .../OptionsPages/ConnectionOptionsPage.cs | 58 +------------------ 2 files changed, 9 insertions(+), 63 deletions(-) diff --git a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs index 8dd682977..af180620a 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.Designer.cs @@ -162,14 +162,14 @@ namespace XenAdmin.Dialogs.OptionsPages this.tableLayoutPanel1.SetColumnSpan(this.BypassForServersCheckbox, 6); this.BypassForServersCheckbox.Name = "BypassForServersCheckbox"; this.BypassForServersCheckbox.UseVisualStyleBackColor = true; - this.BypassForServersCheckbox.CheckedChanged += new System.EventHandler(this.BypassForServersCheckbox_CheckedChanged); + this.BypassForServersCheckbox.CheckedChanged += new System.EventHandler(this.GeneralProxySettingsChanged); // // ProxyPasswordTextBox // resources.ApplyResources(this.ProxyPasswordTextBox, "ProxyPasswordTextBox"); this.ProxyPasswordTextBox.Name = "ProxyPasswordTextBox"; this.ProxyPasswordTextBox.UseSystemPasswordChar = true; - this.ProxyPasswordTextBox.TextChanged += new System.EventHandler(this.ProxyPasswordTextBox_TextChanged); + this.ProxyPasswordTextBox.TextChanged += new System.EventHandler(this.ProxyAuthenticationSettingsChanged); // // ProxyUsernameLabel // @@ -182,7 +182,7 @@ namespace XenAdmin.Dialogs.OptionsPages this.tableLayoutPanel1.SetColumnSpan(this.ProxyUsernameTextBox, 2); resources.ApplyResources(this.ProxyUsernameTextBox, "ProxyUsernameTextBox"); this.ProxyUsernameTextBox.Name = "ProxyUsernameTextBox"; - this.ProxyUsernameTextBox.TextChanged += new System.EventHandler(this.ProxyUsernameTextBox_TextChanged); + this.ProxyUsernameTextBox.TextChanged += new System.EventHandler(this.ProxyAuthenticationSettingsChanged); // // ProxyPasswordLabel // @@ -233,13 +233,13 @@ namespace XenAdmin.Dialogs.OptionsPages this.tableLayoutPanel1.SetColumnSpan(this.ProxyAddressTextBox, 3); resources.ApplyResources(this.ProxyAddressTextBox, "ProxyAddressTextBox"); this.ProxyAddressTextBox.Name = "ProxyAddressTextBox"; - this.ProxyAddressTextBox.TextChanged += new System.EventHandler(this.ProxyAddressTextBox_TextChanged); + this.ProxyAddressTextBox.TextChanged += new System.EventHandler(this.GeneralProxySettingsChanged); // // ProxyPortTextBox // resources.ApplyResources(this.ProxyPortTextBox, "ProxyPortTextBox"); this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.TextChanged += new System.EventHandler(this.ProxyPortTextBox_TextChanged); + this.ProxyPortTextBox.TextChanged += new System.EventHandler(this.GeneralProxySettingsChanged); // // ProxyPortLabel // @@ -265,14 +265,14 @@ namespace XenAdmin.Dialogs.OptionsPages resources.ApplyResources(this.DigestRadioButton, "DigestRadioButton"); this.DigestRadioButton.Name = "DigestRadioButton"; this.DigestRadioButton.UseVisualStyleBackColor = true; - this.DigestRadioButton.CheckedChanged += new System.EventHandler(this.DigestRadioButton_CheckedChanged); + this.DigestRadioButton.CheckedChanged += new System.EventHandler(this.ProxyAuthenticationSettingsChanged); // // BasicRadioButton // resources.ApplyResources(this.BasicRadioButton, "BasicRadioButton"); this.BasicRadioButton.Name = "BasicRadioButton"; this.BasicRadioButton.UseVisualStyleBackColor = true; - this.BasicRadioButton.CheckedChanged += new System.EventHandler(this.BasicRadioButton_CheckedChanged); + this.BasicRadioButton.CheckedChanged += new System.EventHandler(this.ProxyAuthenticationSettingsChanged); // // ConnectionOptionsPage // diff --git a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs index 0382caace..0f0866e5c 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConnectionOptionsPage.cs @@ -151,73 +151,19 @@ namespace XenAdmin.Dialogs.OptionsPages enableOK(); } - private void ProxyAddressTextBox_TextChanged(object sender, EventArgs e) + private void GeneralProxySettingsChanged(object sender, EventArgs e) { if (eventsDisabled) return; - SelectUseThisProxyServer(); - enableOK(); } - private void ProxyPortTextBox_TextChanged(object sender, EventArgs e) + private void ProxyAuthenticationSettingsChanged(object sender, EventArgs e) { if (eventsDisabled) return; - - SelectUseThisProxyServer(); - - enableOK(); - } - - private void ProxyUsernameTextBox_TextChanged(object sender, EventArgs e) - { - if (eventsDisabled) - return; - SelectProvideCredentials(); - - enableOK(); - } - - private void ProxyPasswordTextBox_TextChanged(object sender, EventArgs e) - { - if (eventsDisabled) - return; - - SelectProvideCredentials(); - - enableOK(); - } - - private void BypassForServersCheckbox_CheckedChanged(object sender, EventArgs e) - { - if (eventsDisabled) - return; - - SelectUseThisProxyServer(); - - enableOK(); - } - - private void BasicRadioButton_CheckedChanged(object sender, EventArgs e) - { - if (eventsDisabled) - return; - - SelectProvideCredentials(); - - enableOK(); - } - - private void DigestRadioButton_CheckedChanged(object sender, EventArgs e) - { - if (eventsDisabled) - return; - - SelectProvideCredentials(); - enableOK(); }