Compare commits

..

9 Commits

Author SHA1 Message Date
David Sparer
5bd43afcd3 refactored relationship between protocol objects and interfacecontrol 2018-02-11 20:35:14 -06:00
David Sparer
d85c46930f added class for testing rdp version suppport 2018-02-10 21:13:20 -06:00
David Sparer
4614de1dea renamed event invocation methods to be more descriptive 2018-02-10 20:42:59 -06:00
David Sparer
f33102d545 simplification of protocol base class 2018-02-10 20:38:46 -06:00
David Sparer
8003f410a7 support rdp client v6 through 10 2018-02-10 20:38:28 -06:00
David Sparer
b21dc9a062 began splitting rdp implementations by version so we can dynamically support whatever is on the user's machine 2018-02-09 16:52:19 -06:00
David Sparer
36ed189177 bit more refactoring 2018-02-09 15:25:55 -06:00
David Sparer
b3b961c647 moved rdp enums out of the rdp protocol class 2018-02-09 13:14:27 -06:00
David Sparer
a212121f4a moved all rdp enums to their own files 2018-02-09 13:14:27 -06:00
244 changed files with 4302 additions and 7334 deletions

View File

@@ -1,30 +1,16 @@
<!--- Provide a general summary of the issue in the Title above -->
<!--
Only file GitHub issues for bugs and feature requests. All other topics will be closed.
## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
Before opening an issue, please search for a duplicate or closed issue.
Please provide as much detail as possible for us to fix your issue.
-->
## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
<!-- Bug -->
|Detail|Value|
|--:|---|
|Operating system | Windows 10 x64 |
|mRemoteNG version| 1.75.7008 |
## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
## Steps to Reproduce (for bugs)
<!--- Provide an unambiguous set of steps to reproduce -->
<!--- this bug. Include code to reproduce, if relevant -->
1.
2.
3.
4.
## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Version used:
* Operating System and version (e.g. Windows 10 1709 x64):
<!-- Feature Request -->
<!-- If you file a feature request, please delete the bug section -->

View File

@@ -1,29 +1,4 @@
<!--- Provide a general summary of your changes in the Title above -->
## Description
<!--- Describe your changes in detail -->
## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
## Screenshots (if appropriate):
## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the **CONTRIBUTING** document.
<!--
Please provide as much detail as possible with what your pull request does.
Include a reference to a filed issue if it exists.
-->

View File

@@ -1,139 +1,12 @@
1.76.12 (2018-11-08):
Features/Enhancements:
----------------------
#1180: Allow saving certain connection properties locally when using database
Fixes:
------
#1181: Connections sometimes dont immediately load when switching to sql feature
#1173: Fixed memory leak when loading connections multiple times
#1168: Autohide Connection and Config tab won't open when ssh connection active
#1134: Fixed issue where opening a connection opens same connection on other clients when using database feature
#449: Encrypt passwords saved to database
1.76.11 (2018-10-18):
Fixes:
------
#1139: Feature "Reconnect to previously opened sessions" not working
#1136: Putty window not maximized
1.76.10 (2018-10-07):
Fixes:
------
#1124: Enabling themes causes an exception
1.76.9 (2018-10-07):
Fixes:
------
#1117: Duplicate panel created when "Reconnect on Startup" and "Create Empty Panel" settings enabled
#1115: Exception when changing from xml data storage to SQL
#1110: Pressing Delete button during connection rename attempts to delete the connection instead of the text
#1106: Inheritance does not work when parent has C# default type set
#1092: Invalid Cast Exceptions loading default connectioninfo
#1091: Minor themeing issues
#853: Added some additional safety checks and logging to help address RDP crashes
1.76.8 (2018-08-25):
Fixes:
------
#1088: Delete and Launch buttons are not disabled when last external tool deleted
#1087: 'Save connections after every edit' setting not honored
#1082: Connections not given GUID if Id is empty in connection xml
1.76.7 (2018-08-22):
Fixes:
------
#1076: Wrong object selected when duplicating connection then switching between properties and inheritance in config window
#1068: Fixed some toolbar positioning bugs
1.76.6 (2018-08-03):
Fixes:
------
#1062: Entering correct password when starting app does not load connections file
1.76.5 (2018-08-02):
Fixes:
------
#1057: Hitting F2 with no connection node selected caused unhandled exception
#1052: 'Switch to notification panel' feature does not always switch
#1051: Tooltips always displayed regardless of 'Show description tooltips in connection tree' setting
#1050: Config window retains access to previously selected node after loading new connections file
#1045: Config window shows several incorrect properties for HTTPS connections
#1040: Canceling "select panel" form does not cancel
#1039: Set default theme when themes disabled
#1038: Unable to add connection with active filter
#1036: Exception when themes are active and options page closed on Connections then reopened
#1034: Connection context menu not being translated
#1030: Exception thrown if importing from port scan and no tree node is selected
#1020: BackupFileKeepCount setting not limiting backup file count
#1004: Duplicating root or PuTTy node through hotkey causes unhandled exception
#1002: Disabling filtering without clearing keyword leaves filtered state
#1001: Connection tree context menu hotkeys stop working and disappear in some cases
#999: Some hotkeys stop working if File menu was called when PuTTy Saved Sessions was selected
#998: Can sometimes add connection under PuTTY Sessions node
#991: Error when deleting host in filtered view
#971: Portable Settings now apply to any machine they are used on
#961: Connections file overwritten if correct decryption password not provided
#893: Removed unneeded files from build/package
#868: if statement returned the same value
#762: Increased button size to fit locaized text
1.76.4 Alpha 6 (2018-06-03):
Features/Enhancements:
----------------------
#948: Fixed issue where many menu item translations were not being used
#942: Improved Russian translation of several items
#924: Notification for "No Host Specified" when clicking folders in quick-connect menu
#902: Menu bar can once again be moved. View -> "Lock toolbar positions" now also locks the menu position
Added option for creating an empty panel on startup
Fixes:
------
#938: Minor layout improvements on the Port Scan screen
#916: Default properties were not being saved
1.76.3 Alpha 5 (2018-03-14):
Fixes:
------
#911: Csv exports sometimes do not include all fields
#807: Inheritance is sometimes turned on for nodes under root Connections node
1.76.2 Alpha 4 (2018-03-03):
Fixes:
------
#899: DoNotPlay is Case Sensitive in XML Serialization
1.76.1 Alpha 3 (2018-02-24):
1.76.0 Alpha 3 (2018-xx-xx):
Features/Enhancements:
----------------------
#625: Added ability to import mRemoteNG formatted CSV files
#648: The port scan ping timeout is now configurable
Fixes:
------
Fixed a few Xml serialization bugs that would occur if boolean values weren't capitalized
1.76.0 Alpha 2 (2018-02-01):

View File

@@ -23,8 +23,6 @@ github.com/DamianBis
github.com/pfjason
github.com/sirLoaf
github.com/Fyers
Vladimir Semenov (github.com/sli-pro)
Stephan (github.com/st-schuler)
Past Contributors
@@ -61,8 +59,6 @@ Lukas Plachy (github.com/rheingold)
Gyuha Shin
Stefan (github.com/polluks)
github.com/emazv72
Vladimir Semenov (github.com/sli-pro)
Marco Sousa (github.com/marcomsousa)
Included Source Code

8
Jenkinsfile vendored
View File

@@ -1,8 +1,8 @@
#!groovy
node('windows') {
def jobDir = pwd()
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\""
def msBuild = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\msbuild.exe"
def vsToolsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools"
def vsExtensionsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow"
def nunitConsolePath = "${jobDir}\\packages\\NUnit.ConsoleRunner.3.7.0\\tools\\nunit3-console.exe"
def openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe"
def reportGeneratorPath = "${jobDir}\\packages\\ReportGenerator.3.0.2\\tools\\ReportGenerator.exe"
@@ -24,11 +24,11 @@ node('windows') {
}
stage ('Build mRemoteNG (Normal)') {
bat "\"${msBuild}\" /nologo /p:Platform=x86 \"${jobDir}\\mRemoteV1.sln\""
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /p:Platform=x86 \"${jobDir}\\mRemoteV1.sln\""
}
stage ('Build mRemoteNG (Portable)') {
bat "\"${msBuild}\" /nologo /p:Configuration=\"Debug Portable\";Platform=x86 \"${jobDir}\\mRemoteV1.sln\""
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /p:Configuration=\"Debug Portable\";Platform=x86 \"${jobDir}\\mRemoteV1.sln\""
}
stage ('Run Unit Tests (Normal, w/coverage)') {

View File

@@ -1,13 +1,9 @@
node('windows') {
def jobDir = pwd()
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\""
def msBuild = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\msbuild.exe"
def nunitConsolePath = "${jobDir}\\packages\\NUnit.ConsoleRunner.3.7.0\\tools\\nunit3-console.exe"
def openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe"
def testResultFilePrefix = "TestResult"
def testResultFileNormal = "${testResultFilePrefix}_UnitTests_normal.xml"
def testResultFilePortable = "${testResultFilePrefix}_UnitTests_portable.xml"
def coverageReport = "code_coverage_report.xml"
def vsToolsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools"
def vsExtensionsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow"
def nunitTestAdapterPath = "C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\VisualStudio\\14.0\\Extensions"
stage ('Clean output dir') {
@@ -36,24 +32,24 @@ node('windows') {
withCredentials([file(credentialsId: '9b674d57-6792-48e3-984a-4d1bab2abb64', variable: 'CODE_SIGNING_CERT')]) {
withCredentials([usernamePassword(credentialsId: '05b7449b-05c0-490f-8661-236242526e62', passwordVariable: 'MRNG_CERT_PASSWORD', usernameVariable: 'NO_USERNAME')]) {
stage ('Build mRemoteNG (Normal - MSI)') {
bat "\"${msBuild}\" /nologo /t:Clean,Build /p:Configuration=\"Release Installer\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /t:Clean,Build /p:Configuration=\"Release Installer\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
archiveArtifacts artifacts: "Release\\*.msi", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
}
stage ('Build mRemoteNG (Portable)') {
bat "\"${msBuild}\" /nologo /t:Clean,Build /p:Configuration=\"Release Portable\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && msbuild.exe /nologo /t:Clean,Build /p:Configuration=\"Release Portable\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
archiveArtifacts artifacts: "Release\\*.zip", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
}
}
}
stage ('Run Unit Tests (Normal - MSI)') {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release\\mRemoteNGTests.dll\" --result=${testResultFileNormal} --x86"
}
stage ('Run Unit Tests (Portable)') {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release portable\\mRemoteNGTests.dll\" --result=${testResultFilePortable} --x86"
}
stage ('Run Unit Tests (Normal - MSI)') {
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release\\mRemoteNGTests.dll\""
}
stage ('Run Unit Tests (Portable)') {
bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release Portable\\mRemoteNGTests.dll\""
}
stage ('Generate UpdateCheck Files') {
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\create_upg_chk_files.ps1\" -TagName \"${env.TagName}\" -UpdateChannel \"${env.UpdateChannel}\""
@@ -62,10 +58,11 @@ node('windows') {
stage ('Publish to GitHub') {
withCredentials([string(credentialsId: '5443a369-dbe8-42d3-b4e8-04d0b4e9039a', variable: 'GH_AUTH_TOKEN')]) {
def releaseFolder = "${jobDir}\\Release"
def zipPath = "${jobDir}\\Release\\*.zip"
def msiPath = "${jobDir}\\Release\\*.msi"
// because batch files suck at handling newline characters, we have to convert to base64 in groovy and back to text in powershell
def base64Description = env.ReleaseDescription.bytes.encodeBase64().toString()
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\publish_to_github.ps1\" -Owner \"mRemoteNG\" -Repository \"mRemoteNG\" -ReleaseTitle \"${env.ReleaseTitle}\" -TagName \"${env.TagName}\" -TargetCommitish \"${env.TargetBranch}\" -Description \"${base64Description}\" -IsDraft ${env.IsDraft} -IsPrerelease ${env.IsPreRelease} -ReleaseFolderPath \"${releaseFolder}\" -AuthToken \"${env.GH_AUTH_TOKEN}\" -DescriptionIsBase64Encoded"
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\publish_to_github.ps1\" -Owner \"mRemoteNG\" -Repository \"mRemoteNG\" -ReleaseTitle \"${env.ReleaseTitle}\" -TagName \"${env.TagName}\" -TargetCommitish \"${env.TargetBranch}\" -Description \"${base64Description}\" -IsDraft ${env.IsDraft} -IsPrerelease ${env.IsPreRelease} -ZipFilePath \"${zipPath}\" -MsiFilePath \"${msiPath}\" -AuthToken \"${env.GH_AUTH_TOKEN}\" -DescriptionIsBase64Encoded"
}
}
}

View File

@@ -10,9 +10,9 @@
| Update Channel | Build Status | Downloads |
| ---------------|--------------|-----------|
| Stable | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/master?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/master) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75.7012/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75.7012) |
| Beta | | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75.7012/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75.7012) |
| Development | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/develop?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/develop) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76Alpha5/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76Alpha5) |
| Stable | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/master?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/master) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75.7011/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75.7011) |
| Beta | | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75.7011/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75.7011) |
| Development | [![Build status](https://ci.appveyor.com/api/projects/status/k0sdbxmq90fgdmj6/branch/develop?svg=true)](https://ci.appveyor.com/project/mremoteng/mremoteng/branch/develop) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76Alpha2/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76Alpha2) |
mRemoteNG is the next generation of mRemote, a full-featured, multi-tab remote connections manager.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3,7 +3,7 @@
License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Copyright (C) 1999-2018 Igor Pavlov.
Copyright (C) 1999-2016 Igor Pavlov.
7-Zip Extra files are under the GNU LGPL license.

View File

@@ -1,25 +1,6 @@
7-Zip Extra history
-------------------
This file contains only information about changes related to that package exclusively.
The full history of changes is listed in history.txt in main 7-Zip program.
18.05 2018-04-30
-------------------------
- The speed for LZMA/LZMA2 compressing was increased
by 8% for fastest/fast compression levels and
by 3% for normal/maximum compression levels.
18.03 beta 2018-03-04
-------------------------
- The speed for single-thread LZMA/LZMA2 decoding
was increased by 30% in x64 version and by 3% in x86 version.
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
if there are multiple independent data chunks in LZMA2 stream.
9.35 beta 2014-12-07
------------------------------
- SFX modules were moved to LZMA SDK package.

View File

@@ -1,9 +1,9 @@
7-Zip Extra 18.05
7-Zip Extra 16.02
-----------------
7-Zip Extra is package of extra modules of 7-Zip.
7-Zip Copyright (C) 1999-2018 Igor Pavlov.
7-Zip Copyright (C) 1999-2016 Igor Pavlov.
7-Zip is free software. Read License.txt for more information about license.

View File

@@ -1,114 +0,0 @@
#####################################
# Author: David Sparer
# Summary:
# This is intended to be a template for creating connections in bulk. This uses the serializers directly from the mRemoteNG binaries.
# You will still need to create the connection info objects, but the library will handle serialization. It is expected that you
# are familiar with PowerShell. If this is not the case, reach out to the mRemoteNG community for help.
# Usage:
# Replace or modify the examples that are shown toward the end of the script to create your own connection info objects.
#####################################
$EncryptionKey = (Get-Credential -Message "Enter the encryption key you would like to use. This must match the encryption key used by the rest of the confCons file." -UserName "DontNeedUsername").Password
$PathToMrngFolder = ""
if ($PathToMrngFolder -eq "") {
Write-Error -Message 'You must set the $PathToMrngFolder variable in this script to the folder which contains mRemoteNG.exe'
}
$assembly = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $PathToMrngFolder -ChildPath "mRemoteNG.exe"))
$assembly = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $PathToMrngFolder -ChildPath "BouncyCastle.Crypto.dll"))
function New-mRemoteNGXmlSerializer {
[CmdletBinding()]
param (
[SecureString]
$EncryptionKey
)
PROCESS {
$cryptoProvider = New-Object -TypeName mRemoteNG.Security.SymmetricEncryption.AeadCryptographyProvider
$saveFilter = New-Object -TypeName mRemoteNG.Security.SaveFilter -ArgumentList @($false)
$xmlSerializer = New-Object -TypeName mRemoteNG.Config.Serializers.XmlConnectionNodeSerializer -ArgumentList @($cryptoProvider, $encryptionKey, $saveFilter)
Write-Output $xmlSerializer
}
}
function New-mRemoteNGConnectionInfo {
[CmdletBinding()]
param ()
PROCESS {
$connectionInfo = New-Object -TypeName mRemoteNG.Connection.ConnectionInfo
Write-Output $connectionInfo
}
}
function New-mRemoteNGContainerInfo {
[CmdletBinding()]
param ()
PROCESS {
$connectionInfo = New-Object -TypeName mRemoteNG.Container.ContainerInfo
Write-Output $connectionInfo
}
}
# Setup the services needed to do serialization
$xmlSerializer = New-mRemoteNGXmlSerializer -EncryptionKey $EncryptionKey
#----------------------------------------------------------------
# Example 1: serialize many connections, no containers
# Here you can define the number of connection info objects to create
# You can also provide a list of desired hostnames and iterate over those
$xml = ""
foreach($i in 1..5)
{
$connectionInfo = New-mRemoteNGConnectionInfo
# Set connection info properties
$connectionInfo.Name = "server-$i"
$connectionInfo.Hostname = "some-win-server-$i"
$connectionInfo.Protocol = [mRemoteNG.Connection.Protocol.ProtocolType]::RDP
$connectionInfo.Inheritance.Username = $true
$connectionInfo.Inheritance.Domain = $true
$connectionInfo.Inheritance.Password = $true
$serializedConnection = $xmlSerializer.SerializeConnectionInfo($connectionInfo).ToString()
$xml += $serializedConnection + [System.Environment]::NewLine
}
Write-Output $xml
#----------------------------------------------------------------
# Example 2: serialize a container which has connections
# You can also create containers and add connections to them, which will be nested correctly when serialized
$xml = ""
$container = New-mRemoteNGContainerInfo
$container.Name = "ProductionServers"
$serializedContainer = $xmlSerializer.SerializeConnectionInfo($container)
foreach($i in 1..3)
{
$connectionInfo = New-mRemoteNGConnectionInfo
# Set connection info properties
$connectionInfo.Name = "server-$i"
$connectionInfo.Hostname = "some-linux-server-$i"
$connectionInfo.Protocol = [mRemoteNG.Connection.Protocol.ProtocolType]::SSH2
$connectionInfo.Inheritance.Username = $true
$connectionInfo.Inheritance.Domain = $true
$connectionInfo.Inheritance.Password = $true
# serialize the connection
$serializedConnection = $xmlSerializer.SerializeConnectionInfo($connectionInfo)
# add the connection to the container
$serializedContainer.Add($serializedConnection)
}
# Call ToString() on the top-level container to get the XML of it and all its children
Write-Output $serializedContainer.ToString()

View File

@@ -1,6 +1,5 @@
$githubUrl = 'https://api.github.com'
# GitHub doesn't support the default powershell protocol (TLS 1.0)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
function Publish-GitHubRelease {
param (
@@ -171,27 +170,13 @@ function Upload-GitHubReleaseAsset {
[string]
[Parameter(Mandatory=$true)]
# The OAuth2 token to use for authentication.
$AuthToken,
[string]
# A short description label for the asset
$Label = ""
$AuthToken
)
$UploadUri = $UploadUri -replace "(\{[\w,\?]*\})$"
$files = Get-Item -Path $FilePath
$file = Get-Item -Path $FilePath
$labelParam = ""
if ($Label -ne "") {
$labelParam = "&label=$Label"
}
# Get-Item could produce an array of files if a wildcard is provided. (C:\*.txt)
# Upload each matching item individually
foreach ($file in $files) {
Write-Output "Uploading asset to GitHub release: '$($file.FullName)'"
$req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)$labelParam" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
}
$req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
}

View File

@@ -45,6 +45,5 @@ Format-Table -AutoSize -Wrap -InputObject @{
& "$PSScriptRoot\verify_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath
& "$PSScriptRoot\zip_symbols.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName

View File

@@ -43,8 +43,13 @@ param (
[string]
[Parameter(Mandatory=$true)]
# Path to the folder which contains release assets to upload
$ReleaseFolderPath,
# Path to the zip file to upload with the release
$ZipFilePath,
[string]
[Parameter(Mandatory=$true)]
#Path to the msi file to upload with the release
$MsiFilePath,
[string]
[Parameter(Mandatory=$true)]
@@ -65,17 +70,7 @@ if ($DescriptionIsBase64Encoded) {
. "$PSScriptRoot\github_functions.ps1"
$releaseFolderItems = Get-ChildItem -Path $ReleaseFolderPath
$mrngPortablePath = ($releaseFolderItems | ?{$_.Name -match "portable-[\d\.]+\.zip"}).FullName
$mrngNormalPath = ($releaseFolderItems | ?{$_.Name -match "installer-[\d\.]+\.msi"}).FullName
$mrngPortableSymbolsPath = ($releaseFolderItems | ?{$_.Name -match "mremoteng-portable-symbols-[\d\.]+\.zip"}).FullName
$mrngNormalSymbolsPath = ($releaseFolderItems | ?{$_.Name -match "mremoteng-symbols-[\d\.]+\.zip"}).FullName
$release = Publish-GitHubRelease -Owner $Owner -Repository $Repository -ReleaseTitle $ReleaseTitle -TagName $TagName -TargetCommitish $TargetCommitish -Description $Description -IsDraft ([bool]::Parse($IsDraft)) -IsPrerelease ([bool]::Parse($IsPrerelease)) -AuthToken $AuthToken
$zipUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngPortablePath -ContentType "application/zip" -AuthToken $AuthToken -Label "Portable Edition (zip)"
$msiUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngNormalPath -ContentType "application/octet-stream" -AuthToken $AuthToken -Label "Normal Edition (msi)"
$portableEditionSymbols = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngPortableSymbolsPath -ContentType "application/zip" -AuthToken $AuthToken -Label "Portable Edition Debug Symbols"
$normalEditionSymbols = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngNormalSymbolsPath -ContentType "application/zip" -AuthToken $AuthToken -Label "Normal Edition Debug Symbols"
$zipUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $ZipFilePath -ContentType "application/zip" -AuthToken $AuthToken
$msiUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $MsiFilePath -ContentType "application/octet-stream" -AuthToken $AuthToken
Write-Output (Get-GitHubRelease -Owner $Owner -Repository $Repository -ReleaseId $release.id -AuthToken $AuthToken)

View File

@@ -9,7 +9,7 @@ Write-Host $SolutionDir
Write-Host $renameTarget
$targetVersionedFile = "$SolutionDir\mRemoteV1\bin\Release\mRemoteNG.exe"
$version = &"$SolutionDir\Tools\exes\sigcheck.exe" /accepteula -q -n $targetVersionedFile
$version = &"$SolutionDir\Tools\sigcheck.exe" /accepteula -q -n $targetVersionedFile
$renameTargetFileObject = Get-Item -Path $renameTarget -ErrorAction SilentlyContinue

View File

@@ -15,6 +15,7 @@ if ($ConfigurationName -match "Release") {
Write-Output "Removing unnecessary files from Release versions"
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force
$filesToDelete = Get-ChildItem -Path $TargetDir -Recurse -Include @(
"*.pdb",
"*.publish",
"*.xml",
"*.backup",

View File

@@ -8,7 +8,6 @@ param (
$ConfigurationName,
[string]
[Parameter(Mandatory=$true)]
# The code signing certificate to use when signing the files.
$CertificatePath
)

View File

@@ -13,49 +13,13 @@ param (
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
$path_packageZipScript = Join-Path -Path $SolutionDir -ChildPath "Tools\build-relport.cmd"
if(-not [string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {
Write-Output "Too early to run via Appveyor - artifacts don't get generated properly. Exiting"
Exit
}
Write-Output "Solution Dir: '$($SolutionDir)'"
Write-Output "Target Dir: '$($TargetDir)'"
$ConfigurationName = $ConfigurationName.Trim()
Write-Output "Config Name (tirmmed): '$($ConfigurationName)'"
# Windows Sysinternals Sigcheck from http://technet.microsoft.com/en-us/sysinternals/bb897441
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
# Package Zip
if ($ConfigurationName -eq "Release Portable") {
if ($ConfigurationName -match "Release" -and $ConfigurationName -match "Portable") {
Write-Output "Packaging Release Portable ZIP"
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe"
Write-Output "Version is $($version)"
$PortableZip="$($SolutionDir)Release\mRemoteNG-Portable-$($version).zip"
$tempFolderPath = Join-Path -Path $SolutionDir -ChildPath "mRemoteV1\bin\package"
Remove-Item -Recurse $tempFolderPath -ErrorAction SilentlyContinue | Out-Null
New-Item $tempFolderPath -ItemType "directory" | Out-Null
Copy-Item "$($SolutionDir)mRemoteV1\Resources\PuTTYNG.exe" -Destination $tempFolderPath
#Write-Output "$($SolutionDir)mRemoteV1\bin\$ConfigurationName"
#Write-Output "$($SolutionDir)mRemoteV1\bin\package"
Copy-Item "$($SolutionDir)mRemoteV1\bin\$ConfigurationName\*" -Destination $tempFolderPath -Recurse -Force
# Delete any PDB files that accidentally get copied into the temp folder
Get-ChildItem -Path $tempFolderPath -Filter "*.pdb" | Remove-Item
Copy-Item "$($SolutionDir)*.txt" -Destination $tempFolderPath
Write-Output "Creating portable ZIP file $($PortableZip)"
Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip (Join-Path -Path $tempFolderPath -ChildPath "*.*")
#& $SEVENZIP a -bt -mx=9 -tzip -y $PortableZip "$($SolutionDir)*.TXT"
& $path_packageZipScript
}
else {
Write-Output "We will not zip anything - this isnt a portable release build."

View File

@@ -1,39 +0,0 @@
if([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {
Write-Output "NOT running via Appveyor - Exiting"
Exit
}
$appvDir = $Env:APPVEYOR_BUILD_FOLDER
Write-Output "Appveyor Build Dir: '$($appvDir)'"
$ConfigurationName = $Env:CONFIGURATION.Trim()
Write-Output "Config Name (tirmmed): '$($ConfigurationName)'"
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
if ($ConfigurationName -eq "Release Portable") {
Write-Output "Packaging Release Portable ZIP"
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe"
Write-Output "Version is $($version)"
$PortableZip="$($SolutionDir)Release\mRemoteNG-Portable-$($version).zip"
Remove-Item -Recurse "$($SolutionDir)mRemoteV1\bin\package" -ErrorAction SilentlyContinue | Out-Null
New-Item "$($SolutionDir)mRemoteV1\bin\package" -ItemType "directory" | Out-Null
Copy-Item "$($SolutionDir)mRemoteV1\Resources\PuTTYNG.exe" -Destination "$($SolutionDir)mRemoteV1\bin\package"
Copy-Item "$($SolutionDir)mRemoteV1\bin\$ConfigurationName\*" -Destination "$($SolutionDir)mRemoteV1\bin\package" -Recurse -Force
Copy-Item "$($SolutionDir)*.txt" -Destination "$($SolutionDir)mRemoteV1\bin\package"
Write-Output "Creating portable ZIP file $($PortableZip)"
Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip "$($SolutionDir)mRemoteV1\bin\package\*.*"
}
else {
Write-Output "We will not zip anything - this isnt a portable release build."
}

View File

@@ -1,56 +0,0 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir,
[string]
[Parameter(Mandatory=$true)]
$ConfigurationName
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
if(-not [string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {
Write-Output "Too early to run via Appveyor - artifacts don't get generated properly. Exiting"
Exit
}
Write-Output "Solution Dir: '$($SolutionDir)'"
Write-Output "Target Dir: '$($TargetDir)'"
$ConfigurationName = $ConfigurationName.Trim()
Write-Output "Config Name (trimmed): '$($ConfigurationName)'"
# Windows Sysinternals Sigcheck from http://technet.microsoft.com/en-us/sysinternals/bb897441
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
# Package Zip
if ($ConfigurationName -match "Release") {
Write-Output "Packaging debug symbols"
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteV1\bin\$($ConfigurationName)\mRemoteNG.exe"
Write-Output "Version is $($version)"
if ($ConfigurationName -match "Portable") {
$zipFilePrefix = "mRemoteNG-Portable-symbols"
} else {
$zipFilePrefix = "mRemoteNG-symbols"
}
$outputZipPath="$($SolutionDir)Release\$zipFilePrefix-$($version).zip"
Write-Output "Creating debug symbols ZIP file $($outputZipPath)"
Remove-Item -Force $outputZipPath -ErrorAction SilentlyContinue
& $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath (Join-Path -Path $TargetDir -ChildPath "*.pdb")
}
else {
Write-Output "We will not package debug symbols - this isnt a release build."
}
Write-Output ""

View File

@@ -1,11 +1,10 @@
version: 1.76.{build}
version: 1.0.{build}
pull_requests:
do_not_increment_build_number: true
image: Visual Studio 2017
configuration:
- Release
- Release Portable
- Release Installer
platform: x86
clone_depth: 1
install:
@@ -15,14 +14,7 @@ before_build:
build:
project: mRemoteV1.sln
verbosity: normal
after_build:
- ps: "if([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) {\n Write-Output \"NOT running via Appveyor - Exiting\"\n Exit\n}\n\n$appvDir = $Env:APPVEYOR_BUILD_FOLDER\n\nWrite-Output \"Appveyor Build Dir: '$($appvDir)'\"\n$ConfigurationName = $Env:CONFIGURATION.Trim()\nWrite-Output \"Config Name (tirmmed): '$($ConfigurationName)'\"\n\n\n$SIGCHECK=\"$($SolutionDir)Tools\\exes\\sigcheck.exe\"\n$SEVENZIP=\"$($SolutionDir)Tools\\7zip\\7za.exe\"\n\nif ($ConfigurationName -eq \"Release Portable\") {\n Write-Output \"Packaging Release Portable ZIP\"\n \n $version = & $SIGCHECK /accepteula -q -n \"$($SolutionDir)mRemoteV1\\bin\\$($ConfigurationName)\\mRemoteNG.exe\"\n\n Write-Output \"Version is $($version)\"\n\n $PortableZip=\"$($SolutionDir)Release\\mRemoteNG-Portable-$($version).zip\"\n\n Remove-Item -Recurse \"$($SolutionDir)mRemoteV1\\bin\\package\" -ErrorAction SilentlyContinue | Out-Null\n New-Item \"$($SolutionDir)mRemoteV1\\bin\\package\" -ItemType \"directory\" | Out-Null\n \n Copy-Item \"$($SolutionDir)mRemoteV1\\Resources\\PuTTYNG.exe\" -Destination \"$($SolutionDir)mRemoteV1\\bin\\package\"\n\n Copy-Item \"$($SolutionDir)mRemoteV1\\bin\\$ConfigurationName\\*\" -Destination \"$($SolutionDir)mRemoteV1\\bin\\package\" -Recurse -Force \n Copy-Item \"$($SolutionDir)*.txt\" -Destination \"$($SolutionDir)mRemoteV1\\bin\\package\"\n\n Write-Output \"Creating portable ZIP file $($PortableZip)\"\n Remove-Item -Force $PortableZip -ErrorAction SilentlyContinue\n & $SEVENZIP a -bt -bd -bb1 -mx=9 -tzip -y -r $PortableZip \"$($SolutionDir)mRemoteV1\\bin\\package\\*.*\"\n}\nelse {\n Write-Output \"We will not zip anything - this isnt a portable release build.\"\n}"
test:
assemblies:
only:
- mRemoteNGTests\bin\$(configuration)\mRemoteNGTests.dll
artifacts:
- path: Release\*.msi
name: mRemoteNG-installer.msi
- path: Release\*.zip
name: mRemoteNG-portable.zip
- mRemoteNGTests\bin\$(configuration)\mRemoteNGTests.dll

View File

@@ -4,7 +4,6 @@ using System.Security;
using System.Xml.Linq;
using mRemoteNG.Config;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;

View File

@@ -1,96 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Security;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNGTests.TestHelpers;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
{
public class ValidateXmlSchemas
{
private XmlConnectionsSerializer _serializer;
private ConnectionTreeModel _connectionTreeModel;
private ICryptographyProvider _cryptographyProvider;
private XmlReaderSettings _xmlReaderSettings;
[SetUp]
public void Setup()
{
_connectionTreeModel = new ConnectionTreeModelBuilder().Build();
_cryptographyProvider = new AeadCryptographyProvider();
var connectionNodeSerializer = new XmlConnectionNodeSerializer26(
_cryptographyProvider,
_connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
new SaveFilter());
_serializer = new XmlConnectionsSerializer(_cryptographyProvider, connectionNodeSerializer);
_xmlReaderSettings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
XmlSchemaValidationFlags.ProcessSchemaLocation |
XmlSchemaValidationFlags.ReportValidationWarnings
};
}
[Test]
public void ValidateSchema()
{
var sb = new StringBuilder();
var xml = _serializer.Serialize(_connectionTreeModel);
var schemaFile = GetTargetPath("mremoteng_confcons_v2_6.xsd");
_xmlReaderSettings.Schemas.Add("http://mremoteng.org", schemaFile);
_xmlReaderSettings.ValidationEventHandler += (sender, args) =>
{
sb.AppendLine($"{args.Severity}: {args.Message}");
};
using (var stream = GenerateStreamFromString(xml))
{
var reader = XmlReader.Create(stream, _xmlReaderSettings);
while (reader.Read()) ;
}
Assert.That(sb.ToString(), Is.Empty);
}
public string GetTargetPath(string fileName, [CallerFilePath] string sourceFilePath = "")
{
const string debugOrRelease =
#if DEBUG
"Debug";
#else
"Release";
#endif
const string normalOrPortable =
#if PORTABLE
" Portable";
#else
"";
#endif
var path = Path.GetDirectoryName(sourceFilePath);
var filePath = $@"{path}\..\..\..\..\bin\{debugOrRelease}{normalOrPortable}\Schemas\{fileName}";
return filePath;
}
private Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
}
}

View File

@@ -1,7 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
@@ -9,7 +9,7 @@ using mRemoteNG.Tree;
using mRemoteNGTests.Properties;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers
{
public class XmlConnectionsDeserializerTests
{
@@ -18,7 +18,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
public void Setup(string confCons, string password)
{
_xmlConnectionsDeserializer = new XmlConnectionsDeserializer(() => password.ConvertToSecureString());
_xmlConnectionsDeserializer = new XmlConnectionsDeserializer(password.ConvertToSecureString);
_connectionTreeModel = _xmlConnectionsDeserializer.Deserialize(confCons);
}
@@ -104,14 +104,6 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
Assert.That(folder22.Inheritance.Username, Is.True);
}
[TestCaseSource(typeof(XmlConnectionsDeserializerFixtureData), nameof(XmlConnectionsDeserializerFixtureData.FixtureParams))]
public void ExpandedPropertyGetsDeserialized(Datagram testData)
{
Setup(testData.ConfCons, testData.Password);
var folder1 = GetFolderNamed("Folder1", _connectionTreeModel.GetRecursiveChildList());
Assert.That(folder1.IsExpanded, Is.True);
}
private bool ContainsNodeNamed(string name, IEnumerable<ConnectionInfo> list)
{
return list.Any(node => node.Name == name);

View File

@@ -1,7 +1,6 @@
using System.Linq;
using System.Xml.XPath;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
@@ -10,7 +9,7 @@ using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers
{
public class XmlConnectionsDocumentCompilerTests
{

View File

@@ -1,7 +1,6 @@
using System.Linq;
using System.Xml.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
@@ -10,7 +9,7 @@ using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers
{
public class XmlConnectionsDocumentEncryptorTests
{

View File

@@ -2,7 +2,6 @@
using System.Xml;
using System.Xml.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
@@ -11,7 +10,7 @@ using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers
{
public class XmlConnectionsSerializerTests
{
@@ -56,7 +55,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
[TestCase("Username", "")]
[TestCase("Domain", "")]
[TestCase("Password", "")]
[TestCase("InheritAutomaticResize", "false")]
[TestCase("InheritAutomaticResize", "False")]
public void SerializerRespectsSaveFilterSettings(string attributeName, string expectedValue)
{
var connectionNodeSerializer = new XmlConnectionNodeSerializer26(

View File

@@ -2,14 +2,13 @@
using System.Collections;
using System.Xml.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Security;
using mRemoteNG.Security.Factories;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tree.Root;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers
{
public class XmlRootNodeSerializerTests
{
@@ -76,7 +75,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
{
var element = _rootNodeSerializer.SerializeRootNodeInfo(_rootNodeInfo, _cryptographyProvider, fullFileEncryption);
var attributeValue = element.Attribute(XName.Get("FullFileEncryption"))?.Value;
Assert.That(bool.Parse(attributeValue), Is.EqualTo(fullFileEncryption));
Assert.That(attributeValue, Is.EqualTo(fullFileEncryption.ToString()));
}
[TestCase("", "ThisIsNotProtected")]

View File

@@ -1,12 +1,10 @@
using System.Data;
using System.Security;
using mRemoteNG.Config.Serializers.MsSql;
using System.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Connection;
using mRemoteNG.Security;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tree;
using mRemoteNGTests.TestHelpers;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers
@@ -14,37 +12,30 @@ namespace mRemoteNGTests.Config.Serializers
public class DataTableDeserializerTests
{
private DataTableDeserializer _deserializer;
private ICryptographyProvider _cryptographyProvider;
[SetUp]
public void Setup()
{
_cryptographyProvider = new LegacyRijndaelCryptographyProvider();
}
[Test]
public void WeCanDeserializeATree()
{
var model = CreateConnectionTreeModel();
var dataTable = CreateDataTable(model.RootNodes[0]);
_deserializer = new DataTableDeserializer(_cryptographyProvider, new SecureString());
_deserializer = new DataTableDeserializer();
var output = _deserializer.Deserialize(dataTable);
Assert.That(output.GetRecursiveChildList().Count, Is.EqualTo(model.GetRecursiveChildList().Count));
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(model.GetRecursiveChildList().Count()));
}
[Test]
public void WeCanDeserializeASingleEntry()
{
var dataTable = CreateDataTable(new ConnectionInfo());
_deserializer = new DataTableDeserializer(_cryptographyProvider, new SecureString());
_deserializer = new DataTableDeserializer();
var output = _deserializer.Deserialize(dataTable);
Assert.That(output.GetRecursiveChildList().Count, Is.EqualTo(1));
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(1));
}
private DataTable CreateDataTable(ConnectionInfo tableContent)
{
var serializer = new DataTableSerializer(new SaveFilter(), _cryptographyProvider, new SecureString());
var serializer = new DataTableSerializer(new SaveFilter());
return serializer.Serialize(tableContent);
}

View File

@@ -1,15 +1,10 @@
using System.Linq;
using System.Security;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.MsSql;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNGTests.TestHelpers;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers
@@ -23,10 +18,7 @@ namespace mRemoteNGTests.Config.Serializers
public void Setup()
{
_saveFilter = new SaveFilter();
_dataTableSerializer = new DataTableSerializer(
_saveFilter,
new LegacyRijndaelCryptographyProvider(),
new SecureString());
_dataTableSerializer = new DataTableSerializer(_saveFilter);
}
[Test]
@@ -34,7 +26,7 @@ namespace mRemoteNGTests.Config.Serializers
{
var model = CreateConnectionTreeModel();
var dataTable = _dataTableSerializer.Serialize(model);
Assert.That(dataTable.Rows.Count, Is.EqualTo(model.GetRecursiveChildList().Count()));
Assert.That(dataTable.Rows.Count, Is.EqualTo(3));
}
[Test]

View File

@@ -1,7 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.MiscSerializers;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
@@ -10,29 +11,28 @@ using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNGTests.TestHelpers;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
public class CsvConnectionsDeserializerMremotengFormatTests
public class CsvConnectionsDeserializerMremotengFormatTests
{
private CsvConnectionsDeserializerMremotengFormat _deserializer;
private CsvConnectionsSerializerMremotengFormat _serializer;
private ICredentialRepositoryList _credentialRepositoryList;
[SetUp]
public void Setup()
{
_deserializer = new CsvConnectionsDeserializerMremotengFormat();
var credentialRepositoryList = Substitute.For<ICredentialRepositoryList>();
_serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), credentialRepositoryList);
_credentialRepositoryList = Substitute.For<ICredentialRepositoryList>();
}
[TestCaseSource(typeof(DeserializationTestSource), nameof(DeserializationTestSource.ConnectionPropertyTestCases))]
public object ConnectionPropertiesDeserializedCorrectly(string propertyToCheck)
{
var csv = _serializer.Serialize(GetTestConnection());
var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList);
var csv = serializer.Serialize(GetTestConnection());
var deserializedConnections = _deserializer.Deserialize(csv);
var connection = deserializedConnections.GetRecursiveChildList().FirstOrDefault();
var propertyValue = typeof(ConnectionInfo).GetProperty(propertyToCheck)?.GetValue(connection);
@@ -42,29 +42,14 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
[TestCaseSource(typeof(DeserializationTestSource), nameof(DeserializationTestSource.InheritanceTestCases))]
public object InheritancePropertiesDeserializedCorrectly(string propertyToCheck)
{
var csv = _serializer.Serialize(GetTestConnectionWithAllInherited());
var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList);
var csv = serializer.Serialize(GetTestConnectionWithAllInherited());
var deserializedConnections = _deserializer.Deserialize(csv);
var connection = deserializedConnections.GetRecursiveChildList().FirstOrDefault();
connection?.RemoveParent();
var propertyValue = typeof(ConnectionInfoInheritance).GetProperty(propertyToCheck)?.GetValue(connection?.Inheritance);
return propertyValue;
}
[Test]
public void TreeStructureDeserializedCorrectly()
{
//Root
// |- folder1
// | |- Con1
// |- Con2
var treeModel = new ConnectionTreeModelBuilder().Build();
var csv = _serializer.Serialize(treeModel);
var deserializedConnections = _deserializer.Deserialize(csv);
var con1 = deserializedConnections.GetRecursiveChildList().First(info => info.Name == "Con1");
var folder1 = deserializedConnections.GetRecursiveChildList().First(info => info.Name == "folder1");
Assert.That(con1.Parent, Is.EqualTo(folder1));
}
internal static ConnectionInfo GetTestConnection()
{
return new ConnectionInfo
@@ -97,9 +82,9 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
UseCredSsp = true,
RenderingEngine = HTTPBase.RenderingEngine.Gecko,
ICAEncryptionStrength = IcaProtocol.EncryptionStrength.Encr40Bit,
RDPAuthenticationLevel = RdpProtocol.AuthenticationLevel.WarnOnFailedAuth,
Colors = RdpProtocol.RDPColors.Colors16Bit,
Resolution = RdpProtocol.RDPResolutions.Res1366x768,
RDPAuthenticationLevel = RdpAuthenticationLevel.WarnOnFailedAuth,
Colors = RdpColors.Colors16Bit,
Resolution = RdpResolutions.Res1366x768,
AutomaticResize = true,
DisplayWallpaper = true,
DisplayThemes = true,
@@ -110,7 +95,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
RedirectPorts = true,
RedirectPrinters = true,
RedirectSmartCards = true,
RedirectSound = RdpProtocol.RDPSounds.LeaveAtRemoteComputer,
RedirectSound = RdpSounds.LeaveAtRemoteComputer,
RedirectKeys = true,
VNCCompression = ProtocolVNC.Compression.Comp4,
VNCEncoding = ProtocolVNC.Encoding.EncRRE,
@@ -120,8 +105,8 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
VNCColors = ProtocolVNC.Colors.Col8Bit,
VNCSmartSizeMode = ProtocolVNC.SmartSizeMode.SmartSAspect,
VNCViewOnly = true,
RDGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Detect,
RDGatewayUseConnectionCredentials = RdpProtocol.RDGatewayUseConnectionCredentials.SmartCard
RDGatewayUsageMethod = RDGatewayUsageMethod.Detect,
RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.SmartCard
};
}

View File

@@ -1,17 +1,13 @@
using System;
using System.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNGTests.TestHelpers;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
public class CsvConnectionsSerializerMremotengFormatTests
{
@@ -32,24 +28,6 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
_credentialRepositoryList.GetCredentialRecord(new Guid()).ReturnsForAnyArgs(credRecord);
}
[Test]
public void SerializesNodeId()
{
var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList);
var connectionInfo = BuildConnectionInfo();
var csv = serializer.Serialize(connectionInfo);
Assert.That(csv, Does.Match(connectionInfo.ConstantID));
}
[Test]
public void DoesntSerializeTheRootNode()
{
var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList);
var treeModel = new ConnectionTreeModelBuilder().Build();
var csv = serializer.Serialize(treeModel);
Assert.That(csv, Does.Not.Match($"{treeModel.RootNodes[0].ConstantID};.*;{TreeNodeType.Root}"));
}
[TestCase(Username)]
[TestCase(Domain)]
[TestCase(Password)]
@@ -104,32 +82,6 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
Assert.Throws<ArgumentNullException>(() => serializer.Serialize((ConnectionTreeModel)null));
}
[Test]
public void FoldersAreSerialized()
{
var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList);
var container = BuildContainer();
var csv = serializer.Serialize(container);
Assert.That(csv, Does.Match(container.Name));
Assert.That(csv, Does.Match(container.Username));
Assert.That(csv, Does.Match(container.Domain));
Assert.That(csv, Does.Match(container.Password));
Assert.That(csv, Does.Contain(TreeNodeType.Container.ToString()));
}
[Test]
public void SerializationIncludesRawInheritedValuesIfObjectInheritsFromParentOutsideOfSerializationScope()
{
var serializer = new CsvConnectionsSerializerMremotengFormat(new SaveFilter(), _credentialRepositoryList);
var treeModel = new ConnectionTreeModelBuilder().Build();
var serializationTarget = treeModel.GetRecursiveChildList().First(info => info.Name == "folder3");
var csv = serializer.Serialize(serializationTarget);
var lineWithFolder3 = csv.Split(new[] {Environment.NewLine}, StringSplitOptions.None).First(s => s.Contains(serializationTarget.Name));
Assert.That(lineWithFolder3, Does.Contain(serializationTarget.Username));
Assert.That(lineWithFolder3, Does.Contain(serializationTarget.Domain));
Assert.That(lineWithFolder3, Does.Contain(serializationTarget.Password));
}
private ConnectionInfo BuildConnectionInfo()
{
return new ConnectionInfo
@@ -141,16 +93,5 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
Inheritance = {Colors = true}
};
}
private ContainerInfo BuildContainer()
{
return new ContainerInfo
{
Name = "MyFolder",
Username = "BlahBlah1",
Domain = "aklkskkksh8",
Password = "qweraslkdjf87"
};
}
}
}

View File

@@ -8,7 +8,7 @@ using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
public class RemoteDesktopConnectionDeserializerTests
public class RemoteDesktopConnectionDeserializerTests
{
// .rdp file schema: https://technet.microsoft.com/en-us/library/ff393699(v=ws.10).aspx
private RemoteDesktopConnectionDeserializer _deserializer;
@@ -18,9 +18,9 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
private const string ExpectedDomain = "myspecialdomain";
private const string ExpectedGatewayHostname = "gatewayhostname.domain.com";
private const int ExpectedPort = 9933;
private const RdpProtocol.RDPColors ExpectedColors = RdpProtocol.RDPColors.Colors24Bit;
private const RdpColors ExpectedColors = RdpColors.Colors24Bit;
private const bool ExpectedBitmapCaching = false;
private const RdpProtocol.RDPResolutions ExpectedResolutionMode = RdpProtocol.RDPResolutions.FitToWindow;
private const RdpResolutions ExpectedResolutionMode = RdpResolutions.FitToWindow;
private const bool ExpectedWallpaperDisplay = true;
private const bool ExpectedThemesDisplay = true;
private const bool ExpectedFontSmoothing = true;
@@ -29,7 +29,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
private const bool ExpectedDriveRedirection = true;
private const bool ExpectedPortRedirection = true;
private const bool ExpectedPrinterRedirection = true;
private const RdpProtocol.RDPSounds ExpectedSoundRedirection = RdpProtocol.RDPSounds.BringToThisComputer;
private const RdpSounds ExpectedSoundRedirection = RdpSounds.BringToThisComputer;
[OneTimeSetUp]

View File

@@ -10,7 +10,7 @@ using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
public class RemoteDesktopConnectionManager27DeserializerTests
public class RemoteDesktopConnectionManager27DeserializerTests
{
private string _connectionFileContents;
private RemoteDesktopConnectionManagerDeserializer _deserializer;
@@ -23,20 +23,20 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
private const string ExpectedPassword = "passwordHere!";
private const bool ExpectedUseConsoleSession = true;
private const int ExpectedPort = 9933;
private const RdpProtocol.RDGatewayUsageMethod ExpectedGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Always;
private const RDGatewayUsageMethod ExpectedGatewayUsageMethod = RDGatewayUsageMethod.Always;
private const string ExpectedGatewayHostname = "gatewayserverhost.innerdomain.net";
private const string ExpectedGatewayUsername = "gatewayusername";
private const string ExpectedGatewayDomain = "innerdomain";
private const string ExpectedGatewayPassword = "gatewayPassword123";
private const RdpProtocol.RDPResolutions ExpectedRdpResolution = RdpProtocol.RDPResolutions.FitToWindow;
private const RdpProtocol.RDPColors ExpectedRdpColorDepth = RdpProtocol.RDPColors.Colors24Bit;
private const RdpProtocol.RDPSounds ExpectedAudioRedirection = RdpProtocol.RDPSounds.DoNotPlay;
private const RdpResolutions ExpectedRdpResolution = RdpResolutions.FitToWindow;
private const RdpColors ExpectedRdpColorDepth = RdpColors.Colors24Bit;
private const RdpSounds ExpectedAudioRedirection = RdpSounds.DoNotPlay;
private const bool ExpectedKeyRedirection = true;
private const bool ExpectedSmartcardRedirection = true;
private const bool ExpectedDriveRedirection = true;
private const bool ExpectedPortRedirection = true;
private const bool ExpectedPrinterRedirection = true;
private const RdpProtocol.AuthenticationLevel ExpectedAuthLevel = RdpProtocol.AuthenticationLevel.WarnOnFailedAuth;
private const RdpAuthenticationLevel ExpectedAuthLevel = RdpAuthenticationLevel.WarnOnFailedAuth;
[OneTimeSetUp]

View File

@@ -10,7 +10,7 @@ using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{
public class RemoteDesktopConnectionManagerDeserializerTests
public class RemoteDesktopConnectionManagerDeserializerTests
{
private string _connectionFileContents;
private RemoteDesktopConnectionManagerDeserializer _deserializer;
@@ -23,20 +23,20 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
private const string ExpectedPassword = "passwordHere!";
private const bool ExpectedUseConsoleSession = true;
private const int ExpectedPort = 9933;
private const RdpProtocol.RDGatewayUsageMethod ExpectedGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Always;
private const RDGatewayUsageMethod ExpectedGatewayUsageMethod = RDGatewayUsageMethod.Always;
private const string ExpectedGatewayHostname = "gatewayserverhost.innerdomain.net";
private const string ExpectedGatewayUsername = "gatewayusername";
private const string ExpectedGatewayDomain = "innerdomain";
private const string ExpectedGatewayPassword = "gatewayPassword123";
private const RdpProtocol.RDPResolutions ExpectedRdpResolution = RdpProtocol.RDPResolutions.FitToWindow;
private const RdpProtocol.RDPColors ExpectedRdpColorDepth = RdpProtocol.RDPColors.Colors24Bit;
private const RdpProtocol.RDPSounds ExpectedAudioRedirection = RdpProtocol.RDPSounds.DoNotPlay;
private const RdpResolutions ExpectedRdpResolution = RdpResolutions.FitToWindow;
private const RdpColors ExpectedRdpColorDepth = RdpColors.Colors24Bit;
private const RdpSounds ExpectedAudioRedirection = RdpSounds.DoNotPlay;
private const bool ExpectedKeyRedirection = true;
private const bool ExpectedSmartcardRedirection = true;
private const bool ExpectedDriveRedirection = true;
private const bool ExpectedPortRedirection = true;
private const bool ExpectedPrinterRedirection = true;
private const RdpProtocol.AuthenticationLevel ExpectedAuthLevel = RdpProtocol.AuthenticationLevel.AuthRequired;
private const RdpAuthenticationLevel ExpectedAuthLevel = RdpAuthenticationLevel.AuthRequired;
[OneTimeSetUp]

View File

@@ -1,5 +1,4 @@
using System;
using mRemoteNG.Connection;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.ICA;
@@ -13,11 +12,7 @@ namespace mRemoteNGTests.Connection
public class AbstractConnectionInfoDataTests
{
#pragma warning disable 618
private class TestAbstractConnectionInfoData : AbstractConnectionRecord {
public TestAbstractConnectionInfoData() : base(Guid.NewGuid().ToString())
{
}
}
private class TestAbstractConnectionInfoData : AbstractConnectionRecord {}
#pragma warning restore 618
private TestAbstractConnectionInfoData _testAbstractConnectionInfoData;
@@ -165,7 +160,7 @@ namespace mRemoteNGTests.Connection
{
var wasCalled = false;
_testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true;
_testAbstractConnectionInfoData.RDPAuthenticationLevel = RdpProtocol.AuthenticationLevel.AuthRequired;
_testAbstractConnectionInfoData.RDPAuthenticationLevel = RdpAuthenticationLevel.AuthRequired;
Assert.That(wasCalled, Is.True);
}
@@ -201,7 +196,7 @@ namespace mRemoteNGTests.Connection
{
var wasCalled = false;
_testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true;
_testAbstractConnectionInfoData.RDGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Always;
_testAbstractConnectionInfoData.RDGatewayUsageMethod = RDGatewayUsageMethod.Always;
Assert.That(wasCalled, Is.True);
}
@@ -219,7 +214,7 @@ namespace mRemoteNGTests.Connection
{
var wasCalled = false;
_testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true;
_testAbstractConnectionInfoData.RDGatewayUseConnectionCredentials = RdpProtocol.RDGatewayUseConnectionCredentials.SmartCard;
_testAbstractConnectionInfoData.RDGatewayUseConnectionCredentials = RDGatewayUseConnectionCredentials.SmartCard;
Assert.That(wasCalled, Is.True);
}
@@ -255,7 +250,7 @@ namespace mRemoteNGTests.Connection
{
var wasCalled = false;
_testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true;
_testAbstractConnectionInfoData.Resolution = RdpProtocol.RDPResolutions.Res1366x768;
_testAbstractConnectionInfoData.Resolution = RdpResolutions.Res1366x768;
Assert.That(wasCalled, Is.True);
}
@@ -273,7 +268,7 @@ namespace mRemoteNGTests.Connection
{
var wasCalled = false;
_testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true;
_testAbstractConnectionInfoData.Colors = RdpProtocol.RDPColors.Colors16Bit;
_testAbstractConnectionInfoData.Colors = RdpColors.Colors16Bit;
Assert.That(wasCalled, Is.True);
}
@@ -372,7 +367,7 @@ namespace mRemoteNGTests.Connection
{
var wasCalled = false;
_testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true;
_testAbstractConnectionInfoData.RedirectSound = RdpProtocol.RDPSounds.DoNotPlay;
_testAbstractConnectionInfoData.RedirectSound = RdpSounds.DoNotPlay;
Assert.That(wasCalled, Is.True);
}

View File

@@ -1,9 +1,8 @@
using mRemoteNG.Connection;
using mRemoteNG.Container;
using NUnit.Framework;
using System.Reflection;
using System.Collections;
using System.Linq;
using System.Reflection;
namespace mRemoteNGTests.Connection
{
@@ -75,22 +74,6 @@ namespace mRemoteNGTests.Connection
Assert.That(hasEverythingInheritedProperty, Is.False);
}
[Test]
public void AlwaysReturnInheritedValueIfRequested()
{
var expectedSetting = false;
var container = new ContainerInfo { AutomaticResize = expectedSetting };
var con1 = new ConnectionInfo
{
AutomaticResize = true,
Inheritance = {AutomaticResize = true}
};
container.AddChild(con1);
Assert.That(con1.AutomaticResize, Is.EqualTo(expectedSetting));
}
private bool AllInheritancePropertiesAreTrue()
{
var allPropertiesTrue = true;

View File

@@ -27,6 +27,22 @@ namespace mRemoteNGTests.Connection
_connectionInfo = null;
}
[Test]
public void CreatingConnectionInfoWithParentSetsTheParentProperty()
{
var container = new ContainerInfo();
var connectionInfo = new ConnectionInfo(container);
Assert.That(connectionInfo.Parent, Is.EqualTo(container));
}
[Test]
public void CreatingConnectionInfoWithParentAddsToTheParentsChildList()
{
var container = new ContainerInfo();
var connectionInfo = new ConnectionInfo(container);
Assert.That(container.Children, Does.Contain(connectionInfo));
}
[Test]
public void CopyCreatesMemberwiseCopy()
{
@@ -43,20 +59,6 @@ namespace mRemoteNGTests.Connection
Assert.That(clonedConnection.Parent, Is.Null);
}
[Test]
public void CloneAlsoCopiesInheritanceObject()
{
var clonedConnection = _connectionInfo.Clone();
Assert.That(clonedConnection.Inheritance, Is.Not.EqualTo(_connectionInfo.Inheritance));
}
[Test]
public void CloneCorrectlySetsParentOfInheritanceObject()
{
var clonedConnection = _connectionInfo.Clone();
Assert.That(clonedConnection.Inheritance.Parent, Is.EqualTo(clonedConnection));
}
[Test]
public void CopyFromCopiesProperties()
{
@@ -79,7 +81,7 @@ namespace mRemoteNGTests.Connection
{
var eventWasCalled = false;
_connectionInfo.PropertyChanged += (sender, args) => eventWasCalled = true;
_connectionInfo.OpenConnections.Add(new ProtocolSSH2());
_connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionInfo));
Assert.That(eventWasCalled);
}
@@ -88,7 +90,7 @@ namespace mRemoteNGTests.Connection
{
var nameOfModifiedProperty = "";
_connectionInfo.PropertyChanged += (sender, args) => nameOfModifiedProperty = args.PropertyName;
_connectionInfo.OpenConnections.Add(new ProtocolSSH2());
_connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionInfo));
Assert.That(nameOfModifiedProperty, Is.EqualTo("OpenConnections"));
}

View File

@@ -1,62 +1,73 @@
using System.Collections.Generic;
using System.Reflection;
using mRemoteNG.Connection;
using mRemoteNGTests.TestHelpers;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using NUnit.Framework;
namespace mRemoteNGTests.Connection
{
public class DefaultConnectionInfoTests
{
private ConnectionInfo _randomizedConnectionInfo;
public class DefaultConnectionInfoTests
{
private string _testDomain = "somedomain";
[SetUp]
public void Setup()
{
_randomizedConnectionInfo = ConnectionInfoHelpers.GetRandomizedConnectionInfo();
DefaultConnectionInfo.Instance.Domain = "";
}
[TestCaseSource(nameof(GetConnectionInfoProperties))]
public void LoadingDefaultInfoUpdatesAllProperties(PropertyInfo property)
[Test]
public void LoadingDefaultInfoUpdatesAllProperties()
{
DefaultConnectionInfo.Instance.LoadFrom(_randomizedConnectionInfo);
var valueInDestination = property.GetValue(DefaultConnectionInfo.Instance);
var valueInSource = property.GetValue(_randomizedConnectionInfo);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
var connectionInfoSource = new ConnectionInfo { Domain = _testDomain };
DefaultConnectionInfo.Instance.LoadFrom(connectionInfoSource);
Assert.That(DefaultConnectionInfo.Instance.Domain, Is.EqualTo(_testDomain));
}
[TestCaseSource(nameof(GetConnectionInfoProperties))]
public void SavingDefaultConnectionInfoExportsAllProperties(PropertyInfo property)
[Test]
public void SavingDefaultConnectionInfoExportsAllProperties()
{
var saveTarget = new ConnectionInfo();
var randomizedValue = property.GetValue(_randomizedConnectionInfo);
property.SetValue(DefaultConnectionInfo.Instance, randomizedValue);
DefaultConnectionInfo.Instance.Domain = _testDomain;
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
var valueInDestination = property.GetValue(saveTarget);
var valueInSource = property.GetValue(DefaultConnectionInfo.Instance);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
Assert.That(saveTarget.Domain, Is.EqualTo(_testDomain));
}
[TestCaseSource(nameof(GetConnectionInfoProperties))]
public void CanSaveDefaultConnectionToModelWithAllStringProperties(PropertyInfo property)
{
var saveTarget = new SerializableConnectionInfoAllPropertiesOfType<string>();
// randomize default connnection values to ensure we dont get false passing tests
var randomizedValue = property.GetValue(_randomizedConnectionInfo);
property.SetValue(DefaultConnectionInfo.Instance, randomizedValue);
[Test]
public void CanSaveEnumValuesToString()
{
const ProtocolType targetProtocol = ProtocolType.RAW;
var saveTarget = new AllStringPropertySaveTarget();
DefaultConnectionInfo.Instance.Protocol = targetProtocol;
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
var valueInSource = property.GetValue(DefaultConnectionInfo.Instance).ToString();
var valueInDestination = saveTarget.GetType().GetProperty(property.Name).GetValue(saveTarget).ToString();
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
Assert.That(saveTarget.Protocol, Is.EqualTo(targetProtocol.ToString()));
}
private static IEnumerable<PropertyInfo> GetConnectionInfoProperties()
{
return new ConnectionInfo().GetSerializableProperties();
}
[Test]
public void CanSaveIntegerValuesToString()
{
const int targetValue = 123;
var saveTarget = new AllStringPropertySaveTarget();
DefaultConnectionInfo.Instance.RDPMinutesToIdleTimeout = targetValue;
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
Assert.That(saveTarget.RDPMinutesToIdleTimeout, Is.EqualTo(targetValue.ToString()));
}
[Test]
public void CanSaveStringValuesToString()
{
const string targetName = "hello";
var saveTarget = new AllStringPropertySaveTarget();
DefaultConnectionInfo.Instance.Username = targetName;
DefaultConnectionInfo.Instance.SaveTo(saveTarget);
Assert.That(saveTarget.Username, Is.EqualTo(targetName));
}
private class AllStringPropertySaveTarget
{
public string Username { get; set; }
public string Protocol { get; set; }
public string RDPMinutesToIdleTimeout { get; set; }
}
}
}

View File

@@ -1,40 +1,34 @@
using System.Collections.Generic;
using System.Reflection;
using mRemoteNG.Connection;
using mRemoteNG.Connection;
using NUnit.Framework;
namespace mRemoteNGTests.Connection
{
public class DefaultConnectionInheritanceTests
public class DefaultConnectionInheritanceTests
{
[TestCaseSource(nameof(GetInheritanceProperties))]
public void LoadingDefaultInheritanceUpdatesAllProperties(PropertyInfo property)
[SetUp]
public void Setup()
{
var inheritanceSource = new ConnectionInfoInheritance(new object(), true);
DefaultConnectionInheritance.Instance.TurnOffInheritanceCompletely();
}
[Test]
public void LoadingDefaultInheritanceUpdatesAllProperties()
{
var inheritanceSource = new ConnectionInfoInheritance(new object(), true);
inheritanceSource.TurnOnInheritanceCompletely();
DefaultConnectionInheritance.Instance.TurnOffInheritanceCompletely();
DefaultConnectionInheritance.Instance.LoadFrom(inheritanceSource);
Assert.That(DefaultConnectionInheritance.Instance.EverythingInherited, Is.True);
}
var valueInDestination = property.GetValue(DefaultConnectionInheritance.Instance);
var valueInSource = property.GetValue(inheritanceSource);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
}
[TestCaseSource(nameof(GetInheritanceProperties))]
public void SavingDefaultInheritanceExportsAllProperties(PropertyInfo property)
[Test]
public void SavingDefaultInheritanceExportsAllProperties()
{
var saveTarget = new ConnectionInfoInheritance(new object(), true);
saveTarget.TurnOffInheritanceCompletely();
DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely();
DefaultConnectionInheritance.Instance.SaveTo(saveTarget);
var valueInDestination = property.GetValue(saveTarget);
var valueInSource = property.GetValue(DefaultConnectionInheritance.Instance);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
}
var inheritanceDestination = new ConnectionInfoInheritance(new object(), true);
DefaultConnectionInheritance.Instance.AutomaticResize = true;
DefaultConnectionInheritance.Instance.SaveTo(inheritanceDestination);
Assert.That(inheritanceDestination.AutomaticResize, Is.True);
}
[Test]
public void NewInheritanceInstancesCreatedWithDefaultInheritanceValues()
@@ -44,20 +38,12 @@ namespace mRemoteNGTests.Connection
Assert.That(inheritanceInstance.Domain, Is.True);
}
[TestCaseSource(nameof(GetInheritanceProperties))]
public void NewInheritanceInstancesCreatedWithAllDefaultInheritanceValues(PropertyInfo property)
[Test]
public void NewInheritanceInstancesCreatedWithAllDefaultInheritanceValues()
{
DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely();
var inheritanceInstance = new ConnectionInfoInheritance(new object());
var valueInDestination = property.GetValue(inheritanceInstance);
var valueInSource = property.GetValue(DefaultConnectionInheritance.Instance);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
}
private static IEnumerable<PropertyInfo> GetInheritanceProperties()
{
return new ConnectionInfoInheritance(new object(), true).GetProperties();
}
}
Assert.That(inheritanceInstance.EverythingInherited, Is.True);
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Collections.ObjectModel;
using mRemoteNG.App;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Tools;
@@ -12,7 +11,7 @@ namespace mRemoteNGTests.Connection.Protocol
{
public class IntegratedProgramTests
{
private readonly ExternalTool _extTool = new ExternalTool
private readonly ExternalTool _extTool = new ExternalTool
{
DisplayName = "notepad",
FileName = @"%windir%\system32\notepad.exe",
@@ -20,13 +19,13 @@ namespace mRemoteNGTests.Connection.Protocol
TryIntegrate = true
};
[Test]
public void CanStartExternalApp()
{
SetExternalToolList(_extTool);
var sut = new IntegratedProgram();
sut.InterfaceControl = BuildInterfaceControl("notepad", sut);
var connectionInfo = new ConnectionInfo { ExtApp = _extTool.DisplayName };
var sut = new IntegratedProgram(connectionInfo);
sut.InterfaceControl = BuildInterfaceControl(sut);
sut.Initialize();
var appStarted = sut.Connect();
sut.Disconnect();
@@ -37,8 +36,9 @@ namespace mRemoteNGTests.Connection.Protocol
public void ConnectingToExternalAppThatDoesntExistDoesNothing()
{
SetExternalToolList(_extTool);
var sut = new IntegratedProgram();
sut.InterfaceControl = BuildInterfaceControl("doesntExist", sut);
var connectionInfo = new ConnectionInfo { ExtApp = "doesntExist" };
var sut = new IntegratedProgram(connectionInfo);
sut.InterfaceControl = BuildInterfaceControl(sut);
var appInitialized = sut.Initialize();
Assert.That(appInitialized, Is.False);
}
@@ -48,11 +48,10 @@ namespace mRemoteNGTests.Connection.Protocol
Runtime.ExternalToolsService.ExternalTools = new FullyObservableCollection<ExternalTool> {externalTool};
}
private InterfaceControl BuildInterfaceControl(string extAppName, ProtocolBase sut)
private InterfaceControl BuildInterfaceControl(ProtocolBase sut)
{
var connectionWindow = new ConnectionWindow(new DockContent());
var connectionInfo = new ConnectionInfo {ExtApp = extAppName};
return new InterfaceControl(connectionWindow, sut, connectionInfo);
return new InterfaceControl(connectionWindow, sut);
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Specialized;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Connection.Protocol.Telnet;
@@ -21,9 +22,9 @@ namespace mRemoteNGTests.Connection.Protocol
public void Setup()
{
_protocolList = new ProtocolList();
_protocol1 = new ProtocolTelnet();
_protocol2 = new ProtocolSSH2();
_protocol3 = new ProtocolVNC();
_protocol1 = new ProtocolTelnet(new ConnectionInfo());
_protocol2 = new ProtocolSSH2(new ConnectionInfo());
_protocol3 = new ProtocolVNC(new ConnectionInfo());
}
[TearDown]

View File

@@ -1,18 +0,0 @@
using mRemoteNG.Connection;
using mRemoteNG.Tree.Root;
using NUnit.Framework;
namespace mRemoteNGTests.Container
{
public class RootNodeInfoTests
{
[Test]
public void InheritanceIsDisabledForNodesDirectlyUnderRootNode()
{
var rootNode = new RootNodeInfo(RootNodeType.Connection);
var con1 = new ConnectionInfo { Inheritance = { Password = true } };
rootNode.AddChild(con1);
Assert.That(con1.Inheritance.Password, Is.False);
}
}
}

View File

@@ -1,8 +1,5 @@
using System;
using System.Linq;
using System.Xml.Linq;
using System.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
@@ -31,19 +28,20 @@ namespace mRemoteNGTests.IntegrationTests
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
_deserializer = new XmlConnectionsDeserializer();
}
[TearDown]
public void Teardown()
{
_serializer = null;
_deserializer = null;
}
[Test]
public void SerializeThenDeserialize()
{
var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
@@ -55,6 +53,7 @@ namespace mRemoteNGTests.IntegrationTests
{
_serializer.UseFullEncryption = true;
var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
@@ -66,6 +65,7 @@ namespace mRemoteNGTests.IntegrationTests
{
var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" };
var serializedContent = _serializer.Serialize(originalConnectionInfo);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description));
@@ -83,26 +83,13 @@ namespace mRemoteNGTests.IntegrationTests
new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel));
}
[Test]
public void GuidCreatedIfNonExistedInXml()
{
var originalConnectionInfo = new ConnectionInfo { Name = "con1" };
var serializedContent = _serializer.Serialize(originalConnectionInfo);
// remove GUID from connection xml
serializedContent = serializedContent.Replace(originalConnectionInfo.ConstantID, "");
var deserializedModel = _deserializer.Deserialize(serializedContent);
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
Assert.That(Guid.TryParse(deserializedConnectionInfo.ConstantID, out var guid));
}
private ConnectionTreeModel SetupConnectionTreeModel()
{

View File

@@ -34,9 +34,8 @@
using System.Collections;
using System.Windows.Forms;
using NUnit.Extensions.Forms;
namespace mRemoteNGTests
namespace NUnit.Extensions.Forms
{
/// <summary>
/// A ControlTester for testing List Views.

View File

@@ -2,7 +2,6 @@
using mRemoteNG.Security;
using mRemoteNG.Security.Authentication;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
using NUnit.Framework;
@@ -10,31 +9,35 @@ namespace mRemoteNGTests.Security.Authentication
{
public class PasswordAuthenticatorTests
{
private ICryptographyProvider _cryptographyProvider;
private string _cipherText;
private PasswordAuthenticator _authenticator;
private readonly SecureString _correctPassword = "9theCorrectPass#5".ConvertToSecureString();
private readonly SecureString _wrongPassword = "wrongPassword".ConvertToSecureString();
[SetUp]
public void Setup()
{
_cryptographyProvider = new AeadCryptographyProvider {KeyDerivationIterations = 10000};
_cipherText = "MPELiwk7+xeNlruIyt5uxTvVB+/RLVoLdUGnwY4CWCqwKe7T2IBwWo4oaKum5hdv7447g5m2nZsYPrfARSlotQB4r1KZQg==";
var cryptoProvider = new AeadCryptographyProvider {KeyDerivationIterations = 10000};
const string cipherText = "MPELiwk7+xeNlruIyt5uxTvVB+/RLVoLdUGnwY4CWCqwKe7T2IBwWo4oaKum5hdv7447g5m2nZsYPrfARSlotQB4r1KZQg==";
_authenticator = new PasswordAuthenticator(cryptoProvider, cipherText);
}
[TearDown]
public void Teardown()
{
_authenticator = null;
}
[Test]
public void AuthenticatingWithCorrectPasswordReturnsTrue()
{
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, () => Optional<SecureString>.Empty);
var authenticated = authenticator.Authenticate(_correctPassword);
var authenticated = _authenticator.Authenticate(_correctPassword);
Assert.That(authenticated);
}
[Test]
public void AuthenticatingWithWrongPasswordReturnsFalse()
{
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, () => Optional<SecureString>.Empty);
var authenticated = authenticator.Authenticate(_wrongPassword);
var authenticated = _authenticator.Authenticate(_wrongPassword);
Assert.That(!authenticated);
}
@@ -42,15 +45,12 @@ namespace mRemoteNGTests.Security.Authentication
public void AuthenticationRequestorIsCalledWhenInitialPasswordIsWrong()
{
var wasCalled = false;
Optional<SecureString> AuthenticationRequestor()
_authenticator.AuthenticationRequestor = () =>
{
wasCalled = true;
return _correctPassword;
}
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor);
authenticator.Authenticate(_wrongPassword);
};
_authenticator.Authenticate(_wrongPassword);
Assert.That(wasCalled);
}
@@ -58,30 +58,28 @@ namespace mRemoteNGTests.Security.Authentication
public void AuthenticationRequestorNotCalledWhenInitialPasswordIsCorrect()
{
var wasCalled = false;
Optional<SecureString> AuthenticationRequestor()
_authenticator.AuthenticationRequestor = () =>
{
wasCalled = true;
return _correctPassword;
}
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor);
authenticator.Authenticate(_correctPassword);
};
_authenticator.Authenticate(_correctPassword);
Assert.That(!wasCalled);
}
[Test]
public void ProvidingCorrectPasswordToTheAuthenticationRequestorReturnsTrue()
{
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, () => _correctPassword);
var authenticated = authenticator.Authenticate(_wrongPassword);
_authenticator.AuthenticationRequestor = () => _correctPassword;
var authenticated = _authenticator.Authenticate(_wrongPassword);
Assert.That(authenticated);
}
[Test]
public void AuthenticationFailsWhenAuthenticationRequestorGivenEmptyPassword()
{
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, () => new SecureString());
var authenticated = authenticator.Authenticate(_wrongPassword);
_authenticator.AuthenticationRequestor = () => new SecureString();
var authenticated = _authenticator.Authenticate(_wrongPassword);
Assert.That(!authenticated);
}
@@ -89,34 +87,27 @@ namespace mRemoteNGTests.Security.Authentication
public void AuthenticatorRespectsMaxAttempts()
{
var authAttempts = 0;
Optional<SecureString> AuthenticationRequestor()
_authenticator.AuthenticationRequestor = () =>
{
authAttempts++;
return _wrongPassword;
}
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor);
authenticator.Authenticate(_wrongPassword);
Assert.That(authAttempts == authenticator.MaxAttempts);
};
_authenticator.Authenticate(_wrongPassword);
Assert.That(authAttempts == _authenticator.MaxAttempts);
}
[Test]
public void AuthenticatorRespectsMaxAttemptsCustomValue()
{
const int customMaxAttempts = 5;
_authenticator.MaxAttempts = customMaxAttempts;
var authAttempts = 0;
Optional<SecureString> AuthenticationRequestor()
_authenticator.AuthenticationRequestor = () =>
{
authAttempts++;
return _wrongPassword;
}
var authenticator =
new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor)
{
MaxAttempts = customMaxAttempts
};
authenticator.Authenticate(_wrongPassword);
};
_authenticator.Authenticate(_wrongPassword);
Assert.That(authAttempts == customMaxAttempts);
}
}

View File

@@ -1,132 +0,0 @@
using System;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.ICA;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.VNC;
namespace mRemoteNGTests.TestHelpers
{
internal static class ConnectionInfoHelpers
{
private static readonly Random _random = new Random();
/// <summary>
/// Returns a <see cref="ConnectionInfo"/> object with randomized
/// values in all fields.
/// </summary>
internal static ConnectionInfo GetRandomizedConnectionInfo(bool randomizeInheritance = false)
{
var connectionInfo = new ConnectionInfo
{
// string types
Name = RandomString(),
Hostname = RandomString(),
Description = RandomString(),
Domain = RandomString(),
ExtApp = RandomString(),
Icon = RandomString(),
LoadBalanceInfo = RandomString(),
MacAddress = RandomString(),
Panel = RandomString(),
Password = RandomString(),
PostExtApp = RandomString(),
PreExtApp = RandomString(),
PuttySession = RandomString(),
RDGatewayHostname = RandomString(),
RDGatewayUsername = RandomString(),
RDGatewayDomain = RandomString(),
RDGatewayPassword = RandomString(),
UserField = RandomString(),
Username = RandomString(),
VNCProxyIP = RandomString(),
VNCProxyPassword = RandomString(),
VNCProxyUsername = RandomString(),
// bool types
AutomaticResize = RandomBool(),
CacheBitmaps = RandomBool(),
DisplayThemes = RandomBool(),
DisplayWallpaper = RandomBool(),
EnableDesktopComposition = RandomBool(),
EnableFontSmoothing = RandomBool(),
IsContainer = RandomBool(),
IsDefault = RandomBool(),
IsQuickConnect = RandomBool(),
PleaseConnect = RandomBool(),
RDPAlertIdleTimeout = RandomBool(),
RedirectDiskDrives = RandomBool(),
RedirectKeys = RandomBool(),
RedirectPorts = RandomBool(),
RedirectPrinters = RandomBool(),
RedirectSmartCards = RandomBool(),
UseConsoleSession = RandomBool(),
UseCredSsp = RandomBool(),
VNCViewOnly = RandomBool(),
// ints
Port = RandomInt(),
RDPMinutesToIdleTimeout = RandomInt(),
VNCProxyPort = RandomInt(),
// enums
Colors = RandomEnum<RdpProtocol.RDPColors>(),
ICAEncryptionStrength = RandomEnum<IcaProtocol.EncryptionStrength> (),
Protocol = RandomEnum<ProtocolType>(),
RDGatewayUsageMethod = RandomEnum<RdpProtocol.RDGatewayUsageMethod>(),
RDGatewayUseConnectionCredentials = RandomEnum<RdpProtocol.RDGatewayUseConnectionCredentials>(),
RDPAuthenticationLevel = RandomEnum<RdpProtocol.AuthenticationLevel>(),
RedirectSound = RandomEnum<RdpProtocol.RDPSounds>(),
RenderingEngine = RandomEnum<HTTPBase.RenderingEngine>(),
Resolution = RandomEnum<RdpProtocol.RDPResolutions>(),
SoundQuality = RandomEnum<RdpProtocol.RDPSoundQuality>(),
VNCAuthMode = RandomEnum<ProtocolVNC.AuthMode>(),
VNCColors = RandomEnum<ProtocolVNC.Colors>(),
VNCCompression = RandomEnum<ProtocolVNC.Compression>(),
VNCEncoding = RandomEnum<ProtocolVNC.Encoding>(),
VNCProxyType = RandomEnum<ProtocolVNC.ProxyType>(),
VNCSmartSizeMode = RandomEnum<ProtocolVNC.SmartSizeMode>(),
};
if (randomizeInheritance)
connectionInfo.Inheritance = GetRandomizedInheritance(connectionInfo);
return connectionInfo;
}
internal static ConnectionInfoInheritance GetRandomizedInheritance(ConnectionInfo parent)
{
var inheritance = new ConnectionInfoInheritance(parent, true);
foreach (var property in inheritance.GetProperties())
{
property.SetValue(inheritance, RandomBool());
}
return inheritance;
}
internal static string RandomString()
{
return Guid.NewGuid().ToString("N");
}
internal static bool RandomBool()
{
return _random.Next() % 2 == 0;
}
internal static int RandomInt()
{
return _random.Next();
}
internal static T RandomEnum<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
throw new ArgumentException("T must be an enum");
var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(_random.Next(values.Length));
}
}
}

View File

@@ -7,52 +7,17 @@ namespace mRemoteNGTests.TestHelpers
{
public class ConnectionTreeModelBuilder
{
/// <summary>
/// Builds a tree which looks like:
/// Root
/// |- folder1
/// | |- con1
/// |- con2
/// |- folder2
/// |- folder3
/// |- con3
/// </summary>
/// <returns></returns>
public ConnectionTreeModel Build()
{
var model = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
var folder1 = new ContainerInfo { Name = "folder1", Username = "user1", Domain = "domain1", Password = "password1" };
var folder2 = new ContainerInfo { Name = "folder2", Username = "user2", Domain = "domain2", Password = "password2" };
var folder3 = new ContainerInfo
{
Name = "folder3",
Inheritance =
{
Username = true,
Domain = true,
Password = true
}
};
var con1 = new ConnectionInfo { Name = "Con1", Username = "user1", Domain = "domain1", Password = "password1" };
var con2 = new ConnectionInfo { Name = "Con2", Username = "user2", Domain = "domain2", Password = "password2" };
var con3 = new ContainerInfo
{
Name = "con3",
Inheritance =
{
Username = true,
Domain = true,
Password = true
}
};
root.AddChild(folder1);
root.AddChild(con2);
folder1.AddChild(con1);
root.AddChild(folder2);
folder2.AddChild(folder3);
folder3.AddChild(con3);
model.AddRootNode(root);
return model;
}

View File

@@ -1,63 +0,0 @@
namespace mRemoteNGTests.TestHelpers
{
/// <summary>
/// A ConnectionInfo that has only the serializable properties as string types.
/// Only used for testing.
/// </summary>
internal class SerializableConnectionInfoAllPropertiesOfType<TType>
{
public TType Description { get; set; }
public TType Icon { get; set; }
public TType Panel { get; set; }
public TType Username { get; set; }
public TType Password { get; set; }
public TType Domain { get; set; }
public TType Protocol { get; set; }
public TType ExtApp { get; set; }
public TType PuttySession { get; set; }
public TType ICAEncryptionStrength { get; set; }
public TType UseConsoleSession { get; set; }
public TType RDPAuthenticationLevel { get; set; }
public TType RDPMinutesToIdleTimeout { get; set; }
public TType RDPAlertIdleTimeout { get; set; }
public TType LoadBalanceInfo { get; set; }
public TType RenderingEngine { get; set; }
public TType UseCredSsp { get; set; }
public TType RDGatewayUsageMethod { get; set; }
public TType RDGatewayHostname { get; set; }
public TType RDGatewayUseConnectionCredentials { get; set; }
public TType RDGatewayUsername { get; set; }
public TType RDGatewayPassword { get; set; }
public TType RDGatewayDomain { get; set; }
public TType Resolution { get; set; }
public TType AutomaticResize { get; set; }
public TType Colors { get; set; }
public TType CacheBitmaps { get; set; }
public TType DisplayWallpaper { get; set; }
public TType DisplayThemes { get; set; }
public TType EnableFontSmoothing { get; set; }
public TType EnableDesktopComposition { get; set; }
public TType RedirectKeys { get; set; }
public TType RedirectDiskDrives { get; set; }
public TType RedirectPrinters { get; set; }
public TType RedirectPorts { get; set; }
public TType RedirectSmartCards { get; set; }
public TType RedirectSound { get; set; }
public TType SoundQuality { get; set; }
public TType PreExtApp { get; set; }
public TType PostExtApp { get; set; }
public TType MacAddress { get; set; }
public TType UserField { get; set; }
public TType VNCCompression { get; set; }
public TType VNCEncoding { get; set; }
public TType VNCAuthMode { get; set; }
public TType VNCProxyType { get; set; }
public TType VNCProxyIP { get; set; }
public TType VNCProxyPort { get; set; }
public TType VNCProxyUsername { get; set; }
public TType VNCProxyPassword { get; set; }
public TType VNCColors { get; set; }
public TType VNCSmartSizeMode { get; set; }
public TType VNCViewOnly { get; set; }
}
}

View File

@@ -3,12 +3,12 @@ using NUnit.Framework;
namespace mRemoteNGTests.Tools
{
public class OptionalTests
public class MaybeTests
{
[Test]
public void MaybeReturnsEmptyListWhenGivenNullValue()
{
var sut = new Optional<object>(null);
var sut = new Maybe<object>(null);
Assert.That(sut, Is.Empty);
}
@@ -16,7 +16,7 @@ namespace mRemoteNGTests.Tools
public void MaybeReturnsValueIfNotNull()
{
var expected = new object();
var sut = new Optional<object>(expected);
var sut = new Maybe<object>(expected);
Assert.That(sut, Has.Member(expected));
}

View File

@@ -8,7 +8,7 @@ using NUnit.Framework;
namespace mRemoteNGTests.Tree
{
public class NodeSearcherTests
public class NodeSearcherTests
{
private NodeSearcher _nodeSearcher;
private ContainerInfo _folder1;
@@ -104,14 +104,6 @@ namespace mRemoteNGTests.Tree
_con4 = new ConnectionInfo { Name = "con4", Description="description6", Hostname="hostname6" };
_con5 = new ConnectionInfo { Name = "con5", Description="description7", Hostname="hostname7" };
_folder1.Inheritance.TurnOffInheritanceCompletely();
_con1.Inheritance.TurnOffInheritanceCompletely();
_con2.Inheritance.TurnOffInheritanceCompletely();
_folder2.Inheritance.TurnOffInheritanceCompletely();
_con3.Inheritance.TurnOffInheritanceCompletely();
_con4.Inheritance.TurnOffInheritanceCompletely();
_con5.Inheritance.TurnOffInheritanceCompletely();
connectionTreeModel.AddRootNode(root);
root.AddChildRange(new [] { _folder1, _folder2, _con5 });
_folder1.AddChildRange(new [] { _con1, _con2 });

View File

@@ -1,5 +1,4 @@
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.Tree.Root;
using NUnit.Framework;
@@ -47,13 +46,5 @@ namespace mRemoteNGTests.Tree
_rootNodeInfo.PasswordString = password;
Assert.That(_rootNodeInfo.PasswordString, Is.EqualTo(password));
}
[TestCase(RootNodeType.Connection, TreeNodeType.Root)]
[TestCase(RootNodeType.PuttySessions, TreeNodeType.PuttyRoot)]
public void RootNodeHasCorrectTreeNodeType(RootNodeType rootNodeType, TreeNodeType expectedTreeNodeType)
{
var rootNode = new RootNodeInfo(rootNodeType);
Assert.That(rootNode.GetTreeNodeType(), Is.EqualTo(expectedTreeNodeType));
}
}
}

View File

@@ -1,202 +0,0 @@
using System.Linq;
using System.Threading;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Controls;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Controls
{
public class ConnectionTreeTests
{
private ConnectionTreeSearchTextFilter _filter;
private ConnectionTree _connectionTree;
[SetUp]
public void Setup()
{
_filter = new ConnectionTreeSearchTextFilter();
_connectionTree = new ConnectionTree
{
UseFiltering = true
};
}
[Test]
[Apartment(ApartmentState.STA)]
public void FilteringIsRetainedAndUpdatedWhenNodeDeleted()
{
// root
// |- folder1
// | |- con1
// | |- dontshowme
// |- folder2
// |- con2
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
var folder1 = new ContainerInfo {Name = "folder1"};
var folder2 = new ContainerInfo {Name = "folder2"};
var con1 = new ConnectionInfo {Name = "con1"};
var con2 = new ConnectionInfo {Name = "con2"};
var conDontShow = new ConnectionInfo {Name = "dontshowme" };
root.AddChildRange(new []{folder1, folder2});
folder1.AddChildRange(new []{con1, conDontShow});
folder2.AddChild(con2);
connectionTreeModel.AddRootNode(root);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
// ensure all folders expanded
_connectionTree.ExpandAll();
// apply filtering on the tree
_filter.FilterText = "con";
_connectionTree.ModelFilter = _filter;
connectionTreeModel.DeleteNode(con1);
Assert.That(_connectionTree.IsFiltering, Is.True);
Assert.That(_connectionTree.FilteredObjects, Does.Not.Contain(con1));
Assert.That(_connectionTree.FilteredObjects, Does.Not.Contain(conDontShow));
Assert.That(_connectionTree.FilteredObjects, Does.Contain(con2));
}
[Test]
[Apartment(ApartmentState.STA)]
public void CannotAddConnectionToPuttySessionNode()
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
var puttyRoot = new RootNodeInfo(RootNodeType.PuttySessions);
connectionTreeModel.AddRootNode(root);
connectionTreeModel.AddRootNode(puttyRoot);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.SelectedObject = puttyRoot;
_connectionTree.AddConnection();
Assert.That(puttyRoot.Children, Is.Empty);
}
[Test]
[Apartment(ApartmentState.STA)]
public void CannotAddFolderToPuttySessionNode()
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
var puttyRoot = new RootNodeInfo(RootNodeType.PuttySessions);
connectionTreeModel.AddRootNode(root);
connectionTreeModel.AddRootNode(puttyRoot);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.SelectedObject = puttyRoot;
_connectionTree.AddFolder();
Assert.That(puttyRoot.Children, Is.Empty);
}
[Test]
[Apartment(ApartmentState.STA)]
public void CannotDuplicateRootConnectionNode()
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
connectionTreeModel.AddRootNode(root);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.SelectedObject = root;
_connectionTree.DuplicateSelectedNode();
Assert.That(connectionTreeModel.RootNodes, Has.One.Items);
}
[Test]
[Apartment(ApartmentState.STA)]
public void CannotDuplicateRootPuttyNode()
{
var connectionTreeModel = new ConnectionTreeModel();
var puttyRoot = new RootNodeInfo(RootNodeType.PuttySessions);
connectionTreeModel.AddRootNode(puttyRoot);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.SelectedObject = puttyRoot;
_connectionTree.DuplicateSelectedNode();
Assert.That(connectionTreeModel.RootNodes, Has.One.Items);
}
[Test]
[Apartment(ApartmentState.STA)]
public void CannotDuplicatePuttyConnectionNode()
{
var connectionTreeModel = new ConnectionTreeModel();
var puttyRoot = new RootNodeInfo(RootNodeType.PuttySessions);
var puttyConnection = new PuttySessionInfo();
puttyRoot.AddChild(puttyConnection);
connectionTreeModel.AddRootNode(puttyRoot);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.ExpandAll();
_connectionTree.SelectedObject = puttyConnection;
_connectionTree.DuplicateSelectedNode();
Assert.That(puttyRoot.Children, Has.One.Items);
}
[Test]
[Apartment(ApartmentState.STA)]
public void DuplicatingWithNoNodeSelectedDoesNothing()
{
var connectionTreeModel = new ConnectionTreeModel();
var puttyRoot = new RootNodeInfo(RootNodeType.PuttySessions);
connectionTreeModel.AddRootNode(puttyRoot);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.SelectedObject = null;
_connectionTree.DuplicateSelectedNode();
Assert.That(connectionTreeModel.RootNodes, Has.One.Items);
}
[Test]
[Apartment(ApartmentState.STA)]
public void ExpandingAllItemsUpdatesColumnWidthAppropriately()
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
connectionTreeModel.AddRootNode(root);
ContainerInfo parent = root;
foreach (var i in Enumerable.Repeat("", 8))
{
var newContainer = new ContainerInfo {IsExpanded = false};
parent.AddChild(newContainer);
parent = newContainer;
}
_connectionTree.ConnectionTreeModel = connectionTreeModel;
var widthBefore = _connectionTree.Columns[0].Width;
_connectionTree.ExpandAll();
var widthAfter = _connectionTree.Columns[0].Width;
Assert.That(widthAfter, Is.GreaterThan(widthBefore));
}
[Test]
[Apartment(ApartmentState.STA)]
public void RenamingNodeWithNothingSelectedDoesNothing()
{
var connectionTreeModel = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection);
connectionTreeModel.AddRootNode(root);
_connectionTree.ConnectionTreeModel = connectionTreeModel;
_connectionTree.SelectedObject = null;
Assert.DoesNotThrow(() => _connectionTree.RenameSelectedNode());
}
}
}

View File

@@ -1,224 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Container;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Window;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
public class ConfigWindowGeneralTests
{
private ConfigWindow _configWindow;
[SetUp]
public void Setup()
{
_configWindow = new ConfigWindow
{
PropertiesVisible = true
};
}
[TestCaseSource(nameof(ConnectionInfoGeneralTestCases))]
public void PropertyGridShowCorrectPropertiesForConnectionInfo(ConnectionInfo connectionInfo, IEnumerable<string> expectedVisibleProperties)
{
_configWindow.SelectedTreeNode = connectionInfo;
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
}
[Test]
public void PropertyGridShowCorrectPropertiesForRootConnectionInfo()
{
var expectedVisibleProperties = new[]
{
nameof(RootNodeInfo.Name),
nameof(RootNodeInfo.Password),
};
_configWindow.SelectedTreeNode = new RootNodeInfo(RootNodeType.Connection);
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
}
[Test]
public void PropertyGridShowCorrectPropertiesForRootPuttyInfo()
{
var expectedVisibleProperties = new[]
{
nameof(RootNodeInfo.Name),
};
_configWindow.SelectedTreeNode = new RootPuttySessionsNodeInfo();
Assert.That(_configWindow.VisibleObjectProperties, Is.EquivalentTo(expectedVisibleProperties));
}
private static IEnumerable<TestCaseData> ConnectionInfoGeneralTestCases()
{
var protocolTypes = typeof(ProtocolType).GetEnumValues().OfType<ProtocolType>();
var testCases = new List<TestCaseData>();
foreach (var protocol in protocolTypes)
{
var expectedPropertyListConnection = BuildExpectedConnectionInfoPropertyList(protocol, false);
var connectionInfo = ConstructConnectionInfo(protocol, false);
var testCaseConnection = new TestCaseData(connectionInfo, expectedPropertyListConnection)
.SetName(protocol + ", ConnectionInfo");
testCases.Add(testCaseConnection);
var expectedPropertyListContainer = BuildExpectedConnectionInfoPropertyList(protocol, true);
var containerInfo = ConstructConnectionInfo(protocol, true);
var testCaseContainer = new TestCaseData(containerInfo, expectedPropertyListContainer)
.SetName(protocol + ", ContainerInfo");
testCases.Add(testCaseContainer);
}
return testCases;
}
internal static ConnectionInfo ConstructConnectionInfo(ProtocolType protocol, bool isContainer)
{
// build connection info. set certain connection properties so
// that toggled properties are hidden in the property grid. We
// will test those separately in the special protocol tests.
var node = isContainer
? new ContainerInfo()
: new ConnectionInfo();
node.Protocol = protocol;
node.Resolution = RdpProtocol.RDPResolutions.Res800x600;
node.RDGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Never;
node.RDGatewayUseConnectionCredentials = RdpProtocol.RDGatewayUseConnectionCredentials.Yes;
node.RedirectSound = RdpProtocol.RDPSounds.DoNotPlay;
node.VNCAuthMode = ProtocolVNC.AuthMode.AuthVNC;
node.VNCProxyType = ProtocolVNC.ProxyType.ProxyNone;
node.Inheritance.TurnOffInheritanceCompletely();
return node;
}
internal static List<string> BuildExpectedConnectionInfoPropertyList(ProtocolType protocol, bool isContainer)
{
var expectedProperties = new List<string>
{
nameof(ConnectionInfo.Name),
nameof(ConnectionInfo.Description),
nameof(ConnectionInfo.Icon),
nameof(ConnectionInfo.Panel),
nameof(ConnectionInfo.Protocol),
nameof(ConnectionInfo.PreExtApp),
nameof(ConnectionInfo.PostExtApp),
nameof(ConnectionInfo.MacAddress),
nameof(ConnectionInfo.UserField),
};
if (!isContainer)
{
expectedProperties.AddRange(new []
{
nameof(ConnectionInfo.Hostname),
});
}
switch (protocol)
{
case ProtocolType.RDP:
expectedProperties.AddRange(new []
{
nameof(ConnectionInfo.Username),
nameof(ConnectionInfo.Password),
nameof(ConnectionInfo.Domain),
nameof(ConnectionInfo.Port),
nameof(ConnectionInfo.UseConsoleSession),
nameof(ConnectionInfo.RDPAuthenticationLevel),
nameof(ConnectionInfo.RDPMinutesToIdleTimeout),
nameof(ConnectionInfo.LoadBalanceInfo),
nameof(ConnectionInfo.UseCredSsp),
nameof(ConnectionInfo.RDGatewayUsageMethod),
nameof(ConnectionInfo.Resolution),
nameof(ConnectionInfo.Colors),
nameof(ConnectionInfo.CacheBitmaps),
nameof(ConnectionInfo.DisplayWallpaper),
nameof(ConnectionInfo.DisplayThemes),
nameof(ConnectionInfo.EnableFontSmoothing),
nameof(ConnectionInfo.EnableDesktopComposition),
nameof(ConnectionInfo.RedirectKeys),
nameof(ConnectionInfo.RedirectDiskDrives),
nameof(ConnectionInfo.RedirectPrinters),
nameof(ConnectionInfo.RedirectPorts),
nameof(ConnectionInfo.RedirectSmartCards),
nameof(ConnectionInfo.RedirectSound),
});
break;
case ProtocolType.VNC:
expectedProperties.AddRange(new []
{
nameof(ConnectionInfo.Password),
nameof(ConnectionInfo.Port),
nameof(ConnectionInfo.VNCSmartSizeMode),
nameof(ConnectionInfo.VNCViewOnly),
});
break;
case ProtocolType.SSH1:
case ProtocolType.SSH2:
expectedProperties.AddRange(new []
{
nameof(ConnectionInfo.Username),
nameof(ConnectionInfo.Password),
nameof(ConnectionInfo.Port),
nameof(ConnectionInfo.PuttySession)
});
break;
case ProtocolType.Telnet:
case ProtocolType.Rlogin:
case ProtocolType.RAW:
expectedProperties.AddRange(new[]
{
nameof(ConnectionInfo.Port),
nameof(ConnectionInfo.PuttySession),
});
break;
case ProtocolType.HTTP:
case ProtocolType.HTTPS:
expectedProperties.AddRange(new []
{
nameof(ConnectionInfo.Username),
nameof(ConnectionInfo.Password),
nameof(ConnectionInfo.Port),
nameof(ConnectionInfo.RenderingEngine),
});
break;
case ProtocolType.ICA:
expectedProperties.AddRange(new []
{
nameof(ConnectionInfo.Username),
nameof(ConnectionInfo.Password),
nameof(ConnectionInfo.Domain),
nameof(ConnectionInfo.ICAEncryptionStrength),
nameof(ConnectionInfo.Resolution),
nameof(ConnectionInfo.Colors),
nameof(ConnectionInfo.CacheBitmaps),
});
break;
case ProtocolType.IntApp:
expectedProperties.AddRange(new[]
{
nameof(ConnectionInfo.Username),
nameof(ConnectionInfo.Password),
nameof(ConnectionInfo.Domain),
nameof(ConnectionInfo.Port),
nameof(ConnectionInfo.ExtApp),
});
break;
default:
throw new ArgumentOutOfRangeException(nameof(protocol), protocol, null);
}
return expectedProperties;
}
}
}

View File

@@ -1,73 +0,0 @@
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.RDP;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
public class ConfigWindowRdpSpecialTests : ConfigWindowSpecialTestsBase
{
protected override ProtocolType Protocol => ProtocolType.RDP;
[Test]
public void PropertyShownWhenActive_RdpMinutesToIdleTimeout()
{
ConnectionInfo.RDPMinutesToIdleTimeout = 1;
ExpectedPropertyList.Add(nameof(mRemoteNG.Connection.ConnectionInfo.RDPAlertIdleTimeout));
RunVerification();
}
[TestCase(RdpProtocol.RDGatewayUsageMethod.Always)]
[TestCase(RdpProtocol.RDGatewayUsageMethod.Detect)]
public void RdGatewayPropertiesShown_WhenRdGatewayUsageMethodIsNotNever(RdpProtocol.RDGatewayUsageMethod gatewayUsageMethod)
{
ConnectionInfo.RDGatewayUsageMethod = gatewayUsageMethod;
ConnectionInfo.RDGatewayUseConnectionCredentials = RdpProtocol.RDGatewayUseConnectionCredentials.Yes;
ExpectedPropertyList.AddRange(new []
{
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayHostname),
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayUseConnectionCredentials)
});
RunVerification();
}
[TestCase(RdpProtocol.RDGatewayUseConnectionCredentials.No)]
[TestCase(RdpProtocol.RDGatewayUseConnectionCredentials.SmartCard)]
public void RdGatewayPropertiesShown_WhenRDGatewayUseConnectionCredentialsIsNotYes(RdpProtocol.RDGatewayUseConnectionCredentials useConnectionCredentials)
{
ConnectionInfo.RDGatewayUsageMethod = RdpProtocol.RDGatewayUsageMethod.Always;
ConnectionInfo.RDGatewayUseConnectionCredentials = useConnectionCredentials;
ExpectedPropertyList.AddRange(new []
{
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayHostname),
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayUsername),
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayPassword),
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayDomain),
nameof(mRemoteNG.Connection.ConnectionInfo.RDGatewayUseConnectionCredentials)
});
RunVerification();
}
[Test]
public void SoundQualityPropertyShown_WhenRdpSoundsSetToBringToThisComputer()
{
ConnectionInfo.RedirectSound = RdpProtocol.RDPSounds.BringToThisComputer;
ExpectedPropertyList.Add(nameof(mRemoteNG.Connection.ConnectionInfo.SoundQuality));
RunVerification();
}
[TestCase(RdpProtocol.RDPResolutions.FitToWindow)]
[TestCase(RdpProtocol.RDPResolutions.Fullscreen)]
public void AutomaticResizePropertyShown_WhenResolutionIsDynamic(RdpProtocol.RDPResolutions resolution)
{
ConnectionInfo.Resolution = resolution;
ExpectedPropertyList.Add(nameof(mRemoteNG.Connection.ConnectionInfo.AutomaticResize));
RunVerification();
}
}
}

View File

@@ -1,37 +0,0 @@
using System.Collections.Generic;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.UI.Window;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
public abstract class ConfigWindowSpecialTestsBase
{
protected abstract ProtocolType Protocol { get; }
protected bool TestAgainstContainerInfo { get; set; } = false;
protected ConfigWindow ConfigWindow;
protected ConnectionInfo ConnectionInfo;
protected List<string> ExpectedPropertyList;
[SetUp]
public virtual void Setup()
{
ConnectionInfo = ConfigWindowGeneralTests.ConstructConnectionInfo(Protocol, TestAgainstContainerInfo);
ExpectedPropertyList = ConfigWindowGeneralTests.BuildExpectedConnectionInfoPropertyList(Protocol, TestAgainstContainerInfo);
ConfigWindow = new ConfigWindow
{
PropertiesVisible = true,
};
}
public void RunVerification()
{
ConfigWindow.SelectedTreeNode = ConnectionInfo;
Assert.That(
ConfigWindow.VisibleObjectProperties,
Is.EquivalentTo(ExpectedPropertyList));
}
}
}

View File

@@ -1,37 +0,0 @@
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.VNC;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
public class ConfigWindowVncSpecialTests : ConfigWindowSpecialTestsBase
{
protected override ProtocolType Protocol => ProtocolType.VNC;
[Test]
public void UserDomainPropertiesShown_WhenAuthModeIsWindows()
{
ConnectionInfo.VNCAuthMode = ProtocolVNC.AuthMode.AuthWin;
ExpectedPropertyList.AddRange(new []
{
nameof(ConnectionInfo.Username),
nameof(ConnectionInfo.Domain),
});
}
[TestCase(ProtocolVNC.ProxyType.ProxyHTTP)]
[TestCase(ProtocolVNC.ProxyType.ProxySocks5)]
[TestCase(ProtocolVNC.ProxyType.ProxyUltra)]
public void ProxyPropertiesShown_WhenProxyModeIsNotNone(ProtocolVNC.ProxyType proxyType)
{
ConnectionInfo.VNCProxyType = proxyType;
ExpectedPropertyList.AddRange(new[]
{
nameof(ConnectionInfo.VNCProxyIP),
nameof(ConnectionInfo.VNCProxyPort),
nameof(ConnectionInfo.VNCProxyUsername),
nameof(ConnectionInfo.VNCProxyPassword),
});
}
}
}

View File

@@ -114,7 +114,6 @@
<Compile Include="Config\DataProviders\FileBackupCreatorTests.cs" />
<Compile Include="Config\DataProviders\FileDataProviderTests.cs" />
<Compile Include="Config\DataProviders\FileDataProviderWithRollingBackupTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\ValidateXmlSchemas.cs" />
<Compile Include="Config\Serializers\DataTableDeserializerTests.cs" />
<Compile Include="Config\CredentialHarvesterTests.cs" />
<Compile Include="Config\CredentialRecordLoaderTests.cs" />
@@ -122,21 +121,21 @@
<Compile Include="Config\Serializers\CredentialProviderSerializerTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialPasswordDecryptorDecoratorTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialPasswordEncryptorDecoratorTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Csv\CsvConnectionsDeserializerMremotengFormatTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Csv\CsvConnectionsSerializerMremotengFormatTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\CsvConnectionsDeserializerMremotengFormatTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\CsvConnectionsSerializerMremotengFormatTests.cs" />
<Compile Include="Config\Serializers\DataTableSerializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\PortScanDeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\PuttyConnectionManagerDeserializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsDeserializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsDeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionDeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManager27DeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManagerDeserializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsDocumentCompilerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsDocumentEncryptorTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsSerializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsDocumentCompilerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsDocumentEncryptorTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsSerializerTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialRecordDeserializerTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialSerializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlRootNodeSerializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\XmlRootNodeSerializerTests.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion22To23UpgraderTests.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion23To24UpgraderTests.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion24To25UpgraderTests.cs" />
@@ -146,7 +145,6 @@
<Compile Include="Connection\ConnectionInfoComparerTests.cs" />
<Compile Include="Connection\Protocol\IntegratedProgramTests.cs" />
<Compile Include="Connection\Protocol\ProtocolListTests.cs" />
<Compile Include="Container\RootNodeInfoTests.cs" />
<Compile Include="Credential\CompositeRepositoryUnlockerTests.cs" />
<Compile Include="Credential\CredentialChangedEventArgsTests.cs" />
<Compile Include="Credential\CredentialDeletionMsgBoxConfirmerTests.cs" />
@@ -170,14 +168,12 @@
<Compile Include="Security\PasswordCreation\PasswordLengthConstraintTests.cs" />
<Compile Include="Security\RandomGeneratorTests.cs" />
<Compile Include="Security\SecureStringExtensionsTests.cs" />
<Compile Include="TestHelpers\ConnectionInfoHelpers.cs" />
<Compile Include="TestHelpers\ConnectionTreeModelBuilder.cs" />
<Compile Include="Security\XmlCryptoProviderBuilderTests.cs" />
<Compile Include="TestHelpers\FileTestHelpers.cs" />
<Compile Include="TestHelpers\SerializableConnectionInfoAllPropertiesOfType.cs" />
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
<Compile Include="Tools\FullyObservableCollectionTests.cs" />
<Compile Include="Tools\OptionalTests.cs" />
<Compile Include="Tools\MaybeTests.cs" />
<Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" />
<Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" />
<Compile Include="Tree\ConnectionTreeModelTests.cs" />
@@ -207,7 +203,6 @@
<Compile Include="Tree\RootNodeInfoTests.cs" />
<Compile Include="Tree\ClickHandlers\SwitchToConnectionClickHandlerTests.cs" />
<Compile Include="Tree\SelectedConnectionDeletionConfirmerTests.cs" />
<Compile Include="UI\Controls\ConnectionTreeTests.cs" />
<Compile Include="UI\Controls\PageSequenceTests.cs" />
<Compile Include="UI\Controls\SecureTextBoxTestForm.cs">
<SubType>Form</SubType>
@@ -232,10 +227,6 @@
<Compile Include="UI\Forms\OptionsFormSetupAndTeardown.cs" />
<Compile Include="UI\Forms\PasswordFormTests.cs" />
<Compile Include="UI\WindowListTests.cs" />
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowGeneralTests.cs" />
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowRdpSpecialTests.cs" />
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowSpecialTestsBase.cs" />
<Compile Include="UI\Window\ConfigWindowTests\ConfigWindowVncSpecialTests.cs" />
<Compile Include="UI\Window\ConnectionTreeWindowTests.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -33,19 +33,16 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.Build.0 = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|Any CPU.ActiveCfg = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|Any CPU.Build.0 = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.ActiveCfg = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.Build.0 = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.Build.0 = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.Build.0 = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.Build.0 = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|Any CPU.Build.0 = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.Build.0 = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|Any CPU.ActiveCfg = Release|x86
@@ -53,26 +50,24 @@ Global
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.Build.0 = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|Any CPU.ActiveCfg = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|Any CPU.Build.0 = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.ActiveCfg = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.Build.0 = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.Build.0 = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|Any CPU.Build.0 = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.Build.0 = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.Build.0 = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.Build.0 = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|x86.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|Any CPU.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.ActiveCfg = Debug|x86
@@ -82,6 +77,7 @@ Global
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.Build.0 = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|Any CPU.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|Any CPU.Build.0 = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Portable|x86.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|Any CPU.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|Any CPU.Build.0 = Release|x86
@@ -90,8 +86,8 @@ Global
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|Any CPU.ActiveCfg = Debug|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x86.ActiveCfg = Debug|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.Build.0 = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.ActiveCfg = Release Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.Build.0 = Release Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.Build.0 = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86

View File

@@ -4,8 +4,6 @@ using System.Windows.Forms;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;

View File

@@ -2,15 +2,14 @@
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using mRemoteNG.Connection;
namespace mRemoteNG.App.Info
{
public static class SettingsFileInfo
{
private static readonly string ExePath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(ConnectionInfo))?.Location);
private static readonly string ExePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
public static string SettingsPath => Runtime.IsPortableEdition ? ExePath : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Application.ProductName;
public static string SettingsPath { get; } = Runtime.IsPortableEdition ? ExePath : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Application.ProductName;
public static string LayoutFileName { get; } = "pnlLayout.xml";
public static string ExtAppsFilesName { get; } = "extApps.xml";
public static string ThemesFileName { get; } = "Themes.xml";

View File

@@ -1,4 +1,11 @@
using System;
using System.IO;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App.Info;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Putty;
using mRemoteNG.Connection;
using mRemoteNG.Credential;
@@ -10,15 +17,10 @@ using mRemoteNG.Tree.Root;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.TaskDialog;
using System;
using System.IO;
using System.Security;
using System.Threading;
using System.Windows.Forms;
namespace mRemoteNG.App
{
public static class Runtime
public static class Runtime
{
public static bool IsPortableEdition
{
@@ -43,23 +45,19 @@ namespace mRemoteNG.App
#region Connections Loading/Saving
public static void LoadConnectionsAsync()
{
_withDialog = false;
var t = new Thread(LoadConnectionsBGd);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private static bool _withDialog;
private static void LoadConnectionsBGd()
{
LoadConnections();
LoadConnections(_withDialog);
}
/// <summary>
///
/// </summary>
/// <param name="withDialog">
/// Should we show the file selection dialog to allow the user to select
/// a connection file
/// </param>
public static void LoadConnections(bool withDialog = false)
{
var connectionFileName = "";
@@ -69,19 +67,24 @@ namespace mRemoteNG.App
// disable sql update checking while we are loading updates
ConnectionsService.RemoteConnectionsSyncronizer?.Disable();
if (withDialog)
if (!Settings.Default.UseSQLServer)
{
var loadDialog = DialogFactory.BuildLoadConnectionsDialog();
if (loadDialog.ShowDialog() != DialogResult.OK)
return;
if (withDialog)
{
var loadDialog = DialogFactory.BuildLoadConnectionsDialog();
if (loadDialog.ShowDialog() != DialogResult.OK) return;
connectionFileName = loadDialog.FileName;
}
else
{
connectionFileName = ConnectionsService.GetStartupConnectionFileName();
}
connectionFileName = loadDialog.FileName;
Settings.Default.UseSQLServer = false;
Settings.Default.Save();
}
else if (!Settings.Default.UseSQLServer)
{
connectionFileName = ConnectionsService.GetStartupConnectionFileName();
var backupFileCreator = new FileBackupCreator();
backupFileCreator.CreateBackupFile(connectionFileName);
var backupPruner = new FileBackupPruner();
backupPruner.PruneBackupFiles(connectionFileName);
}
ConnectionsService.LoadConnections(Settings.Default.UseSQLServer, false, connectionFileName);
@@ -90,6 +93,18 @@ namespace mRemoteNG.App
{
ConnectionsService.LastSqlUpdate = DateTime.Now;
}
else
{
if (connectionFileName == ConnectionsService.GetDefaultStartupConnectionFileName())
{
Settings.Default.LoadConsFromCustomLocation = false;
}
else
{
Settings.Default.LoadConsFromCustomLocation = true;
Settings.Default.CustomConsPath = connectionFileName;
}
}
// re-enable sql update checking after updates are loaded
ConnectionsService.RemoteConnectionsSyncronizer?.Enable();

View File

@@ -1,8 +1,8 @@
using System;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
using System;
using mRemoteNG.Messages;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
namespace mRemoteNG.App
{
@@ -15,14 +15,8 @@ namespace mRemoteNG.App
private static PortScanWindow _portscanForm;
private static UltraVNCWindow _ultravncscForm;
private static ComponentsCheckWindow _componentscheckForm;
private static ConnectionTreeWindow _treeForm;
internal static ConnectionTreeWindow TreeForm
{
get => _treeForm ?? (_treeForm = new ConnectionTreeWindow());
set => _treeForm = value;
}
internal static ConnectionTreeWindow TreeForm { get; set; } = new ConnectionTreeWindow();
internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
internal static ScreenshotManagerWindow ScreenshotForm { get; set; } = new ScreenshotManagerWindow();

View File

@@ -10,7 +10,7 @@ namespace mRemoteNG.Config.Connections
/// The previous <see cref="ConnectionTreeModel"/> that is being
/// unloaded.
/// </summary>
public Optional<ConnectionTreeModel> PreviousConnectionTreeModel { get; }
public Maybe<ConnectionTreeModel> PreviousConnectionTreeModel { get; }
/// <summary>
/// True if the previous <see cref="ConnectionTreeModel"/> was loaded from
@@ -37,7 +37,7 @@ namespace mRemoteNG.Config.Connections
public string NewSourcePath { get; }
public ConnectionsLoadedEventArgs(
Optional<ConnectionTreeModel> previousTreeModelModel, ConnectionTreeModel newTreeModelModel,
Maybe<ConnectionTreeModel> previousTreeModelModel, ConnectionTreeModel newTreeModelModel,
bool previousSourceWasDatabase, bool newSourceIsDatabase,
string newSourcePath)
{

View File

@@ -2,7 +2,6 @@
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Security;
using mRemoteNG.Tree;
@@ -24,7 +23,7 @@ namespace mRemoteNG.Config.Connections
_saveFilter = saveFilter;
}
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
public void Save(ConnectionTreeModel connectionTreeModel)
{
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, Runtime.CredentialProviderCatalog);
var dataProvider = new FileDataProvider(_connectionFileName);

View File

@@ -1,9 +0,0 @@
using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections
{
public interface IConnectionsLoader
{
ConnectionTreeModel Load();
}
}

View File

@@ -1,7 +1,6 @@
using mRemoteNG.App;
using System;
using System;
using System.Timers;
using mRemoteNG.App;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Config.Connections.Multiuser

View File

@@ -1,11 +1,11 @@
using mRemoteNG.App;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Messages;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Threading;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
namespace mRemoteNG.Config.Connections
{
@@ -13,7 +13,7 @@ namespace mRemoteNG.Config.Connections
{
private readonly SqlDatabaseConnector _sqlConnector;
private readonly SqlCommand _sqlQuery;
private DateTime LastUpdateTime => Runtime.ConnectionsService.LastSqlUpdate;
private DateTime _lastUpdateTime;
private DateTime _lastDatabaseUpdateTime;
@@ -21,6 +21,7 @@ namespace mRemoteNG.Config.Connections
{
_sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
_sqlQuery = new SqlCommand("SELECT * FROM tblUpdate", _sqlConnector.SqlConnection);
_lastUpdateTime = default(DateTime);
_lastDatabaseUpdateTime = default(DateTime);
}
@@ -57,14 +58,14 @@ namespace mRemoteNG.Config.Connections
private bool DatabaseIsMoreUpToDateThanUs()
{
var lastUpdateInDb = GetLastUpdateTimeFromDbResponse();
var amTheLastoneUpdated = CheckIfIAmTheLastOneUpdated(lastUpdateInDb);
return (lastUpdateInDb > LastUpdateTime && !amTheLastoneUpdated);
var IAmTheLastoneUpdated = CheckIfIAmTheLastOneUpdated(lastUpdateInDb);
return (lastUpdateInDb > _lastUpdateTime && !IAmTheLastoneUpdated);
}
private bool CheckIfIAmTheLastOneUpdated(DateTime lastUpdateInDb)
{
DateTime lastSqlUpdateWithoutMilliseconds = new DateTime(LastUpdateTime.Ticks - (LastUpdateTime.Ticks % TimeSpan.TicksPerSecond), LastUpdateTime.Kind);
return lastUpdateInDb == lastSqlUpdateWithoutMilliseconds;
DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(Runtime.ConnectionsService.LastSqlUpdate.Ticks - (Runtime.ConnectionsService.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), Runtime.ConnectionsService.LastSqlUpdate.Kind);
return lastUpdateInDb == LastSqlUpdateWithoutMilliseconds;
}
private DateTime GetLastUpdateTimeFromDbResponse()
@@ -103,9 +104,10 @@ namespace mRemoteNG.Config.Connections
public event ConnectionsUpdateAvailableEventHandler ConnectionsUpdateAvailable;
private void RaiseConnectionsUpdateAvailableEvent()
{
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Remote connection update is available");
var args = new ConnectionsUpdateAvailableEventArgs(_sqlConnector, _lastDatabaseUpdateTime);
ConnectionsUpdateAvailable?.Invoke(this, args);
if(args.Handled)
_lastUpdateTime = _lastDatabaseUpdateTime;
}
public void Dispose()

View File

@@ -2,7 +2,6 @@
using System.Collections.Specialized;
using System.ComponentModel;
using mRemoteNG.Connection;
using mRemoteNG.UI.Forms;
namespace mRemoteNG.Config.Connections
{
@@ -21,9 +20,10 @@ namespace mRemoteNG.Config.Connections
private void ConnectionsServiceOnConnectionsLoaded(object sender, ConnectionsLoadedEventArgs connectionsLoadedEventArgs)
{
connectionsLoadedEventArgs.NewConnectionTreeModel.CollectionChanged += ConnectionTreeModelOnCollectionChanged;
connectionsLoadedEventArgs.NewConnectionTreeModel.PropertyChanged += ConnectionTreeModelOnPropertyChanged;
foreach (var oldTree in connectionsLoadedEventArgs.PreviousConnectionTreeModel)
{
oldTree.CollectionChanged -= ConnectionTreeModelOnCollectionChanged;
@@ -33,7 +33,7 @@ namespace mRemoteNG.Config.Connections
private void ConnectionTreeModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
SaveConnectionOnEdit(propertyChangedEventArgs.PropertyName);
SaveConnectionOnEdit();
}
private void ConnectionTreeModelOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
@@ -41,14 +41,11 @@ namespace mRemoteNG.Config.Connections
SaveConnectionOnEdit();
}
private void SaveConnectionOnEdit(string propertyName = "")
private void SaveConnectionOnEdit()
{
if (!mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit)
return;
if (FrmMain.Default.IsClosing)
return;
_connectionsService.SaveConnectionsAsync(propertyName);
_connectionsService.SaveConnections();
}
}
}

View File

@@ -1,89 +1,22 @@
using System;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.MsSql;
using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Container;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using mRemoteNG.Security;
using mRemoteNG.Security.Authentication;
using mRemoteNG.Security.SymmetricEncryption;
namespace mRemoteNG.Config.Connections
{
public class SqlConnectionsLoader : IConnectionsLoader
public class SqlConnectionsLoader
{
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> _localConnectionPropertiesDeserializer;
private readonly IDataProvider<string> _dataProvider;
public Func<Optional<SecureString>> AuthenticationRequestor { get; set; } =
() => MiscTools.PasswordDialog("", false);
public SqlConnectionsLoader(
IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> localConnectionPropertiesDeserializer,
IDataProvider<string> dataProvider)
{
_localConnectionPropertiesDeserializer = localConnectionPropertiesDeserializer.ThrowIfNull(nameof(localConnectionPropertiesDeserializer));
_dataProvider = dataProvider.ThrowIfNull(nameof(dataProvider));
}
public ConnectionTreeModel Load()
{
var connector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
var dataProvider = new SqlDataProvider(connector);
var metaDataRetriever = new SqlDatabaseMetaDataRetriever();
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
var cryptoProvider = new LegacyRijndaelCryptographyProvider();
var metaData = metaDataRetriever.GetDatabaseMetaData(connector);
var decryptionKey = GetDecryptionKey(metaData);
if (!decryptionKey.Any())
throw new Exception("Could not load SQL connections");
databaseVersionVerifier.VerifyDatabaseVersion(metaData.ConfVersion);
databaseVersionVerifier.VerifyDatabaseVersion();
var dataTable = dataProvider.Load();
var deserializer = new DataTableDeserializer(cryptoProvider, decryptionKey.First());
var connectionTree = deserializer.Deserialize(dataTable);
ApplyLocalConnectionProperties(connectionTree.RootNodes.First(i => i is RootNodeInfo));
return connectionTree;
}
private Optional<SecureString> GetDecryptionKey(SqlConnectionListMetaData metaData)
{
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var cipherText = metaData.Protected;
var authenticator = new PasswordAuthenticator(cryptographyProvider, cipherText, AuthenticationRequestor);
var authenticated = authenticator.Authenticate(new RootNodeInfo(RootNodeType.Connection).DefaultPassword.ConvertToSecureString());
if (authenticated)
return authenticator.LastAuthenticatedPassword;
return Optional<SecureString>.Empty;
}
private void ApplyLocalConnectionProperties(ContainerInfo rootNode)
{
var localPropertiesXml = _dataProvider.Load();
var localConnectionProperties = _localConnectionPropertiesDeserializer.Deserialize(localPropertiesXml);
rootNode
.GetRecursiveChildList()
.Join(localConnectionProperties,
con => con.ConstantID,
locals => locals.ConnectionId,
(con, locals) => new {Connection = con, LocalProperties = locals})
.ForEach(x =>
{
x.Connection.PleaseConnect = x.LocalProperties.Connected;
if (x.Connection is ContainerInfo container)
container.IsExpanded = x.LocalProperties.Expanded;
});
var deserializer = new DataTableDeserializer();
return deserializer.Deserialize(dataTable);
}
}
}

View File

@@ -1,9 +1,13 @@
using mRemoteNG.App;
using System;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Security;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.MsSql;
using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Container;
using mRemoteNG.Messages;
@@ -12,13 +16,6 @@ using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Security;
using mRemoteNG.Connection;
namespace mRemoteNG.Config.Connections
{
@@ -26,87 +23,40 @@ namespace mRemoteNG.Config.Connections
{
private SecureString _password = Runtime.EncryptionKey;
private readonly SaveFilter _saveFilter;
private readonly ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> _localPropertiesSerializer;
private readonly IDataProvider<string> _dataProvider;
public SqlConnectionsSaver(
SaveFilter saveFilter,
ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> localPropertieSerializer,
IDataProvider<string> localPropertiesDataProvider)
public SqlConnectionsSaver(SaveFilter saveFilter)
{
if (saveFilter == null)
throw new ArgumentNullException(nameof(saveFilter));
_saveFilter = saveFilter;
_localPropertiesSerializer = localPropertieSerializer.ThrowIfNull(nameof(localPropertieSerializer));
_dataProvider = localPropertiesDataProvider.ThrowIfNull(nameof(localPropertiesDataProvider));
}
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
public void Save(ConnectionTreeModel connectionTreeModel)
{
var rootTreeNode = connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
UpdateLocalConnectionProperties(rootTreeNode);
if (PropertyIsLocalOnly(propertyNameTrigger))
{
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg,
$"Property {propertyNameTrigger} is local only. Not saving to database.");
return;
}
if (SqlUserIsReadOnly())
{
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Trying to save connection tree but the SQL read only checkbox is checked, aborting!");
return;
}
using (var sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings())
{
sqlConnector.Connect();
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector);
var metaDataRetriever = new SqlDatabaseMetaDataRetriever();
var metaData = metaDataRetriever.GetDatabaseMetaData(sqlConnector);
if (!databaseVersionVerifier.VerifyDatabaseVersion(metaData.ConfVersion))
if (!databaseVersionVerifier.VerifyDatabaseVersion())
{
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorConnectionListSaveFailed);
return;
}
var rootTreeNode = connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
UpdateRootNodeTable(rootTreeNode, sqlConnector);
UpdateConnectionsTable(rootTreeNode, sqlConnector);
UpdateUpdatesTable(sqlConnector);
}
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Saved connections to database");
}
/// <summary>
/// Determines if a given property name should be only saved
/// locally.
/// </summary>
/// <param name="property">
/// The name of the property that triggered the save event
/// </param>
/// <returns></returns>
private bool PropertyIsLocalOnly(string property)
{
return property == nameof(ConnectionInfo.OpenConnections) ||
property == nameof(ContainerInfo.IsExpanded);
}
private void UpdateLocalConnectionProperties(ContainerInfo rootNode)
{
var a = rootNode.GetRecursiveChildList().Select(info => new LocalConnectionPropertiesModel
{
ConnectionId = info.ConstantID,
Connected = info.OpenConnections.Count > 0,
Expanded = info is ContainerInfo c && c.IsExpanded
});
var serializedProperties = _localPropertiesSerializer.Serialize(a);
_dataProvider.Save(serializedProperties);
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Saved local connection properties");
}
private void UpdateRootNodeTable(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
@@ -149,15 +99,13 @@ namespace mRemoteNG.Config.Connections
}
}
private void UpdateConnectionsTable(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
private void UpdateConnectionsTable(ContainerInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
{
var cryptoProvider = new LegacyRijndaelCryptographyProvider();
var serializer = new DataTableSerializer(_saveFilter, cryptoProvider, rootTreeNode.PasswordString.ConvertToSecureString());
var dataTable = serializer.Serialize(rootTreeNode);
var dataProvider = new SqlDataProvider(sqlDatabaseConnector);
var sqlQuery = new SqlCommand("DELETE FROM tblCons", sqlDatabaseConnector.SqlConnection);
sqlQuery.ExecuteNonQuery();
var serializer = new DataTableSerializer(_saveFilter);
var dataTable = serializer.Serialize(rootTreeNode);
var dataProvider = new SqlDataProvider(sqlDatabaseConnector);
dataProvider.Save(dataTable);
}

View File

@@ -1,14 +1,14 @@
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.Xml;
using System;
using System.Security;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using System;
using System.IO;
using System.Security;
namespace mRemoteNG.Config.Connections
{
public class XmlConnectionsLoader : IConnectionsLoader
public class XmlConnectionsLoader
{
private readonly string _connectionFilePath;
@@ -31,7 +31,7 @@ namespace mRemoteNG.Config.Connections
return deserializer.Deserialize(xmlString);
}
private Optional<SecureString> PromptForPassword()
private SecureString PromptForPassword()
{
var password = MiscTools.PasswordDialog("", false);
return password;

View File

@@ -3,7 +3,6 @@ using System.Linq;
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Security;
using mRemoteNG.Security.Factories;
using mRemoteNG.Tree;
@@ -27,7 +26,7 @@ namespace mRemoteNG.Config.Connections
_saveFilter = saveFilter;
}
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
public void Save(ConnectionTreeModel connectionTreeModel)
{
try
{

View File

@@ -18,7 +18,7 @@ namespace mRemoteNG.Config
_dataProvider = dataProvider;
}
public void Save(IEnumerable<ICredentialRepository> repositories, string propertyNameTrigger = "")
public void Save(IEnumerable<ICredentialRepository> repositories)
{
var serializer = new CredentialRepositoryListSerializer();
var data = serializer.Serialize(repositories);

View File

@@ -1,29 +1,26 @@
using System.IO;
using System.Linq;
using System;
using System.IO;
namespace mRemoteNG.Config.DataProviders
{
public class FileBackupPruner
{
public void PruneBackupFiles(string filePath, int maxBackupsToKeep)
public void PruneBackupFiles(string baseName)
{
var fileName = Path.GetFileName(filePath);
var directoryName = Path.GetDirectoryName(filePath);
var fileName = Path.GetFileName(baseName);
var directoryName = Path.GetDirectoryName(baseName);
if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(directoryName))
return;
if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(directoryName)) return;
var searchPattern = string.Format(mRemoteNG.Settings.Default.BackupFileNameFormat, fileName, "*");
var files = Directory.GetFiles(directoryName, searchPattern);
if (files.Length <= maxBackupsToKeep)
return;
if (files.Length <= mRemoteNG.Settings.Default.BackupFileKeepCount) return;
var filesToDelete = files
.OrderByDescending(s => s)
.Skip(maxBackupsToKeep);
Array.Sort(files);
Array.Resize(ref files, files.Length - mRemoteNG.Settings.Default.BackupFileKeepCount);
foreach (var file in filesToDelete)
foreach (var file in files)
{
File.Delete(file);
}

View File

@@ -2,6 +2,6 @@
{
public interface ISaver<in T>
{
void Save(T model, string propertyNameTrigger = "");
void Save(T model);
}
}

View File

@@ -2,7 +2,7 @@
using System.Linq;
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Config.Serializers.MiscSerializers;
using mRemoteNG.Container;
using mRemoteNG.Messages;

View File

@@ -3,7 +3,6 @@ using System.Linq;
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Container;
using mRemoteNG.Messages;

View File

@@ -1,13 +1,13 @@
using mRemoteNG.Tools;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using mRemoteNG.Tools;
using mRemoteNG.Tree.Root;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Config.Putty
{
public class PuttySessionsManager
public class PuttySessionsManager
{
public static PuttySessionsManager Instance { get; } = new PuttySessionsManager();
@@ -35,12 +35,10 @@ namespace mRemoteNG.Config.Putty
}
}
private void AddSessionsFromProvider(AbstractPuttySessionsProvider puttySessionProvider)
private void AddSessionsFromProvider(AbstractPuttySessionsProvider provider)
{
puttySessionProvider.ThrowIfNull(nameof(puttySessionProvider));
var rootTreeNode = puttySessionProvider.RootInfo;
puttySessionProvider.GetSessions();
var rootTreeNode = provider.RootInfo;
provider.GetSessions();
if (!RootPuttySessionsNodes.Contains(rootTreeNode) && rootTreeNode.HasChildren())
RootPuttySessionsNodes.Add(rootTreeNode);

View File

@@ -1,19 +1,19 @@
using Microsoft.Win32;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Messages;
using System;
using System.Collections.Generic;
using System.Management;
using System.Security.Principal;
using System.Text;
using System.Web;
using Microsoft.Win32;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Messages;
namespace mRemoteNG.Config.Putty
{
public class PuttySessionsRegistryProvider : AbstractPuttySessionsProvider
public class PuttySessionsRegistryProvider : AbstractPuttySessionsProvider
{
private const string PuttySessionsKey = "Software\\SimonTatham\\PuTTY\\Sessions";
private static ManagementEventWatcher _eventWatcher;
@@ -39,10 +39,7 @@ namespace mRemoteNG.Config.Putty
}
public override PuttySessionInfo GetSession(string sessionName)
{
if (string.IsNullOrEmpty(sessionName))
return null;
{
var sessionsKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey);
var sessionKey = sessionsKey?.OpenSubKey(sessionName);
if (sessionKey == null) return null;
@@ -53,15 +50,10 @@ namespace mRemoteNG.Config.Putty
{
PuttySession = sessionName,
Name = sessionName,
Hostname = sessionKey.GetValue("HostName")?.ToString() ?? "",
Username = sessionKey.GetValue("UserName")?.ToString() ?? ""
Hostname = Convert.ToString(sessionKey.GetValue("HostName")),
Username = Convert.ToString(sessionKey.GetValue("UserName"))
};
var protocol = string.IsNullOrEmpty(sessionKey.GetValue("Protocol")?.ToString())
? "ssh"
: sessionKey.GetValue("Protocol").ToString();
var protocol = Convert.ToString(sessionKey.GetValue("Protocol")) ?? "ssh";
switch (protocol.ToLowerInvariant())
{
case "raw":
@@ -73,15 +65,16 @@ namespace mRemoteNG.Config.Putty
case "serial":
return null;
case "ssh":
int.TryParse(sessionKey.GetValue("SshProt")?.ToString(), out var sshVersion);
/* Per PUTTY.H in PuTTYNG & PuTTYNG Upstream (PuTTY proper currently)
* expect 0 for SSH1, 3 for SSH2 ONLY
* 1 for SSH1 with a 2 fallback
* 2 for SSH2 with a 1 fallback
*
* default to SSH2 if any other value is received
*/
sessionInfo.Protocol = sshVersion == 1 || sshVersion == 0 ? ProtocolType.SSH1 : ProtocolType.SSH2;
var sshVersionObject = sessionKey.GetValue("SshProt");
if (sshVersionObject != null)
{
var sshVersion = Convert.ToInt32(sshVersionObject);
sessionInfo.Protocol = sshVersion >= 2 ? ProtocolType.SSH2 : ProtocolType.SSH1;
}
else
{
sessionInfo.Protocol = ProtocolType.SSH2;
}
break;
case "telnet":
sessionInfo.Protocol = ProtocolType.Telnet;
@@ -89,12 +82,7 @@ namespace mRemoteNG.Config.Putty
default:
return null;
}
int.TryParse(sessionKey.GetValue("PortNumber")?.ToString(), out var portNumber);
if (portNumber == default(int))
sessionInfo.SetDefaultPort();
else
sessionInfo.Port = portNumber;
sessionInfo.Port = Convert.ToInt32(sessionKey.GetValue("PortNumber"));
return sessionInfo;
}

View File

@@ -33,7 +33,6 @@ namespace mRemoteNG.Config.Putty
foreach (var sessionName in Directory.GetFiles(sessionsFolderPath))
{
var sessionFileName = Path.GetFileName(sessionName);
// ReSharper disable once ConstantConditionalAccessQualifier
sessionNames.Add(raw ? sessionFileName : System.Web.HttpUtility.UrlDecode(sessionFileName?.Replace("+", "%2B")));
}
@@ -126,6 +125,9 @@ namespace mRemoteNG.Config.Putty
public override void StartWatcher()
{
PuttySessionsRegistryProvider.StartWatcher();
PuttySessionsRegistryProvider.PuttySessionChanged += OnRegistrySessionChanged;
if (_eventWatcher != null)
{
return;
@@ -134,22 +136,18 @@ namespace mRemoteNG.Config.Putty
try
{
var sessionsFolderPath = GetSessionsFolderPath();
if (!Directory.Exists(sessionsFolderPath))
{
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, $"XmingPortablePuttySessions.Watcher.StartWatching() failed: '{sessionsFolderPath}' does not exist.", true);
return;
}
_eventWatcher = new FileSystemWatcher(sessionsFolderPath)
{
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite
};
_eventWatcher.Changed += OnFileSystemEventArrived;
_eventWatcher.Created += OnFileSystemEventArrived;
_eventWatcher.Deleted += OnFileSystemEventArrived;
_eventWatcher.Renamed += OnFileSystemEventArrived;
_eventWatcher.EnableRaisingEvents = true;
if (Directory.Exists(sessionsFolderPath))
{
_eventWatcher = new FileSystemWatcher(sessionsFolderPath)
{
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite
};
_eventWatcher.Changed += OnFileSystemEventArrived;
_eventWatcher.Created += OnFileSystemEventArrived;
_eventWatcher.Deleted += OnFileSystemEventArrived;
_eventWatcher.Renamed += OnFileSystemEventArrived;
_eventWatcher.EnableRaisingEvents = true;
}
}
catch (Exception ex)
{
@@ -175,8 +173,7 @@ namespace mRemoteNG.Config.Putty
private static string GetPuttyConfPath()
{
var puttyPath = mRemoteNG.Settings.Default.UseCustomPuttyPath ? mRemoteNG.Settings.Default.CustomPuttyPath : App.Info.GeneralAppInfo.PuttyPath;
puttyPath = Path.GetDirectoryName(puttyPath);
return string.IsNullOrEmpty(puttyPath) ? null : Path.Combine(puttyPath, "putty.conf");
return Path.Combine(Path.GetDirectoryName(puttyPath), "putty.conf");
}
private static string GetSessionsFolderPath()
@@ -203,9 +200,6 @@ namespace mRemoteNG.Config.Putty
private static PuttySessionInfo ModifyRegistrySessionInfo(PuttySessionInfo sessionInfo)
{
if (sessionInfo == null)
return null;
sessionInfo.Name = string.Format(RegistrySessionNameFormat, sessionInfo.Name);
sessionInfo.PuttySession = string.Format(RegistrySessionNameFormat, sessionInfo.PuttySession);
return sessionInfo;

View File

@@ -1,211 +0,0 @@
using System;
using System.Linq;
using System.Text;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.Csv
{
public class CsvConnectionsSerializerMremotengFormat : ISerializer<ConnectionInfo,string>
{
private readonly SaveFilter _saveFilter;
private readonly ICredentialRepositoryList _credentialRepositoryList;
public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter, ICredentialRepositoryList credentialRepositoryList)
{
saveFilter.ThrowIfNull(nameof(saveFilter));
credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
_saveFilter = saveFilter;
_credentialRepositoryList = credentialRepositoryList;
}
public string Serialize(ConnectionTreeModel connectionTreeModel)
{
connectionTreeModel.ThrowIfNull(nameof(connectionTreeModel));
var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);
return Serialize(rootNode);
}
public string Serialize(ConnectionInfo serializationTarget)
{
serializationTarget.ThrowIfNull(nameof(serializationTarget));
var sb = new StringBuilder();
WriteCsvHeader(sb);
SerializeNodesRecursive(serializationTarget, sb);
return sb.ToString();
}
private void WriteCsvHeader(StringBuilder sb)
{
sb.Append("Name;Id;Parent;NodeType;Description;Icon;Panel;");
if (_saveFilter.SaveUsername)
sb.Append("Username;");
if (_saveFilter.SavePassword)
sb.Append("Password;");
if (_saveFilter.SaveDomain)
sb.Append("Domain;");
sb.Append("Hostname;Protocol;PuttySession;Port;ConnectToConsole;UseCredSsp;RenderingEngine;ICAEncryptionStrength;RDPAuthenticationLevel;LoadBalanceInfo;Colors;Resolution;AutomaticResize;DisplayWallpaper;DisplayThemes;EnableFontSmoothing;EnableDesktopComposition;CacheBitmaps;RedirectDiskDrives;RedirectPorts;RedirectPrinters;RedirectSmartCards;RedirectSound;RedirectKeys;PreExtApp;PostExtApp;MacAddress;UserField;ExtApp;VNCCompression;VNCEncoding;VNCAuthMode;VNCProxyType;VNCProxyIP;VNCProxyPort;VNCProxyUsername;VNCProxyPassword;VNCColors;VNCSmartSizeMode;VNCViewOnly;RDGatewayUsageMethod;RDGatewayHostname;RDGatewayUseConnectionCredentials;RDGatewayUsername;RDGatewayPassword;RDGatewayDomain;");
if (_saveFilter.SaveInheritance)
sb.Append("InheritCacheBitmaps;InheritColors;InheritDescription;InheritDisplayThemes;InheritDisplayWallpaper;InheritEnableFontSmoothing;InheritEnableDesktopComposition;InheritDomain;InheritIcon;InheritPanel;InheritPassword;InheritPort;InheritProtocol;InheritPuttySession;InheritRedirectDiskDrives;InheritRedirectKeys;InheritRedirectPorts;InheritRedirectPrinters;InheritRedirectSmartCards;InheritRedirectSound;InheritResolution;InheritAutomaticResize;InheritUseConsoleSession;InheritUseCredSsp;InheritRenderingEngine;InheritUsername;InheritICAEncryptionStrength;InheritRDPAuthenticationLevel;InheritLoadBalanceInfo;InheritPreExtApp;InheritPostExtApp;InheritMacAddress;InheritUserField;InheritExtApp;InheritVNCCompression;InheritVNCEncoding;InheritVNCAuthMode;InheritVNCProxyType;InheritVNCProxyIP;InheritVNCProxyPort;InheritVNCProxyUsername;InheritVNCProxyPassword;InheritVNCColors;InheritVNCSmartSizeMode;InheritVNCViewOnly;InheritRDGatewayUsageMethod;InheritRDGatewayHostname;InheritRDGatewayUseConnectionCredentials;InheritRDGatewayUsername;InheritRDGatewayPassword;InheritRDGatewayDomain;InheritRDPAlertIdleTimeout;InheritRDPMinutesToIdleTimeout;InheritSoundQuality");
}
private void SerializeNodesRecursive(ConnectionInfo node, StringBuilder sb)
{
var nodeAsContainer = node as ContainerInfo;
if (nodeAsContainer != null)
{
foreach (var child in nodeAsContainer.Children)
{
SerializeNodesRecursive(child, sb);
}
}
// dont serialize the root node
if (node is RootNodeInfo)
return;
SerializeConnectionInfo(node, sb);
}
private void SerializeConnectionInfo(ConnectionInfo con, StringBuilder sb)
{
sb.AppendLine();
sb.Append(FormatForCsv(con.Name))
.Append(FormatForCsv(con.ConstantID))
.Append(FormatForCsv(con.Parent?.ConstantID ?? ""))
.Append(FormatForCsv(con.GetTreeNodeType()))
.Append(FormatForCsv(con.Description))
.Append(FormatForCsv(con.Icon))
.Append(FormatForCsv(con.Panel));
if (_saveFilter.SaveUsername)
sb.Append(FormatForCsv(con.Username));
if (_saveFilter.SavePassword)
sb.Append(FormatForCsv(con.Password));
if (_saveFilter.SaveDomain)
sb.Append(FormatForCsv(con.Domain));
sb.Append(FormatForCsv(con.Hostname))
.Append(FormatForCsv(con.Protocol))
.Append(FormatForCsv(con.PuttySession))
.Append(FormatForCsv(con.Port))
.Append(FormatForCsv(con.UseConsoleSession))
.Append(FormatForCsv(con.UseCredSsp))
.Append(FormatForCsv(con.RenderingEngine))
.Append(FormatForCsv(con.ICAEncryptionStrength))
.Append(FormatForCsv(con.RDPAuthenticationLevel))
.Append(FormatForCsv(con.LoadBalanceInfo))
.Append(FormatForCsv(con.Colors))
.Append(FormatForCsv(con.Resolution))
.Append(FormatForCsv(con.AutomaticResize))
.Append(FormatForCsv(con.DisplayWallpaper))
.Append(FormatForCsv(con.DisplayThemes))
.Append(FormatForCsv(con.EnableFontSmoothing))
.Append(FormatForCsv(con.EnableDesktopComposition))
.Append(FormatForCsv(con.CacheBitmaps))
.Append(FormatForCsv(con.RedirectDiskDrives))
.Append(FormatForCsv(con.RedirectPorts))
.Append(FormatForCsv(con.RedirectPrinters))
.Append(FormatForCsv(con.RedirectSmartCards))
.Append(FormatForCsv(con.RedirectSound))
.Append(FormatForCsv(con.RedirectKeys))
.Append(FormatForCsv(con.PreExtApp))
.Append(FormatForCsv(con.PostExtApp))
.Append(FormatForCsv(con.MacAddress))
.Append(FormatForCsv(con.UserField))
.Append(FormatForCsv(con.ExtApp))
.Append(FormatForCsv(con.VNCCompression))
.Append(FormatForCsv(con.VNCEncoding))
.Append(FormatForCsv(con.VNCAuthMode))
.Append(FormatForCsv(con.VNCProxyType))
.Append(FormatForCsv(con.VNCProxyIP))
.Append(FormatForCsv(con.VNCProxyPort))
.Append(FormatForCsv(con.VNCProxyUsername))
.Append(FormatForCsv(con.VNCProxyPassword))
.Append(FormatForCsv(con.VNCColors))
.Append(FormatForCsv(con.VNCSmartSizeMode))
.Append(FormatForCsv(con.VNCViewOnly))
.Append(FormatForCsv(con.RDGatewayUsageMethod))
.Append(FormatForCsv(con.RDGatewayHostname))
.Append(FormatForCsv(con.RDGatewayUseConnectionCredentials))
.Append(FormatForCsv(con.RDGatewayUsername))
.Append(FormatForCsv(con.RDGatewayPassword))
.Append(FormatForCsv(con.RDGatewayDomain));
if (!_saveFilter.SaveInheritance)
return;
sb.Append(FormatForCsv(con.Inheritance.CacheBitmaps))
.Append(FormatForCsv(con.Inheritance.Colors))
.Append(FormatForCsv(con.Inheritance.Description))
.Append(FormatForCsv(con.Inheritance.DisplayThemes))
.Append(FormatForCsv(con.Inheritance.DisplayWallpaper))
.Append(FormatForCsv(con.Inheritance.EnableFontSmoothing))
.Append(FormatForCsv(con.Inheritance.EnableDesktopComposition))
.Append(FormatForCsv(con.Inheritance.Domain))
.Append(FormatForCsv(con.Inheritance.Icon))
.Append(FormatForCsv(con.Inheritance.Panel))
.Append(FormatForCsv(con.Inheritance.Password))
.Append(FormatForCsv(con.Inheritance.Port))
.Append(FormatForCsv(con.Inheritance.Protocol))
.Append(FormatForCsv(con.Inheritance.PuttySession))
.Append(FormatForCsv(con.Inheritance.RedirectDiskDrives))
.Append(FormatForCsv(con.Inheritance.RedirectKeys))
.Append(FormatForCsv(con.Inheritance.RedirectPorts))
.Append(FormatForCsv(con.Inheritance.RedirectPrinters))
.Append(FormatForCsv(con.Inheritance.RedirectSmartCards))
.Append(FormatForCsv(con.Inheritance.RedirectSound))
.Append(FormatForCsv(con.Inheritance.Resolution))
.Append(FormatForCsv(con.Inheritance.AutomaticResize))
.Append(FormatForCsv(con.Inheritance.UseConsoleSession))
.Append(FormatForCsv(con.Inheritance.UseCredSsp))
.Append(FormatForCsv(con.Inheritance.RenderingEngine))
.Append(FormatForCsv(con.Inheritance.Username))
.Append(FormatForCsv(con.Inheritance.ICAEncryptionStrength))
.Append(FormatForCsv(con.Inheritance.RDPAuthenticationLevel))
.Append(FormatForCsv(con.Inheritance.LoadBalanceInfo))
.Append(FormatForCsv(con.Inheritance.PreExtApp))
.Append(FormatForCsv(con.Inheritance.PostExtApp))
.Append(FormatForCsv(con.Inheritance.MacAddress))
.Append(FormatForCsv(con.Inheritance.UserField))
.Append(FormatForCsv(con.Inheritance.ExtApp))
.Append(FormatForCsv(con.Inheritance.VNCCompression))
.Append(FormatForCsv(con.Inheritance.VNCEncoding))
.Append(FormatForCsv(con.Inheritance.VNCAuthMode))
.Append(FormatForCsv(con.Inheritance.VNCProxyType))
.Append(FormatForCsv(con.Inheritance.VNCProxyIP))
.Append(FormatForCsv(con.Inheritance.VNCProxyPort))
.Append(FormatForCsv(con.Inheritance.VNCProxyUsername))
.Append(FormatForCsv(con.Inheritance.VNCProxyPassword))
.Append(FormatForCsv(con.Inheritance.VNCColors))
.Append(FormatForCsv(con.Inheritance.VNCSmartSizeMode))
.Append(FormatForCsv(con.Inheritance.VNCViewOnly))
.Append(FormatForCsv(con.Inheritance.RDGatewayUsageMethod))
.Append(FormatForCsv(con.Inheritance.RDGatewayHostname))
.Append(FormatForCsv(con.Inheritance.RDGatewayUseConnectionCredentials))
.Append(FormatForCsv(con.Inheritance.RDGatewayUsername))
.Append(FormatForCsv(con.Inheritance.RDGatewayPassword))
.Append(FormatForCsv(con.Inheritance.RDGatewayDomain))
.Append(FormatForCsv(con.Inheritance.RDPAlertIdleTimeout))
.Append(FormatForCsv(con.Inheritance.RDPMinutesToIdleTimeout))
.Append(FormatForCsv(con.Inheritance.SoundQuality));
}
private string FormatForCsv(object value)
{
var cleanedString = value.ToString().Replace(";", "");
return cleanedString + ";";
}
}
}

View File

@@ -1,20 +0,0 @@
namespace mRemoteNG.Config.Serializers.MsSql
{
public class LocalConnectionPropertiesModel
{
/// <summary>
/// The unique Id of this tree node
/// </summary>
public string ConnectionId { get; set; }
/// <summary>
/// Indicates whether this connection is connected
/// </summary>
public bool Connected { get; set; }
/// <summary>
/// Indicates whether this container is expanded in the tree
/// </summary>
public bool Expanded { get; set; }
}
}

View File

@@ -1,60 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace mRemoteNG.Config.Serializers.MsSql
{
public class LocalConnectionPropertiesXmlSerializer :
ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string>,
IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>>
{
public string Serialize(IEnumerable<LocalConnectionPropertiesModel> models)
{
var localConnections = models
.Select(m => new XElement("Node",
new XAttribute("ConnectionId", m.ConnectionId),
new XAttribute("Connected", m.Connected),
new XAttribute("Expanded", m.Expanded)));
var root = new XElement("LocalConnections", localConnections);
var xdoc = new XDocument(new XDeclaration("1.0", "utf-8", null), root);
return WriteXmlToString(xdoc);
}
public IEnumerable<LocalConnectionPropertiesModel> Deserialize(string serializedData)
{
if (string.IsNullOrWhiteSpace(serializedData))
return Enumerable.Empty<LocalConnectionPropertiesModel>();
var xdoc = XDocument.Parse(serializedData);
return xdoc
.Descendants("Node")
.Where(e => e.Attribute("ConnectionId") != null)
.Select(e => new LocalConnectionPropertiesModel
{
ConnectionId = e.Attribute("ConnectionId")?.Value,
Connected = bool.Parse(e.Attribute("Connected")?.Value ?? "False"),
Expanded = bool.Parse(e.Attribute("Expanded")?.Value ?? "False")
});
}
private static string WriteXmlToString(XNode xmlDocument)
{
string xmlString;
var xmlWriterSettings = new XmlWriterSettings { Indent = true, IndentChars = " ", Encoding = Encoding.UTF8 };
var memoryStream = new MemoryStream();
using (var xmlTextWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{
xmlDocument.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
var streamReader = new StreamReader(memoryStream, Encoding.UTF8, true);
memoryStream.Seek(0, SeekOrigin.Begin);
xmlString = streamReader.ReadToEnd();
}
return xmlString;
}
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Security;
namespace mRemoteNG.Config.Serializers.MsSql
{
public class SqlConnectionListMetaData
{
public string Name { get; set; }
public string Protected { get; set; }
public bool Export { get; set; }
public Version ConfVersion { get; set; }
}
}

View File

@@ -5,7 +5,8 @@ using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
namespace mRemoteNG.Config.Serializers.Xml
namespace mRemoteNG.Config.Serializers
{
// ReSharper disable once InconsistentNaming
public class XmlConnectionNodeSerializer26 : ISerializer<ConnectionInfo,XElement>
@@ -42,7 +43,7 @@ namespace mRemoteNG.Config.Serializers.Xml
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().ToLowerInvariant()));
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));
@@ -65,30 +66,30 @@ namespace mRemoteNG.Config.Serializers.Xml
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().ToLowerInvariant()));
element.Add(new XAttribute("UseCredSsp", connectionInfo.UseCredSsp.ToString().ToLowerInvariant()));
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("RDPAlertIdleTimeout", connectionInfo.RDPAlertIdleTimeout.ToString().ToLowerInvariant()));
element.Add(new XAttribute("RDPAlertIdleTimeout", connectionInfo.RDPAlertIdleTimeout));
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().ToLowerInvariant()));
element.Add(new XAttribute("DisplayWallpaper", connectionInfo.DisplayWallpaper.ToString().ToLowerInvariant()));
element.Add(new XAttribute("DisplayThemes", connectionInfo.DisplayThemes.ToString().ToLowerInvariant()));
element.Add(new XAttribute("EnableFontSmoothing", connectionInfo.EnableFontSmoothing.ToString().ToLowerInvariant()));
element.Add(new XAttribute("EnableDesktopComposition", connectionInfo.EnableDesktopComposition.ToString().ToLowerInvariant()));
element.Add(new XAttribute("CacheBitmaps", connectionInfo.CacheBitmaps.ToString().ToLowerInvariant()));
element.Add(new XAttribute("RedirectDiskDrives", connectionInfo.RedirectDiskDrives.ToString().ToLowerInvariant()));
element.Add(new XAttribute("RedirectPorts", connectionInfo.RedirectPorts.ToString().ToLowerInvariant()));
element.Add(new XAttribute("RedirectPrinters", connectionInfo.RedirectPrinters.ToString().ToLowerInvariant()));
element.Add(new XAttribute("RedirectSmartCards", connectionInfo.RedirectSmartCards.ToString().ToLowerInvariant()));
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().ToLowerInvariant()));
element.Add(new XAttribute("Connected", (connectionInfo.OpenConnections.Count > 0).ToString().ToLowerInvariant()));
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));
@@ -112,7 +113,7 @@ namespace mRemoteNG.Config.Serializers.Xml
element.Add(new XAttribute("VNCColors", connectionInfo.VNCColors));
element.Add(new XAttribute("VNCSmartSizeMode", connectionInfo.VNCSmartSizeMode));
element.Add(new XAttribute("VNCViewOnly", connectionInfo.VNCViewOnly.ToString().ToLowerInvariant()));
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));
@@ -135,118 +136,117 @@ namespace mRemoteNG.Config.Serializers.Xml
{
if (_saveFilter.SaveInheritance)
{
element.Add(new XAttribute("InheritCacheBitmaps", connectionInfo.Inheritance.CacheBitmaps.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritColors", connectionInfo.Inheritance.Colors.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritDescription", connectionInfo.Inheritance.Description.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritDisplayThemes", connectionInfo.Inheritance.DisplayThemes.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritDisplayWallpaper", connectionInfo.Inheritance.DisplayWallpaper.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritEnableFontSmoothing", connectionInfo.Inheritance.EnableFontSmoothing.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritEnableDesktopComposition", connectionInfo.Inheritance.EnableDesktopComposition.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritDomain", connectionInfo.Inheritance.Domain.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritIcon", connectionInfo.Inheritance.Icon.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritPanel", connectionInfo.Inheritance.Panel.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritPassword", connectionInfo.Inheritance.Password.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritPort", connectionInfo.Inheritance.Port.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritProtocol", connectionInfo.Inheritance.Protocol.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritPuttySession", connectionInfo.Inheritance.PuttySession.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRedirectDiskDrives", connectionInfo.Inheritance.RedirectDiskDrives.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRedirectKeys", connectionInfo.Inheritance.RedirectKeys.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRedirectPorts", connectionInfo.Inheritance.RedirectPorts.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRedirectPrinters", connectionInfo.Inheritance.RedirectPrinters.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRedirectSmartCards", connectionInfo.Inheritance.RedirectSmartCards.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRedirectSound", connectionInfo.Inheritance.RedirectSound.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritSoundQuality", connectionInfo.Inheritance.SoundQuality.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritResolution", connectionInfo.Inheritance.Resolution.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritAutomaticResize", connectionInfo.Inheritance.AutomaticResize.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritUseConsoleSession", connectionInfo.Inheritance.UseConsoleSession.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritUseCredSsp", connectionInfo.Inheritance.UseCredSsp.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRenderingEngine", connectionInfo.Inheritance.RenderingEngine.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritUsername", connectionInfo.Inheritance.Username.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritICAEncryptionStrength", connectionInfo.Inheritance.ICAEncryptionStrength.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDPAuthenticationLevel", connectionInfo.Inheritance.RDPAuthenticationLevel.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", connectionInfo.Inheritance.RDPMinutesToIdleTimeout.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDPAlertIdleTimeout", connectionInfo.Inheritance.RDPAlertIdleTimeout.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritLoadBalanceInfo", connectionInfo.Inheritance.LoadBalanceInfo.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritPreExtApp", connectionInfo.Inheritance.PreExtApp.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritPostExtApp", connectionInfo.Inheritance.PostExtApp.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritMacAddress", connectionInfo.Inheritance.MacAddress.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritUserField", connectionInfo.Inheritance.UserField.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritExtApp", connectionInfo.Inheritance.ExtApp.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCCompression", connectionInfo.Inheritance.VNCCompression.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCEncoding", connectionInfo.Inheritance.VNCEncoding.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCAuthMode", connectionInfo.Inheritance.VNCAuthMode.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCProxyType", connectionInfo.Inheritance.VNCProxyType.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCProxyIP", connectionInfo.Inheritance.VNCProxyIP.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCProxyPort", connectionInfo.Inheritance.VNCProxyPort.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCProxyUsername", connectionInfo.Inheritance.VNCProxyUsername.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCProxyPassword", connectionInfo.Inheritance.VNCProxyPassword.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCColors", connectionInfo.Inheritance.VNCColors.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCSmartSizeMode", connectionInfo.Inheritance.VNCSmartSizeMode.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritVNCViewOnly", connectionInfo.Inheritance.VNCViewOnly.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDGatewayUsageMethod", connectionInfo.Inheritance.RDGatewayUsageMethod.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDGatewayHostname", connectionInfo.Inheritance.RDGatewayHostname.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDGatewayUseConnectionCredentials", connectionInfo.Inheritance.RDGatewayUseConnectionCredentials.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDGatewayUsername", connectionInfo.Inheritance.RDGatewayUsername.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDGatewayPassword", connectionInfo.Inheritance.RDGatewayPassword.ToString().ToLowerInvariant()));
element.Add(new XAttribute("InheritRDGatewayDomain", connectionInfo.Inheritance.RDGatewayDomain.ToString().ToLowerInvariant()));
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("InheritRDPAlertIdleTimeout", connectionInfo.Inheritance.RDPAlertIdleTimeout.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
{
var falseString = false.ToString().ToLowerInvariant();
element.Add(new XAttribute("InheritCacheBitmaps", falseString));
element.Add(new XAttribute("InheritColors", falseString));
element.Add(new XAttribute("InheritDescription", falseString));
element.Add(new XAttribute("InheritDisplayThemes", falseString));
element.Add(new XAttribute("InheritDisplayWallpaper", falseString));
element.Add(new XAttribute("InheritEnableFontSmoothing", falseString));
element.Add(new XAttribute("InheritEnableDesktopComposition", falseString));
element.Add(new XAttribute("InheritDomain", falseString));
element.Add(new XAttribute("InheritIcon", falseString));
element.Add(new XAttribute("InheritPanel", falseString));
element.Add(new XAttribute("InheritPassword", falseString));
element.Add(new XAttribute("InheritPort", falseString));
element.Add(new XAttribute("InheritProtocol", falseString));
element.Add(new XAttribute("InheritPuttySession", falseString));
element.Add(new XAttribute("InheritRedirectDiskDrives", falseString));
element.Add(new XAttribute("InheritRedirectKeys", falseString));
element.Add(new XAttribute("InheritRedirectPorts", falseString));
element.Add(new XAttribute("InheritRedirectPrinters", falseString));
element.Add(new XAttribute("InheritRedirectSmartCards", falseString));
element.Add(new XAttribute("InheritRedirectSound", falseString));
element.Add(new XAttribute("InheritSoundQuality", falseString));
element.Add(new XAttribute("InheritResolution", falseString));
element.Add(new XAttribute("InheritAutomaticResize", falseString));
element.Add(new XAttribute("InheritUseConsoleSession", falseString));
element.Add(new XAttribute("InheritUseCredSsp", falseString));
element.Add(new XAttribute("InheritRenderingEngine", falseString));
element.Add(new XAttribute("InheritUsername", falseString));
element.Add(new XAttribute("InheritICAEncryptionStrength", falseString));
element.Add(new XAttribute("InheritRDPAuthenticationLevel", falseString));
element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", falseString));
element.Add(new XAttribute("InheritRDPAlertIdleTimeout", falseString));
element.Add(new XAttribute("InheritLoadBalanceInfo", falseString));
element.Add(new XAttribute("InheritPreExtApp", falseString));
element.Add(new XAttribute("InheritPostExtApp", falseString));
element.Add(new XAttribute("InheritMacAddress", falseString));
element.Add(new XAttribute("InheritUserField", falseString));
element.Add(new XAttribute("InheritExtApp", falseString));
element.Add(new XAttribute("InheritVNCCompression", falseString));
element.Add(new XAttribute("InheritVNCEncoding", falseString));
element.Add(new XAttribute("InheritVNCAuthMode", falseString));
element.Add(new XAttribute("InheritVNCProxyType", falseString));
element.Add(new XAttribute("InheritVNCProxyIP", falseString));
element.Add(new XAttribute("InheritVNCProxyPort", falseString));
element.Add(new XAttribute("InheritVNCProxyUsername", falseString));
element.Add(new XAttribute("InheritVNCProxyPassword", falseString));
element.Add(new XAttribute("InheritVNCColors", falseString));
element.Add(new XAttribute("InheritVNCSmartSizeMode", falseString));
element.Add(new XAttribute("InheritVNCViewOnly", falseString));
element.Add(new XAttribute("InheritRDGatewayUsageMethod", falseString));
element.Add(new XAttribute("InheritRDGatewayHostname", falseString));
element.Add(new XAttribute("InheritRDGatewayUseConnectionCredentials", falseString));
element.Add(new XAttribute("InheritRDGatewayUsername", falseString));
element.Add(new XAttribute("InheritRDGatewayPassword", falseString));
element.Add(new XAttribute("InheritRDGatewayDomain", falseString));
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("InheritRDPAlertIdleTimeout", 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()));
}
}
}

View File

@@ -19,9 +19,9 @@ using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.TaskDialog;
namespace mRemoteNG.Config.Serializers.Xml
namespace mRemoteNG.Config.Serializers
{
public class XmlConnectionsDeserializer : IDeserializer<string, ConnectionTreeModel>
public class XmlConnectionsDeserializer : IDeserializer<string, ConnectionTreeModel>
{
private XmlDocument _xmlDocument;
private double _confVersion;
@@ -30,9 +30,9 @@ namespace mRemoteNG.Config.Serializers.Xml
private const double MaxSupportedConfVersion = 2.8;
private readonly RootNodeInfo _rootNodeInfo = new RootNodeInfo(RootNodeType.Connection);
public Func<Optional<SecureString>> AuthenticationRequestor { get; set; }
public Func<SecureString> AuthenticationRequestor { get; set; }
public XmlConnectionsDeserializer(Func<Optional<SecureString>> authenticationRequestor = null)
public XmlConnectionsDeserializer(Func<SecureString> authenticationRequestor = null)
{
AuthenticationRequestor = authenticationRequestor;
}
@@ -48,6 +48,8 @@ namespace mRemoteNG.Config.Serializers.Xml
{
LoadXmlConnectionData(xml);
ValidateConnectionFileVersion();
if (!import)
Runtime.ConnectionsService.IsConnectionsFileLoaded = false;
var rootXmlElement = _xmlDocument.DocumentElement;
InitializeRootNode(rootXmlElement);
@@ -61,14 +63,15 @@ namespace mRemoteNG.Config.Serializers.Xml
var protectedString = _xmlDocument.DocumentElement?.Attributes["Protected"].Value;
if (!_decryptor.ConnectionsFileIsAuthentic(protectedString, _rootNodeInfo.PasswordString.ConvertToSecureString()))
{
mRemoteNG.Settings.Default.LoadConsFromCustomLocation = false;
mRemoteNG.Settings.Default.CustomConsPath = "";
return null;
}
}
if (_confVersion >= 2.6)
{
var fullFileEncryptionValue = rootXmlElement?.Attributes["FullFileEncryption"].Value ?? "";
if (bool.Parse(fullFileEncryptionValue))
if (rootXmlElement?.Attributes["FullFileEncryption"].Value == "True")
{
var decryptedContent = _decryptor.Decrypt(rootXmlElement.InnerText);
rootXmlElement.InnerXml = decryptedContent;
@@ -140,10 +143,10 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 2.6)
{
BlockCipherEngines engine;
Enum.TryParse(connectionsRootElement?.Attributes["EncryptionEngine"].Value, true, out engine);
Enum.TryParse(connectionsRootElement?.Attributes["EncryptionEngine"].Value, out engine);
BlockCipherModes mode;
Enum.TryParse(connectionsRootElement?.Attributes["BlockCipherMode"].Value, true, out mode);
Enum.TryParse(connectionsRootElement?.Attributes["BlockCipherMode"].Value, out mode);
int keyDerivationIterations;
int.TryParse(connectionsRootElement?.Attributes["KdfIterations"].Value, out keyDerivationIterations);
@@ -183,10 +186,7 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 0.9)
containerInfo.CopyFrom(GetConnectionInfoFromXml(xmlNode));
if (_confVersion >= 0.8)
{
var expandedValue = xmlNode.Attributes?["Expanded"].Value ?? "";
containerInfo.IsExpanded = bool.Parse(expandedValue);
}
containerInfo.IsExpanded = xmlNode.Attributes?["Expanded"].Value == "True";
parentContainer.AddChild(containerInfo);
AddNodesFromXmlRecursive(xmlNode, containerInfo);
@@ -204,11 +204,7 @@ namespace mRemoteNG.Config.Serializers.Xml
private ConnectionInfo GetConnectionInfoFromXml(XmlNode xmlnode)
{
if (xmlnode.Attributes == null) return null;
var connectionId = xmlnode.Attributes["Id"]?.Value;
if (string.IsNullOrWhiteSpace(connectionId))
connectionId = Guid.NewGuid().ToString();
var connectionInfo = new ConnectionInfo(connectionId);
var connectionInfo = new ConnectionInfo();
try
{
@@ -223,9 +219,7 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion < 1.1) //1.0 - 0.1
{
connectionInfo.Resolution = Convert.ToBoolean(xmlnode.Attributes["Fullscreen"].Value)
? RdpProtocol.RDPResolutions.Fullscreen
: RdpProtocol.RDPResolutions.FitToWindow;
connectionInfo.Resolution = Convert.ToBoolean(xmlnode.Attributes["Fullscreen"].Value) ? RdpResolutions.Fullscreen : RdpResolutions.FitToWindow;
}
if (_confVersion <= 2.6) // 0.2 - 2.6
@@ -255,7 +249,7 @@ namespace mRemoteNG.Config.Serializers.Xml
}
else
{
connectionInfo.Port = (int)RdpProtocol.Defaults.Port;
connectionInfo.Port = (int)RdpProtocol6.Defaults.Port;
connectionInfo.Protocol = ProtocolType.RDP;
}
@@ -263,9 +257,7 @@ namespace mRemoteNG.Config.Serializers.Xml
{
if (_confVersion < 0.7)
{
connectionInfo.Port = Convert.ToInt32(Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value)
? xmlnode.Attributes["VNCPort"].Value
: xmlnode.Attributes["RDPPort"].Value);
connectionInfo.Port = Convert.ToInt32(Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value) ? xmlnode.Attributes["VNCPort"].Value : xmlnode.Attributes["RDPPort"].Value);
}
connectionInfo.UseConsoleSession = bool.Parse(xmlnode.Attributes["ConnectToConsole"].Value);
@@ -277,7 +269,7 @@ namespace mRemoteNG.Config.Serializers.Xml
if (Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value))
connectionInfo.Port = (int)ProtocolVNC.Defaults.Port;
else
connectionInfo.Port = (int)RdpProtocol.Defaults.Port;
connectionInfo.Port = (int)RdpProtocol6.Defaults.Port;
}
connectionInfo.UseConsoleSession = false;
}
@@ -299,9 +291,7 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 0.7)
{
ProtocolType protocolType;
Enum.TryParse(xmlnode.Attributes["Protocol"].Value, true, out protocolType);
connectionInfo.Protocol = protocolType;
connectionInfo.Protocol = (ProtocolType)MiscTools.StringToEnum(typeof(ProtocolType), xmlnode.Attributes["Protocol"].Value);
connectionInfo.Port = Convert.ToInt32(xmlnode.Attributes["Port"].Value);
}
@@ -317,34 +307,34 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 1.3)
{
connectionInfo.Colors = (RdpProtocol.RDPColors)Enum.Parse(typeof(RdpProtocol.RDPColors), xmlnode.Attributes["Colors"].Value, true);
connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), xmlnode.Attributes["Resolution"].Value, true);
connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Enum.Parse(typeof(RdpProtocol.RDPSounds), xmlnode.Attributes["RedirectSound"].Value, true);
connectionInfo.Colors = (RdpColors)MiscTools.StringToEnum(typeof(RdpColors), xmlnode.Attributes["Colors"].Value);
connectionInfo.Resolution = (RdpResolutions)MiscTools.StringToEnum(typeof(RdpResolutions), Convert.ToString(xmlnode.Attributes["Resolution"].Value));
connectionInfo.RedirectSound = (RdpSounds)MiscTools.StringToEnum(typeof(RdpSounds), Convert.ToString(xmlnode.Attributes["RedirectSound"].Value));
}
else
{
switch (Convert.ToInt32(xmlnode.Attributes["Colors"].Value))
{
case 0:
connectionInfo.Colors = RdpProtocol.RDPColors.Colors256;
connectionInfo.Colors = RdpColors.Colors256;
break;
case 1:
connectionInfo.Colors = RdpProtocol.RDPColors.Colors16Bit;
connectionInfo.Colors = RdpColors.Colors16Bit;
break;
case 2:
connectionInfo.Colors = RdpProtocol.RDPColors.Colors24Bit;
connectionInfo.Colors = RdpColors.Colors24Bit;
break;
case 3:
connectionInfo.Colors = RdpProtocol.RDPColors.Colors32Bit;
connectionInfo.Colors = RdpColors.Colors32Bit;
break;
// ReSharper disable once RedundantCaseLabel
case 4:
default:
connectionInfo.Colors = RdpProtocol.RDPColors.Colors15Bit;
connectionInfo.Colors = RdpColors.Colors15Bit;
break;
}
connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Convert.ToInt32(xmlnode.Attributes["RedirectSound"].Value);
connectionInfo.RedirectSound = (RdpSounds)Convert.ToInt32(xmlnode.Attributes["RedirectSound"].Value);
}
if (_confVersion >= 1.3)
@@ -395,7 +385,7 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 1.6)
{
connectionInfo.ICAEncryptionStrength = (IcaProtocol.EncryptionStrength)Enum.Parse(typeof(IcaProtocol.EncryptionStrength), xmlnode.Attributes["ICAEncryptionStrength"].Value, true);
connectionInfo.ICAEncryptionStrength = (IcaProtocol.EncryptionStrength)MiscTools.StringToEnum(typeof(IcaProtocol.EncryptionStrength), xmlnode.Attributes["ICAEncryptionStrength"].Value);
connectionInfo.Inheritance.ICAEncryptionStrength = bool.Parse(xmlnode.Attributes["InheritICAEncryptionStrength"].Value);
connectionInfo.PreExtApp = xmlnode.Attributes["PreExtApp"].Value;
connectionInfo.PostExtApp = xmlnode.Attributes["PostExtApp"].Value;
@@ -405,16 +395,16 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 1.7)
{
connectionInfo.VNCCompression = (ProtocolVNC.Compression)Enum.Parse(typeof(ProtocolVNC.Compression), xmlnode.Attributes["VNCCompression"].Value, true);
connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)Enum.Parse(typeof(ProtocolVNC.Encoding), xmlnode.Attributes["VNCEncoding"].Value, true);
connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)Enum.Parse(typeof(ProtocolVNC.AuthMode), xmlnode.Attributes["VNCAuthMode"].Value, true);
connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)Enum.Parse(typeof(ProtocolVNC.ProxyType), xmlnode.Attributes["VNCProxyType"].Value, true);
connectionInfo.VNCCompression = (ProtocolVNC.Compression)MiscTools.StringToEnum(typeof(ProtocolVNC.Compression), xmlnode.Attributes["VNCCompression"].Value);
connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)MiscTools.StringToEnum(typeof(ProtocolVNC.Encoding), Convert.ToString(xmlnode.Attributes["VNCEncoding"].Value));
connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)MiscTools.StringToEnum(typeof(ProtocolVNC.AuthMode), xmlnode.Attributes["VNCAuthMode"].Value);
connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)MiscTools.StringToEnum(typeof(ProtocolVNC.ProxyType), xmlnode.Attributes["VNCProxyType"].Value);
connectionInfo.VNCProxyIP = xmlnode.Attributes["VNCProxyIP"].Value;
connectionInfo.VNCProxyPort = Convert.ToInt32(xmlnode.Attributes["VNCProxyPort"].Value);
connectionInfo.VNCProxyUsername = xmlnode.Attributes["VNCProxyUsername"].Value;
connectionInfo.VNCProxyPassword = _decryptor.Decrypt(xmlnode.Attributes["VNCProxyPassword"].Value);
connectionInfo.VNCColors = (ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), xmlnode.Attributes["VNCColors"].Value, true);
connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), xmlnode.Attributes["VNCSmartSizeMode"].Value, true);
connectionInfo.VNCColors = (ProtocolVNC.Colors)MiscTools.StringToEnum(typeof(ProtocolVNC.Colors), xmlnode.Attributes["VNCColors"].Value);
connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)MiscTools.StringToEnum(typeof(ProtocolVNC.SmartSizeMode), xmlnode.Attributes["VNCSmartSizeMode"].Value);
connectionInfo.VNCViewOnly = bool.Parse(xmlnode.Attributes["VNCViewOnly"].Value);
connectionInfo.Inheritance.VNCCompression = bool.Parse(xmlnode.Attributes["InheritVNCCompression"].Value);
connectionInfo.Inheritance.VNCEncoding = bool.Parse(xmlnode.Attributes["InheritVNCEncoding"].Value);
@@ -431,13 +421,13 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 1.8)
{
connectionInfo.RDPAuthenticationLevel = (RdpProtocol.AuthenticationLevel)Enum.Parse(typeof(RdpProtocol.AuthenticationLevel), xmlnode.Attributes["RDPAuthenticationLevel"].Value, true);
connectionInfo.RDPAuthenticationLevel = (RdpAuthenticationLevel)MiscTools.StringToEnum(typeof(RdpAuthenticationLevel), xmlnode.Attributes["RDPAuthenticationLevel"].Value);
connectionInfo.Inheritance.RDPAuthenticationLevel = bool.Parse(xmlnode.Attributes["InheritRDPAuthenticationLevel"].Value);
}
if (_confVersion >= 1.9)
{
connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), xmlnode.Attributes["RenderingEngine"].Value, true);
connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)MiscTools.StringToEnum(typeof(HTTPBase.RenderingEngine), xmlnode.Attributes["RenderingEngine"].Value);
connectionInfo.MacAddress = xmlnode.Attributes["MacAddress"].Value;
connectionInfo.Inheritance.RenderingEngine = bool.Parse(xmlnode.Attributes["InheritRenderingEngine"].Value);
connectionInfo.Inheritance.MacAddress = bool.Parse(xmlnode.Attributes["InheritMacAddress"].Value);
@@ -458,9 +448,9 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 2.2)
{
// Get settings
connectionInfo.RDGatewayUsageMethod = (RdpProtocol.RDGatewayUsageMethod)Enum.Parse(typeof(RdpProtocol.RDGatewayUsageMethod), xmlnode.Attributes["RDGatewayUsageMethod"].Value, true);
connectionInfo.RDGatewayUsageMethod = (RDGatewayUsageMethod)MiscTools.StringToEnum(typeof(RDGatewayUsageMethod), Convert.ToString(xmlnode.Attributes["RDGatewayUsageMethod"].Value));
connectionInfo.RDGatewayHostname = xmlnode.Attributes["RDGatewayHostname"].Value;
connectionInfo.RDGatewayUseConnectionCredentials = (RdpProtocol.RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RdpProtocol.RDGatewayUseConnectionCredentials), xmlnode.Attributes["RDGatewayUseConnectionCredentials"].Value, true);
connectionInfo.RDGatewayUseConnectionCredentials = (RDGatewayUseConnectionCredentials)MiscTools.StringToEnum(typeof(RDGatewayUseConnectionCredentials), Convert.ToString(xmlnode.Attributes["RDGatewayUseConnectionCredentials"].Value));
connectionInfo.RDGatewayUsername = xmlnode.Attributes["RDGatewayUsername"].Value;
connectionInfo.RDGatewayPassword = _decryptor.Decrypt(Convert.ToString(xmlnode.Attributes["RDGatewayPassword"].Value));
connectionInfo.RDGatewayDomain = xmlnode.Attributes["RDGatewayDomain"].Value;
@@ -501,7 +491,8 @@ namespace mRemoteNG.Config.Serializers.Xml
if (_confVersion >= 2.6)
{
connectionInfo.SoundQuality = (RdpProtocol.RDPSoundQuality)Enum.Parse(typeof(RdpProtocol.RDPSoundQuality), xmlnode.Attributes["SoundQuality"].Value, true);
connectionInfo.ConstantID = xmlnode.Attributes["Id"]?.Value ?? connectionInfo.ConstantID;
connectionInfo.SoundQuality = (RdpSoundQuality)MiscTools.StringToEnum(typeof(RdpSoundQuality), Convert.ToString(xmlnode.Attributes["SoundQuality"].Value));
connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value);
connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0");
connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False");

View File

@@ -8,7 +8,8 @@ using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.Xml
namespace mRemoteNG.Config.Serializers
{
public class XmlConnectionsDocumentCompiler
{

View File

@@ -2,7 +2,8 @@
using System.Xml.Linq;
using mRemoteNG.Security;
namespace mRemoteNG.Config.Serializers.Xml
namespace mRemoteNG.Config.Serializers
{
public class XmlConnectionsDocumentEncryptor
{

View File

@@ -10,7 +10,7 @@ using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.Xml
namespace mRemoteNG.Config.Serializers
{
public class XmlConnectionsSerializer : ISerializer<ConnectionTreeModel,string>, ISerializer<ConnectionInfo, string>
{

View File

@@ -2,21 +2,19 @@
using mRemoteNG.Security;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.Xml
namespace mRemoteNG.Config.Serializers
{
public class XmlRootNodeSerializer
public class XmlRootNodeSerializer
{
public XElement SerializeRootNodeInfo(RootNodeInfo rootNodeInfo, ICryptographyProvider cryptographyProvider, bool fullFileEncryption = false)
{
XNamespace xmlNamespace = "http://mremoteng.org";
var element = new XElement(xmlNamespace + "Connections");
element.Add(new XAttribute(XNamespace.Xmlns+"mrng", xmlNamespace));
var element = new XElement("Connections");
element.Add(new XAttribute(XName.Get("Name"), rootNodeInfo.Name));
element.Add(new XAttribute(XName.Get("Export"), "false"));
element.Add(new XAttribute(XName.Get("EncryptionEngine"), cryptographyProvider.CipherEngine));
element.Add(new XAttribute(XName.Get("EncryptionEngine"), cryptographyProvider.CipherEngine));
element.Add(new XAttribute(XName.Get("BlockCipherMode"), cryptographyProvider.CipherMode));
element.Add(new XAttribute(XName.Get("KdfIterations"), cryptographyProvider.KeyDerivationIterations));
element.Add(new XAttribute(XName.Get("FullFileEncryption"), fullFileEncryption.ToString().ToLowerInvariant()));
element.Add(new XAttribute(XName.Get("FullFileEncryption"), fullFileEncryption.ToString()));
element.Add(CreateProtectedAttribute(rootNodeInfo, cryptographyProvider));
element.Add(new XAttribute(XName.Get("ConfVersion"), "2.6"));
return element;

View File

@@ -1,4 +1,8 @@
using mRemoteNG.App;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.Http;
@@ -8,28 +12,11 @@ using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Security;
using mRemoteNG.Security;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Serializers.MsSql
namespace mRemoteNG.Config.Serializers
{
public class DataTableDeserializer : IDeserializer<DataTable, ConnectionTreeModel>
public class DataTableDeserializer : IDeserializer<DataTable, ConnectionTreeModel>
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly SecureString _decryptionKey;
public DataTableDeserializer(ICryptographyProvider cryptographyProvider, SecureString decryptionKey)
{
_cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
_decryptionKey = decryptionKey.ThrowIfNull(nameof(decryptionKey));
}
public ConnectionTreeModel Deserialize(DataTable table)
{
var connectionList = CreateNodesFromTable(table);
@@ -47,10 +34,10 @@ namespace mRemoteNG.Config.Serializers.MsSql
switch ((string)row["Type"])
{
case "Connection":
nodeList.Add(DeserializeConnectionInfo(row));
nodeList.Add(DeserializeConnectionInfo(row));
break;
case "Container":
nodeList.Add(DeserializeContainerInfo(row));
nodeList.Add(DeserializeContainerInfo(row));
break;
}
}
@@ -59,16 +46,14 @@ namespace mRemoteNG.Config.Serializers.MsSql
private ConnectionInfo DeserializeConnectionInfo(DataRow row)
{
var connectionId = row["ConstantID"] as string ?? Guid.NewGuid().ToString();
var connectionInfo = new ConnectionInfo(connectionId);
var connectionInfo = new ConnectionInfo();
PopulateConnectionInfoFromDatarow(row, connectionInfo);
return connectionInfo;
}
private ContainerInfo DeserializeContainerInfo(DataRow row)
{
var containerId = row["ConstantID"] as string ?? Guid.NewGuid().ToString();
var containerInfo = new ContainerInfo(containerId);
var containerInfo = new ContainerInfo();
PopulateConnectionInfoFromDatarow(row, containerInfo);
return containerInfo;
}
@@ -76,17 +61,22 @@ namespace mRemoteNG.Config.Serializers.MsSql
private void PopulateConnectionInfoFromDatarow(DataRow dataRow, ConnectionInfo connectionInfo)
{
connectionInfo.Name = (string)dataRow["Name"];
connectionInfo.ConstantID = (string)dataRow["ConstantID"];
// This throws a NPE - Parent is a connectionInfo object which will be null at this point.
// The Parent object is linked properly later in CreateNodeHierarchy()
//connectionInfo.Parent.ConstantID = (string)dataRow["ParentID"];
var info = connectionInfo as ContainerInfo;
if(info != null)
info.IsExpanded = (bool)dataRow["Expanded"];
connectionInfo.Description = (string)dataRow["Description"];
connectionInfo.Icon = (string)dataRow["Icon"];
connectionInfo.Panel = (string)dataRow["Panel"];
connectionInfo.Username = (string)dataRow["Username"];
connectionInfo.Domain = (string)dataRow["DomainName"];
connectionInfo.Password = DecryptValue((string)dataRow["Password"]);
connectionInfo.Password = (string)dataRow["Password"];
connectionInfo.Hostname = (string)dataRow["Hostname"];
connectionInfo.Protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), (string)dataRow["Protocol"]);
connectionInfo.PuttySession = (string)dataRow["PuttySession"];
@@ -95,12 +85,12 @@ namespace mRemoteNG.Config.Serializers.MsSql
connectionInfo.UseCredSsp = (bool)dataRow["UseCredSsp"];
connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), (string)dataRow["RenderingEngine"]);
connectionInfo.ICAEncryptionStrength = (IcaProtocol.EncryptionStrength)Enum.Parse(typeof(IcaProtocol.EncryptionStrength), (string)dataRow["ICAEncryptionStrength"]);
connectionInfo.RDPAuthenticationLevel = (RdpProtocol.AuthenticationLevel)Enum.Parse(typeof(RdpProtocol.AuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]);
connectionInfo.RDPAuthenticationLevel = (RdpAuthenticationLevel)Enum.Parse(typeof(RdpAuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]);
connectionInfo.RDPMinutesToIdleTimeout = (int)dataRow["RDPMinutesToIdleTimeout"];
connectionInfo.RDPAlertIdleTimeout = (bool)dataRow["RDPAlertIdleTimeout"];
connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"];
connectionInfo.Colors = (RdpProtocol.RDPColors)Enum.Parse(typeof(RdpProtocol.RDPColors) ,(string)dataRow["Colors"]);
connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), (string)dataRow["Resolution"]);
connectionInfo.Colors = (RdpColors)Enum.Parse(typeof(RdpColors) ,(string)dataRow["Colors"]);
connectionInfo.Resolution = (RdpResolutions)Enum.Parse(typeof(RdpResolutions), (string)dataRow["Resolution"]);
connectionInfo.AutomaticResize = (bool)dataRow["AutomaticResize"];
connectionInfo.DisplayWallpaper = (bool)dataRow["DisplayWallpaper"];
connectionInfo.DisplayThemes = (bool)dataRow["DisplayThemes"];
@@ -111,9 +101,10 @@ namespace mRemoteNG.Config.Serializers.MsSql
connectionInfo.RedirectPorts = (bool)dataRow["RedirectPorts"];
connectionInfo.RedirectPrinters = (bool)dataRow["RedirectPrinters"];
connectionInfo.RedirectSmartCards = (bool)dataRow["RedirectSmartCards"];
connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Enum.Parse(typeof(RdpProtocol.RDPSounds), (string)dataRow["RedirectSound"]);
connectionInfo.SoundQuality = (RdpProtocol.RDPSoundQuality)Enum.Parse(typeof(RdpProtocol.RDPSoundQuality), (string)dataRow["SoundQuality"]);
connectionInfo.RedirectSound = (RdpSounds)Enum.Parse(typeof(RdpSounds), (string)dataRow["RedirectSound"]);
connectionInfo.SoundQuality = (RdpSoundQuality)Enum.Parse(typeof(RdpSoundQuality), (string)dataRow["SoundQuality"]);
connectionInfo.RedirectKeys = (bool)dataRow["RedirectKeys"];
connectionInfo.PleaseConnect = (bool)dataRow["Connected"];
connectionInfo.PreExtApp = (string)dataRow["PreExtApp"];
connectionInfo.PostExtApp = (string)dataRow["PostExtApp"];
connectionInfo.MacAddress = (string)dataRow["MacAddress"];
@@ -126,15 +117,15 @@ namespace mRemoteNG.Config.Serializers.MsSql
connectionInfo.VNCProxyIP = (string)dataRow["VNCProxyIP"];
connectionInfo.VNCProxyPort = (int)dataRow["VNCProxyPort"];
connectionInfo.VNCProxyUsername = (string)dataRow["VNCProxyUsername"];
connectionInfo.VNCProxyPassword = DecryptValue((string)dataRow["VNCProxyPassword"]);
connectionInfo.VNCProxyPassword = (string)dataRow["VNCProxyPassword"];
connectionInfo.VNCColors = (ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), (string)dataRow["VNCColors"]);
connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), (string)dataRow["VNCSmartSizeMode"]);
connectionInfo.VNCViewOnly = (bool)dataRow["VNCViewOnly"];
connectionInfo.RDGatewayUsageMethod = (RdpProtocol.RDGatewayUsageMethod)Enum.Parse(typeof(RdpProtocol.RDGatewayUsageMethod), (string)dataRow["RDGatewayUsageMethod"]);
connectionInfo.RDGatewayUsageMethod = (RDGatewayUsageMethod)Enum.Parse(typeof(RDGatewayUsageMethod), (string)dataRow["RDGatewayUsageMethod"]);
connectionInfo.RDGatewayHostname = (string)dataRow["RDGatewayHostname"];
connectionInfo.RDGatewayUseConnectionCredentials = (RdpProtocol.RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RdpProtocol.RDGatewayUseConnectionCredentials), (string)dataRow["RDGatewayUseConnectionCredentials"]);
connectionInfo.RDGatewayUseConnectionCredentials = (RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RDGatewayUseConnectionCredentials), (string)dataRow["RDGatewayUseConnectionCredentials"]);
connectionInfo.RDGatewayUsername = (string)dataRow["RDGatewayUsername"];
connectionInfo.RDGatewayPassword = DecryptValue((string)dataRow["RDGatewayPassword"]);
connectionInfo.RDGatewayPassword = (string)dataRow["RDGatewayPassword"];
connectionInfo.RDGatewayDomain = (string)dataRow["RDGatewayDomain"];
connectionInfo.Inheritance.CacheBitmaps = (bool)dataRow["InheritCacheBitmaps"];
@@ -193,26 +184,10 @@ namespace mRemoteNG.Config.Serializers.MsSql
connectionInfo.Inheritance.RDGatewayDomain = (bool)dataRow["InheritRDGatewayDomain"];
}
private string DecryptValue(string cipherText)
{
try
{
return _cryptographyProvider.Decrypt(cipherText, _decryptionKey);
}
catch (EncryptionException)
{
// value may not be encrypted
return cipherText;
}
}
private ConnectionTreeModel CreateNodeHierarchy(List<ConnectionInfo> connectionList, DataTable dataTable)
{
var connectionTreeModel = new ConnectionTreeModel();
var rootNode = new RootNodeInfo(RootNodeType.Connection, "0")
{
PasswordString = _decryptionKey.ConvertToUnsecureString()
};
var rootNode = new RootNodeInfo(RootNodeType.Connection) {ConstantID = "0"};
connectionTreeModel.AddRootNode(rootNode);
foreach (DataRow row in dataTable.Rows)

View File

@@ -1,31 +1,25 @@
using mRemoteNG.Connection;
using System;
using System.Data;
using System.Data.SqlTypes;
using System.Linq;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using System;
using System.Data;
using System.Data.SqlTypes;
using System.Linq;
using System.Security;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Serializers.MsSql
namespace mRemoteNG.Config.Serializers
{
public class DataTableSerializer : ISerializer<ConnectionInfo,DataTable>
{
private readonly ICryptographyProvider _cryptographyProvider;
private readonly SecureString _encryptionKey;
private DataTable _dataTable;
private const string TableName = "tblCons";
private readonly SaveFilter _saveFilter;
private int _currentNodeIndex;
public DataTableSerializer(SaveFilter saveFilter, ICryptographyProvider cryptographyProvider, SecureString encryptionKey)
public DataTableSerializer(SaveFilter saveFilter)
{
_saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter));
_cryptographyProvider = cryptographyProvider.ThrowIfNull(nameof(cryptographyProvider));
_encryptionKey = encryptionKey.ThrowIfNull(nameof(encryptionKey));
_saveFilter = saveFilter;
}
@@ -210,15 +204,14 @@ namespace mRemoteNG.Config.Serializers.MsSql
dataRow["ParentID"] = connectionInfo.Parent?.ConstantID ?? "";
dataRow["PositionID"] = _currentNodeIndex;
dataRow["LastChange"] = (SqlDateTime)DateTime.Now;
dataRow["Expanded"] = false; // TODO: this column can eventually be removed. we now save this property locally
var info = connectionInfo as ContainerInfo;
dataRow["Expanded"] = info != null && info.IsExpanded;
dataRow["Description"] = connectionInfo.Description;
dataRow["Icon"] = connectionInfo.Icon;
dataRow["Panel"] = connectionInfo.Panel;
dataRow["Username"] = _saveFilter.SaveUsername ? connectionInfo.Username : "";
dataRow["DomainName"] = _saveFilter.SaveDomain ? connectionInfo.Domain : "";
dataRow["Password"] = _saveFilter.SavePassword
? _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey)
: "";
dataRow["Password"] = _saveFilter.SavePassword ? connectionInfo.Password : "";
dataRow["Hostname"] = connectionInfo.Hostname;
dataRow["Protocol"] = connectionInfo.Protocol;
dataRow["PuttySession"] = connectionInfo.PuttySession;
@@ -246,7 +239,7 @@ namespace mRemoteNG.Config.Serializers.MsSql
dataRow["RedirectSound"] = connectionInfo.RedirectSound;
dataRow["SoundQuality"] = connectionInfo.SoundQuality;
dataRow["RedirectKeys"] = connectionInfo.RedirectKeys;
dataRow["Connected"] = false; // TODO: this column can eventually be removed. we now save this property locally
dataRow["Connected"] = connectionInfo.OpenConnections.Count > 0;
dataRow["PreExtApp"] = connectionInfo.PreExtApp;
dataRow["PostExtApp"] = connectionInfo.PostExtApp;
dataRow["MacAddress"] = connectionInfo.MacAddress;
@@ -259,14 +252,14 @@ namespace mRemoteNG.Config.Serializers.MsSql
dataRow["VNCProxyIP"] = connectionInfo.VNCProxyIP;
dataRow["VNCProxyPort"] = connectionInfo.VNCProxyPort;
dataRow["VNCProxyUsername"] = connectionInfo.VNCProxyUsername;
dataRow["VNCProxyPassword"] = _cryptographyProvider.Encrypt(connectionInfo.VNCProxyPassword, _encryptionKey);
dataRow["VNCProxyPassword"] = connectionInfo.VNCProxyPassword;
dataRow["VNCColors"] = connectionInfo.VNCColors;
dataRow["VNCSmartSizeMode"] = connectionInfo.VNCSmartSizeMode;
dataRow["VNCViewOnly"] = connectionInfo.VNCViewOnly;
dataRow["RDGatewayUsageMethod"] = connectionInfo.RDGatewayUsageMethod;
dataRow["RDGatewayHostname"] = connectionInfo.RDGatewayHostname;
dataRow["RDGatewayUseConnectionCredentials"] = connectionInfo.RDGatewayUseConnectionCredentials;
dataRow["RDGatewayUsername"] = _cryptographyProvider.Encrypt(connectionInfo.RDGatewayUsername, _encryptionKey);
dataRow["RDGatewayUsername"] = connectionInfo.RDGatewayUsername;
dataRow["RDGatewayPassword"] = connectionInfo.RDGatewayPassword;
dataRow["RDGatewayDomain"] = connectionInfo.RDGatewayDomain;
if (_saveFilter.SaveInheritance)

View File

@@ -11,16 +11,16 @@ using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers.Csv
namespace mRemoteNG.Config.Serializers.MiscSerializers
{
public class CsvConnectionsDeserializerMremotengFormat : IDeserializer<string, ConnectionTreeModel>
public class CsvConnectionsDeserializerMremotengFormat : IDeserializer<string, ConnectionTreeModel>
{
public ConnectionTreeModel Deserialize(string serializedData)
{
var root = new RootNodeInfo(RootNodeType.Connection);
var lines = serializedData.Split(new []{"\r\n", "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries);
var csvHeaders = new List<string>();
// used to map a connectioninfo to it's parent's GUID
var parentMapping = new Dictionary<ConnectionInfo, string>();
for (var lineNumber = 0; lineNumber < lines.Length; lineNumber++)
{
@@ -30,61 +30,39 @@ namespace mRemoteNG.Config.Serializers.Csv
else
{
var connectionInfo = ParseConnectionInfo(csvHeaders, line);
parentMapping.Add(connectionInfo, line[csvHeaders.IndexOf("Parent")]);
var folder = ParseConnectionFolder(line[csvHeaders.IndexOf("Folder")], root);
folder.AddChild(connectionInfo);
}
}
var root = CreateTreeStructure(parentMapping);
var connectionTreeModel = new ConnectionTreeModel();
connectionTreeModel.AddRootNode(root);
return connectionTreeModel;
}
private RootNodeInfo CreateTreeStructure(Dictionary<ConnectionInfo, string> parentMapping)
private ContainerInfo ParseConnectionFolder(string folderString, ContainerInfo rootContainer)
{
var root = new RootNodeInfo(RootNodeType.Connection);
var containerNames = folderString.Split('\\');
var parentContainer = rootContainer;
foreach (var node in parentMapping)
for (var i = containerNames.Length - 2; i >= 0; i--)
{
// no parent mapped, add to root
if (string.IsNullOrEmpty(node.Value))
var containerName = containerNames[i];
var container = parentContainer.Children.OfType<ContainerInfo>().FirstOrDefault(info => info.Name == containerName);
if (container == null)
{
root.AddChild(node.Key);
continue;
}
// search for parent in the list by GUID
var parent = parentMapping
.Keys
.OfType<ContainerInfo>()
.FirstOrDefault(info => info.ConstantID == node.Value);
if (parent != null)
{
parent.AddChild(node.Key);
}
else
{
root.AddChild(node.Key);
container = new ContainerInfo {Name = containerName};
parentContainer.AddChild(container);
}
parentContainer = container;
}
return root;
return parentContainer;
}
private ConnectionInfo ParseConnectionInfo(IList<string> headers, string[] connectionCsv)
{
var nodeType = headers.Contains("NodeType")
? (TreeNodeType)Enum.Parse(typeof(TreeNodeType), connectionCsv[headers.IndexOf("NodeType")], true)
: TreeNodeType.Connection;
var nodeId = headers.Contains("Id")
? connectionCsv[headers.IndexOf("Id")]
: Guid.NewGuid().ToString();
var connectionRecord = nodeType == TreeNodeType.Connection
? new ConnectionInfo(nodeId)
: new ContainerInfo(nodeId);
var connectionRecord = new ConnectionInfo();
connectionRecord.Name = headers.Contains("Name") ? connectionCsv[headers.IndexOf("Name")] : "";
connectionRecord.Description = headers.Contains("Description") ? connectionCsv[headers.IndexOf("Description")] : "";
@@ -153,21 +131,21 @@ namespace mRemoteNG.Config.Serializers.Csv
if (headers.Contains("RDPAuthenticationLevel"))
{
RdpProtocol.AuthenticationLevel value;
RdpAuthenticationLevel value;
if (Enum.TryParse(connectionCsv[headers.IndexOf("RDPAuthenticationLevel")], out value))
connectionRecord.RDPAuthenticationLevel = value;
}
if (headers.Contains("Colors"))
{
RdpProtocol.RDPColors value;
RdpColors value;
if (Enum.TryParse(connectionCsv[headers.IndexOf("Colors")], out value))
connectionRecord.Colors = value;
}
if (headers.Contains("Resolution"))
{
RdpProtocol.RDPResolutions value;
RdpResolutions value;
if (Enum.TryParse(connectionCsv[headers.IndexOf("Resolution")], out value))
connectionRecord.Resolution = value;
}
@@ -244,7 +222,7 @@ namespace mRemoteNG.Config.Serializers.Csv
if (headers.Contains("RedirectSound"))
{
RdpProtocol.RDPSounds value;
RdpSounds value;
if (Enum.TryParse(connectionCsv[headers.IndexOf("RedirectSound")], out value))
connectionRecord.RedirectSound = value;
}
@@ -314,14 +292,14 @@ namespace mRemoteNG.Config.Serializers.Csv
if (headers.Contains("RDGatewayUsageMethod"))
{
RdpProtocol.RDGatewayUsageMethod value;
RDGatewayUsageMethod value;
if (Enum.TryParse(connectionCsv[headers.IndexOf("RDGatewayUsageMethod")], out value))
connectionRecord.RDGatewayUsageMethod = value;
}
if (headers.Contains("RDGatewayUseConnectionCredentials"))
{
RdpProtocol.RDGatewayUseConnectionCredentials value;
RDGatewayUseConnectionCredentials value;
if (Enum.TryParse(connectionCsv[headers.IndexOf("RDGatewayUseConnectionCredentials")], out value))
connectionRecord.RDGatewayUseConnectionCredentials = value;
}

View File

@@ -0,0 +1,238 @@
using System;
using System.Linq;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers
{
public class CsvConnectionsSerializerMremotengFormat : ISerializer<ConnectionInfo,string>
{
private string _csv = "";
private ConnectionInfo _serializationTarget;
private readonly SaveFilter _saveFilter;
private readonly ICredentialRepositoryList _credentialRepositoryList;
public CsvConnectionsSerializerMremotengFormat(SaveFilter saveFilter, ICredentialRepositoryList credentialRepositoryList)
{
if (saveFilter == null)
throw new ArgumentNullException(nameof(saveFilter));
if (credentialRepositoryList == null)
throw new ArgumentNullException(nameof(credentialRepositoryList));
_saveFilter = saveFilter;
_credentialRepositoryList = credentialRepositoryList;
}
public string Serialize(ConnectionTreeModel connectionTreeModel)
{
if (connectionTreeModel == null)
throw new ArgumentNullException(nameof(connectionTreeModel));
var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo);
return Serialize(rootNode);
}
public string Serialize(ConnectionInfo serializationTarget)
{
if (serializationTarget == null)
throw new ArgumentNullException(nameof(serializationTarget));
_csv = "";
_serializationTarget = serializationTarget;
WriteCsvHeader();
SerializeNodesRecursive(serializationTarget);
return _csv;
}
private void WriteCsvHeader()
{
var csvHeader = string.Empty;
csvHeader += "Name;Folder;Description;Icon;Panel;";
if (_saveFilter.SaveUsername)
csvHeader += "Username;";
if (_saveFilter.SavePassword)
csvHeader += "Password;";
if (_saveFilter.SaveDomain)
csvHeader += "Domain;";
csvHeader += "Hostname;Protocol;PuttySession;Port;ConnectToConsole;UseCredSsp;RenderingEngine;ICAEncryptionStrength;RDPAuthenticationLevel;LoadBalanceInfo;Colors;Resolution;AutomaticResize;DisplayWallpaper;DisplayThemes;EnableFontSmoothing;EnableDesktopComposition;CacheBitmaps;RedirectDiskDrives;RedirectPorts;RedirectPrinters;RedirectSmartCards;RedirectSound;RedirectKeys;PreExtApp;PostExtApp;MacAddress;UserField;ExtApp;VNCCompression;VNCEncoding;VNCAuthMode;VNCProxyType;VNCProxyIP;VNCProxyPort;VNCProxyUsername;VNCProxyPassword;VNCColors;VNCSmartSizeMode;VNCViewOnly;RDGatewayUsageMethod;RDGatewayHostname;RDGatewayUseConnectionCredentials;RDGatewayUsername;RDGatewayPassword;RDGatewayDomain;";
if (_saveFilter.SaveInheritance)
csvHeader += "InheritCacheBitmaps;InheritColors;InheritDescription;InheritDisplayThemes;InheritDisplayWallpaper;InheritEnableFontSmoothing;InheritEnableDesktopComposition;InheritDomain;InheritIcon;InheritPanel;InheritPassword;InheritPort;InheritProtocol;InheritPuttySession;InheritRedirectDiskDrives;InheritRedirectKeys;InheritRedirectPorts;InheritRedirectPrinters;InheritRedirectSmartCards;InheritRedirectSound;InheritResolution;InheritAutomaticResize;InheritUseConsoleSession;InheritUseCredSsp;InheritRenderingEngine;InheritUsername;InheritICAEncryptionStrength;InheritRDPAuthenticationLevel;InheritLoadBalanceInfo;InheritPreExtApp;InheritPostExtApp;InheritMacAddress;InheritUserField;InheritExtApp;InheritVNCCompression;InheritVNCEncoding;InheritVNCAuthMode;InheritVNCProxyType;InheritVNCProxyIP;InheritVNCProxyPort;InheritVNCProxyUsername;InheritVNCProxyPassword;InheritVNCColors;InheritVNCSmartSizeMode;InheritVNCViewOnly;InheritRDGatewayUsageMethod;InheritRDGatewayHostname;InheritRDGatewayUseConnectionCredentials;InheritRDGatewayUsername;InheritRDGatewayPassword;InheritRDGatewayDomain;InheritRDPAlertIdleTimeout;InheritRDPMinutesToIdleTimeout;InheritSoundQuality";
_csv += csvHeader;
}
private void SerializeNodesRecursive(ConnectionInfo node)
{
var nodeAsContainer = node as ContainerInfo;
if (nodeAsContainer != null)
{
foreach (var child in nodeAsContainer.Children)
{
var info = child as ContainerInfo;
if (info != null)
SerializeNodesRecursive(info);
else
SerializeConnectionInfo(child);
}
}
else
SerializeConnectionInfo(node);
}
private void SerializeConnectionInfo(ConnectionInfo con)
{
var csvLine = Environment.NewLine;
csvLine += CleanStringForCsv(con.Name) + ";" +
CleanStringForCsv(GetNodePath(con)) + ";" +
CleanStringForCsv(con.Description) + ";" +
CleanStringForCsv(con.Icon) + ";" +
CleanStringForCsv(con.Panel) + ";";
if (_saveFilter.SaveUsername)
csvLine += CleanStringForCsv(con.Username) + ";";
if (_saveFilter.SavePassword)
csvLine += CleanStringForCsv(con.Password) + ";";
if (_saveFilter.SaveDomain)
csvLine += CleanStringForCsv(con.Domain) + ";";
csvLine += CleanStringForCsv(con.Hostname) + ";" +
CleanStringForCsv(con.Protocol) + ";" +
CleanStringForCsv(con.PuttySession) + ";" +
CleanStringForCsv(con.Port) + ";" +
CleanStringForCsv(con.UseConsoleSession) + ";" +
CleanStringForCsv(con.UseCredSsp) + ";" +
CleanStringForCsv(con.RenderingEngine) + ";" +
CleanStringForCsv(con.ICAEncryptionStrength) + ";" +
CleanStringForCsv(con.RDPAuthenticationLevel) + ";" +
CleanStringForCsv(con.LoadBalanceInfo) + ";" +
CleanStringForCsv(con.Colors) + ";" +
CleanStringForCsv(con.Resolution) + ";" +
CleanStringForCsv(con.AutomaticResize) + ";" +
CleanStringForCsv(con.DisplayWallpaper) + ";" +
CleanStringForCsv(con.DisplayThemes) + ";" +
CleanStringForCsv(con.EnableFontSmoothing) + ";" +
CleanStringForCsv(con.EnableDesktopComposition) + ";" +
CleanStringForCsv(con.CacheBitmaps) + ";" +
CleanStringForCsv(con.RedirectDiskDrives) + ";" +
CleanStringForCsv(con.RedirectPorts) + ";" +
CleanStringForCsv(con.RedirectPrinters) + ";" +
CleanStringForCsv(con.RedirectSmartCards) + ";" +
CleanStringForCsv(con.RedirectSound) + ";" +
CleanStringForCsv(con.RedirectKeys) + ";" +
CleanStringForCsv(con.PreExtApp) + ";" +
CleanStringForCsv(con.PostExtApp) + ";" +
CleanStringForCsv(con.MacAddress) + ";" +
CleanStringForCsv(con.UserField) + ";" +
CleanStringForCsv(con.ExtApp) + ";" +
CleanStringForCsv(con.VNCCompression) + ";" +
CleanStringForCsv(con.VNCEncoding) + ";" +
CleanStringForCsv(con.VNCAuthMode) + ";" +
CleanStringForCsv(con.VNCProxyType) + ";" +
CleanStringForCsv(con.VNCProxyIP) + ";" +
CleanStringForCsv(con.VNCProxyPort) + ";" +
CleanStringForCsv(con.VNCProxyUsername) + ";" +
CleanStringForCsv(con.VNCProxyPassword) + ";" +
CleanStringForCsv(con.VNCColors) + ";" +
CleanStringForCsv(con.VNCSmartSizeMode) + ";" +
CleanStringForCsv(con.VNCViewOnly) + ";" +
CleanStringForCsv(con.RDGatewayUsageMethod) + ";" +
CleanStringForCsv(con.RDGatewayHostname) + ";" +
CleanStringForCsv(con.RDGatewayUseConnectionCredentials) + ";" +
CleanStringForCsv(con.RDGatewayUsername) + ";" +
CleanStringForCsv(con.RDGatewayPassword) + ";" +
CleanStringForCsv(con.RDGatewayDomain) + ";";
if (_saveFilter.SaveInheritance)
{
csvLine += con.Inheritance.CacheBitmaps + ";" +
con.Inheritance.Colors + ";" +
con.Inheritance.Description + ";" +
con.Inheritance.DisplayThemes + ";" +
con.Inheritance.DisplayWallpaper + ";" +
con.Inheritance.EnableFontSmoothing + ";" +
con.Inheritance.EnableDesktopComposition + ";" +
con.Inheritance.Domain + ";" +
con.Inheritance.Icon + ";" +
con.Inheritance.Panel + ";" +
con.Inheritance.Password + ";" +
con.Inheritance.Port + ";" +
con.Inheritance.Protocol + ";" +
con.Inheritance.PuttySession + ";" +
con.Inheritance.RedirectDiskDrives + ";" +
con.Inheritance.RedirectKeys + ";" +
con.Inheritance.RedirectPorts + ";" +
con.Inheritance.RedirectPrinters + ";" +
con.Inheritance.RedirectSmartCards + ";" +
con.Inheritance.RedirectSound + ";" +
con.Inheritance.Resolution + ";" +
con.Inheritance.AutomaticResize + ";" +
con.Inheritance.UseConsoleSession + ";" +
con.Inheritance.UseCredSsp + ";" +
con.Inheritance.RenderingEngine + ";" +
con.Inheritance.Username + ";" +
con.Inheritance.ICAEncryptionStrength + ";" +
con.Inheritance.RDPAuthenticationLevel + ";" +
con.Inheritance.LoadBalanceInfo + ";" +
con.Inheritance.PreExtApp + ";" +
con.Inheritance.PostExtApp + ";" +
con.Inheritance.MacAddress + ";" +
con.Inheritance.UserField + ";" +
con.Inheritance.ExtApp + ";" +
con.Inheritance.VNCCompression + ";" +
con.Inheritance.VNCEncoding + ";" +
con.Inheritance.VNCAuthMode + ";" +
con.Inheritance.VNCProxyType + ";" +
con.Inheritance.VNCProxyIP + ";" +
con.Inheritance.VNCProxyPort + ";" +
con.Inheritance.VNCProxyUsername + ";" +
con.Inheritance.VNCProxyPassword + ";" +
con.Inheritance.VNCColors + ";" +
con.Inheritance.VNCSmartSizeMode + ";" +
con.Inheritance.VNCViewOnly + ";" +
con.Inheritance.RDGatewayUsageMethod + ";" +
con.Inheritance.RDGatewayHostname + ";" +
con.Inheritance.RDGatewayUseConnectionCredentials + ";" +
con.Inheritance.RDGatewayUsername + ";" +
con.Inheritance.RDGatewayPassword + ";" +
con.Inheritance.RDGatewayDomain + ";" +
con.Inheritance.RDPAlertIdleTimeout + ";" +
con.Inheritance.RDPMinutesToIdleTimeout + ";" +
con.Inheritance.SoundQuality;
}
_csv += csvLine;
}
/// <summary>
/// Remove text that is unsafe for use in CSV files
/// </summary>
/// <param name="text"></param>
private string CleanStringForCsv(object text)
{
return text.ToString().Replace(";", "");
}
private string GetNodePath(ConnectionInfo connectionInfo)
{
var nodePath = "";
var currentItem = connectionInfo;
while (currentItem != _serializationTarget)
{
currentItem = currentItem.Parent;
if (currentItem == null)
break;
nodePath += $@"{currentItem.Name}\";
}
nodePath = nodePath.TrimEnd('\\');
return nodePath;
}
}
}

View File

@@ -6,7 +6,7 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers
{
public class RemoteDesktopConnectionDeserializer : IDeserializer<string, ConnectionTreeModel>
public class RemoteDesktopConnectionDeserializer : IDeserializer<string, ConnectionTreeModel>
{
// .rdp file schema: https://technet.microsoft.com/en-us/library/ff393699(v=ws.10).aspx
@@ -59,19 +59,19 @@ namespace mRemoteNG.Config.Serializers
switch (value)
{
case "8":
connectionInfo.Colors = RdpProtocol.RDPColors.Colors256;
connectionInfo.Colors = RdpColors.Colors256;
break;
case "15":
connectionInfo.Colors = RdpProtocol.RDPColors.Colors15Bit;
connectionInfo.Colors = RdpColors.Colors15Bit;
break;
case "16":
connectionInfo.Colors = RdpProtocol.RDPColors.Colors16Bit;
connectionInfo.Colors = RdpColors.Colors16Bit;
break;
case "24":
connectionInfo.Colors = RdpProtocol.RDPColors.Colors24Bit;
connectionInfo.Colors = RdpColors.Colors24Bit;
break;
case "32":
connectionInfo.Colors = RdpProtocol.RDPColors.Colors32Bit;
connectionInfo.Colors = RdpColors.Colors32Bit;
break;
}
break;
@@ -79,7 +79,7 @@ namespace mRemoteNG.Config.Serializers
connectionInfo.CacheBitmaps = value == "1";
break;
case "screen mode id":
connectionInfo.Resolution = value == "2" ? RdpProtocol.RDPResolutions.Fullscreen : RdpProtocol.RDPResolutions.FitToWindow;
connectionInfo.Resolution = value == "2" ? RdpResolutions.Fullscreen : RdpResolutions.FitToWindow;
break;
case "connect to console":
connectionInfo.UseConsoleSession = value == "1";
@@ -112,13 +112,13 @@ namespace mRemoteNG.Config.Serializers
switch (value)
{
case "0":
connectionInfo.RedirectSound = RdpProtocol.RDPSounds.BringToThisComputer;
connectionInfo.RedirectSound = RdpSounds.BringToThisComputer;
break;
case "1":
connectionInfo.RedirectSound = RdpProtocol.RDPSounds.LeaveAtRemoteComputer;
connectionInfo.RedirectSound = RdpSounds.LeaveAtRemoteComputer;
break;
case "2":
connectionInfo.RedirectSound = RdpProtocol.RDPSounds.DoNotPlay;
connectionInfo.RedirectSound = RdpSounds.DoNotPlay;
break;
}
break;

View File

@@ -13,7 +13,7 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers
{
public class RemoteDesktopConnectionManagerDeserializer : IDeserializer<string, ConnectionTreeModel>
public class RemoteDesktopConnectionManagerDeserializer : IDeserializer<string, ConnectionTreeModel>
{
private static int _schemaVersion; /* 1 = RDCMan v2.2
3 = RDCMan v2.7 */
@@ -60,7 +60,7 @@ namespace mRemoteNG.Config.Serializers
}
else
{
var versionNode = rdcManNode?.SelectSingleNode("./version")?.InnerText;
var versionNode = rdcManNode.SelectSingleNode("./version")?.InnerText;
if (versionNode != null)
{
var version = new Version(versionNode);
@@ -101,16 +101,15 @@ namespace mRemoteNG.Config.Serializers
{
if (_schemaVersion == 1)
{
// Program Version 2.2 wraps all setting inside the Properties tags
// Program Verison 2.2 wraps all setting inside the Properties tags
containerPropertiesNode = containerPropertiesNode.SelectSingleNode("./properties");
}
var newContainer = new ContainerInfo();
var connectionInfo = ConnectionInfoFromXml(containerPropertiesNode);
newContainer.CopyFrom(connectionInfo);
if (_schemaVersion == 3)
{
// Program Version 2.7 wraps these properties
// Program Verison 2.7 wraps these properties
containerPropertiesNode = containerPropertiesNode.SelectSingleNode("./properties");
}
newContainer.Name = containerPropertiesNode?.SelectSingleNode("./name")?.InnerText ?? Language.strNewFolder;
@@ -131,22 +130,20 @@ namespace mRemoteNG.Config.Serializers
var propertiesNode = xmlNode.SelectSingleNode("./properties");
if (_schemaVersion == 1) propertiesNode = xmlNode; // Version 2.2 defines the container name at the root instead
connectionInfo.Hostname = propertiesNode?.SelectSingleNode("./name")?.InnerText ?? "";
connectionInfo.Name = propertiesNode?.SelectSingleNode("./displayName")?.InnerText ?? connectionInfo.Hostname;
connectionInfo.Description = propertiesNode?.SelectSingleNode("./comment")?.InnerText ?? string.Empty;
if (_schemaVersion == 1) propertiesNode = xmlNode; // Version 2.2 defines the container name at the root instead
connectionInfo.Hostname = propertiesNode.SelectSingleNode("./name")?.InnerText;
connectionInfo.Name = propertiesNode.SelectSingleNode("./displayName")?.InnerText ?? connectionInfo.Hostname;
connectionInfo.Description = propertiesNode.SelectSingleNode("./comment")?.InnerText ?? String.Empty;
var logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials");
if (logonCredentialsNode?.Attributes?["inherit"]?.Value == "None")
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);
connectionInfo.Password = passwordNode?.Attributes?["storeAsClearText"].Value == "True" ? passwordNode.InnerText : DecryptRdcManPassword(passwordNode?.InnerText);
}
else
{
@@ -163,7 +160,7 @@ namespace mRemoteNG.Config.Serializers
}
var connectionSettingsNode = xmlNode.SelectSingleNode("./connectionSettings");
if (connectionSettingsNode?.Attributes?["inherit"]?.Value == "None")
if (connectionSettingsNode?.Attributes?["inherit"].Value == "None")
{
connectionInfo.UseConsoleSession = bool.Parse(connectionSettingsNode.SelectSingleNode("./connectToConsole")?.InnerText ?? "false");
// ./startProgram
@@ -177,9 +174,9 @@ namespace mRemoteNG.Config.Serializers
}
var gatewaySettingsNode = xmlNode.SelectSingleNode("./gatewaySettings");
if (gatewaySettingsNode?.Attributes?["inherit"]?.Value == "None")
if (gatewaySettingsNode?.Attributes?["inherit"].Value == "None")
{
connectionInfo.RDGatewayUsageMethod = gatewaySettingsNode.SelectSingleNode("./enabled")?.InnerText == "True" ? RdpProtocol.RDGatewayUsageMethod.Always : RdpProtocol.RDGatewayUsageMethod.Never;
connectionInfo.RDGatewayUsageMethod = gatewaySettingsNode.SelectSingleNode("./enabled")?.InnerText == "True" ? RDGatewayUsageMethod.Always : RDGatewayUsageMethod.Never;
connectionInfo.RDGatewayHostname = gatewaySettingsNode.SelectSingleNode("./hostName")?.InnerText;
connectionInfo.RDGatewayUsername = gatewaySettingsNode.SelectSingleNode("./userName")?.InnerText;
@@ -201,31 +198,31 @@ namespace mRemoteNG.Config.Serializers
}
var remoteDesktopNode = xmlNode.SelectSingleNode("./remoteDesktop");
if (remoteDesktopNode?.Attributes?["inherit"]?.Value == "None")
if (remoteDesktopNode?.Attributes?["inherit"].Value == "None")
{
var resolutionString = remoteDesktopNode.SelectSingleNode("./size")?.InnerText.Replace(" ", "");
try
{
connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), "Res" + resolutionString);
connectionInfo.Resolution = (RdpResolutions)Enum.Parse(typeof(RdpResolutions), "Res" + resolutionString);
}
catch (ArgumentException)
{
connectionInfo.Resolution = RdpProtocol.RDPResolutions.FitToWindow;
connectionInfo.Resolution = RdpResolutions.FitToWindow;
}
if (remoteDesktopNode.SelectSingleNode("./sameSizeAsClientArea")?.InnerText == "True")
{
connectionInfo.Resolution = RdpProtocol.RDPResolutions.FitToWindow;
connectionInfo.Resolution = RdpResolutions.FitToWindow;
}
if (remoteDesktopNode.SelectSingleNode("./fullScreen")?.InnerText == "True")
{
connectionInfo.Resolution = RdpProtocol.RDPResolutions.Fullscreen;
connectionInfo.Resolution = RdpResolutions.Fullscreen;
}
var colorDepth = remoteDesktopNode.SelectSingleNode("./colorDepth")?.InnerText;
if (colorDepth != null)
connectionInfo.Colors = (RdpProtocol.RDPColors)Enum.Parse(typeof(RdpProtocol.RDPColors), colorDepth);
connectionInfo.Colors = (RdpColors)Enum.Parse(typeof(RdpColors), colorDepth);
}
else
{
@@ -234,22 +231,22 @@ namespace mRemoteNG.Config.Serializers
}
var localResourcesNode = xmlNode.SelectSingleNode("./localResources");
if (localResourcesNode?.Attributes?["inherit"]?.Value == "None")
if (localResourcesNode?.Attributes?["inherit"].Value == "None")
{
// ReSharper disable once SwitchStatementMissingSomeCases
switch (localResourcesNode.SelectSingleNode("./audioRedirection")?.InnerText)
{
case "0": // Bring to this computer
case "Client":
connectionInfo.RedirectSound = RdpProtocol.RDPSounds.BringToThisComputer;
connectionInfo.RedirectSound = RdpSounds.BringToThisComputer;
break;
case "1": // Leave at remote computer
case "Remote":
connectionInfo.RedirectSound = RdpProtocol.RDPSounds.LeaveAtRemoteComputer;
connectionInfo.RedirectSound = RdpSounds.LeaveAtRemoteComputer;
break;
case "2": // Do not play
case "NoSound":
connectionInfo.RedirectSound = RdpProtocol.RDPSounds.DoNotPlay;
connectionInfo.RedirectSound = RdpSounds.DoNotPlay;
break;
}
@@ -274,10 +271,10 @@ namespace mRemoteNG.Config.Serializers
}
// ./redirectClipboard
connectionInfo.RedirectDiskDrives = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectDrives")?.InnerText ?? "false");
connectionInfo.RedirectPorts = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectPorts")?.InnerText ?? "false");
connectionInfo.RedirectPrinters = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectPrinters")?.InnerText ?? "false");
connectionInfo.RedirectSmartCards = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectSmartCards")?.InnerText ?? "false");
connectionInfo.RedirectDiskDrives = bool.Parse(localResourcesNode.SelectSingleNode("./redirectDrives")?.InnerText ?? "false");
connectionInfo.RedirectPorts = bool.Parse(localResourcesNode.SelectSingleNode("./redirectPorts")?.InnerText ?? "false");
connectionInfo.RedirectPrinters = bool.Parse(localResourcesNode.SelectSingleNode("./redirectPrinters")?.InnerText ?? "false");
connectionInfo.RedirectSmartCards = bool.Parse(localResourcesNode.SelectSingleNode("./redirectSmartCards")?.InnerText ?? "false");
}
else
{
@@ -290,22 +287,22 @@ namespace mRemoteNG.Config.Serializers
}
var securitySettingsNode = xmlNode.SelectSingleNode("./securitySettings");
if (securitySettingsNode?.Attributes?["inherit"]?.Value == "None")
if (securitySettingsNode?.Attributes?["inherit"].Value == "None")
{
// ReSharper disable once SwitchStatementMissingSomeCases
switch (securitySettingsNode.SelectSingleNode("./authentication")?.InnerText)
{
case "0": // No authentication
case "None":
connectionInfo.RDPAuthenticationLevel = RdpProtocol.AuthenticationLevel.NoAuth;
connectionInfo.RDPAuthenticationLevel = RdpAuthenticationLevel.NoAuth;
break;
case "1": // Do not connect if authentication fails
case "Required":
connectionInfo.RDPAuthenticationLevel = RdpProtocol.AuthenticationLevel.AuthRequired;
connectionInfo.RDPAuthenticationLevel = RdpAuthenticationLevel.AuthRequired;
break;
case "2": // Warn if authentication fails
case "Warn":
connectionInfo.RDPAuthenticationLevel = RdpProtocol.AuthenticationLevel.WarnOnFailedAuth;
connectionInfo.RDPAuthenticationLevel = RdpAuthenticationLevel.WarnOnFailedAuth;
break;
}
}
@@ -324,7 +321,7 @@ namespace mRemoteNG.Config.Serializers
private static string DecryptRdcManPassword(string ciphertext)
{
if (string.IsNullOrEmpty(ciphertext))
return string.Empty;
return null;
try
{
@@ -335,7 +332,7 @@ namespace mRemoteNG.Config.Serializers
catch (Exception /*ex*/)
{
//Runtime.MessageCollector.AddExceptionMessage("RemoteDesktopConnectionManager.DecryptPassword() failed.", ex, logOnly: true);
return string.Empty;
return null;
}
}
}

Some files were not shown because too many files have changed in this diff Show More