implemented importing of basic RDM connection types

This commit is contained in:
David Sparer
2020-01-26 16:43:09 -06:00
parent 9257b7ac52
commit 11ea575898
12 changed files with 942 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
using mRemoteNG.Config.Serializers.MiscSerializers;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNGTests.Properties;
using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
public class RemoteDesktopManagerDeserializerTests
{
private readonly RemoteDesktopManagerDeserializer _sut = new RemoteDesktopManagerDeserializer();
private readonly Dictionary<ProtocolType, string> _rdmExports = new Dictionary<ProtocolType, string>
{
{ProtocolType.RDP, Resources.rdp_rdm_export},
{ProtocolType.SSH2, Resources.ssh_rdm_export},
{ProtocolType.VNC, Resources.vnc_rdm_export},
{ProtocolType.Telnet, Resources.telnet_rdm_export},
{ProtocolType.HTTPS, Resources.website_rdm_export},
};
[TestCaseSource(nameof(RdpPropertiesAndValues))]
public void CorrectlyImportsRdpProperties(string propertyName, object expectedValue)
{
var rootContainer = _sut.Deserialize(_rdmExports[ProtocolType.RDP]);
var node = rootContainer.RootNodes[0].Children.FirstOrDefault(i => i.Protocol == ProtocolType.RDP);
Assert.That(node, Is.Not.Null);
var actualValue = node.GetType().GetProperty(propertyName)?.GetValue(node);
Assert.That(actualValue, Is.EqualTo(expectedValue));
}
[TestCaseSource(nameof(SshPropertiesAndValues))]
public void CorrectlyImportsSshProperties(string propertyName, object expectedValue)
{
var rootContainer = _sut.Deserialize(_rdmExports[ProtocolType.SSH2]);
var node = rootContainer.RootNodes[0].Children.FirstOrDefault(i => i.Protocol == ProtocolType.SSH2);
Assert.That(node, Is.Not.Null);
var actualValue = node.GetType().GetProperty(propertyName)?.GetValue(node);
Assert.That(actualValue, Is.EqualTo(expectedValue));
}
[TestCaseSource(nameof(VncPropertiesAndValues))]
public void CorrectlyImportsVncProperties(string propertyName, object expectedValue)
{
var rootContainer = _sut.Deserialize(_rdmExports[ProtocolType.VNC]);
var node = rootContainer.RootNodes[0].Children.FirstOrDefault(i => i.Protocol == ProtocolType.VNC);
Assert.That(node, Is.Not.Null);
var actualValue = node.GetType().GetProperty(propertyName)?.GetValue(node);
Assert.That(actualValue, Is.EqualTo(expectedValue));
}
[TestCaseSource(nameof(TelnetPropertiesAndValues))]
public void CorrectlyImportsTelnetProperties(string propertyName, object expectedValue)
{
var rootContainer = _sut.Deserialize(_rdmExports[ProtocolType.Telnet]);
var node = rootContainer.RootNodes[0].Children.FirstOrDefault(i => i.Protocol == ProtocolType.Telnet);
Assert.That(node, Is.Not.Null);
var actualValue = node.GetType().GetProperty(propertyName)?.GetValue(node);
Assert.That(actualValue, Is.EqualTo(expectedValue));
}
[TestCaseSource(nameof(WebsitePropertiesAndValues))]
public void CorrectlyImportsWebsiteProperties(string propertyName, object expectedValue)
{
var rootContainer = _sut.Deserialize(_rdmExports[ProtocolType.HTTPS]);
var node = rootContainer.RootNodes[0].Children.FirstOrDefault(i => i.Protocol == ProtocolType.HTTPS);
Assert.That(node, Is.Not.Null);
var actualValue = node.GetType().GetProperty(propertyName)?.GetValue(node);
Assert.That(actualValue, Is.EqualTo(expectedValue));
}
private static IEnumerable<TestCaseData> RdpPropertiesAndValues()
{
return new[]
{
new TestCaseData(nameof(ConnectionInfo.ConstantID), "1f36e6f0-90ca-4607-b6ec-86227738486d"),
new TestCaseData(nameof(ConnectionInfo.Name), "rdp connection"),
new TestCaseData(nameof(ConnectionInfo.Protocol), ProtocolType.RDP),
new TestCaseData(nameof(ConnectionInfo.Hostname), "my.rdp.host.com"),
new TestCaseData(nameof(ConnectionInfo.Description), "This is a general description"),
new TestCaseData(nameof(ConnectionInfo.Username), "user1"),
new TestCaseData(nameof(ConnectionInfo.Domain), "domain1"),
//new TestCaseData(nameof(ConnectionInfo.Password), "password1"),
new TestCaseData(nameof(ConnectionInfo.Resolution), RDPResolutions.FitToWindow),
new TestCaseData(nameof(ConnectionInfo.AutomaticResize), true),
new TestCaseData(nameof(ConnectionInfo.CacheBitmaps), false),
new TestCaseData(nameof(ConnectionInfo.DisplayThemes), false),
new TestCaseData(nameof(ConnectionInfo.DisplayWallpaper), false),
new TestCaseData(nameof(ConnectionInfo.EnableDesktopComposition), true),
new TestCaseData(nameof(ConnectionInfo.EnableFontSmoothing), true),
new TestCaseData(nameof(ConnectionInfo.RedirectSound), RDPSounds.DoNotPlay),
new TestCaseData(nameof(ConnectionInfo.RedirectAudioCapture), true),
new TestCaseData(nameof(ConnectionInfo.RedirectClipboard), false),
new TestCaseData(nameof(ConnectionInfo.RedirectDiskDrives), false),
new TestCaseData(nameof(ConnectionInfo.RedirectPrinters), true),
new TestCaseData(nameof(ConnectionInfo.RedirectPorts), false),
new TestCaseData(nameof(ConnectionInfo.RedirectSmartCards), true),
new TestCaseData(nameof(ConnectionInfo.RDPMinutesToIdleTimeout), 17),
new TestCaseData(nameof(ConnectionInfo.MacAddress), "mac-add-goes-here"),
new TestCaseData(nameof(ConnectionInfo.UseCredSsp), true),
new TestCaseData(nameof(ConnectionInfo.Port), 1234),
new TestCaseData(nameof(ConnectionInfo.RdpVersion), RdpVersion.Rdc7),
new TestCaseData(nameof(ConnectionInfo.RedirectKeys), true),
new TestCaseData(nameof(ConnectionInfo.UseConsoleSession), true),
new TestCaseData(nameof(ConnectionInfo.RDPAuthenticationLevel), AuthenticationLevel.WarnOnFailedAuth),
new TestCaseData(nameof(ConnectionInfo.RDGatewayUsageMethod), RDGatewayUsageMethod.Always),
new TestCaseData(nameof(ConnectionInfo.RDGatewayUseConnectionCredentials), RDGatewayUseConnectionCredentials.Yes),
new TestCaseData(nameof(ConnectionInfo.RDGatewayHostname), "rdhost1"),
new TestCaseData(nameof(ConnectionInfo.RDGatewayUsername), "rduser1"),
new TestCaseData(nameof(ConnectionInfo.RDGatewayDomain), "rddomain1"),
//new TestCaseData(nameof(ConnectionInfo.RDGatewayPassword), "rdpassword1"),
new TestCaseData(nameof(ConnectionInfo.UseEnhancedMode), true),
new TestCaseData(nameof(ConnectionInfo.UseVmId), true),
new TestCaseData(nameof(ConnectionInfo.VmId), "instance-id-here"),
};
}
private static IEnumerable<TestCaseData> SshPropertiesAndValues()
{
return new[]
{
new TestCaseData(nameof(ConnectionInfo.ConstantID), "44ae261f-0094-48a2-93cb-bc5abcfcc394"),
new TestCaseData(nameof(ConnectionInfo.Name), "ssh connection"),
new TestCaseData(nameof(ConnectionInfo.Protocol), ProtocolType.SSH2),
new TestCaseData(nameof(ConnectionInfo.Hostname), "mysshhost"),
new TestCaseData(nameof(ConnectionInfo.Description), "This is a linux host description"),
new TestCaseData(nameof(ConnectionInfo.Username), "linuxuser1"),
//new TestCaseData(nameof(ConnectionInfo.Password), "linuxpassword1"),
new TestCaseData(nameof(ConnectionInfo.MacAddress), "some-mac-here"),
new TestCaseData(nameof(ConnectionInfo.Port), 4321),
};
}
private static IEnumerable<TestCaseData> VncPropertiesAndValues()
{
return new[]
{
new TestCaseData(nameof(ConnectionInfo.ConstantID), "16ff7dd6-2ac3-4e27-96cf-435b5bfe5a00"),
new TestCaseData(nameof(ConnectionInfo.Name), "vnc connection"),
new TestCaseData(nameof(ConnectionInfo.Protocol), ProtocolType.VNC),
new TestCaseData(nameof(ConnectionInfo.Hostname), "vnchost1"),
new TestCaseData(nameof(ConnectionInfo.Port), 9987),
new TestCaseData(nameof(ConnectionInfo.Description), "This is a VNC description"),
new TestCaseData(nameof(ConnectionInfo.Username), "winuser1"),
new TestCaseData(nameof(ConnectionInfo.Domain), "windomain1"),
//new TestCaseData(nameof(ConnectionInfo.Password), "vncpassword1"),
new TestCaseData(nameof(ConnectionInfo.MacAddress), "some-mac-here"),
new TestCaseData(nameof(ConnectionInfo.VNCEncoding), ProtocolVNC.Encoding.EncTight),
new TestCaseData(nameof(ConnectionInfo.VNCAuthMode), ProtocolVNC.AuthMode.AuthWin),
new TestCaseData(nameof(ConnectionInfo.VNCCompression), ProtocolVNC.Compression.Comp4),
new TestCaseData(nameof(ConnectionInfo.VNCViewOnly), true),
new TestCaseData(nameof(ConnectionInfo.VNCProxyIP), "proxyhost"),
new TestCaseData(nameof(ConnectionInfo.VNCProxyPort), 7777),
};
}
private static IEnumerable<TestCaseData> TelnetPropertiesAndValues()
{
return new[]
{
new TestCaseData(nameof(ConnectionInfo.ConstantID), "8d77d3ac-b414-4b51-ac10-60304d63cc6f"),
new TestCaseData(nameof(ConnectionInfo.Name), "telnet connection"),
new TestCaseData(nameof(ConnectionInfo.Protocol), ProtocolType.Telnet),
new TestCaseData(nameof(ConnectionInfo.Hostname), "telnethost1"),
new TestCaseData(nameof(ConnectionInfo.Description), "Telnet description"),
new TestCaseData(nameof(ConnectionInfo.Username), "user1"),
//new TestCaseData(nameof(ConnectionInfo.Password), "password1"),
new TestCaseData(nameof(ConnectionInfo.MacAddress), "some-mac-here"),
new TestCaseData(nameof(ConnectionInfo.Port), 7648),
};
}
private static IEnumerable<TestCaseData> WebsitePropertiesAndValues()
{
return new[]
{
new TestCaseData(nameof(ConnectionInfo.ConstantID), "65092747-6870-42c9-b8bc-35ec9fb5b3fb"),
new TestCaseData(nameof(ConnectionInfo.Name), "website connection"),
new TestCaseData(nameof(ConnectionInfo.Protocol), ProtocolType.HTTPS),
new TestCaseData(nameof(ConnectionInfo.Hostname), "www.google.com"),
new TestCaseData(nameof(ConnectionInfo.Description), "Website description"),
new TestCaseData(nameof(ConnectionInfo.Username), "user1"),
new TestCaseData(nameof(ConnectionInfo.Domain), "domain1"),
//new TestCaseData(nameof(ConnectionInfo.Password), "password1"),
new TestCaseData(nameof(ConnectionInfo.Port), 8080),
new TestCaseData(nameof(ConnectionInfo.RenderingEngine), HTTPBase.RenderingEngine.Gecko),
};
}
}
}

View File

@@ -194,6 +194,71 @@ namespace mRemoteNGTests.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot;?&gt;
///&lt;ArrayOfConnection&gt;
/// &lt;Connection&gt;
/// &lt;AuthentificationLevel&gt;WarnMe&lt;/AuthentificationLevel&gt;
/// &lt;AutomaticallyClose&gt;true&lt;/AutomaticallyClose&gt;
/// &lt;AutomaticallyCloseInterval&gt;17&lt;/AutomaticallyCloseInterval&gt;
/// &lt;ConnectionType&gt;RDPConfigured&lt;/ConnectionType&gt;
/// &lt;Console&gt;true&lt;/Console&gt;
/// &lt;Description&gt;This is a general description&lt;/Description&gt;
/// &lt;DesktopComposition&gt;true&lt;/DesktopComposition&gt;
/// &lt;DisableBitmapCache&gt;true&lt;/DisableBitmapCache&gt;
/// &lt;DisableThemes&gt;true&lt;/Disable [rest of string was truncated]&quot;;.
/// </summary>
internal static string rdp_rdm_export {
get {
return ResourceManager.GetString("rdp_rdm_export", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot;?&gt;
///&lt;ArrayOfConnection&gt;
/// &lt;Connection&gt;
/// &lt;ConnectionType&gt;SSHShell&lt;/ConnectionType&gt;
/// &lt;Description&gt;This is a linux host description&lt;/Description&gt;
/// &lt;ID&gt;44ae261f-0094-48a2-93cb-bc5abcfcc394&lt;/ID&gt;
/// &lt;Name&gt;ssh connection&lt;/Name&gt;
/// &lt;OpenEmbedded&gt;true&lt;/OpenEmbedded&gt;
/// &lt;Stamp&gt;ab007011-2836-426f-a8e0-9fef1ff88865&lt;/Stamp&gt;
/// &lt;MetaInformation&gt;
/// &lt;MAC&gt;some-mac-here&lt;/MAC&gt;
/// &lt;PasswordHistory&gt;
/// &lt;PasswordHistory&gt;
/// &lt;LoggedModifiedBy&gt;LEVIATHAN\David&lt;/LoggedMo [rest of string was truncated]&quot;;.
/// </summary>
internal static string ssh_rdm_export {
get {
return ResourceManager.GetString("ssh_rdm_export", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot;?&gt;
///&lt;ArrayOfConnection&gt;
/// &lt;Connection&gt;
/// &lt;ConnectionType&gt;Telnet&lt;/ConnectionType&gt;
/// &lt;Description&gt;Telnet description&lt;/Description&gt;
/// &lt;ID&gt;8d77d3ac-b414-4b51-ac10-60304d63cc6f&lt;/ID&gt;
/// &lt;Name&gt;telnet connection&lt;/Name&gt;
/// &lt;OpenEmbedded&gt;true&lt;/OpenEmbedded&gt;
/// &lt;Stamp&gt;08aaa9ff-3583-4dc0-8622-3a0f4d37a7c4&lt;/Stamp&gt;
/// &lt;MetaInformation&gt;
/// &lt;MAC&gt;some-mac-here&lt;/MAC&gt;
/// &lt;PasswordHistory&gt;
/// &lt;PasswordHistory&gt;
/// &lt;LoggedModifiedBy&gt;LEVIATHAN\David&lt;/LoggedModifiedBy&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string telnet_rdm_export {
get {
return ResourceManager.GetString("telnet_rdm_export", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
///&lt;!-- ****************************************************************--&gt;
@@ -416,5 +481,48 @@ namespace mRemoteNGTests.Properties {
return ResourceManager.GetString("update_portable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot;?&gt;
///&lt;ArrayOfConnection&gt;
/// &lt;Connection&gt;
/// &lt;ConnectionSubType&gt;UltraVNC&lt;/ConnectionSubType&gt;
/// &lt;ConnectionType&gt;VNC&lt;/ConnectionType&gt;
/// &lt;Description&gt;This is a VNC description&lt;/Description&gt;
/// &lt;ID&gt;16ff7dd6-2ac3-4e27-96cf-435b5bfe5a00&lt;/ID&gt;
/// &lt;Name&gt;vnc connection&lt;/Name&gt;
/// &lt;OpenEmbedded&gt;true&lt;/OpenEmbedded&gt;
/// &lt;Stamp&gt;a44e3b58-2e14-47bf-8a79-0646b1e4ba46&lt;/Stamp&gt;
/// &lt;MetaInformation&gt;
/// &lt;MAC&gt;some-mac-here&lt;/MAC&gt;
/// &lt;PasswordHistory&gt;
/// &lt;PasswordHistory&gt;
/// &lt;L [rest of string was truncated]&quot;;.
/// </summary>
internal static string vnc_rdm_export {
get {
return ResourceManager.GetString("vnc_rdm_export", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot;?&gt;
///&lt;ArrayOfConnection&gt;
/// &lt;Connection&gt;
/// &lt;ConnectionSubType&gt;FireFox&lt;/ConnectionSubType&gt;
/// &lt;ConnectionType&gt;WebBrowser&lt;/ConnectionType&gt;
/// &lt;Description&gt;Website description&lt;/Description&gt;
/// &lt;ID&gt;65092747-6870-42c9-b8bc-35ec9fb5b3fb&lt;/ID&gt;
/// &lt;Name&gt;website connection&lt;/Name&gt;
/// &lt;OpenEmbedded&gt;true&lt;/OpenEmbedded&gt;
/// &lt;Stamp&gt;d04a9abb-4d4c-4ba5-8ef8-1699bd84b734&lt;/Stamp&gt;
/// &lt;WebBrowserApplication&gt;FireFox&lt;/WebBrowserApplication&gt;
/// &lt;WebBrowserUrl&gt;https://www.google.com:8080&lt;/WebBrow [rest of string was truncated]&quot;;.
/// </summary>
internal static string website_rdm_export {
get {
return ResourceManager.GetString("website_rdm_export", resourceCulture);
}
}
}
}

View File

@@ -190,4 +190,19 @@
<data name="update_portable" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="rdp_rdm_export" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\rdp.rdm;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="ssh_rdm_export" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ssh.rdm;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1</value>
</data>
<data name="telnet_rdm_export" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\telnet.rdm;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="vnc_rdm_export" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\vnc.rdm;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="website_rdm_export" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\website.rdm;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0"?>
<ArrayOfConnection>
<Connection>
<AuthentificationLevel>WarnMe</AuthentificationLevel>
<AutomaticallyClose>true</AutomaticallyClose>
<AutomaticallyCloseInterval>17</AutomaticallyCloseInterval>
<ConnectionType>RDPConfigured</ConnectionType>
<Console>true</Console>
<Description>This is a general description</Description>
<DesktopComposition>true</DesktopComposition>
<DisableBitmapCache>true</DisableBitmapCache>
<DisableThemes>true</DisableThemes>
<DisableWallpaper>true</DisableWallpaper>
<FontSmoothing>true</FontSmoothing>
<ID>1f36e6f0-90ca-4607-b6ec-86227738486d</ID>
<KeyboardHook>OnTheRemoteComputer</KeyboardHook>
<Name>rdp connection</Name>
<OpenEmbedded>true</OpenEmbedded>
<ScreenColor>C256</ScreenColor>
<ScreenSize>CurrentScreenSize</ScreenSize>
<SoundHook>DoNotPlay</SoundHook>
<Stamp>22400949-a0b8-46c1-8f27-49232ac1fb27</Stamp>
<Url>my.rdp.host.com:1234</Url>
<UsesClipboard>false</UsesClipboard>
<UsesHardDrives>false</UsesHardDrives>
<UsesPrinters>true</UsesPrinters>
<UsesSerialPorts>false</UsesSerialPorts>
<UsesSmartDevices>true</UsesSmartDevices>
<MetaInformation>
<MAC>mac-add-goes-here</MAC>
<PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T14:40:54</ModifiedDateTime>
<SafePassword>T2/JO7Aps+GMZG0vk5Jo8A==</SafePassword>
</PasswordHistory>
</PasswordHistory>
</MetaInformation>
<RDP>
<AudioCaptureRedirectionMode>true</AudioCaptureRedirectionMode>
<Domain>domain1</Domain>
<EnableCredSSPSupport>True</EnableCredSSPSupport>
<GatewayCredentialsSource>UserPassword</GatewayCredentialsSource>
<GatewayDomain>rddomain1</GatewayDomain>
<GatewayHostname>rdhost1</GatewayHostname>
<GatewayProfileUsageMethod>Explicit</GatewayProfileUsageMethod>
<GatewaySafePassword>kLaEwH4EDrZEaaK21HgqHg==</GatewaySafePassword>
<GatewayUsageMethod>ModeDirect</GatewayUsageMethod>
<GatewayUserName>rduser1</GatewayUserName>
<HyperVInstanceID>instance-id-here</HyperVInstanceID>
<KeepAliveInterval>6</KeepAliveInterval>
<KeyboardLayoutText>Default</KeyboardLayoutText>
<NetworkLevelAuthentication>true</NetworkLevelAuthentication>
<PromptCredentialOnce>true</PromptCredentialOnce>
<RDPType>HyperV</RDPType>
<SafePassword>tW7TUhUf1KUzuzuAdANJvg==</SafePassword>
<ScreenSizingMode>AutoScale</ScreenSizingMode>
<ShadowSessionConsentPrompt>false</ShadowSessionConsentPrompt>
<UseEnhancedSessionMode>true</UseEnhancedSessionMode>
<UserName>user1</UserName>
<Version>RDP70</Version>
</RDP>
</Connection>
</ArrayOfConnection>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0"?>
<ArrayOfConnection>
<Connection>
<ConnectionType>SSHShell</ConnectionType>
<Description>This is a linux host description</Description>
<ID>44ae261f-0094-48a2-93cb-bc5abcfcc394</ID>
<Name>ssh connection</Name>
<OpenEmbedded>true</OpenEmbedded>
<Stamp>ab007011-2836-426f-a8e0-9fef1ff88865</Stamp>
<MetaInformation>
<MAC>some-mac-here</MAC>
<PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T20:46:26</ModifiedDateTime>
<SafePassword>rV4oZM9LrfZ6SYHIlwTwvA==</SafePassword>
</PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T14:42:38</ModifiedDateTime>
<SafePassword>rV4oZM9LrfbUvSh5Y2lNDw==</SafePassword>
</PasswordHistory>
</PasswordHistory>
</MetaInformation>
<Terminal>
<Host>mysshhost</Host>
<HostPort>4321</HostPort>
<PrivateKeyPromptForPassPhrase>false</PrivateKeyPromptForPassPhrase>
<SafePassword>/et4Enc7v6HUQXJP6chuhA==</SafePassword>
<Username>linuxuser1</Username>
</Terminal>
<TerminalMac />
</Connection>
</ArrayOfConnection>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0"?>
<ArrayOfConnection>
<Connection>
<ConnectionType>Telnet</ConnectionType>
<Description>Telnet description</Description>
<ID>8d77d3ac-b414-4b51-ac10-60304d63cc6f</ID>
<Name>telnet connection</Name>
<OpenEmbedded>true</OpenEmbedded>
<Stamp>08aaa9ff-3583-4dc0-8622-3a0f4d37a7c4</Stamp>
<MetaInformation>
<MAC>some-mac-here</MAC>
<PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T21:50:48</ModifiedDateTime>
<SafePassword>T2/JO7Aps+GMZG0vk5Jo8A==</SafePassword>
</PasswordHistory>
</PasswordHistory>
</MetaInformation>
<Terminal>
<Host>telnethost1</Host>
<HostPort>7648</HostPort>
<ProxyMode>Custom</ProxyMode>
<SafePassword>yLHh9AVRl8TilluPKnidMw==</SafePassword>
<Username>user1</Username>
</Terminal>
<TerminalMac />
</Connection>
</ArrayOfConnection>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0"?>
<ArrayOfConnection>
<Connection>
<ConnectionSubType>UltraVNC</ConnectionSubType>
<ConnectionType>VNC</ConnectionType>
<Description>This is a VNC description</Description>
<ID>16ff7dd6-2ac3-4e27-96cf-435b5bfe5a00</ID>
<Name>vnc connection</Name>
<OpenEmbedded>true</OpenEmbedded>
<Stamp>a44e3b58-2e14-47bf-8a79-0646b1e4ba46</Stamp>
<MetaInformation>
<MAC>some-mac-here</MAC>
<PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T21:12:44</ModifiedDateTime>
<SafePassword>aHjuKKmVmbivKM+wovI3aA==</SafePassword>
</PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T21:08:16</ModifiedDateTime>
<SafePassword>uEGtwH/QfjSvKM+wovI3aA==</SafePassword>
</PasswordHistory>
</PasswordHistory>
</MetaInformation>
<VNC>
<CustomCompressionLevel>4</CustomCompressionLevel>
<DisableClipboard>true</DisableClipboard>
<Host>vnchost1</Host>
<JPEGCompressionLevel>3</JPEGCompressionLevel>
<MsDomain>windomain1</MsDomain>
<MsSafePassword>bUWiWCi7qod7YQ5XXK5LFQ==</MsSafePassword>
<MsUser>winuser1</MsUser>
<Port>9987</Port>
<PreferredEncoding>Tight</PreferredEncoding>
<ProxyHost>proxyhost:7777</ProxyHost>
<SafePassword>oGzaL3q/dK17YQ5XXK5LFQ==</SafePassword>
<ScreenColorDepth>C8</ScreenColorDepth>
<ViewOnly>true</ViewOnly>
<VNCEmbeddedType>UltraVNC</VNCEmbeddedType>
</VNC>
</Connection>
</ArrayOfConnection>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<ArrayOfConnection>
<Connection>
<ConnectionSubType>FireFox</ConnectionSubType>
<ConnectionType>WebBrowser</ConnectionType>
<Description>Website description</Description>
<ID>65092747-6870-42c9-b8bc-35ec9fb5b3fb</ID>
<Name>website connection</Name>
<OpenEmbedded>true</OpenEmbedded>
<Stamp>d04a9abb-4d4c-4ba5-8ef8-1699bd84b734</Stamp>
<WebBrowserApplication>FireFox</WebBrowserApplication>
<WebBrowserUrl>https://www.google.com:8080</WebBrowserUrl>
<MetaInformation>
<PasswordHistory>
<PasswordHistory>
<LoggedModifiedBy>LEVIATHAN\David</LoggedModifiedBy>
<ModifiedBy>LEVIATHAN\David</ModifiedBy>
<ModifiedDateTime>2020-01-26T22:01:26</ModifiedDateTime>
<SafePassword>T2/JO7Aps+GMZG0vk5Jo8A==</SafePassword>
</PasswordHistory>
</PasswordHistory>
</MetaInformation>
<Web>
<Domain>domain1</Domain>
<SafePassword>24ifhl01e7Le3Aj8NxM4ww==</SafePassword>
<UserName>user1</UserName>
</Web>
</Connection>
</ArrayOfConnection>

View File

@@ -123,6 +123,7 @@
<Compile Include="Config\DataProviders\FileBackupCreatorTests.cs" />
<Compile Include="Config\DataProviders\FileDataProviderTests.cs" />
<Compile Include="Config\DataProviders\FileDataProviderWithRollingBackupTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopManagerDeserializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\ValidateXmlSchemas.cs" />
<Compile Include="Config\Serializers\DataTableDeserializerTests.cs" />
<Compile Include="Config\CredentialHarvesterTests.cs" />
@@ -254,6 +255,10 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Resources\rdp.rdm" />
<None Include="Resources\ssh.rdm" />
<None Include="Resources\vnc.rdm" />
<None Include="Resources\website.rdm" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
@@ -273,6 +278,7 @@
<ItemGroup>
<None Include="packages.config" />
<None Include="Resources\confCons_v2_5.xml" />
<None Include="Resources\telnet.rdm" />
<None Include="Resources\test_puttyConnectionManager_database.dat" />
<None Include="Resources\test_rdcman_badVersionNumber.rdg" />
<None Include="Resources\test_rdcman_noversion.rdg" />

View File

@@ -1,5 +1,6 @@
using System;
using System.Xml;
using System.Xml.Linq;
namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
{
@@ -44,5 +45,45 @@ namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml
? valueAsEnum
: defaultValue;
}
public static string GetChildElementAsString(this XElement xmlNode, string elementName, string defaultValue = "")
{
var value = xmlNode?.Element(elementName)?.Value;
return value ?? defaultValue;
}
public static bool GetChildElementAsBool(this XElement xmlNode, string elementName, bool defaultValue = false)
{
var value = xmlNode?.GetChildElementAsString(elementName);
if (string.IsNullOrWhiteSpace(value))
return defaultValue;
return bool.TryParse(value, out var valueAsBool)
? valueAsBool
: defaultValue;
}
public static int GetChildElementAsInt(this XElement xmlNode, string elementName, int defaultValue = 0)
{
var value = xmlNode?.GetChildElementAsString(elementName);
if (string.IsNullOrWhiteSpace(value))
return defaultValue;
return int.TryParse(value, out var valueAsBool)
? valueAsBool
: defaultValue;
}
public static T GetChildElementAsEnum<T>(this XElement xmlNode, string elementName, T defaultValue = default(T))
where T : struct
{
var value = xmlNode?.GetChildElementAsString(elementName);
if (string.IsNullOrWhiteSpace(value))
return defaultValue;
return Enum.TryParse<T>(value, true, out var valueAsEnum)
? valueAsEnum
: defaultValue;
}
}
}

View File

@@ -0,0 +1,366 @@
using System;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using mRemoteNG.Config.Serializers.ConnectionSerializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.MiscSerializers
{
public class RemoteDesktopManagerDeserializer : IDeserializer<string, ConnectionTreeModel>
{
public ConnectionTreeModel Deserialize(string serializedData)
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
connectionTreeModel.AddRootNode(root);
var xdoc = XDocument.Parse(serializedData);
var descendants = xdoc.Root.Descendants("Connection");
foreach (var descendant in descendants)
{
var connection = CreateConnectionFromXml(descendant);
root.AddChild(connection);
}
return connectionTreeModel;
}
private ConnectionInfo CreateConnectionFromXml(XElement xml)
{
var protocol = ParseProtocol(xml);
var protocolSpecificNode = GetProtocolSpecificNode(xml, protocol);
var metaInfoNode = xml.Element("MetaInformation");
var connectionId = xml.GetChildElementAsString("ID", Guid.NewGuid().ToString());
var connection = new ConnectionInfo(connectionId)
{
Name = xml.GetChildElementAsString("Name"),
Protocol = protocol,
Description = xml.GetChildElementAsString("Description"),
Username = protocolSpecificNode.GetChildElementAsString("UserName",
protocolSpecificNode.GetChildElementAsString("Username",
protocolSpecificNode.GetChildElementAsString("MsUser"))),
Domain = protocolSpecificNode.GetChildElementAsString("Domain",
protocolSpecificNode.GetChildElementAsString("MsDomain")),
Password = protocolSpecificNode.GetChildElementAsString("SafePassword"),
Resolution = ParseResolution(xml),
AutomaticResize = protocolSpecificNode.GetChildElementAsString("ScreenSizingMode") == "AutoScale",
RedirectSound = ParseSoundRedirection(xml),
Colors = ParseScreenColors(xml),
CacheBitmaps = !xml.GetChildElementAsBool("DisableBitmapCache"),
DisplayThemes = !xml.GetChildElementAsBool("DisableThemes"),
DisplayWallpaper = !xml.GetChildElementAsBool("DisableWallpaper"),
EnableDesktopComposition = xml.GetChildElementAsBool("DesktopComposition"),
EnableFontSmoothing = xml.GetChildElementAsBool("FontSmoothing"),
RedirectAudioCapture = protocolSpecificNode.GetChildElementAsBool("AudioCaptureRedirectionMode"),
RedirectClipboard = xml.GetChildElementAsBool("UsesClipboard", DefaultConnectionInfo.Instance.RedirectClipboard),
RedirectDiskDrives = xml.GetChildElementAsBool("UsesHardDrives", DefaultConnectionInfo.Instance.RedirectDiskDrives),
RedirectPrinters = xml.GetChildElementAsBool("UsesPrinters", DefaultConnectionInfo.Instance.RedirectPrinters),
RedirectPorts = xml.GetChildElementAsBool("UsesSerialPorts", DefaultConnectionInfo.Instance.RedirectPorts),
RedirectSmartCards = xml.GetChildElementAsBool("UsesSmartDevices", DefaultConnectionInfo.Instance.RedirectSmartCards),
RDPMinutesToIdleTimeout = xml.GetChildElementAsInt("AutomaticallyCloseInterval"),
MacAddress = metaInfoNode.GetChildElementAsString("MAC"),
RdpVersion = ParseRdpVersion(protocolSpecificNode),
RedirectKeys = xml.GetChildElementAsString("KeyboardHook") == "OnTheRemoteComputer",
UseConsoleSession = xml.GetChildElementAsBool("Console"),
RDPAuthenticationLevel = ParseAuthenticationLevel(xml),
UseCredSsp = protocolSpecificNode.GetChildElementAsBool("EnableCredSSPSupport"),
RDGatewayUsageMethod = ParseRdpGatewayUsageMethod(protocolSpecificNode),
RDGatewayHostname = protocolSpecificNode.GetChildElementAsString("GatewayHostname"),
UseEnhancedMode = protocolSpecificNode.GetChildElementAsBool("UseEnhancedSessionMode"),
UseVmId = protocolSpecificNode.GetChildElementAsString("RDPType") == "HyperV",
VmId = protocolSpecificNode.GetChildElementAsString("HyperVInstanceID"),
VNCEncoding = ParseVncEncoding(protocolSpecificNode),
VNCCompression = ParseVncCompressionLevel(protocolSpecificNode),
VNCAuthMode = DetermineVncAuthMode(protocolSpecificNode),
VNCViewOnly = protocolSpecificNode.GetChildElementAsBool("ViewOnly"),
RenderingEngine = ParseWebRenderingEngine(xml),
};
SetHostnameAndPort(connection, xml, protocolSpecificNode);
SetRdpGatewayCredentials(connection, protocolSpecificNode);
SetVncProxyHostAndPort(connection, protocolSpecificNode);
return connection;
}
private ProtocolType ParseProtocol(XElement xml)
{
switch (xml.GetChildElementAsString("ConnectionType"))
{
case "RDPConfigured":
return ProtocolType.RDP;
case "SSHShell":
return ProtocolType.SSH2;
case "VNC":
return ProtocolType.VNC;
case "Telnet":
return ProtocolType.Telnet;
case "WebBrowser":
return xml.GetChildElementAsString("WebBrowserUrl").StartsWith("http://")
? ProtocolType.HTTP
: ProtocolType.HTTPS;
default:
throw new Exception();
}
}
private XElement GetProtocolSpecificNode(XElement xml, ProtocolType protocol)
{
switch (protocol)
{
case ProtocolType.RDP:
return xml.Element("RDP");
case ProtocolType.SSH1:
case ProtocolType.SSH2:
case ProtocolType.Telnet:
return xml.Element("Terminal");
case ProtocolType.VNC:
return xml.Element("VNC");
case ProtocolType.HTTP:
case ProtocolType.HTTPS:
return xml.Element("Web");
default:
throw new Exception();
}
}
private void SetHostnameAndPort(ConnectionInfo connection, XElement xml, XElement protocolSpecificNode)
{
var urlElement = xml.Element("Url") ?? xml.Element("WebBrowserUrl");
if (urlElement != null)
{
var urlRegex = new Regex(@"((?<protocol>https?)://)?(?<host>[\w\.]+):?(?<port>\d*)");
var urlMatch = urlRegex.Match(urlElement.Value);
connection.Hostname = urlMatch.Groups["host"]?.Value ?? string.Empty;
if (int.TryParse(urlMatch.Groups["port"]?.Value, out var port))
{
connection.Port = port;
}
}
else
{
connection.Hostname = protocolSpecificNode.GetChildElementAsString("Host");
if (protocolSpecificNode.Element("HostPort") != null)
{
connection.Port = protocolSpecificNode.GetChildElementAsInt("HostPort");
}
if (protocolSpecificNode.Element("Port") != null)
{
connection.Port = protocolSpecificNode.GetChildElementAsInt("Port");
}
}
}
private RDPResolutions ParseResolution(XElement xml)
{
var resolution = xml.GetChildElementAsString("ScreenSize");
// attempt to convert "R800x600" style descriptors
// to our "Res800x600" style enum
if (resolution.StartsWith("R"))
{
var fixedResolution = resolution.Replace("R", "Res");
if (Enum.TryParse<RDPResolutions>(fixedResolution, out var convertedRes))
{
return convertedRes;
}
}
switch (resolution)
{
case "FullScreen":
return RDPResolutions.Fullscreen;
case "CurrentWorkAreaSize":
case "CurrentScreenSize":
return RDPResolutions.FitToWindow;
}
switch (xml.GetChildElementAsString("ScreenSizingMode"))
{
// This is confusing, but what they show as "Smart sizing" in the UI
// gets serialized to FitToWindow in the xml.
case "FitToWindow":
return RDPResolutions.SmartSize;
}
return DefaultConnectionInfo.Instance.Resolution;
}
private RDPSounds ParseSoundRedirection(XElement xml)
{
switch (xml.GetChildElementAsString("SoundHook"))
{
case "LeaveAtRemoteComputer":
return RDPSounds.LeaveAtRemoteComputer;
case "DoNotPlay":
return RDPSounds.DoNotPlay;
default: // there is no xml element when set to BringToThisComputer
return RDPSounds.BringToThisComputer;
}
}
private RDPColors ParseScreenColors(XElement xml)
{
switch (xml.GetChildElementAsString("ScreenColor"))
{
case "C15Bits":
return RDPColors.Colors15Bit;
case "C16Bits":
return RDPColors.Colors16Bit;
case "C24Bits":
return RDPColors.Colors24Bit;
case "C32Bits":
return RDPColors.Colors32Bit;
case "C256":
return RDPColors.Colors256;
default:
return DefaultConnectionInfo.Instance.Colors;
}
}
private RdpVersion ParseRdpVersion(XElement xml)
{
switch (xml.GetChildElementAsString("Version"))
{
case "RDP50":
case "RDP60":
case "RDP61":
return RdpVersion.Rdc6;
case "RDP70":
return RdpVersion.Rdc7;
case "RDP80":
case "RDP81":
return RdpVersion.Rdc8;
default: // no xml node = use latest
return RdpVersion.Highest;
}
}
private AuthenticationLevel ParseAuthenticationLevel(XElement xml)
{
switch (xml.GetChildElementAsString("AuthentificationLevel"))
{
case "WarnMe":
return AuthenticationLevel.WarnOnFailedAuth;
case "DontConnect":
return AuthenticationLevel.AuthRequired;
default: // "Connect and don't warn me"
return AuthenticationLevel.NoAuth;
}
}
private RDGatewayUsageMethod ParseRdpGatewayUsageMethod(XElement xml)
{
switch (xml.GetChildElementAsString("GatewayUsageMethod"))
{
case "ModeDirect":
return RDGatewayUsageMethod.Always;
case "NoneDetect":
return RDGatewayUsageMethod.Never;
default: // no xml node = detect
return RDGatewayUsageMethod.Detect;
}
}
private void SetRdpGatewayCredentials(ConnectionInfo connection, XElement xml)
{
if (xml.GetChildElementAsString("GatewayCredentialsSource") == "Smartcard")
{
connection.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.SmartCard;
}
else
{
connection.RDGatewayUseConnectionCredentials =
xml.GetChildElementAsBool("PromptCredentialOnce")
? RDGatewayUseConnectionCredentials.Yes
: RDGatewayUseConnectionCredentials.No;
}
connection.RDGatewayUsername = xml.GetChildElementAsString("GatewayUserName");
connection.RDGatewayDomain = xml.GetChildElementAsString("GatewayDomain");
connection.RDGatewayPassword = xml.GetChildElementAsString("GatewaySafePassword");
}
private ProtocolVNC.Encoding ParseVncEncoding(XElement xml)
{
switch (xml.GetChildElementAsString("PreferredEncoding"))
{
case "CoRRE":
return ProtocolVNC.Encoding.EncCorre;
case "Hextile":
return ProtocolVNC.Encoding.EncHextile;
case "Raw":
return ProtocolVNC.Encoding.EncRaw;
case "RRE":
return ProtocolVNC.Encoding.EncRRE;
case "Tight":
return ProtocolVNC.Encoding.EncTight;
case "Zlib":
return ProtocolVNC.Encoding.EncZlib;
case "ZlibHEX":
return ProtocolVNC.Encoding.EncZLibHex;
case "ZRLE":
return ProtocolVNC.Encoding.EncZRLE;
default:
return DefaultConnectionInfo.Instance.VNCEncoding;
}
}
private ProtocolVNC.Compression ParseVncCompressionLevel(XElement xml)
{
var compressionXml = xml.GetChildElementAsString("CustomCompressionLevel");
return Enum.TryParse<ProtocolVNC.Compression>("Comp" + compressionXml, out var compression)
? compression
: DefaultConnectionInfo.Instance.VNCCompression;
}
private ProtocolVNC.AuthMode DetermineVncAuthMode(XElement xml)
{
return xml.Element("MsUser") != null
? ProtocolVNC.AuthMode.AuthWin
: ProtocolVNC.AuthMode.AuthVNC;
}
private void SetVncProxyHostAndPort(ConnectionInfo connection, XElement xml)
{
var proxy = xml.GetChildElementAsString("ProxyHost").Split(':');
if (proxy.Length >= 1)
{
connection.VNCProxyIP = proxy[0];
}
if (proxy.Length >= 2 && int.TryParse(proxy[1], out var port))
{
connection.VNCProxyPort = port;
}
}
private HTTPBase.RenderingEngine ParseWebRenderingEngine(XElement xml)
{
if (xml.GetChildElementAsString("ConnectionType") != "WebBrowser")
return DefaultConnectionInfo.Instance.RenderingEngine;
switch (xml.GetChildElementAsString("ConnectionSubType"))
{
case "IE":
return HTTPBase.RenderingEngine.IE;
case "FireFox":
return HTTPBase.RenderingEngine.Gecko;
default:
return DefaultConnectionInfo.Instance.RenderingEngine;
}
}
}
}

View File

@@ -203,6 +203,7 @@
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManagerDeserializer.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionNodeSerializer26.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\MsSql\SqlDatabaseMetaDataRetriever.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopManagerDeserializer.cs" />
<Compile Include="Config\Serializers\Versioning\IVersionUpgrader.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion22To23Upgrader.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion23To24Upgrader.cs" />