made the rdcm 2.7 importer compatible with credential management

This commit is contained in:
David Sparer
2019-01-20 12:38:39 -06:00
parent 9ead7e8e16
commit 8906e08704
4 changed files with 139 additions and 231 deletions

View File

@@ -2,7 +2,6 @@
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNGTests.Properties;
using NUnit.Framework;
using System.IO;
@@ -14,7 +13,8 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
private string _connectionFileContents;
private RemoteDesktopConnectionManagerDeserializer _deserializer;
private ConnectionTreeModel _connectionTreeModel;
private SerializationResult _serializationResult;
private ContainerInfo _rootContainerInfo;
private const string ExpectedName = "server1_displayname";
private const string ExpectedHostname = "server1";
private const string ExpectedDescription = "Comment text here";
@@ -44,38 +44,21 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
_connectionFileContents = Resources.test_rdcman_v2_7_schema3;
_deserializer = new RemoteDesktopConnectionManagerDeserializer();
_connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
}
[Test]
public void ConnectionTreeModelHasARootNode()
{
var numberOfRootNodes = _connectionTreeModel.RootNodes.Count;
Assert.That(numberOfRootNodes, Is.GreaterThan(0));
}
[Test]
public void RootNodeHasContents()
{
var rootNodeContents = _connectionTreeModel.RootNodes.First().Children;
Assert.That(rootNodeContents, Is.Not.Empty);
_serializationResult = _deserializer.Deserialize(_connectionFileContents);
_rootContainerInfo = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First();
}
[Test]
public void AllSubRootFoldersImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var rootNodeContents = importedRdcmanRootNode.Children.Count(node => node.Name == "Group1" || node.Name == "Group2");
var rootNodeContents = _rootContainerInfo.Children.Count(node => node.Name == "Group1" || node.Name == "Group2");
Assert.That(rootNodeContents, Is.EqualTo(2));
}
[Test]
public void ConnectionDisplayNameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Name, Is.EqualTo(ExpectedName));
}
@@ -83,9 +66,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionHostnameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Hostname, Is.EqualTo(ExpectedHostname));
}
@@ -93,31 +74,32 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionDescriptionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Description, Is.EqualTo(ExpectedDescription));
}
[Test]
public void CredentialIdCorrectlySet()
{
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
var cred = _serializationResult.ConnectionToCredentialMap.DistinctCredentialRecords.First();
Assert.That(connection.CredentialRecordId.FirstOrDefault(), Is.EqualTo(cred.Id));
}
[Test]
public void ConnectionUsernameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.CredentialRecord.Username, Is.EqualTo(ExpectedUsername));
var cred = _serializationResult.ConnectionToCredentialMap.DistinctCredentialRecords.First();
Assert.That(cred.Username, Is.EqualTo(ExpectedUsername));
}
[Test]
public void ConnectionDomainImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.CredentialRecord.Domain, Is.EqualTo(ExpectedDomain));
var cred = _serializationResult.ConnectionToCredentialMap.DistinctCredentialRecords.First();
Assert.That(cred.Domain, Is.EqualTo(ExpectedDomain));
}
// Since password is encrypted with a machine key, cant test decryption on another machine
@@ -134,9 +116,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionProtocolSetToRdp()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Protocol, Is.EqualTo(ProtocolType.RDP));
}
@@ -144,9 +124,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionUseConsoleSessionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.UseConsoleSession, Is.EqualTo(ExpectedUseConsoleSession));
}
@@ -154,9 +132,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionPortImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Port, Is.EqualTo(ExpectedPort));
}
@@ -164,9 +140,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayUsageMethodImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayUsageMethod, Is.EqualTo(ExpectedGatewayUsageMethod));
}
@@ -174,9 +148,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayHostnameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayHostname, Is.EqualTo(ExpectedGatewayHostname));
}
@@ -184,9 +156,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayUsernameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayUsername, Is.EqualTo(ExpectedGatewayUsername));
}
@@ -205,9 +175,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayDomainImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayDomain, Is.EqualTo(ExpectedGatewayDomain));
}
@@ -215,9 +183,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionResolutionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Resolution, Is.EqualTo(ExpectedRdpResolution));
}
@@ -225,9 +191,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionColorDepthImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Colors, Is.EqualTo(ExpectedRdpColorDepth));
}
@@ -235,9 +199,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionAudioRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectSound, Is.EqualTo(ExpectedAudioRedirection));
}
@@ -245,9 +207,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionKeyRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectKeys, Is.EqualTo(ExpectedKeyRedirection));
}
@@ -255,9 +215,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionDriveRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectDiskDrives, Is.EqualTo(ExpectedDriveRedirection));
}
@@ -265,9 +223,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionPortRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectPorts, Is.EqualTo(ExpectedPortRedirection));
}
@@ -275,9 +231,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionPrinterRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectPrinters, Is.EqualTo(ExpectedPrinterRedirection));
}
@@ -285,9 +239,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionSmartcardRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectSmartCards, Is.EqualTo(ExpectedSmartcardRedirection));
}
@@ -295,9 +247,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionauthenticationLevelImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _rootContainerInfo.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDPAuthenticationLevel, Is.EqualTo(ExpectedAuthLevel));
}

View File

@@ -2,7 +2,6 @@
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNGTests.Properties;
using NUnit.Framework;
using System.IO;
@@ -14,7 +13,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
private string _connectionFileContents;
private RemoteDesktopConnectionManagerDeserializer _deserializer;
private ConnectionTreeModel _connectionTreeModel;
private SerializationResult _serializationResult;
private const string ExpectedName = "server1_displayname";
private const string ExpectedHostname = "server1";
private const string ExpectedDescription = "Comment text here";
@@ -44,38 +43,20 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
_connectionFileContents = Resources.test_rdcman_v2_2_schema1;
_deserializer = new RemoteDesktopConnectionManagerDeserializer();
_connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
}
[Test]
public void ConnectionTreeModelHasARootNode()
{
var numberOfRootNodes = _connectionTreeModel.RootNodes.Count;
Assert.That(numberOfRootNodes, Is.GreaterThan(0));
}
[Test]
public void RootNodeHasContents()
{
var rootNodeContents = _connectionTreeModel.RootNodes.First().Children;
Assert.That(rootNodeContents, Is.Not.Empty);
_serializationResult = _deserializer.Deserialize(_connectionFileContents);
}
[Test]
public void AllSubRootFoldersImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var rootNodeContents = importedRdcmanRootNode.Children.Count(node => node.Name == "Group1" || node.Name == "Group2");
var rootNodeContents = _serializationResult.ConnectionRecords.Count(node => node.Name == "Group1" || node.Name == "Group2");
Assert.That(rootNodeContents, Is.EqualTo(2));
}
[Test]
public void ConnectionDisplayNameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Name, Is.EqualTo(ExpectedName));
}
@@ -83,9 +64,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionHostnameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Hostname, Is.EqualTo(ExpectedHostname));
}
@@ -93,9 +72,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionDescriptionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Description, Is.EqualTo(ExpectedDescription));
}
@@ -103,9 +80,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionUsernameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.CredentialRecord.Username, Is.EqualTo(ExpectedUsername));
}
@@ -113,9 +88,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionDomainImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.CredentialRecord.Domain, Is.EqualTo(ExpectedDomain));
}
@@ -126,7 +99,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
//{
// var rootNode = _connectionTreeModel.RootNodes.First();
// var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
// var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
// var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
// var connection = group1.Children.First();
// Assert.That(connection.Password, Is.EqualTo(ExpectedPassword));
//}
@@ -134,9 +107,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionProtocolSetToRdp()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Protocol, Is.EqualTo(ProtocolType.RDP));
}
@@ -144,9 +115,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionUseConsoleSessionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.UseConsoleSession, Is.EqualTo(ExpectedUseConsoleSession));
}
@@ -154,9 +123,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionPortImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Port, Is.EqualTo(ExpectedPort));
}
@@ -164,9 +131,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayUsageMethodImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayUsageMethod, Is.EqualTo(ExpectedGatewayUsageMethod));
}
@@ -174,9 +139,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayHostnameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayHostname, Is.EqualTo(ExpectedGatewayHostname));
}
@@ -184,9 +147,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayUsernameImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayUsername, Is.EqualTo(ExpectedGatewayUsername));
}
@@ -197,7 +158,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
//{
// var rootNode = _connectionTreeModel.RootNodes.First();
// var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
// var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
// var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
// var connection = group1.Children.First();
// Assert.That(connection.RDGatewayPassword, Is.EqualTo(ExpectedGatewayPassword));
//}
@@ -205,9 +166,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionGatewayDomainImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDGatewayDomain, Is.EqualTo(ExpectedGatewayDomain));
}
@@ -215,9 +174,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionResolutionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Resolution, Is.EqualTo(ExpectedRdpResolution));
}
@@ -225,9 +182,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionColorDepthImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.Colors, Is.EqualTo(ExpectedRdpColorDepth));
}
@@ -235,9 +190,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionAudioRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectSound, Is.EqualTo(ExpectedAudioRedirection));
}
@@ -245,9 +198,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionKeyRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectKeys, Is.EqualTo(ExpectedKeyRedirection));
}
@@ -255,9 +206,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionDriveRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectDiskDrives, Is.EqualTo(ExpectedDriveRedirection));
}
@@ -265,9 +214,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionPortRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectPorts, Is.EqualTo(ExpectedPortRedirection));
}
@@ -275,9 +222,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionPrinterRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectPrinters, Is.EqualTo(ExpectedPrinterRedirection));
}
@@ -285,9 +230,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionSmartcardRedirectionImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RedirectSmartCards, Is.EqualTo(ExpectedSmartcardRedirection));
}
@@ -295,9 +238,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
[Test]
public void ConnectionauthenticationLevelImported()
{
var rootNode = _connectionTreeModel.RootNodes.First();
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var group1 = _serializationResult.ConnectionRecords.OfType<ContainerInfo>().First(node => node.Name == "Group1");
var connection = group1.Children.First();
Assert.That(connection.RDPAuthenticationLevel, Is.EqualTo(ExpectedAuthLevel));
}

View File

@@ -1,4 +1,3 @@
using System.Linq;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Container;
@@ -14,12 +13,9 @@ namespace mRemoteNG.Config.Import
var fileContent = dataProvider.Load();
var deserializer = new RemoteDesktopConnectionManagerDeserializer();
var connectionTreeModel = deserializer.Deserialize(fileContent);
var serializationResult = deserializer.Deserialize(fileContent);
var importedRootNode = connectionTreeModel.RootNodes.First();
if (importedRootNode == null) return;
var childrenToAdd = importedRootNode.Children.ToArray();
destinationContainer.AddChildRange(childrenToAdd);
destinationContainer.AddChildRange(serializationResult.ConnectionRecords);
}
}
}

View File

@@ -1,42 +1,44 @@
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Serializers
{
public class RemoteDesktopConnectionManagerDeserializer : IDeserializer<string, ConnectionTreeModel>
public class RemoteDesktopConnectionManagerDeserializer
{
// 1 = RDCMan v2.2
// 3 = RDCMan v2.7
private static int _schemaVersion;
public ConnectionTreeModel Deserialize(string rdcmConnectionsXml)
public SerializationResult Deserialize(string rdcmConnectionsXml)
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
var serializationResult = new SerializationResult(new List<ConnectionInfo>(), new ConnectionToCredentialMap());
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(rdcmConnectionsXml);
var rdcManNode = xmlDocument.SelectSingleNode("/RDCMan");
VerifySchemaVersion(rdcManNode);
VerifyFileVersion(rdcManNode);
var fileNode = rdcManNode?.SelectSingleNode("./file");
ImportFileOrGroup(fileNode, root);
var importedItem = ImportFileOrGroup(fileNode, serializationResult.ConnectionToCredentialMap);
connectionTreeModel.AddRootNode(root);
return connectionTreeModel;
serializationResult.ConnectionRecords.Add(importedItem);
return serializationResult;
}
private static void VerifySchemaVersion(XmlNode rdcManNode)
@@ -77,28 +79,46 @@ namespace mRemoteNG.Config.Serializers
}
}
private static void ImportFileOrGroup(XmlNode xmlNode, ContainerInfo parentContainer)
private static ContainerInfo ImportFileOrGroup(XmlNode xmlNode, ConnectionToCredentialMap credentialMap)
{
var newContainer = ImportContainer(xmlNode, parentContainer);
var newContainer = ImportContainer(xmlNode);
var childNodes = xmlNode.SelectNodes("./group|./server");
if (childNodes == null) return;
if (childNodes == null)
return newContainer;
foreach (XmlNode childNode in childNodes)
{
ConnectionInfo newChild = null;
// ReSharper disable once SwitchStatementMissingSomeCases
switch (childNode.Name)
{
case "group":
ImportFileOrGroup(childNode, newContainer);
newChild = ImportFileOrGroup(childNode, credentialMap);
break;
case "server":
ImportServer(childNode, newContainer);
newChild = ConnectionInfoFromXml(childNode);
break;
}
if (newChild == null)
return newContainer;
newContainer.AddChild(newChild);
var cred = ParseCredentials(childNode);
if (!cred.Any())
continue;
newChild.CredentialRecordId = cred.First().Id;
credentialMap.Add(Guid.Parse(newChild.ConstantID), cred.First());
}
return newContainer;
}
private static ContainerInfo ImportContainer(XmlNode containerPropertiesNode, ContainerInfo parentContainer)
private static ContainerInfo ImportContainer(XmlNode containerPropertiesNode)
{
if (_schemaVersion == 1)
{
@@ -116,16 +136,9 @@ namespace mRemoteNG.Config.Serializers
}
newContainer.Name = containerPropertiesNode?.SelectSingleNode("./name")?.InnerText ?? Language.strNewFolder;
newContainer.IsExpanded = bool.Parse(containerPropertiesNode?.SelectSingleNode("./expanded")?.InnerText ?? "false");
parentContainer.AddChild(newContainer);
return newContainer;
}
private static void ImportServer(XmlNode serverNode, ContainerInfo parentContainer)
{
var newConnectionInfo = ConnectionInfoFromXml(serverNode);
parentContainer.AddChild(newConnectionInfo);
}
private static ConnectionInfo ConnectionInfoFromXml(XmlNode xmlNode)
{
var connectionInfo = new ConnectionInfo {Protocol = ProtocolType.RDP};
@@ -137,27 +150,8 @@ namespace mRemoteNG.Config.Serializers
connectionInfo.Name = propertiesNode?.SelectSingleNode("./displayName")?.InnerText ?? connectionInfo.Hostname;
connectionInfo.Description = propertiesNode?.SelectSingleNode("./comment")?.InnerText ?? string.Empty;
// TODO: harvest
var logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials");
if (logonCredentialsNode?.Attributes?["inherit"]?.Value == "None")
{
connectionInfo.Username = logonCredentialsNode.SelectSingleNode("userName")?.InnerText;
var passwordNode = logonCredentialsNode.SelectSingleNode("./password");
if (_schemaVersion == 1) // Version 2.2 allows clear text passwords
{
connectionInfo.Password = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True"
? passwordNode.InnerText
: DecryptRdcManPassword(passwordNode?.InnerText);
}
else
{
connectionInfo.Password = DecryptRdcManPassword(passwordNode?.InnerText);
}
connectionInfo.Domain = logonCredentialsNode.SelectSingleNode("./domain")?.InnerText;
}
else
if (logonCredentialsNode?.Attributes?["inherit"]?.Value != "None")
{
connectionInfo.Inheritance.Username = true;
connectionInfo.Inheritance.Password = true;
@@ -186,7 +180,9 @@ namespace mRemoteNG.Config.Serializers
connectionInfo.RDGatewayUsername = gatewaySettingsNode.SelectSingleNode("./userName")?.InnerText;
var passwordNode = gatewaySettingsNode.SelectSingleNode("./password");
connectionInfo.RDGatewayPassword = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True" ? passwordNode.InnerText : DecryptRdcManPassword(passwordNode?.InnerText);
connectionInfo.RDGatewayPassword = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True"
? passwordNode.InnerText
: DecryptRdcManPassword(passwordNode?.InnerText).ConvertToUnsecureString();
connectionInfo.RDGatewayDomain = gatewaySettingsNode.SelectSingleNode("./domain")?.InnerText;
// ./logonMethod
@@ -208,7 +204,9 @@ namespace mRemoteNG.Config.Serializers
var resolutionString = remoteDesktopNode.SelectSingleNode("./size")?.InnerText.Replace(" ", "");
try
{
connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), "Res" + resolutionString);
connectionInfo.Resolution = Enum.TryParse<RdpProtocol.RDPResolutions>("Res" + resolutionString, true, out var resolution)
? resolution
: RdpProtocol.RDPResolutions.FitToWindow;
}
catch (ArgumentException)
{
@@ -325,21 +323,44 @@ namespace mRemoteNG.Config.Serializers
return connectionInfo;
}
private static string DecryptRdcManPassword(string ciphertext)
private static Optional<ICredentialRecord> ParseCredentials(XmlNode xmlNode)
{
var logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials");
if (logonCredentialsNode?.Attributes?["inherit"]?.Value != "None")
return Optional<ICredentialRecord>.Empty;
var username = logonCredentialsNode.SelectSingleNode("userName")?.InnerText ?? "";
var domain = logonCredentialsNode.SelectSingleNode("./domain")?.InnerText ?? "";
var passwordNode = logonCredentialsNode.SelectSingleNode("./password");
var creds = new CredentialRecord
{
Title = domain.Length > 0 ? $"{domain}\\{username}" : $"{username}",
Username = username,
Domain = domain,
Password = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True"
? passwordNode.InnerText.ConvertToSecureString()
: DecryptRdcManPassword(passwordNode?.InnerText)
};
return creds;
}
private static SecureString DecryptRdcManPassword(string ciphertext)
{
if (string.IsNullOrEmpty(ciphertext))
return string.Empty;
return new SecureString();
try
{
var plaintextData = ProtectedData.Unprotect(Convert.FromBase64String(ciphertext), new byte[] { }, DataProtectionScope.LocalMachine);
var charArray = Encoding.Unicode.GetChars(plaintextData);
return new string(charArray);
return Encoding.Unicode.GetString(plaintextData).ConvertToSecureString();
}
catch (Exception /*ex*/)
{
//Runtime.MessageCollector.AddExceptionMessage("RemoteDesktopConnectionManager.DecryptPassword() failed.", ex, logOnly: true);
return string.Empty;
return new SecureString();
}
}
}