From 0d7c3838f6e68e6ad9965efd1d3a30132dfae1ae Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 27 Jan 2017 09:15:07 -0700 Subject: [PATCH] split connection serializer for confcons 2.6 and 2.7 into different classes resolved a bunch of test failures --- .../Config/CredentialHarvesterTests.cs | 5 +- ... => XmlConnectionNodeSerializer27Tests.cs} | 32 +-- .../XmlConnectionsDeserializerTests.cs | 3 +- .../XmlConnectionsDocumentCompilerTests.cs | 8 +- .../XmlConnectionsDocumentEncryptorTests.cs | 6 +- .../XmlConnectionsSerializerTests.cs | 9 +- .../Serializers/XmlRootNodeSerializerTests.cs | 2 +- .../XmlSerializationLifeCycleTests.cs | 36 +-- mRemoteNGTests/mRemoteNGTests.csproj | 2 +- mRemoteV1/App/Export.cs | 7 +- .../Config/Connections/ConnectionsSaver.cs | 3 +- mRemoteV1/Config/CredentialHarvester.cs | 1 - .../Serializers/IConnectionSerializer.cs | 10 + mRemoteV1/Config/Serializers/ISerializer.cs | 7 +- .../XmlConnectionNodeSerializer26.cs | 250 ++++++++++++++++++ ...er.cs => XmlConnectionNodeSerializer27.cs} | 8 +- .../XmlConnectionsDocumentCompiler.cs | 7 +- .../Serializers/XmlConnectionsSerializer.cs | 6 +- .../Connection/AbstractConnectionRecord.cs | 44 +-- mRemoteV1/Connection/ConnectionInfo.cs | 6 + mRemoteV1/mRemoteV1.csproj | 4 +- 21 files changed, 363 insertions(+), 93 deletions(-) rename mRemoteNGTests/Config/Serializers/{XmlConnectionNodeSerializerTests.cs => XmlConnectionNodeSerializer27Tests.cs} (89%) create mode 100644 mRemoteV1/Config/Serializers/IConnectionSerializer.cs create mode 100644 mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer26.cs rename mRemoteV1/Config/Serializers/{XmlConnectionNodeSerializer.cs => XmlConnectionNodeSerializer27.cs} (97%) diff --git a/mRemoteNGTests/Config/CredentialHarvesterTests.cs b/mRemoteNGTests/Config/CredentialHarvesterTests.cs index e67fe4ad0..02f5a053f 100644 --- a/mRemoteNGTests/Config/CredentialHarvesterTests.cs +++ b/mRemoteNGTests/Config/CredentialHarvesterTests.cs @@ -90,8 +90,9 @@ namespace mRemoteNGTests.Config { var rootNode = new RootNodeInfo(RootNodeType.Connection) {PasswordString = _key.ConvertToUnsecureString()}; rootNode.AddChild(connectionInfo); - var serialier = new XmlConnectionsSerializer(_cryptographyProvider); - var serializedData = serialier.Serialize(rootNode); + var nodeSerializer = new XmlConnectionNodeSerializer26(_cryptographyProvider, _key); + var serializer = new XmlConnectionsSerializer(_cryptographyProvider, nodeSerializer); + var serializedData = serializer.Serialize(rootNode); return XDocument.Parse(serializedData); } } diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionNodeSerializerTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionNodeSerializer27Tests.cs similarity index 89% rename from mRemoteNGTests/Config/Serializers/XmlConnectionNodeSerializerTests.cs rename to mRemoteNGTests/Config/Serializers/XmlConnectionNodeSerializer27Tests.cs index 9136450e7..332816f36 100644 --- a/mRemoteNGTests/Config/Serializers/XmlConnectionNodeSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionNodeSerializer27Tests.cs @@ -9,29 +9,29 @@ using NUnit.Framework; namespace mRemoteNGTests.Config.Serializers { - public class XmlConnectionNodeSerializerTests + public class XmlConnectionNodeSerializer27Tests { - private XmlConnectionNodeSerializer _connectionNodeSerializer; + private XmlConnectionNodeSerializer27 _connectionNodeSerializer; [SetUp] public void Setup() { var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider( BlockCipherEngines.AES, BlockCipherModes.GCM); - _connectionNodeSerializer = new XmlConnectionNodeSerializer(cryptoProvider, "myPassword1".ConvertToSecureString()); + _connectionNodeSerializer = new XmlConnectionNodeSerializer27(cryptoProvider, "myPassword1".ConvertToSecureString()); } [Test] public void ReturnsXElement() { - var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(new ConnectionInfo()); + var returnVal = _connectionNodeSerializer.Serialize(new ConnectionInfo()); Assert.That(returnVal, Is.TypeOf()); } [TestCaseSource(typeof(TestCaseDataSource), nameof(TestCaseDataSource.AttributesAndExpectedValues))] public void XmlElementContainsSerializedAttribute(string attributeName, string expectedValue, ConnectionInfo connectionInfo) { - var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(connectionInfo); + var returnVal = _connectionNodeSerializer.Serialize(connectionInfo); var targetAttribute = returnVal.Attribute(XName.Get(attributeName)); Assert.That(targetAttribute?.Value, Is.EqualTo(expectedValue)); } @@ -39,7 +39,7 @@ namespace mRemoteNGTests.Config.Serializers [TestCaseSource(typeof(TestCaseDataSource), nameof(TestCaseDataSource.PasswordAttributes))] public void PasswordFieldsAreSerialized(string attributeName, ConnectionInfo connectionInfo) { - var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(connectionInfo); + var returnVal = _connectionNodeSerializer.Serialize(connectionInfo); var targetAttribute = returnVal.Attribute(XName.Get(attributeName)); Assert.That(targetAttribute?.Value, Is.Not.Empty); } @@ -49,8 +49,8 @@ namespace mRemoteNGTests.Config.Serializers { var saveFilter = new SaveFilter(true); var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); - _connectionNodeSerializer = new XmlConnectionNodeSerializer(cryptoProvider, "myPassword1".ConvertToSecureString(), saveFilter); - var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(connectionInfo); + _connectionNodeSerializer = new XmlConnectionNodeSerializer27(cryptoProvider, "myPassword1".ConvertToSecureString(), saveFilter); + var returnVal = _connectionNodeSerializer.Serialize(connectionInfo); var targetAttribute = returnVal.Attribute(XName.Get(attributeName)); Assert.That(targetAttribute?.Value, Is.EqualTo(string.Empty)); } @@ -60,8 +60,8 @@ namespace mRemoteNGTests.Config.Serializers { var saveFilter = new SaveFilter(true); var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); - _connectionNodeSerializer = new XmlConnectionNodeSerializer(cryptoProvider, "myPassword1".ConvertToSecureString(), saveFilter); - var returnVal = _connectionNodeSerializer.SerializeConnectionInfo(connectionInfo); + _connectionNodeSerializer = new XmlConnectionNodeSerializer27(cryptoProvider, "myPassword1".ConvertToSecureString(), saveFilter); + var returnVal = _connectionNodeSerializer.Serialize(connectionInfo); var targetAttribute = returnVal.Attribute(XName.Get(attributeName)); Assert.That(targetAttribute?.Value, Is.EqualTo(false.ToString())); } @@ -102,9 +102,6 @@ namespace mRemoteNGTests.Config.Serializers { get { - yield return new TestCaseData("Username", ConnectionInfo); - yield return new TestCaseData("Domain", ConnectionInfo); - yield return new TestCaseData("Password", ConnectionInfo); yield return new TestCaseData("RDGatewayUsername", ConnectionInfo); yield return new TestCaseData("RDGatewayDomain", ConnectionInfo); yield return new TestCaseData("RDGatewayPassword", ConnectionInfo); @@ -117,9 +114,6 @@ namespace mRemoteNGTests.Config.Serializers { get { - yield return new TestCaseData("InheritUsername", ConnectionInfoWithInheritance); - yield return new TestCaseData("InheritDomain", ConnectionInfoWithInheritance); - yield return new TestCaseData("InheritPassword", ConnectionInfoWithInheritance); yield return new TestCaseData("InheritRDGatewayUsername", ConnectionInfoWithInheritance); yield return new TestCaseData("InheritRDGatewayDomain", ConnectionInfoWithInheritance); yield return new TestCaseData("InheritRDGatewayPassword", ConnectionInfoWithInheritance); @@ -132,7 +126,6 @@ namespace mRemoteNGTests.Config.Serializers { get { - yield return new TestCaseData("Password", ConnectionInfo); yield return new TestCaseData("VNCProxyPassword", ConnectionInfo); yield return new TestCaseData("RDGatewayPassword", ConnectionInfo); } @@ -149,8 +142,6 @@ namespace mRemoteNGTests.Config.Serializers yield return new TestCaseData("Descr", ConnectionInfo.Description, ConnectionInfo); yield return new TestCaseData("Icon", ConnectionInfo.Icon, ConnectionInfo); yield return new TestCaseData("Panel", "General", ConnectionInfo); - yield return new TestCaseData("Username", ConnectionInfo.Username, ConnectionInfo); - yield return new TestCaseData("Domain", ConnectionInfo.Domain, ConnectionInfo); yield return new TestCaseData("Hostname", ConnectionInfo.Hostname, ConnectionInfo); yield return new TestCaseData("Protocol", "RDP", ConnectionInfo); yield return new TestCaseData("PuttySession", ConnectionInfo.PuttySession, ConnectionInfo); @@ -203,10 +194,8 @@ namespace mRemoteNGTests.Config.Serializers yield return new TestCaseData("InheritDisplayWallpaper", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritEnableFontSmoothing", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritEnableDesktopComposition", false.ToString(), ConnectionInfo); - yield return new TestCaseData("InheritDomain", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritIcon", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritPanel", false.ToString(), ConnectionInfo); - yield return new TestCaseData("InheritPassword", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritPort", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritProtocol", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritPuttySession", false.ToString(), ConnectionInfo); @@ -222,7 +211,6 @@ namespace mRemoteNGTests.Config.Serializers yield return new TestCaseData("InheritUseConsoleSession", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritUseCredSsp", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritRenderingEngine", false.ToString(), ConnectionInfo); - yield return new TestCaseData("InheritUsername", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritICAEncryptionStrength", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritRDPAuthenticationLevel", false.ToString(), ConnectionInfo); yield return new TestCaseData("InheritLoadBalanceInfo", false.ToString(), ConnectionInfo); diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs index b9982f055..3d49b1544 100644 --- a/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs @@ -4,6 +4,7 @@ using System.Linq; using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.Credential; using mRemoteNG.Security; using mRemoteNG.Tree; using mRemoteNGTests.Properties; @@ -18,7 +19,7 @@ namespace mRemoteNGTests.Config.Serializers public void Setup(string confCons, string password) { - _xmlConnectionsDeserializer = new XmlConnectionsDeserializer(confCons, password.ConvertToSecureString); + _xmlConnectionsDeserializer = new XmlConnectionsDeserializer(confCons, new ICredentialRecord[0], password.ConvertToSecureString); _connectionTreeModel = _xmlConnectionsDeserializer.Deserialize(); } diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentCompilerTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentCompilerTests.cs index e7ba07be3..3a6fdbf64 100644 --- a/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentCompilerTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentCompilerTests.cs @@ -1,4 +1,5 @@ -using System.Xml.XPath; +using System.Linq; +using System.Xml.XPath; using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Container; @@ -27,9 +28,10 @@ namespace mRemoteNGTests.Config.Serializers [SetUp] public void Setup() { - _cryptographyProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); - _documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider); _connectionTreeModel = SetupConnectionTreeModel(); + _cryptographyProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); + var connectionNodeSerializer = new XmlConnectionNodeSerializer27(_cryptographyProvider, _connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString()); + _documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider, connectionNodeSerializer); } [Test] diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentEncryptorTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentEncryptorTests.cs index ec17d85de..a865624d8 100644 --- a/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentEncryptorTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionsDocumentEncryptorTests.cs @@ -1,4 +1,5 @@ -using System.Xml.Linq; +using System.Linq; +using System.Xml.Linq; using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Container; @@ -20,7 +21,8 @@ namespace mRemoteNGTests.Config.Serializers { var connectionTreeModel = SetupConnectionTreeModel(); var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); - _originalDocument = new XmlConnectionsDocumentCompiler(cryptoProvider).CompileDocument(connectionTreeModel, false, false); + var connectionNodeSerializer = new XmlConnectionNodeSerializer27(cryptoProvider, connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString()); + _originalDocument = new XmlConnectionsDocumentCompiler(cryptoProvider, connectionNodeSerializer).CompileDocument(connectionTreeModel, false, false); _documentEncryptor = new XmlConnectionsDocumentEncryptor(cryptoProvider); } diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs index 078a1b9b0..94f6e733b 100644 --- a/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs @@ -1,7 +1,9 @@ -using System.Xml; +using System.Linq; +using System.Xml; using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -19,9 +21,10 @@ namespace mRemoteNGTests.Config.Serializers [SetUp] public void Setup() { - var encryptor = new AeadCryptographyProvider(); - _serializer = new XmlConnectionsSerializer(encryptor); _connectionTreeModel = SetupConnectionTreeModel(); + var encryptor = new AeadCryptographyProvider(); + var connectionNodeSerializer = new XmlConnectionNodeSerializer27(encryptor, _connectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString()); + _serializer = new XmlConnectionsSerializer(encryptor, connectionNodeSerializer); } [Test] diff --git a/mRemoteNGTests/Config/Serializers/XmlRootNodeSerializerTests.cs b/mRemoteNGTests/Config/Serializers/XmlRootNodeSerializerTests.cs index ea523b8dd..0757ede27 100644 --- a/mRemoteNGTests/Config/Serializers/XmlRootNodeSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlRootNodeSerializerTests.cs @@ -116,7 +116,7 @@ namespace mRemoteNGTests.Config.Serializers { var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider); var attributeValue = element.Attribute(XName.Get("ConfVersion"))?.Value; - Assert.That(attributeValue, Is.EqualTo("2.6")); + Assert.That(attributeValue, Is.EqualTo("2.7")); } private class TestCaseSources diff --git a/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs b/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs index 1020cb9eb..645f6710c 100644 --- a/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs +++ b/mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs @@ -2,6 +2,7 @@ using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.Credential; using mRemoteNG.Security; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -14,12 +15,15 @@ namespace mRemoteNGTests.IntegrationTests { private XmlConnectionsSerializer _serializer; private XmlConnectionsDeserializer _deserializer; + private ConnectionTreeModel _originalModel; [SetUp] public void Setup() { + _originalModel = SetupConnectionTreeModel(); var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); - _serializer = new XmlConnectionsSerializer(cryptoProvider); + var nodeSerializer = new XmlConnectionNodeSerializer27(cryptoProvider, _originalModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString()); + _serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer); } [TearDown] @@ -32,37 +36,35 @@ namespace mRemoteNGTests.IntegrationTests [Test] public void SerializeThenDeserialize() { - var originalModel = SetupConnectionTreeModel(); - var serializedContent = _serializer.Serialize(originalModel); - _deserializer = new XmlConnectionsDeserializer(serializedContent); + var serializedContent = _serializer.Serialize(_originalModel); + _deserializer = new XmlConnectionsDeserializer(serializedContent, new ICredentialRecord[0]); var deserializedModel = _deserializer.Deserialize(); var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name); - var nodeNamesFromOriginalModel = originalModel.GetRecursiveChildList().Select(node => node.Name); + var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name); Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel)); } [Test] public void SerializeThenDeserializeWithFullEncryption() { - var originalModel = SetupConnectionTreeModel(); _serializer.UseFullEncryption = true; - var serializedContent = _serializer.Serialize(originalModel); - _deserializer = new XmlConnectionsDeserializer(serializedContent); + var serializedContent = _serializer.Serialize(_originalModel); + _deserializer = new XmlConnectionsDeserializer(serializedContent, new ICredentialRecord[0]); var deserializedModel = _deserializer.Deserialize(); var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name); - var nodeNamesFromOriginalModel = originalModel.GetRecursiveChildList().Select(node => node.Name); + var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name); Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel)); } [Test] public void SerializeAndDeserializePropertiesWithInternationalCharacters() { - var originalConnectionInfo = new ConnectionInfo {Name = "con1", Password = "£°úg¶┬ä" }; + var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" }; var serializedContent = _serializer.Serialize(originalConnectionInfo); - _deserializer = new XmlConnectionsDeserializer(serializedContent); + _deserializer = new XmlConnectionsDeserializer(serializedContent, new ICredentialRecord[0]); var deserializedModel = _deserializer.Deserialize(); var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name); - Assert.That(deserializedConnectionInfo.Password, Is.EqualTo(originalConnectionInfo.Password)); + Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description)); } @@ -71,13 +73,13 @@ namespace mRemoteNGTests.IntegrationTests { var cryptoProvider = new CryptographyProviderFactory().CreateAeadCryptographyProvider(BlockCipherEngines.AES, BlockCipherModes.GCM); cryptoProvider.KeyDerivationIterations = 5000; - _serializer = new XmlConnectionsSerializer(cryptoProvider); - var originalModel = SetupConnectionTreeModel(); - var serializedContent = _serializer.Serialize(originalModel); - _deserializer = new XmlConnectionsDeserializer(serializedContent); + var nodeSerializer = new XmlConnectionNodeSerializer27(cryptoProvider, _originalModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString()); + _serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer); + var serializedContent = _serializer.Serialize(_originalModel); + _deserializer = new XmlConnectionsDeserializer(serializedContent, new ICredentialRecord[0]); var deserializedModel = _deserializer.Deserialize(); var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name); - var nodeNamesFromOriginalModel = originalModel.GetRecursiveChildList().Select(node => node.Name); + var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name); Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel)); } diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 9c9607d51..96673c9d7 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -116,7 +116,7 @@ - + diff --git a/mRemoteV1/App/Export.cs b/mRemoteV1/App/Export.cs index ef3fbfa33..d86b50eee 100644 --- a/mRemoteV1/App/Export.cs +++ b/mRemoteV1/App/Export.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Security; using System.Windows.Forms; using mRemoteNG.Config.Connections; using mRemoteNG.Config.DataProviders; @@ -74,9 +75,11 @@ namespace mRemoteNG.App { case ConnectionsSaver.Format.mRXML: var factory = new CryptographyProviderFactory(); - var cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode); + var cryptographyProvider = factory.CreateAeadCryptographyProvider(Settings.Default.EncryptionEngine, Settings.Default.EncryptionBlockCipherMode); cryptographyProvider.KeyDerivationIterations = Settings.Default.EncryptionKeyDerivationIterations; - serializer = new XmlConnectionsSerializer(cryptographyProvider); + var rootNode = exportTarget.GetRootParent() as RootNodeInfo; + var connectionNodeSerializer = new XmlConnectionNodeSerializer27(cryptographyProvider, rootNode?.PasswordString.ConvertToSecureString() ?? new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString()); + serializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer); ((XmlConnectionsSerializer) serializer).SaveFilter = saveFilter; break; case ConnectionsSaver.Format.mRCSV: diff --git a/mRemoteV1/Config/Connections/ConnectionsSaver.cs b/mRemoteV1/Config/Connections/ConnectionsSaver.cs index 0059ca1b4..d31675690 100644 --- a/mRemoteV1/Config/Connections/ConnectionsSaver.cs +++ b/mRemoteV1/Config/Connections/ConnectionsSaver.cs @@ -245,7 +245,8 @@ namespace mRemoteNG.Config.Connections var factory = new CryptographyProviderFactory(); var cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode); cryptographyProvider.KeyDerivationIterations = mRemoteNG.Settings.Default.EncryptionKeyDerivationIterations; - var xmlConnectionsSerializer = new XmlConnectionsSerializer(cryptographyProvider) + var connectionNodeSerializer = new XmlConnectionNodeSerializer27(cryptographyProvider, ConnectionTreeModel.RootNodes.OfType().First().PasswordString.ConvertToSecureString()); + var xmlConnectionsSerializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer) { Export = Export, SaveFilter = SaveFilter, diff --git a/mRemoteV1/Config/CredentialHarvester.cs b/mRemoteV1/Config/CredentialHarvester.cs index c011f5259..a6baadfff 100644 --- a/mRemoteV1/Config/CredentialHarvester.cs +++ b/mRemoteV1/Config/CredentialHarvester.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Security; diff --git a/mRemoteV1/Config/Serializers/IConnectionSerializer.cs b/mRemoteV1/Config/Serializers/IConnectionSerializer.cs new file mode 100644 index 000000000..e57c02c2c --- /dev/null +++ b/mRemoteV1/Config/Serializers/IConnectionSerializer.cs @@ -0,0 +1,10 @@ +using mRemoteNG.Connection; + + +namespace mRemoteNG.Config.Serializers +{ + public interface IConnectionSerializer + { + TFormat Serialize(ConnectionInfo serializationTarget); + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/ISerializer.cs b/mRemoteV1/Config/Serializers/ISerializer.cs index 116ec562b..f53ea6fc5 100644 --- a/mRemoteV1/Config/Serializers/ISerializer.cs +++ b/mRemoteV1/Config/Serializers/ISerializer.cs @@ -1,12 +1,9 @@ -using mRemoteNG.Connection; -using mRemoteNG.Tree; +using mRemoteNG.Tree; namespace mRemoteNG.Config.Serializers { - public interface ISerializer + public interface ISerializer : IConnectionSerializer { TFormat Serialize(ConnectionTreeModel connectionTreeModel); - - TFormat Serialize(ConnectionInfo serializationTarget); } } \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer26.cs b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer26.cs new file mode 100644 index 000000000..ed6635a90 --- /dev/null +++ b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer26.cs @@ -0,0 +1,250 @@ +using System; +using System.Security; +using System.Xml.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Security; + + +namespace mRemoteNG.Config.Serializers +{ + // ReSharper disable once InconsistentNaming + [Obsolete("This serializer version is deprecated. Use XmlConnectionNodeSerializer")] + public class XmlConnectionNodeSerializer26 : IConnectionSerializer + { + private readonly ICryptographyProvider _cryptographyProvider; + private readonly SecureString _encryptionKey; + private readonly SaveFilter _saveFilter = new SaveFilter(); + + public XmlConnectionNodeSerializer26(ICryptographyProvider cryptographyProvider, SecureString encryptionKey) + { + _cryptographyProvider = cryptographyProvider; + _encryptionKey = encryptionKey; + } + + public XmlConnectionNodeSerializer26(ICryptographyProvider cryptographyProvider, SecureString encryptionKey, SaveFilter saveFilter) + { + _cryptographyProvider = cryptographyProvider; + _encryptionKey = encryptionKey; + _saveFilter = saveFilter; + } + + public XElement Serialize(ConnectionInfo connectionInfo) + { + var element = new XElement(XName.Get("Node", "")); + SetElementAttributes(element, connectionInfo); + SetInheritanceAttributes(element, connectionInfo); + return element; + } + + private void SetElementAttributes(XContainer element, ConnectionInfo connectionInfo) + { + var nodeAsContainer = connectionInfo as ContainerInfo; + element.Add(new XAttribute("Name", connectionInfo.Name)); + element.Add(new XAttribute("Type", connectionInfo.GetTreeNodeType().ToString())); + if (nodeAsContainer != null) + element.Add(new XAttribute("Expanded", nodeAsContainer.IsExpanded.ToString())); + element.Add(new XAttribute("Descr", connectionInfo.Description)); + element.Add(new XAttribute("Icon", connectionInfo.Icon)); + 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("Hostname", connectionInfo.Hostname)); + element.Add(new XAttribute("Protocol", connectionInfo.Protocol)); + element.Add(new XAttribute("PuttySession", connectionInfo.PuttySession)); + element.Add(new XAttribute("Port", connectionInfo.Port)); + element.Add(new XAttribute("ConnectToConsole", connectionInfo.UseConsoleSession.ToString())); + element.Add(new XAttribute("UseCredSsp", connectionInfo.UseCredSsp.ToString())); + element.Add(new XAttribute("RenderingEngine", connectionInfo.RenderingEngine)); + element.Add(new XAttribute("ICAEncryptionStrength", connectionInfo.ICAEncryptionStrength)); + element.Add(new XAttribute("RDPAuthenticationLevel", connectionInfo.RDPAuthenticationLevel)); + element.Add(new XAttribute("RDPMinutesToIdleTimeout", connectionInfo.RDPMinutesToIdleTimeout)); + element.Add(new XAttribute("LoadBalanceInfo", connectionInfo.LoadBalanceInfo)); + element.Add(new XAttribute("Colors", connectionInfo.Colors)); + element.Add(new XAttribute("Resolution", connectionInfo.Resolution)); + element.Add(new XAttribute("AutomaticResize", connectionInfo.AutomaticResize.ToString())); + element.Add(new XAttribute("DisplayWallpaper", connectionInfo.DisplayWallpaper.ToString())); + element.Add(new XAttribute("DisplayThemes", connectionInfo.DisplayThemes.ToString())); + element.Add(new XAttribute("EnableFontSmoothing", connectionInfo.EnableFontSmoothing.ToString())); + element.Add(new XAttribute("EnableDesktopComposition", connectionInfo.EnableDesktopComposition.ToString())); + element.Add(new XAttribute("CacheBitmaps", connectionInfo.CacheBitmaps.ToString())); + element.Add(new XAttribute("RedirectDiskDrives", connectionInfo.RedirectDiskDrives.ToString())); + element.Add(new XAttribute("RedirectPorts", connectionInfo.RedirectPorts.ToString())); + element.Add(new XAttribute("RedirectPrinters", connectionInfo.RedirectPrinters.ToString())); + element.Add(new XAttribute("RedirectSmartCards", connectionInfo.RedirectSmartCards.ToString())); + element.Add(new XAttribute("RedirectSound", connectionInfo.RedirectSound.ToString())); + element.Add(new XAttribute("SoundQuality", connectionInfo.SoundQuality.ToString())); + element.Add(new XAttribute("RedirectKeys", connectionInfo.RedirectKeys.ToString())); + element.Add(new XAttribute("Connected", (connectionInfo.OpenConnections.Count > 0).ToString())); + element.Add(new XAttribute("PreExtApp", connectionInfo.PreExtApp)); + element.Add(new XAttribute("PostExtApp", connectionInfo.PostExtApp)); + element.Add(new XAttribute("MacAddress", connectionInfo.MacAddress)); + element.Add(new XAttribute("UserField", connectionInfo.UserField)); + element.Add(new XAttribute("ExtApp", connectionInfo.ExtApp)); + element.Add(new XAttribute("VNCCompression", connectionInfo.VNCCompression)); + element.Add(new XAttribute("VNCEncoding", connectionInfo.VNCEncoding)); + element.Add(new XAttribute("VNCAuthMode", connectionInfo.VNCAuthMode)); + element.Add(new XAttribute("VNCProxyType", connectionInfo.VNCProxyType)); + element.Add(new XAttribute("VNCProxyIP", connectionInfo.VNCProxyIP)); + element.Add(new XAttribute("VNCProxyPort", connectionInfo.VNCProxyPort)); + + element.Add(_saveFilter.SaveUsername + ? new XAttribute("VNCProxyUsername", connectionInfo.VNCProxyUsername) + : new XAttribute("VNCProxyUsername", "")); + + element.Add(_saveFilter.SavePassword + ? new XAttribute("VNCProxyPassword", + _cryptographyProvider.Encrypt(connectionInfo.VNCProxyPassword, _encryptionKey)) + : new XAttribute("VNCProxyPassword", "")); + + element.Add(new XAttribute("VNCColors", connectionInfo.VNCColors)); + element.Add(new XAttribute("VNCSmartSizeMode", connectionInfo.VNCSmartSizeMode)); + element.Add(new XAttribute("VNCViewOnly", connectionInfo.VNCViewOnly.ToString())); + element.Add(new XAttribute("RDGatewayUsageMethod", connectionInfo.RDGatewayUsageMethod)); + element.Add(new XAttribute("RDGatewayHostname", connectionInfo.RDGatewayHostname)); + element.Add(new XAttribute("RDGatewayUseConnectionCredentials", connectionInfo.RDGatewayUseConnectionCredentials)); + + element.Add(_saveFilter.SaveUsername + ? new XAttribute("RDGatewayUsername", connectionInfo.RDGatewayUsername) + : new XAttribute("RDGatewayUsername", "")); + + element.Add(_saveFilter.SavePassword + ? new XAttribute("RDGatewayPassword", + _cryptographyProvider.Encrypt(connectionInfo.RDGatewayPassword, _encryptionKey)) + : new XAttribute("RDGatewayPassword", "")); + + element.Add(_saveFilter.SaveDomain + ? new XAttribute("RDGatewayDomain", connectionInfo.RDGatewayDomain) + : new XAttribute("RDGatewayDomain", "")); + } + + private void SetInheritanceAttributes(XContainer element, IInheritable connectionInfo) + { + if (_saveFilter.SaveInheritance) + { + 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())); + element.Add(new XAttribute("InheritDisplayThemes", connectionInfo.Inheritance.DisplayThemes.ToString())); + 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("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("InheritPort", connectionInfo.Inheritance.Port.ToString())); + element.Add(new XAttribute("InheritProtocol", connectionInfo.Inheritance.Protocol.ToString())); + element.Add(new XAttribute("InheritPuttySession", connectionInfo.Inheritance.PuttySession.ToString())); + element.Add(new XAttribute("InheritRedirectDiskDrives", connectionInfo.Inheritance.RedirectDiskDrives.ToString())); + element.Add(new XAttribute("InheritRedirectKeys", connectionInfo.Inheritance.RedirectKeys.ToString())); + element.Add(new XAttribute("InheritRedirectPorts", connectionInfo.Inheritance.RedirectPorts.ToString())); + element.Add(new XAttribute("InheritRedirectPrinters", connectionInfo.Inheritance.RedirectPrinters.ToString())); + element.Add(new XAttribute("InheritRedirectSmartCards", connectionInfo.Inheritance.RedirectSmartCards.ToString())); + element.Add(new XAttribute("InheritRedirectSound", connectionInfo.Inheritance.RedirectSound.ToString())); + element.Add(new XAttribute("InheritSoundQuality", connectionInfo.Inheritance.SoundQuality.ToString())); + element.Add(new XAttribute("InheritResolution", connectionInfo.Inheritance.Resolution.ToString())); + element.Add(new XAttribute("InheritAutomaticResize", connectionInfo.Inheritance.AutomaticResize.ToString())); + 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("InheritICAEncryptionStrength", connectionInfo.Inheritance.ICAEncryptionStrength.ToString())); + element.Add(new XAttribute("InheritRDPAuthenticationLevel", connectionInfo.Inheritance.RDPAuthenticationLevel.ToString())); + element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", connectionInfo.Inheritance.RDPMinutesToIdleTimeout.ToString())); + element.Add(new XAttribute("InheritLoadBalanceInfo", connectionInfo.Inheritance.LoadBalanceInfo.ToString())); + element.Add(new XAttribute("InheritPreExtApp", connectionInfo.Inheritance.PreExtApp.ToString())); + element.Add(new XAttribute("InheritPostExtApp", connectionInfo.Inheritance.PostExtApp.ToString())); + element.Add(new XAttribute("InheritMacAddress", connectionInfo.Inheritance.MacAddress.ToString())); + element.Add(new XAttribute("InheritUserField", connectionInfo.Inheritance.UserField.ToString())); + element.Add(new XAttribute("InheritExtApp", connectionInfo.Inheritance.ExtApp.ToString())); + element.Add(new XAttribute("InheritVNCCompression", connectionInfo.Inheritance.VNCCompression.ToString())); + element.Add(new XAttribute("InheritVNCEncoding", connectionInfo.Inheritance.VNCEncoding.ToString())); + element.Add(new XAttribute("InheritVNCAuthMode", connectionInfo.Inheritance.VNCAuthMode.ToString())); + element.Add(new XAttribute("InheritVNCProxyType", connectionInfo.Inheritance.VNCProxyType.ToString())); + element.Add(new XAttribute("InheritVNCProxyIP", connectionInfo.Inheritance.VNCProxyIP.ToString())); + element.Add(new XAttribute("InheritVNCProxyPort", connectionInfo.Inheritance.VNCProxyPort.ToString())); + element.Add(new XAttribute("InheritVNCProxyUsername", connectionInfo.Inheritance.VNCProxyUsername.ToString())); + element.Add(new XAttribute("InheritVNCProxyPassword", connectionInfo.Inheritance.VNCProxyPassword.ToString())); + element.Add(new XAttribute("InheritVNCColors", connectionInfo.Inheritance.VNCColors.ToString())); + element.Add(new XAttribute("InheritVNCSmartSizeMode", connectionInfo.Inheritance.VNCSmartSizeMode.ToString())); + element.Add(new XAttribute("InheritVNCViewOnly", connectionInfo.Inheritance.VNCViewOnly.ToString())); + element.Add(new XAttribute("InheritRDGatewayUsageMethod", connectionInfo.Inheritance.RDGatewayUsageMethod.ToString())); + element.Add(new XAttribute("InheritRDGatewayHostname", connectionInfo.Inheritance.RDGatewayHostname.ToString())); + element.Add(new XAttribute("InheritRDGatewayUseConnectionCredentials", connectionInfo.Inheritance.RDGatewayUseConnectionCredentials.ToString())); + element.Add(new XAttribute("InheritRDGatewayUsername", connectionInfo.Inheritance.RDGatewayUsername.ToString())); + element.Add(new XAttribute("InheritRDGatewayPassword", connectionInfo.Inheritance.RDGatewayPassword.ToString())); + element.Add(new XAttribute("InheritRDGatewayDomain", connectionInfo.Inheritance.RDGatewayDomain.ToString())); + } + else + { + element.Add(new XAttribute("InheritCacheBitmaps", false.ToString())); + element.Add(new XAttribute("InheritColors", false.ToString())); + element.Add(new XAttribute("InheritDescription", false.ToString())); + element.Add(new XAttribute("InheritDisplayThemes", false.ToString())); + 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("InheritIcon", false.ToString())); + element.Add(new XAttribute("InheritPanel", 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())); + element.Add(new XAttribute("InheritRedirectDiskDrives", false.ToString())); + element.Add(new XAttribute("InheritRedirectKeys", false.ToString())); + element.Add(new XAttribute("InheritRedirectPorts", false.ToString())); + element.Add(new XAttribute("InheritRedirectPrinters", false.ToString())); + element.Add(new XAttribute("InheritRedirectSmartCards", false.ToString())); + element.Add(new XAttribute("InheritRedirectSound", false.ToString())); + element.Add(new XAttribute("InheritSoundQuality", false.ToString())); + element.Add(new XAttribute("InheritResolution", false.ToString())); + element.Add(new XAttribute("InheritAutomaticResize", false.ToString())); + 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("InheritICAEncryptionStrength", false.ToString())); + element.Add(new XAttribute("InheritRDPAuthenticationLevel", false.ToString())); + element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", false.ToString())); + element.Add(new XAttribute("InheritLoadBalanceInfo", false.ToString())); + element.Add(new XAttribute("InheritPreExtApp", false.ToString())); + element.Add(new XAttribute("InheritPostExtApp", false.ToString())); + element.Add(new XAttribute("InheritMacAddress", false.ToString())); + element.Add(new XAttribute("InheritUserField", false.ToString())); + element.Add(new XAttribute("InheritExtApp", false.ToString())); + element.Add(new XAttribute("InheritVNCCompression", false.ToString())); + element.Add(new XAttribute("InheritVNCEncoding", false.ToString())); + element.Add(new XAttribute("InheritVNCAuthMode", false.ToString())); + element.Add(new XAttribute("InheritVNCProxyType", false.ToString())); + element.Add(new XAttribute("InheritVNCProxyIP", false.ToString())); + element.Add(new XAttribute("InheritVNCProxyPort", false.ToString())); + element.Add(new XAttribute("InheritVNCProxyUsername", false.ToString())); + element.Add(new XAttribute("InheritVNCProxyPassword", false.ToString())); + element.Add(new XAttribute("InheritVNCColors", false.ToString())); + element.Add(new XAttribute("InheritVNCSmartSizeMode", false.ToString())); + element.Add(new XAttribute("InheritVNCViewOnly", false.ToString())); + element.Add(new XAttribute("InheritRDGatewayUsageMethod", false.ToString())); + element.Add(new XAttribute("InheritRDGatewayHostname", false.ToString())); + element.Add(new XAttribute("InheritRDGatewayUseConnectionCredentials", false.ToString())); + element.Add(new XAttribute("InheritRDGatewayUsername", false.ToString())); + element.Add(new XAttribute("InheritRDGatewayPassword", false.ToString())); + element.Add(new XAttribute("InheritRDGatewayDomain", false.ToString())); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer27.cs similarity index 97% rename from mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs rename to mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer27.cs index 7895464ca..807819ecf 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer27.cs @@ -7,26 +7,26 @@ using mRemoteNG.Security; namespace mRemoteNG.Config.Serializers { - public class XmlConnectionNodeSerializer + public class XmlConnectionNodeSerializer27 : IConnectionSerializer { private readonly ICryptographyProvider _cryptographyProvider; private readonly SecureString _encryptionKey; private readonly SaveFilter _saveFilter = new SaveFilter(); - public XmlConnectionNodeSerializer(ICryptographyProvider cryptographyProvider, SecureString encryptionKey) + public XmlConnectionNodeSerializer27(ICryptographyProvider cryptographyProvider, SecureString encryptionKey) { _cryptographyProvider = cryptographyProvider; _encryptionKey = encryptionKey; } - public XmlConnectionNodeSerializer(ICryptographyProvider cryptographyProvider, SecureString encryptionKey, SaveFilter saveFilter) + public XmlConnectionNodeSerializer27(ICryptographyProvider cryptographyProvider, SecureString encryptionKey, SaveFilter saveFilter) { _cryptographyProvider = cryptographyProvider; _encryptionKey = encryptionKey; _saveFilter = saveFilter; } - public XElement SerializeConnectionInfo(ConnectionInfo connectionInfo) + public XElement Serialize(ConnectionInfo connectionInfo) { var element = new XElement(XName.Get("Node", "")); SetElementAttributes(element, connectionInfo); diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDocumentCompiler.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDocumentCompiler.cs index 15e14e198..dfc17f540 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDocumentCompiler.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDocumentCompiler.cs @@ -14,10 +14,12 @@ namespace mRemoteNG.Config.Serializers { private readonly ICryptographyProvider _cryptographyProvider; private SecureString _encryptionKey; + private readonly IConnectionSerializer _connectionNodeSerializer; - public XmlConnectionsDocumentCompiler(ICryptographyProvider cryptographyProvider) + public XmlConnectionsDocumentCompiler(ICryptographyProvider cryptographyProvider, IConnectionSerializer connectionNodeSerializer) { _cryptographyProvider = cryptographyProvider; + _connectionNodeSerializer = connectionNodeSerializer; } public XDocument CompileDocument(ConnectionTreeModel connectionTreeModel, bool fullFileEncryption, bool export) @@ -77,8 +79,7 @@ namespace mRemoteNG.Config.Serializers private XElement CompileConnectionInfoNode(ConnectionInfo connectionInfo) { - var connectionSerializer = new XmlConnectionNodeSerializer(_cryptographyProvider, _encryptionKey); - return connectionSerializer.SerializeConnectionInfo(connectionInfo); + return _connectionNodeSerializer.Serialize(connectionInfo); } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs index 72a6682fc..a38b207ba 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs @@ -15,14 +15,16 @@ namespace mRemoteNG.Config.Serializers public class XmlConnectionsSerializer : ISerializer { private readonly ICryptographyProvider _cryptographyProvider; + private readonly IConnectionSerializer _connectionNodeSerializer; public bool Export { get; set; } public SaveFilter SaveFilter { get; set; } = new SaveFilter(); public bool UseFullEncryption { get; set; } - public XmlConnectionsSerializer(ICryptographyProvider cryptographyProvider) + public XmlConnectionsSerializer(ICryptographyProvider cryptographyProvider, IConnectionSerializer connectionNodeSerializer) { _cryptographyProvider = cryptographyProvider; + _connectionNodeSerializer = connectionNodeSerializer; } public string Serialize(ConnectionTreeModel connectionTreeModel) @@ -41,7 +43,7 @@ namespace mRemoteNG.Config.Serializers var xml = ""; try { - var documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider); + var documentCompiler = new XmlConnectionsDocumentCompiler(_cryptographyProvider, _connectionNodeSerializer); var xmlDocument = documentCompiler.CompileDocument(serializationTarget, UseFullEncryption, Export); xml = WriteXmlToString(xmlDocument); } diff --git a/mRemoteV1/Connection/AbstractConnectionRecord.cs b/mRemoteV1/Connection/AbstractConnectionRecord.cs index 7d5ac2b11..e72bbbcfa 100644 --- a/mRemoteV1/Connection/AbstractConnectionRecord.cs +++ b/mRemoteV1/Connection/AbstractConnectionRecord.cs @@ -17,32 +17,32 @@ namespace mRemoteNG.Connection public abstract class AbstractConnectionRecord : INotifyPropertyChanged { #region Fields - private string _name; - private string _description; - private string _icon; - private string _panel; + private string _name = ""; + private string _description = ""; + private string _icon = ""; + private string _panel = ""; - private string _hostname; + private string _hostname = ""; private ICredentialRecord _credentialRecord; private ProtocolType _protocol; - private string _extApp; + private string _extApp = ""; private int _port; - private string _puttySession; + private string _puttySession = ""; private ProtocolICA.EncryptionStrength _icaEncryption; private bool _useConsoleSession; private ProtocolRDP.AuthenticationLevel _rdpAuthenticationLevel; private int _rdpMinutesToIdleTimeout; - private string _loadBalanceInfo; + private string _loadBalanceInfo = ""; private HTTPBase.RenderingEngine _renderingEngine; private bool _useCredSsp; private ProtocolRDP.RDGatewayUsageMethod _rdGatewayUsageMethod; - private string _rdGatewayHostname; + private string _rdGatewayHostname = ""; private ProtocolRDP.RDGatewayUseConnectionCredentials _rdGatewayUseConnectionCredentials; - private string _rdGatewayUsername; - private string _rdGatewayPassword; - private string _rdGatewayDomain; + private string _rdGatewayUsername = ""; + private string _rdGatewayPassword = ""; + private string _rdGatewayDomain = ""; private ProtocolRDP.RDPResolutions _resolution; private bool _automaticResize; @@ -61,19 +61,19 @@ namespace mRemoteNG.Connection private ProtocolRDP.RDPSounds _redirectSound; private ProtocolRDP.RDPSoundQuality _soundQuality; - private string _preExtApp; - private string _postExtApp; - private string _macAddress; - private string _userField; + private string _preExtApp = ""; + private string _postExtApp = ""; + private string _macAddress = ""; + private string _userField = ""; private ProtocolVNC.Compression _vncCompression; private ProtocolVNC.Encoding _vncEncoding; private ProtocolVNC.AuthMode _vncAuthMode; private ProtocolVNC.ProxyType _vncProxyType; - private string _vncProxyIp; + private string _vncProxyIp = ""; private int _vncProxyPort; - private string _vncProxyUsername; - private string _vncProxyPassword; + private string _vncProxyUsername = ""; + private string _vncProxyPassword = ""; private ProtocolVNC.Colors _vncColors; private ProtocolVNC.SmartSizeMode _vncSmartSizeMode; private bool _vncViewOnly; @@ -142,15 +142,15 @@ namespace mRemoteNG.Connection [Obsolete("Use the CredentialRecord property")] [Browsable(false)] - public virtual string Username { get; set; } + public virtual string Username { get; set; } = ""; [Obsolete("Use the CredentialRecord property")] [Browsable(false)] - public virtual string Domain { get; set; } + public virtual string Domain { get; set; } = ""; [Obsolete("Use the CredentialRecord property")] [Browsable(false)] - public virtual string Password { get; set; } + public virtual string Password { get; set; } = ""; #endregion #region Protocol diff --git a/mRemoteV1/Connection/ConnectionInfo.cs b/mRemoteV1/Connection/ConnectionInfo.cs index a147553da..5e66ac965 100644 --- a/mRemoteV1/Connection/ConnectionInfo.cs +++ b/mRemoteV1/Connection/ConnectionInfo.cs @@ -137,6 +137,12 @@ namespace mRemoteNG.Connection { Parent?.RemoveChild(this); } + + public ConnectionInfo GetRootParent() + { + return Parent != null ? Parent.GetRootParent() : this; + } + #endregion #region Public Enumerations diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index d3bf3b3de..f08f32e73 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -141,11 +141,13 @@ + + @@ -154,7 +156,7 @@ - +