From 3dcfd3738d84bf0fc15b8b78ce474c68f0581dc6 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 26 Jan 2017 14:32:07 -0700 Subject: [PATCH] connectionrecord and its inheritance are now serialized and deserialized --- mRemoteV1/App/Info/ConnectionsFileInfo.cs | 2 +- mRemoteV1/App/Runtime.cs | 4 +- .../Config/Connections/ConnectionsLoader.cs | 6 ++- .../Multiuser/RemoteConnectionsSyncronizer.cs | 2 +- mRemoteV1/Config/Import/mRemoteNGImporter.cs | 2 +- .../XmlConnectionNodeSerializer.cs | 29 +++++-------- .../Serializers/XmlConnectionsDeserializer.cs | 41 +++++++++++++++---- .../Serializers/XmlRootNodeSerializer.cs | 2 +- .../Connection/AbstractConnectionRecord.cs | 8 +++- mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd | 1 + 10 files changed, 61 insertions(+), 36 deletions(-) diff --git a/mRemoteV1/App/Info/ConnectionsFileInfo.cs b/mRemoteV1/App/Info/ConnectionsFileInfo.cs index 36793e36d..d317ed651 100644 --- a/mRemoteV1/App/Info/ConnectionsFileInfo.cs +++ b/mRemoteV1/App/Info/ConnectionsFileInfo.cs @@ -5,6 +5,6 @@ public static readonly string DefaultConnectionsPath = SettingsFileInfo.SettingsPath; public static readonly string DefaultConnectionsFile = "confCons.xml"; public static readonly string DefaultConnectionsFileNew = "confConsNew.xml"; - public static readonly double ConnectionFileVersion = 2.6; + public static readonly double ConnectionFileVersion = 2.7; } } \ No newline at end of file diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index 0b3d14966..ce8f5ba39 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -238,7 +238,7 @@ namespace mRemoteNG.App // Load config connectionsLoader.ConnectionFileName = filename; - ConnectionTreeModel = connectionsLoader.LoadConnections(false); + ConnectionTreeModel = connectionsLoader.LoadConnections(CredentialManager.GetCredentialRecords(), false); Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel; } catch (Exception ex) @@ -289,7 +289,7 @@ namespace mRemoteNG.App } connectionsLoader.UseDatabase = Settings.Default.UseSQLServer; - ConnectionTreeModel = connectionsLoader.LoadConnections(false); + ConnectionTreeModel = connectionsLoader.LoadConnections(CredentialManager.GetCredentialRecords(), false); Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel; if (Settings.Default.UseSQLServer) diff --git a/mRemoteV1/Config/Connections/ConnectionsLoader.cs b/mRemoteV1/Config/Connections/ConnectionsLoader.cs index 11cbad67a..08157e044 100644 --- a/mRemoteV1/Config/Connections/ConnectionsLoader.cs +++ b/mRemoteV1/Config/Connections/ConnectionsLoader.cs @@ -1,8 +1,10 @@ +using System.Collections.Generic; using System.Security; using mRemoteNG.Config.DatabaseConnectors; using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.Putty; using mRemoteNG.Config.Serializers; +using mRemoteNG.Credential; using mRemoteNG.Tools; using mRemoteNG.Tree; using mRemoteNG.UI.Forms; @@ -16,7 +18,7 @@ namespace mRemoteNG.Config.Connections public string ConnectionFileName { get; set; } - public ConnectionTreeModel LoadConnections(bool import) + public ConnectionTreeModel LoadConnections(IEnumerable credentialRecords, bool import) { IDeserializer deserializer; if (UseDatabase) @@ -30,7 +32,7 @@ namespace mRemoteNG.Config.Connections { var dataProvider = new FileDataProvider(ConnectionFileName); var xmlString = dataProvider.Load(); - deserializer = new XmlConnectionsDeserializer(xmlString, PromptForPassword); + deserializer = new XmlConnectionsDeserializer(xmlString, credentialRecords, PromptForPassword); } var connectionTreeModel = deserializer.Deserialize(); diff --git a/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs b/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs index cf9695ead..372378c04 100644 --- a/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs +++ b/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs @@ -33,7 +33,7 @@ namespace mRemoteNG.Config.Connections.Multiuser public void Load() { - Runtime.ConnectionTreeModel = _connectionsLoader.LoadConnections(false); + Runtime.ConnectionTreeModel = _connectionsLoader.LoadConnections(Runtime.CredentialManager.GetCredentialRecords(), false); } private void Load(object sender, ConnectionsUpdateAvailableEventArgs args) diff --git a/mRemoteV1/Config/Import/mRemoteNGImporter.cs b/mRemoteV1/Config/Import/mRemoteNGImporter.cs index ef8fb7d3c..7610935a9 100644 --- a/mRemoteV1/Config/Import/mRemoteNGImporter.cs +++ b/mRemoteV1/Config/Import/mRemoteNGImporter.cs @@ -31,7 +31,7 @@ namespace mRemoteNG.Config.Import { var dataProvider = new FileDataProvider(fileName); var xmlString = dataProvider.Load(); - var xmlConnectionsDeserializer = new XmlConnectionsDeserializer(xmlString); + var xmlConnectionsDeserializer = new XmlConnectionsDeserializer(xmlString, null); var connectionTreeModel = xmlConnectionsDeserializer.Deserialize(true); var rootImportContainer = new ContainerInfo { Name = Path.GetFileNameWithoutExtension(fileName) }; diff --git a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs index 0da6517a0..6de3aed48 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs @@ -46,18 +46,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("Panel", connectionInfo.Panel)); element.Add(new XAttribute("Id", connectionInfo.ConstantID)); - element.Add(_saveFilter.SaveUsername - ? new XAttribute("Username", connectionInfo.Username ?? "") - : new XAttribute("Username", "")); - - element.Add(_saveFilter.SaveDomain - ? new XAttribute("Domain", connectionInfo.Domain ?? "") - : new XAttribute("Domain", "")); - - if (_saveFilter.SavePassword && !connectionInfo.Inheritance.Password) - element.Add(new XAttribute("Password", _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey) ?? "")); - else - element.Add(new XAttribute("Password", "")); + element.Add(new XAttribute("CredentialId", connectionInfo.CredentialRecord?.Id.ToString() ?? "")); element.Add(new XAttribute("Hostname", connectionInfo.Hostname)); element.Add(new XAttribute("Protocol", connectionInfo.Protocol)); @@ -131,7 +120,8 @@ namespace mRemoteNG.Config.Serializers private void SetInheritanceAttributes(XContainer element, IInheritable connectionInfo) { if (_saveFilter.SaveInheritance) - { + { + element.Add(new XAttribute("InheritCredentialRecord", connectionInfo.Inheritance.CredentialRecord)); element.Add(new XAttribute("InheritCacheBitmaps", connectionInfo.Inheritance.CacheBitmaps.ToString())); element.Add(new XAttribute("InheritColors", connectionInfo.Inheritance.Colors.ToString())); element.Add(new XAttribute("InheritDescription", connectionInfo.Inheritance.Description.ToString())); @@ -139,10 +129,10 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritDisplayWallpaper", connectionInfo.Inheritance.DisplayWallpaper.ToString())); element.Add(new XAttribute("InheritEnableFontSmoothing", connectionInfo.Inheritance.EnableFontSmoothing.ToString())); element.Add(new XAttribute("InheritEnableDesktopComposition", connectionInfo.Inheritance.EnableDesktopComposition.ToString())); - element.Add(new XAttribute("InheritDomain", connectionInfo.Inheritance.Domain.ToString())); + //element.Add(new XAttribute("InheritDomain", connectionInfo.Inheritance.Domain.ToString())); element.Add(new XAttribute("InheritIcon", connectionInfo.Inheritance.Icon.ToString())); element.Add(new XAttribute("InheritPanel", connectionInfo.Inheritance.Panel.ToString())); - element.Add(new XAttribute("InheritPassword", connectionInfo.Inheritance.Password.ToString())); + //element.Add(new XAttribute("InheritPassword", connectionInfo.Inheritance.Password.ToString())); element.Add(new XAttribute("InheritPort", connectionInfo.Inheritance.Port.ToString())); element.Add(new XAttribute("InheritProtocol", connectionInfo.Inheritance.Protocol.ToString())); element.Add(new XAttribute("InheritPuttySession", connectionInfo.Inheritance.PuttySession.ToString())); @@ -158,7 +148,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritUseConsoleSession", connectionInfo.Inheritance.UseConsoleSession.ToString())); element.Add(new XAttribute("InheritUseCredSsp", connectionInfo.Inheritance.UseCredSsp.ToString())); element.Add(new XAttribute("InheritRenderingEngine", connectionInfo.Inheritance.RenderingEngine.ToString())); - element.Add(new XAttribute("InheritUsername", connectionInfo.Inheritance.Username.ToString())); + //element.Add(new XAttribute("InheritUsername", connectionInfo.Inheritance.Username.ToString())); element.Add(new XAttribute("InheritICAEncryptionStrength", connectionInfo.Inheritance.ICAEncryptionStrength.ToString())); element.Add(new XAttribute("InheritRDPAuthenticationLevel", connectionInfo.Inheritance.RDPAuthenticationLevel.ToString())); element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", connectionInfo.Inheritance.RDPMinutesToIdleTimeout.ToString())); @@ -188,6 +178,7 @@ namespace mRemoteNG.Config.Serializers } else { + element.Add(new XAttribute("InheritCredentialRecord", false.ToString())); element.Add(new XAttribute("InheritCacheBitmaps", false.ToString())); element.Add(new XAttribute("InheritColors", false.ToString())); element.Add(new XAttribute("InheritDescription", false.ToString())); @@ -195,10 +186,10 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritDisplayWallpaper", false.ToString())); element.Add(new XAttribute("InheritEnableFontSmoothing", false.ToString())); element.Add(new XAttribute("InheritEnableDesktopComposition", false.ToString())); - element.Add(new XAttribute("InheritDomain", false.ToString())); + //element.Add(new XAttribute("InheritDomain", false.ToString())); element.Add(new XAttribute("InheritIcon", false.ToString())); element.Add(new XAttribute("InheritPanel", false.ToString())); - element.Add(new XAttribute("InheritPassword", false.ToString())); + //element.Add(new XAttribute("InheritPassword", false.ToString())); element.Add(new XAttribute("InheritPort", false.ToString())); element.Add(new XAttribute("InheritProtocol", false.ToString())); element.Add(new XAttribute("InheritPuttySession", false.ToString())); @@ -214,7 +205,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritUseConsoleSession", false.ToString())); element.Add(new XAttribute("InheritUseCredSsp", false.ToString())); element.Add(new XAttribute("InheritRenderingEngine", false.ToString())); - element.Add(new XAttribute("InheritUsername", false.ToString())); + //element.Add(new XAttribute("InheritUsername", false.ToString())); element.Add(new XAttribute("InheritICAEncryptionStrength", false.ToString())); element.Add(new XAttribute("InheritRDPAuthenticationLevel", false.ToString())); element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", false.ToString())); diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index cc76c36ae..2f7d4714b 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Security; using System.Windows.Forms; using System.Xml; @@ -11,6 +13,7 @@ using mRemoteNG.Connection.Protocol.ICA; using mRemoteNG.Connection.Protocol.RDP; using mRemoteNG.Connection.Protocol.VNC; using mRemoteNG.Container; +using mRemoteNG.Credential; using mRemoteNG.Messages; using mRemoteNG.Security; using mRemoteNG.Tree; @@ -28,13 +31,15 @@ namespace mRemoteNG.Config.Serializers private XmlConnectionsDecryptor _decryptor; //TODO find way to inject data source info private string ConnectionFileName = ""; - private const double MaxSupportedConfVersion = 2.6; + private const double MaxSupportedConfVersion = 2.7; private RootNodeInfo _rootNodeInfo = new RootNodeInfo(RootNodeType.Connection); + private IEnumerable _credentialRecords; public Func AuthenticationRequestor { get; set; } - public XmlConnectionsDeserializer(string xml, Func authenticationRequestor = null) + public XmlConnectionsDeserializer(string xml, IEnumerable credentialRecords, Func authenticationRequestor = null) { + _credentialRecords = credentialRecords; AuthenticationRequestor = authenticationRequestor; LoadXmlConnectionData(xml); ValidateConnectionFileVersion(); @@ -218,9 +223,6 @@ namespace mRemoteNG.Config.Serializers connectionInfo.Name = xmlnode.Attributes["Name"].Value; connectionInfo.Description = xmlnode.Attributes["Descr"].Value; connectionInfo.Hostname = xmlnode.Attributes["Hostname"].Value; - connectionInfo.Username = xmlnode.Attributes["Username"].Value; - connectionInfo.Password = _decryptor.Decrypt(xmlnode.Attributes["Password"].Value); - connectionInfo.Domain = xmlnode.Attributes["Domain"].Value; connectionInfo.DisplayWallpaper = bool.Parse(xmlnode.Attributes["DisplayWallpaper"].Value); connectionInfo.DisplayThemes = bool.Parse(xmlnode.Attributes["DisplayThemes"].Value); connectionInfo.CacheBitmaps = bool.Parse(xmlnode.Attributes["CacheBitmaps"].Value); @@ -229,6 +231,13 @@ namespace mRemoteNG.Config.Serializers { connectionInfo.Resolution = Convert.ToBoolean(xmlnode.Attributes["Fullscreen"].Value) ? ProtocolRDP.RDPResolutions.Fullscreen : ProtocolRDP.RDPResolutions.FitToWindow; } + + if (_confVersion <= 2.6) // 0.2 - 2.6 + { + connectionInfo.Username = xmlnode.Attributes["Username"].Value; + connectionInfo.Password = _decryptor.Decrypt(xmlnode.Attributes["Password"].Value); + connectionInfo.Domain = xmlnode.Attributes["Domain"].Value; + } } if (_confVersion >= 0.3) @@ -343,10 +352,8 @@ namespace mRemoteNG.Config.Serializers Description = bool.Parse(xmlnode.Attributes["InheritDescription"].Value), DisplayThemes = bool.Parse(xmlnode.Attributes["InheritDisplayThemes"].Value), DisplayWallpaper = bool.Parse(xmlnode.Attributes["InheritDisplayWallpaper"].Value), - Domain = bool.Parse(xmlnode.Attributes["InheritDomain"].Value), Icon = bool.Parse(xmlnode.Attributes["InheritIcon"].Value), Panel = bool.Parse(xmlnode.Attributes["InheritPanel"].Value), - Password = bool.Parse(xmlnode.Attributes["InheritPassword"].Value), Port = bool.Parse(xmlnode.Attributes["InheritPort"].Value), Protocol = bool.Parse(xmlnode.Attributes["InheritProtocol"].Value), PuttySession = bool.Parse(xmlnode.Attributes["InheritPuttySession"].Value), @@ -358,8 +365,13 @@ namespace mRemoteNG.Config.Serializers RedirectSound = bool.Parse(xmlnode.Attributes["InheritRedirectSound"].Value), Resolution = bool.Parse(xmlnode.Attributes["InheritResolution"].Value), UseConsoleSession = bool.Parse(xmlnode.Attributes["InheritUseConsoleSession"].Value), - Username = bool.Parse(xmlnode.Attributes["InheritUsername"].Value) }; + if (_confVersion <= 2.6) // 1.3 - 2.6 + { + connectionInfo.Inheritance.Domain = bool.Parse(xmlnode.Attributes["InheritDomain"].Value); + connectionInfo.Inheritance.Password = bool.Parse(xmlnode.Attributes["InheritPassword"].Value); + connectionInfo.Inheritance.Username = bool.Parse(xmlnode.Attributes["InheritUsername"].Value); + } connectionInfo.Icon = xmlnode.Attributes["Icon"].Value; connectionInfo.Panel = xmlnode.Attributes["Panel"].Value; } @@ -491,6 +503,19 @@ namespace mRemoteNG.Config.Serializers connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0"); connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False"); } + + if (_confVersion >= 2.7) + { + connectionInfo.Inheritance.CredentialRecord = bool.Parse(xmlnode.Attributes["InheritCredentialRecord"]?.Value ?? "False"); + + var requestedCredentialId = xmlnode.Attributes["CredentialId"]?.Value; + if (requestedCredentialId != null && _credentialRecords.Any()) + { + var matchingCredential = _credentialRecords.Where(record => record.Id.ToString() == requestedCredentialId).ToArray(); + if (matchingCredential.Any()) + connectionInfo.CredentialRecord = matchingCredential.First(); + } + } } catch (Exception ex) { diff --git a/mRemoteV1/Config/Serializers/XmlRootNodeSerializer.cs b/mRemoteV1/Config/Serializers/XmlRootNodeSerializer.cs index 7b846ad38..228213712 100644 --- a/mRemoteV1/Config/Serializers/XmlRootNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlRootNodeSerializer.cs @@ -17,7 +17,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute(XName.Get("KdfIterations"), cryptographyProvider.KeyDerivationIterations)); element.Add(new XAttribute(XName.Get("FullFileEncryption"), fullFileEncryption.ToString())); element.Add(CreateProtectedAttribute(rootNodeInfo, cryptographyProvider, export)); - element.Add(new XAttribute(XName.Get("ConfVersion"), "2.6")); + element.Add(new XAttribute(XName.Get("ConfVersion"), "2.7")); return element; } diff --git a/mRemoteV1/Connection/AbstractConnectionRecord.cs b/mRemoteV1/Connection/AbstractConnectionRecord.cs index 97ca50921..b75cb14eb 100644 --- a/mRemoteV1/Connection/AbstractConnectionRecord.cs +++ b/mRemoteV1/Connection/AbstractConnectionRecord.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using mRemoteNG.Connection.Protocol; @@ -139,8 +140,13 @@ namespace mRemoteNG.Connection set { SetField(ref _credentialRecord, value, nameof(CredentialRecord)); } } + [Obsolete("Use the CredentialRecord property")] public virtual string Username { get; set; } + + [Obsolete("Use the CredentialRecord property")] public virtual string Domain { get; set; } + + [Obsolete("Use the CredentialRecord property")] public virtual string Password { get; set; } #endregion diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd index 3c6ec8618..b8d378003 100644 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd +++ b/mRemoteV1/Schemas/mremoteng_confcons_v2_7.xsd @@ -84,6 +84,7 @@ +