diff --git a/ocaml/sdk-gen/csharp/autogen/src/Session.cs b/ocaml/sdk-gen/csharp/autogen/src/Session.cs index 4a84b5bcd0c..82db84a8210 100644 --- a/ocaml/sdk-gen/csharp/autogen/src/Session.cs +++ b/ocaml/sdk-gen/csharp/autogen/src/Session.cs @@ -65,29 +65,15 @@ public Session(JsonRpcClient client) client.KeepAlive = true; client.UserAgent = UserAgent; client.WebProxy = Proxy; - client.JsonRpcVersion = JsonRpcVersion.v2; client.AllowAutoRedirect = true; JsonRpcClient = client; } - [Obsolete("Use Session(string url) { Timeout = ... }; instead.")] - public Session(int timeout, string url) - : this(new JsonRpcClient(url)) - { - JsonRpcClient.Timeout = timeout; - } - public Session(string url) : this(new JsonRpcClient(url)) { } - [Obsolete("Use Session(string host, int port) { Timeout = ... }; instead.")] - public Session(int timeout, string host, int port) - : this(timeout, GetUrl(host, port)) - { - } - public Session(string host, int port) : this(GetUrl(host, port)) { @@ -100,23 +86,6 @@ public Session(string url, string opaqueRef) SetupSessionDetails(); } - /// - /// Create a new Session instance, using the given instance and timeout. The connection details and Xen-API session handle will be - /// copied from the given instance, but a new connection will be created. Use this if you want a duplicate connection to a host, - /// for example when you need to cancel an operation that is blocking the primary connection. - /// - /// - /// - [Obsolete("Use Session(Session session) { Timeout = ... }; instead.")] - public Session(Session session, int timeout) - : this(session) - { - if (JsonRpcClient != null) - { - JsonRpcClient.Timeout = timeout; - } - } - /// /// Create a new Session instance, using the given instance. The connection details /// and Xen-API session handle will be copied from the given instance, but a new @@ -175,6 +144,14 @@ private void SetAPIVersion() Host host = Host.get_record(this, pool.master); APIVersion = Helper.GetAPIVersion(host.API_version_major, host.API_version_minor); } + + if (JsonRpcClient != null) + { + if (APIVersion == API_Version.API_2_6) + JsonRpcClient.JsonRpcVersion = JsonRpcVersion.v1; + else if (APIVersion >= API_Version.API_2_8) + JsonRpcClient.JsonRpcVersion = JsonRpcVersion.v2; + } } private void CopyADFromSession(Session session) diff --git a/ocaml/sdk-gen/csharp/templates/ApiVersion.mustache b/ocaml/sdk-gen/csharp/templates/ApiVersion.mustache index a8be1e4e8a5..9cac0b97c18 100644 --- a/ocaml/sdk-gen/csharp/templates/ApiVersion.mustache +++ b/ocaml/sdk-gen/csharp/templates/ApiVersion.mustache @@ -28,9 +28,6 @@ */ using System; -using System.Collections; -using System.Collections.Generic; - namespace XenAPI { @@ -63,8 +60,7 @@ namespace XenAPI { try { - return (API_Version)Enum.Parse(typeof(API_Version), - string.Format("API_{0}_{1}", major, minor)); + return (API_Version)Enum.Parse(typeof(API_Version), $"API_{major}_{minor}"); } catch (ArgumentException) { @@ -82,30 +78,14 @@ namespace XenAPI { string[] tokens = version.Split('.'); int major, minor; - if (tokens.Length == 2 && int.TryParse(tokens[0], out major) && int.TryParse(tokens[1], out minor)) + if (tokens.Length == 2 && + int.TryParse(tokens[0], out major) && + int.TryParse(tokens[1], out minor)) { return GetAPIVersion(major, minor); } } return API_Version.UNKNOWN; } - - /// - /// Return a positive number if the given session's API version is greater than the given - /// API_version, negative if it is less, and 0 if they are equal. - /// - internal static int APIVersionCompare(Session session, API_Version v) - { - return (int)session.APIVersion - (int)v; - } - - /// - /// Return true if the given session's API version is greater than or equal to the given - /// API_version. - /// - internal static bool APIVersionMeets(Session session, API_Version v) - { - return APIVersionCompare(session, v) >= 0; - } } } diff --git a/ocaml/sdk-gen/powershell/autogen/src/CommonCmdletFunctions.cs b/ocaml/sdk-gen/powershell/autogen/src/CommonCmdletFunctions.cs index 8f29ecde1f5..d22d5eadee0 100644 --- a/ocaml/sdk-gen/powershell/autogen/src/CommonCmdletFunctions.cs +++ b/ocaml/sdk-gen/powershell/autogen/src/CommonCmdletFunctions.cs @@ -39,14 +39,11 @@ namespace Citrix.XenServer { - class CommonCmdletFunctions + internal class CommonCmdletFunctions { private const string SessionsVariable = "global:Citrix.XenServer.Sessions"; - private const string DefaultSessionVariable = "global:XenServer_Default_Session"; - private const string KnownServerCertificatesFilePathVariable = "global:KnownServerCertificatesFilePath"; - static CommonCmdletFunctions() { Session.UserAgent = string.Format("XenServerPSModule/{0}", Assembly.GetExecutingAssembly().GetName().Version); @@ -78,72 +75,12 @@ internal static void SetDefaultXenSession(PSCmdlet cmdlet, Session session) cmdlet.SessionState.PSVariable.Set(DefaultSessionVariable, session); } - internal static string GetKnownServerCertificatesFilePathVariable(PSCmdlet cmdlet) - { - var knownCertificatesFilePathObject = cmdlet.SessionState.PSVariable.GetValue(KnownServerCertificatesFilePathVariable); - if (knownCertificatesFilePathObject is PSObject psObject) - return psObject.BaseObject as string; - return knownCertificatesFilePathObject?.ToString() ?? string.Empty; - } - internal static string GetUrl(string hostname, int port) { - return string.Format("{0}://{1}:{2}", port == 80 ? "http" : "https", hostname, port); - } - - public static Dictionary LoadCertificates(PSCmdlet cmdlet) - { - Dictionary certificates = new Dictionary(); - var knownServerCertificatesFilePath = GetKnownServerCertificatesFilePathVariable(cmdlet); - - if (File.Exists(knownServerCertificatesFilePath)) - { - XmlDocument doc = new XmlDocument(); - doc.Load(knownServerCertificatesFilePath); - - foreach (XmlNode node in doc.GetElementsByTagName("certificate")) - { - XmlAttribute hostAtt = node.Attributes?["hostname"]; - XmlAttribute fngprtAtt = node.Attributes?["fingerprint"]; - - if (hostAtt != null && fngprtAtt != null) - certificates[hostAtt.Value] = fngprtAtt.Value; - } - } - - return certificates; - } - - public static void SaveCertificates(PSCmdlet cmdlet, Dictionary certificates) - { - var knownServerCertificatesFilePath = GetKnownServerCertificatesFilePathVariable(cmdlet); - string dirName = Path.GetDirectoryName(knownServerCertificatesFilePath); - - if (!Directory.Exists(dirName)) - Directory.CreateDirectory(dirName); - - XmlDocument doc = new XmlDocument(); - XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null); - doc.AppendChild(decl); - XmlNode node = doc.CreateElement("certificates"); - - foreach (KeyValuePair cert in certificates) - { - XmlNode certNode = doc.CreateElement("certificate"); - XmlAttribute hostname = doc.CreateAttribute("hostname"); - XmlAttribute fingerprint = doc.CreateAttribute("fingerprint"); - hostname.Value = cert.Key; - fingerprint.Value = cert.Value; - certNode.Attributes?.Append(hostname); - certNode.Attributes?.Append(fingerprint); - node.AppendChild(certNode); - } - - doc.AppendChild(node); - doc.Save(knownServerCertificatesFilePath); + return $"{(port == 80 ? "http" : "https")}://{hostname}:{port}"; } - public static string FingerprintPrettyString(string fingerprint) + internal static string FingerprintPrettyString(string fingerprint) { List pairs = new List(); while (fingerprint.Length > 1) @@ -157,7 +94,7 @@ public static string FingerprintPrettyString(string fingerprint) return string.Join(":", pairs.ToArray()); } - public static Dictionary ConvertHashTableToDictionary(Hashtable tbl) + internal static Dictionary ConvertHashTableToDictionary(Hashtable tbl) { if (tbl == null) return null; @@ -169,7 +106,7 @@ public static Dictionary ConvertHashTableToDictionary(Hashtable tbl) return dict; } - public static Hashtable ConvertDictionaryToHashtable(Dictionary dict) + internal static Hashtable ConvertDictionaryToHashtable(Dictionary dict) { if (dict == null) return null; diff --git a/ocaml/sdk-gen/powershell/autogen/src/Connect-XenServer.cs b/ocaml/sdk-gen/powershell/autogen/src/Connect-XenServer.cs index f300801f5ef..a1dc4ecf964 100644 --- a/ocaml/sdk-gen/powershell/autogen/src/Connect-XenServer.cs +++ b/ocaml/sdk-gen/powershell/autogen/src/Connect-XenServer.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Management.Automation; using System.Net; using System.Net.Security; @@ -36,6 +37,7 @@ using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; +using System.Xml; using XenAPI; namespace Citrix.XenServer.Commands @@ -43,6 +45,8 @@ namespace Citrix.XenServer.Commands [Cmdlet("Connect", "XenServer")] public class ConnectXenServerCommand : PSCmdlet { + private const string CertificatesPathVariable = "global:KnownServerCertificatesFilePath"; + private readonly object _certificateValidationLock = new object(); public ConnectXenServerCommand() @@ -214,7 +218,10 @@ protected override void ProcessRecord() { if (ShouldContinue(ex.Message, ex.Caption)) { - AddCertificate(ex.Hostname, ex.Fingerprint); + var certPath = GetCertificatesPath(); + var certificates = LoadCertificates(certPath); + certificates[ex.Hostname] = ex.Fingerprint; + SaveCertificates(certPath, certificates); i--; continue; } @@ -254,13 +261,6 @@ protected override void ProcessRecord() WriteObject(newSessions.Values, true); } - private void AddCertificate(string hostname, string fingerprint) - { - var certificates = CommonCmdletFunctions.LoadCertificates(this); - certificates[hostname] = fingerprint; - CommonCmdletFunctions.SaveCertificates(this, certificates); - } - private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (sslPolicyErrors == SslPolicyErrors.None) @@ -277,11 +277,11 @@ private bool ValidateServerCertificate(object sender, X509Certificate certificat bool trusted = VerifyInAllStores(new X509Certificate2(certificate)); - var certificates = CommonCmdletFunctions.LoadCertificates(this); + var certPath = GetCertificatesPath(); + var certificates = LoadCertificates(certPath); - if (certificates.ContainsKey(hostname)) + if (certificates.TryGetValue(hostname, out var fingerprintOld)) { - string fingerprintOld = certificates[hostname]; if (fingerprintOld == fingerprint) return true; @@ -295,7 +295,7 @@ private bool ValidateServerCertificate(object sender, X509Certificate certificat } certificates[hostname] = fingerprint; - CommonCmdletFunctions.SaveCertificates(this, certificates); + SaveCertificates(certPath, certificates); return true; } } @@ -312,6 +312,65 @@ private bool VerifyInAllStores(X509Certificate2 certificate2) return false; } } + + private string GetCertificatesPath() + { + var certPathObject = SessionState.PSVariable.GetValue(CertificatesPathVariable); + + return certPathObject is PSObject psObject + ? psObject.BaseObject as string + : certPathObject?.ToString() ?? string.Empty; + } + + private Dictionary LoadCertificates(string certPath) + { + var certificates = new Dictionary(); + + if (File.Exists(certPath)) + { + var doc = new XmlDocument(); + doc.Load(certPath); + + foreach (XmlNode node in doc.GetElementsByTagName("certificate")) + { + var hostAtt = node.Attributes?["hostname"]; + var fngprtAtt = node.Attributes?["fingerprint"]; + + if (hostAtt != null && fngprtAtt != null) + certificates[hostAtt.Value] = fngprtAtt.Value; + } + } + + return certificates; + } + + private void SaveCertificates(string certPath, Dictionary certificates) + { + string dirName = Path.GetDirectoryName(certPath); + + if (!Directory.Exists(dirName)) + Directory.CreateDirectory(dirName); + + XmlDocument doc = new XmlDocument(); + XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null); + doc.AppendChild(decl); + XmlNode node = doc.CreateElement("certificates"); + + foreach (KeyValuePair cert in certificates) + { + XmlNode certNode = doc.CreateElement("certificate"); + XmlAttribute hostname = doc.CreateAttribute("hostname"); + XmlAttribute fingerprint = doc.CreateAttribute("fingerprint"); + hostname.Value = cert.Key; + fingerprint.Value = cert.Value; + certNode.Attributes?.Append(hostname); + certNode.Attributes?.Append(fingerprint); + node.AppendChild(certNode); + } + + doc.AppendChild(node); + doc.Save(certPath); + } } internal abstract class CertificateValidationException : Exception