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
280 changed files with 5917 additions and 11152 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 Before opening an issue, please search for a duplicate or closed issue.
<!--- If you're describing a bug, tell us what should happen --> Please provide as much detail as possible for us to fix your issue.
<!--- If you're suggesting a change/improvement, tell us how it should work --> -->
## Current Behavior <!-- Bug -->
<!--- If describing a bug, tell us what happens instead of the expected behavior --> |Detail|Value|
<!--- If suggesting a change/improvement, explain the difference from current behavior --> |--:|---|
|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) <!-- Feature Request -->
<!--- Provide an unambiguous set of steps to reproduce --> <!-- If you file a feature request, please delete the bug section -->
<!--- 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):

View File

@@ -1,29 +1,4 @@
<!--- Provide a general summary of your changes in the Title above --> <!--
Please provide as much detail as possible with what your pull request does.
## Description Include a reference to a filed issue if it exists.
<!--- 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.

View File

@@ -1,133 +1,12 @@
1.77.0 (2018-xx-xx): 1.76.0 Alpha 3 (2018-xx-xx):
Features/Enhancements:
----------------------
#1072: Russian translation improvements
#1016: Chinese (simplified) translation improvements
#928: Add context menu items to 'Close all but this' and 'Close all tabs to the right'
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):
Features/Enhancements: Features/Enhancements:
---------------------- ----------------------
#625: Added ability to import mRemoteNG formatted CSV files #625: Added ability to import mRemoteNG formatted CSV files
#648: The port scan ping timeout is now configurable
Fixes: Fixes:
------ ------
Fixed a few Xml serialization bugs that would occur if boolean values weren't capitalized
1.76.0 Alpha 2 (2018-02-01): 1.76.0 Alpha 2 (2018-02-01):

View File

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

8
Jenkinsfile vendored
View File

@@ -1,8 +1,8 @@
#!groovy
node('windows') { node('windows') {
def jobDir = pwd() def jobDir = pwd()
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\"" 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 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 openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe"
def reportGeneratorPath = "${jobDir}\\packages\\ReportGenerator.3.0.2\\tools\\ReportGenerator.exe" def reportGeneratorPath = "${jobDir}\\packages\\ReportGenerator.3.0.2\\tools\\ReportGenerator.exe"
@@ -24,11 +24,11 @@ node('windows') {
} }
stage ('Build mRemoteNG (Normal)') { 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)') { 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)') { stage ('Run Unit Tests (Normal, w/coverage)') {

View File

@@ -1,13 +1,9 @@
node('windows') { node('windows') {
def jobDir = pwd() def jobDir = pwd()
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\"" 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 nunitConsolePath = "${jobDir}\\packages\\NUnit.ConsoleRunner.3.7.0\\tools\\nunit3-console.exe" def vsExtensionsDir = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow"
def openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe" def nunitTestAdapterPath = "C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\VisualStudio\\14.0\\Extensions"
def testResultFilePrefix = "TestResult"
def testResultFileNormal = "${testResultFilePrefix}_UnitTests_normal.xml"
def testResultFilePortable = "${testResultFilePrefix}_UnitTests_portable.xml"
def coverageReport = "code_coverage_report.xml"
stage ('Clean output dir') { stage ('Clean output dir') {
@@ -36,24 +32,24 @@ node('windows') {
withCredentials([file(credentialsId: '9b674d57-6792-48e3-984a-4d1bab2abb64', variable: 'CODE_SIGNING_CERT')]) { 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')]) { withCredentials([usernamePassword(credentialsId: '05b7449b-05c0-490f-8661-236242526e62', passwordVariable: 'MRNG_CERT_PASSWORD', usernameVariable: 'NO_USERNAME')]) {
stage ('Build mRemoteNG (Normal - MSI)') { 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 archiveArtifacts artifacts: "Release\\*.msi", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
} }
stage ('Build mRemoteNG (Portable)') { 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 archiveArtifacts artifacts: "Release\\*.zip", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
} }
} }
} }
stage ('Run Unit Tests (Normal - MSI)') { stage ('Run Unit Tests (Normal - MSI)') {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release\\mRemoteNGTests.dll\" --result=${testResultFileNormal} --x86" bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release\\mRemoteNGTests.dll\""
} }
stage ('Run Unit Tests (Portable)') { stage ('Run Unit Tests (Portable)') {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release portable\\mRemoteNGTests.dll\" --result=${testResultFilePortable} --x86" bat "\"${vsToolsDir}\\VsDevCmd.bat\" && VSTest.Console.exe /logger:trx /TestAdapterPath:${nunitTestAdapterPath} \"${jobDir}\\mRemoteNGTests\\bin\\Release Portable\\mRemoteNGTests.dll\""
} }
stage ('Generate UpdateCheck Files') { stage ('Generate UpdateCheck Files') {
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\create_upg_chk_files.ps1\" -TagName \"${env.TagName}\" -UpdateChannel \"${env.UpdateChannel}\"" 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') { stage ('Publish to GitHub') {
withCredentials([string(credentialsId: '5443a369-dbe8-42d3-b4e8-04d0b4e9039a', variable: 'GH_AUTH_TOKEN')]) { 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 // 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() 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 | | 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) | | 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.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.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.76Alpha5/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76Alpha5) | | 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. 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 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. 7-Zip Extra files are under the GNU LGPL license.

View File

@@ -1,25 +1,6 @@
7-Zip Extra history 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 9.35 beta 2014-12-07
------------------------------ ------------------------------
- SFX modules were moved to LZMA SDK package. - 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 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. 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' $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 { function Publish-GitHubRelease {
param ( param (
@@ -171,27 +170,13 @@ function Upload-GitHubReleaseAsset {
[string] [string]
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
# The OAuth2 token to use for authentication. # The OAuth2 token to use for authentication.
$AuthToken, $AuthToken
[string]
# A short description label for the asset
$Label = ""
) )
$UploadUri = $UploadUri -replace "(\{[\w,\?]*\})$" $UploadUri = $UploadUri -replace "(\{[\w,\?]*\})$"
$files = Get-Item -Path $FilePath $file = Get-Item -Path $FilePath
$labelParam = "" $req_uploadZipAsset = Invoke-WebRequest -Uri "$($UploadUri)?name=$($file.Name)" -Method Post -Headers @{"Authorization"="token $AuthToken"} -ContentType $ContentType -InFile $file.FullName -ErrorAction Stop
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
}
} }

View File

@@ -45,6 +45,5 @@ Format-Table -AutoSize -Wrap -InputObject @{
& "$PSScriptRoot\verify_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName & "$PSScriptRoot\verify_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName & "$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\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\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\zip_symbols.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName & "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName

View File

@@ -43,8 +43,13 @@ param (
[string] [string]
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
# Path to the folder which contains release assets to upload # Path to the zip file to upload with the release
$ReleaseFolderPath, $ZipFilePath,
[string]
[Parameter(Mandatory=$true)]
#Path to the msi file to upload with the release
$MsiFilePath,
[string] [string]
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
@@ -65,17 +70,7 @@ if ($DescriptionIsBase64Encoded) {
. "$PSScriptRoot\github_functions.ps1" . "$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 $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)" $zipUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $ZipFilePath -ContentType "application/zip" -AuthToken $AuthToken
$msiUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $mrngNormalPath -ContentType "application/octet-stream" -AuthToken $AuthToken -Label "Normal Edition (msi)" $msiUpload = Upload-GitHubReleaseAsset -UploadUri $release.upload_url -FilePath $MsiFilePath -ContentType "application/octet-stream" -AuthToken $AuthToken
$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"
Write-Output (Get-GitHubRelease -Owner $Owner -Repository $Repository -ReleaseId $release.id -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 Write-Host $renameTarget
$targetVersionedFile = "$SolutionDir\mRemoteV1\bin\Release\mRemoteNG.exe" $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 $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" Write-Output "Removing unnecessary files from Release versions"
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force
$filesToDelete = Get-ChildItem -Path $TargetDir -Recurse -Include @( $filesToDelete = Get-ChildItem -Path $TargetDir -Recurse -Include @(
"*.pdb",
"*.publish", "*.publish",
"*.xml", "*.xml",
"*.backup", "*.backup",

View File

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

View File

@@ -13,49 +13,13 @@ param (
) )
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) =====" 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 # Package Zip
if ($ConfigurationName -eq "Release Portable") { if ($ConfigurationName -match "Release" -and $ConfigurationName -match "Portable") {
Write-Output "Packaging Release Portable ZIP" Write-Output "Packaging Release Portable ZIP"
& $path_packageZipScript
$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"
} }
else { else {
Write-Output "We will not zip anything - this isnt a portable release build." 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: pull_requests:
do_not_increment_build_number: true do_not_increment_build_number: true
image: Visual Studio 2017 image: Visual Studio 2017
configuration: configuration:
- Release - Release
- Release Portable - Release Portable
- Release Installer
platform: x86 platform: x86
clone_depth: 1 clone_depth: 1
install: install:
@@ -15,14 +14,7 @@ before_build:
build: build:
project: mRemoteV1.sln project: mRemoteV1.sln
verbosity: normal 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: test:
assemblies: assemblies:
only: only:
- mRemoteNGTests\bin\$(configuration)\mRemoteNGTests.dll - mRemoteNGTests\bin\$(configuration)\mRemoteNGTests.dll
artifacts:
- path: Release\*.msi
name: mRemoteNG-installer.msi
- path: Release\*.zip
name: mRemoteNG-portable.zip

View File

@@ -1,17 +0,0 @@
using System.Windows.Forms;
using NUnit.Framework;
// Dont put this in a namespace. Leaving it by itself tells NUnit
// to run it on assembly load
[SetUpFixture]
public class AssemblyTestSetup
{
[OneTimeSetUp]
public void AssemblySetup()
{
// ensure window options set before any test window created
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
}
}

View File

@@ -4,7 +4,6 @@ using System.Security;
using System.Xml.Linq; using System.Xml.Linq;
using mRemoteNG.Config; using mRemoteNG.Config;
using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Security; 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,19 +1,15 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows.Forms; using mRemoteNG.Config.Serializers;
using mRemoteNG.App;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Tree; using mRemoteNG.Tree;
using mRemoteNGTests.Properties; using mRemoteNGTests.Properties;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers
{ {
public class XmlConnectionsDeserializerTests public class XmlConnectionsDeserializerTests
{ {
@@ -22,10 +18,7 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
public void Setup(string confCons, string password) public void Setup(string confCons, string password)
{ {
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, _xmlConnectionsDeserializer = new XmlConnectionsDeserializer(password.ConvertToSecureString);
new Import(Substitute.For<IWin32Window>()),
Substitute.For<IWin32Window>());
_xmlConnectionsDeserializer = new XmlConnectionsDeserializer(connectionsService, Substitute.For<IWin32Window>(), () => password.ConvertToSecureString());
_connectionTreeModel = _xmlConnectionsDeserializer.Deserialize(confCons); _connectionTreeModel = _xmlConnectionsDeserializer.Deserialize(confCons);
} }
@@ -111,14 +104,6 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
Assert.That(folder22.Inheritance.Username, Is.True); 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) private bool ContainsNodeNamed(string name, IEnumerable<ConnectionInfo> list)
{ {
return list.Any(node => node.Name == name); return list.Any(node => node.Name == name);

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,7 +5,6 @@ using mRemoteNG.Connection;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Tree; using mRemoteNG.Tree;
using mRemoteNGTests.TestHelpers; using mRemoteNGTests.TestHelpers;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers namespace mRemoteNGTests.Config.Serializers
@@ -19,7 +18,7 @@ namespace mRemoteNGTests.Config.Serializers
{ {
var model = CreateConnectionTreeModel(); var model = CreateConnectionTreeModel();
var dataTable = CreateDataTable(model.RootNodes[0]); var dataTable = CreateDataTable(model.RootNodes[0]);
_deserializer = new DataTableDeserializer(Substitute.For<IConnectionsService>()); _deserializer = new DataTableDeserializer();
var output = _deserializer.Deserialize(dataTable); 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()));
} }
@@ -28,7 +27,7 @@ namespace mRemoteNGTests.Config.Serializers
public void WeCanDeserializeASingleEntry() public void WeCanDeserializeASingleEntry()
{ {
var dataTable = CreateDataTable(new ConnectionInfo()); var dataTable = CreateDataTable(new ConnectionInfo());
_deserializer = new DataTableDeserializer(Substitute.For<IConnectionsService>()); _deserializer = new DataTableDeserializer();
var output = _deserializer.Deserialize(dataTable); var output = _deserializer.Deserialize(dataTable);
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(1)); Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(1));
} }

View File

@@ -1,5 +1,4 @@
using System.Linq; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Security; using mRemoteNG.Security;
@@ -27,7 +26,7 @@ namespace mRemoteNGTests.Config.Serializers
{ {
var model = CreateConnectionTreeModel(); var model = CreateConnectionTreeModel();
var dataTable = _dataTableSerializer.Serialize(model); var dataTable = _dataTableSerializer.Serialize(model);
Assert.That(dataTable.Rows.Count, Is.EqualTo(model.GetRecursiveChildList().Count())); Assert.That(dataTable.Rows.Count, Is.EqualTo(3));
} }
[Test] [Test]

View File

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

View File

@@ -1,17 +1,13 @@
using System; using System;
using System.Linq;
using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Credential; using mRemoteNG.Credential;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Tree; using mRemoteNG.Tree;
using mRemoteNGTests.TestHelpers;
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv namespace mRemoteNGTests.Config.Serializers.MiscSerializers
{ {
public class CsvConnectionsSerializerMremotengFormatTests public class CsvConnectionsSerializerMremotengFormatTests
{ {
@@ -32,24 +28,6 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
_credentialRepositoryList.GetCredentialRecord(new Guid()).ReturnsForAnyArgs(credRecord); _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(Username)]
[TestCase(Domain)] [TestCase(Domain)]
[TestCase(Password)] [TestCase(Password)]
@@ -104,32 +82,6 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
Assert.Throws<ArgumentNullException>(() => serializer.Serialize((ConnectionTreeModel)null)); 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() private ConnectionInfo BuildConnectionInfo()
{ {
return new ConnectionInfo return new ConnectionInfo
@@ -141,16 +93,5 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Csv
Inheritance = {Colors = true} 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 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 // .rdp file schema: https://technet.microsoft.com/en-us/library/ff393699(v=ws.10).aspx
private RemoteDesktopConnectionDeserializer _deserializer; private RemoteDesktopConnectionDeserializer _deserializer;
@@ -18,9 +18,9 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
private const string ExpectedDomain = "myspecialdomain"; private const string ExpectedDomain = "myspecialdomain";
private const string ExpectedGatewayHostname = "gatewayhostname.domain.com"; private const string ExpectedGatewayHostname = "gatewayhostname.domain.com";
private const int ExpectedPort = 9933; 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 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 ExpectedWallpaperDisplay = true;
private const bool ExpectedThemesDisplay = true; private const bool ExpectedThemesDisplay = true;
private const bool ExpectedFontSmoothing = true; private const bool ExpectedFontSmoothing = true;
@@ -29,7 +29,7 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
private const bool ExpectedDriveRedirection = true; private const bool ExpectedDriveRedirection = true;
private const bool ExpectedPortRedirection = true; private const bool ExpectedPortRedirection = true;
private const bool ExpectedPrinterRedirection = true; private const bool ExpectedPrinterRedirection = true;
private const RdpProtocol.RDPSounds ExpectedSoundRedirection = RdpProtocol.RDPSounds.BringToThisComputer; private const RdpSounds ExpectedSoundRedirection = RdpSounds.BringToThisComputer;
[OneTimeSetUp] [OneTimeSetUp]

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,8 @@
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container;
using NUnit.Framework; using NUnit.Framework;
using System.Reflection;
using System.Collections; using System.Collections;
using System.Linq; using System.Linq;
using System.Reflection;
namespace mRemoteNGTests.Connection namespace mRemoteNGTests.Connection
{ {
@@ -75,22 +74,6 @@ namespace mRemoteNGTests.Connection
Assert.That(hasEverythingInheritedProperty, Is.False); 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() private bool AllInheritancePropertiesAreTrue()
{ {
var allPropertiesTrue = true; var allPropertiesTrue = true;

View File

@@ -5,7 +5,6 @@ using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.SSH; using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Tree.Root; using mRemoteNG.Tree.Root;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@@ -14,13 +13,11 @@ namespace mRemoteNGTests.Connection
public class ConnectionInfoTests public class ConnectionInfoTests
{ {
private ConnectionInfo _connectionInfo; private ConnectionInfo _connectionInfo;
private IConnectionsService _connectionsService;
private const string TestDomain = "somedomain"; private const string TestDomain = "somedomain";
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_connectionsService = Substitute.For<IConnectionsService>();
_connectionInfo = new ConnectionInfo(); _connectionInfo = new ConnectionInfo();
} }
@@ -30,6 +27,22 @@ namespace mRemoteNGTests.Connection
_connectionInfo = null; _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] [Test]
public void CopyCreatesMemberwiseCopy() public void CopyCreatesMemberwiseCopy()
{ {
@@ -46,20 +59,6 @@ namespace mRemoteNGTests.Connection
Assert.That(clonedConnection.Parent, Is.Null); 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] [Test]
public void CopyFromCopiesProperties() public void CopyFromCopiesProperties()
{ {
@@ -82,7 +81,7 @@ namespace mRemoteNGTests.Connection
{ {
var eventWasCalled = false; var eventWasCalled = false;
_connectionInfo.PropertyChanged += (sender, args) => eventWasCalled = true; _connectionInfo.PropertyChanged += (sender, args) => eventWasCalled = true;
_connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionsService)); _connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionInfo));
Assert.That(eventWasCalled); Assert.That(eventWasCalled);
} }
@@ -91,7 +90,7 @@ namespace mRemoteNGTests.Connection
{ {
var nameOfModifiedProperty = ""; var nameOfModifiedProperty = "";
_connectionInfo.PropertyChanged += (sender, args) => nameOfModifiedProperty = args.PropertyName; _connectionInfo.PropertyChanged += (sender, args) => nameOfModifiedProperty = args.PropertyName;
_connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionsService)); _connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionInfo));
Assert.That(nameOfModifiedProperty, Is.EqualTo("OpenConnections")); Assert.That(nameOfModifiedProperty, Is.EqualTo("OpenConnections"));
} }

View File

@@ -1,62 +1,73 @@
using System.Collections.Generic; using mRemoteNG.Connection;
using System.Reflection; using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection;
using mRemoteNGTests.TestHelpers;
using NUnit.Framework; using NUnit.Framework;
namespace mRemoteNGTests.Connection namespace mRemoteNGTests.Connection
{ {
public class DefaultConnectionInfoTests public class DefaultConnectionInfoTests
{ {
private ConnectionInfo _randomizedConnectionInfo; private string _testDomain = "somedomain";
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_randomizedConnectionInfo = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); DefaultConnectionInfo.Instance.Domain = "";
} }
[TestCaseSource(nameof(GetConnectionInfoProperties))] [Test]
public void LoadingDefaultInfoUpdatesAllProperties(PropertyInfo property) public void LoadingDefaultInfoUpdatesAllProperties()
{ {
DefaultConnectionInfo.Instance.LoadFrom(_randomizedConnectionInfo); var connectionInfoSource = new ConnectionInfo { Domain = _testDomain };
var valueInDestination = property.GetValue(DefaultConnectionInfo.Instance); DefaultConnectionInfo.Instance.LoadFrom(connectionInfoSource);
var valueInSource = property.GetValue(_randomizedConnectionInfo); Assert.That(DefaultConnectionInfo.Instance.Domain, Is.EqualTo(_testDomain));
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
} }
[TestCaseSource(nameof(GetConnectionInfoProperties))] [Test]
public void SavingDefaultConnectionInfoExportsAllProperties(PropertyInfo property) public void SavingDefaultConnectionInfoExportsAllProperties()
{ {
var saveTarget = new ConnectionInfo(); var saveTarget = new ConnectionInfo();
var randomizedValue = property.GetValue(_randomizedConnectionInfo); DefaultConnectionInfo.Instance.Domain = _testDomain;
property.SetValue(DefaultConnectionInfo.Instance, randomizedValue);
DefaultConnectionInfo.Instance.SaveTo(saveTarget); DefaultConnectionInfo.Instance.SaveTo(saveTarget);
var valueInDestination = property.GetValue(saveTarget); Assert.That(saveTarget.Domain, Is.EqualTo(_testDomain));
var valueInSource = property.GetValue(DefaultConnectionInfo.Instance);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
} }
[TestCaseSource(nameof(GetConnectionInfoProperties))] [Test]
public void CanSaveDefaultConnectionToModelWithAllStringProperties(PropertyInfo property) public void CanSaveEnumValuesToString()
{ {
var saveTarget = new SerializableConnectionInfoAllPropertiesOfType<string>(); const ProtocolType targetProtocol = ProtocolType.RAW;
var saveTarget = new AllStringPropertySaveTarget();
// randomize default connnection values to ensure we dont get false passing tests DefaultConnectionInfo.Instance.Protocol = targetProtocol;
var randomizedValue = property.GetValue(_randomizedConnectionInfo);
property.SetValue(DefaultConnectionInfo.Instance, randomizedValue);
DefaultConnectionInfo.Instance.SaveTo(saveTarget); DefaultConnectionInfo.Instance.SaveTo(saveTarget);
Assert.That(saveTarget.Protocol, Is.EqualTo(targetProtocol.ToString()));
var valueInSource = property.GetValue(DefaultConnectionInfo.Instance).ToString();
var valueInDestination = saveTarget.GetType().GetProperty(property.Name).GetValue(saveTarget).ToString();
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
} }
private static IEnumerable<PropertyInfo> GetConnectionInfoProperties() [Test]
{ public void CanSaveIntegerValuesToString()
return new ConnectionInfo().GetSerializableProperties(); {
} 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 mRemoteNG.Connection;
using System.Reflection;
using mRemoteNG.Connection;
using NUnit.Framework; using NUnit.Framework;
namespace mRemoteNGTests.Connection namespace mRemoteNGTests.Connection
{ {
public class DefaultConnectionInheritanceTests public class DefaultConnectionInheritanceTests
{ {
[TestCaseSource(nameof(GetInheritanceProperties))] [SetUp]
public void LoadingDefaultInheritanceUpdatesAllProperties(PropertyInfo property) 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(); inheritanceSource.TurnOnInheritanceCompletely();
DefaultConnectionInheritance.Instance.TurnOffInheritanceCompletely();
DefaultConnectionInheritance.Instance.LoadFrom(inheritanceSource); DefaultConnectionInheritance.Instance.LoadFrom(inheritanceSource);
Assert.That(DefaultConnectionInheritance.Instance.EverythingInherited, Is.True);
}
var valueInDestination = property.GetValue(DefaultConnectionInheritance.Instance); [Test]
var valueInSource = property.GetValue(inheritanceSource); public void SavingDefaultInheritanceExportsAllProperties()
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
}
[TestCaseSource(nameof(GetInheritanceProperties))]
public void SavingDefaultInheritanceExportsAllProperties(PropertyInfo property)
{ {
var saveTarget = new ConnectionInfoInheritance(new object(), true); var inheritanceDestination = new ConnectionInfoInheritance(new object(), true);
saveTarget.TurnOffInheritanceCompletely(); DefaultConnectionInheritance.Instance.AutomaticResize = true;
DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely(); DefaultConnectionInheritance.Instance.SaveTo(inheritanceDestination);
Assert.That(inheritanceDestination.AutomaticResize, Is.True);
DefaultConnectionInheritance.Instance.SaveTo(saveTarget); }
var valueInDestination = property.GetValue(saveTarget);
var valueInSource = property.GetValue(DefaultConnectionInheritance.Instance);
Assert.That(valueInDestination, Is.EqualTo(valueInSource));
}
[Test] [Test]
public void NewInheritanceInstancesCreatedWithDefaultInheritanceValues() public void NewInheritanceInstancesCreatedWithDefaultInheritanceValues()
@@ -44,20 +38,12 @@ namespace mRemoteNGTests.Connection
Assert.That(inheritanceInstance.Domain, Is.True); Assert.That(inheritanceInstance.Domain, Is.True);
} }
[TestCaseSource(nameof(GetInheritanceProperties))] [Test]
public void NewInheritanceInstancesCreatedWithAllDefaultInheritanceValues(PropertyInfo property) public void NewInheritanceInstancesCreatedWithAllDefaultInheritanceValues()
{ {
DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely(); DefaultConnectionInheritance.Instance.TurnOnInheritanceCompletely();
var inheritanceInstance = new ConnectionInfoInheritance(new object()); var inheritanceInstance = new ConnectionInfoInheritance(new object());
Assert.That(inheritanceInstance.EverythingInherited, Is.True);
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();
}
}
} }

View File

@@ -1,51 +1,31 @@
using System; using mRemoteNG.App;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Tools; using mRemoteNG.Tools;
using mRemoteNG.UI.Controls; using mRemoteNG.Tools.CustomCollections;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window; using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking; using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.Connection.Protocol namespace mRemoteNGTests.Connection.Protocol
{ {
public class IntegratedProgramTests public class IntegratedProgramTests
{ {
private ExternalToolsService _externalToolsService; private readonly ExternalTool _extTool = new ExternalTool
private IConnectionInitiator _connectionInitiator; {
DisplayName = "notepad",
FileName = @"%windir%\system32\notepad.exe",
Arguments = "",
TryIntegrate = true
};
[OneTimeSetUp] [Test]
public void OneTimeSetUp()
{
_connectionInitiator = Substitute.For<IConnectionInitiator>();
var extTool = new ExternalTool(_connectionInitiator, Substitute.For<IConnectionsService>())
{
DisplayName = "notepad",
FileName = @"%windir%\system32\notepad.exe",
Arguments = "",
TryIntegrate = true
};
_externalToolsService = new ExternalToolsService();
_externalToolsService.ExternalTools.Add(extTool);
}
[Test]
[Apartment(ApartmentState.STA)]
public void CanStartExternalApp() public void CanStartExternalApp()
{ {
var sut = new IntegratedProgram(_externalToolsService, Substitute.For<IConnectionsService>()); SetExternalToolList(_extTool);
sut.InterfaceControl = BuildInterfaceControl("notepad", sut); var connectionInfo = new ConnectionInfo { ExtApp = _extTool.DisplayName };
var sut = new IntegratedProgram(connectionInfo);
sut.InterfaceControl = BuildInterfaceControl(sut);
sut.Initialize(); sut.Initialize();
var appStarted = sut.Connect(); var appStarted = sut.Connect();
sut.Disconnect(); sut.Disconnect();
@@ -53,44 +33,25 @@ namespace mRemoteNGTests.Connection.Protocol
} }
[Test] [Test]
[Apartment(ApartmentState.STA)]
public void ConnectingToExternalAppThatDoesntExistDoesNothing() public void ConnectingToExternalAppThatDoesntExistDoesNothing()
{ {
var sut = new IntegratedProgram(_externalToolsService, Substitute.For<IConnectionsService>()); SetExternalToolList(_extTool);
sut.InterfaceControl = BuildInterfaceControl("doesntExist", sut); var connectionInfo = new ConnectionInfo { ExtApp = "doesntExist" };
var sut = new IntegratedProgram(connectionInfo);
sut.InterfaceControl = BuildInterfaceControl(sut);
var appInitialized = sut.Initialize(); var appInitialized = sut.Initialize();
Assert.That(appInitialized, Is.False); Assert.That(appInitialized, Is.False);
} }
private InterfaceControl BuildInterfaceControl(string extAppName, ProtocolBase sut) private void SetExternalToolList(ExternalTool externalTool)
{ {
var frmMain = new FrmMain(); Runtime.ExternalToolsService.ExternalTools = new FullyObservableCollection<ExternalTool> {externalTool};
var import = new Import(Substitute.For<IWin32Window>()); }
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, import, frmMain);
var configWindow = new ConfigWindow(new DockContent(), connectionsService); private InterfaceControl BuildInterfaceControl(ProtocolBase sut)
var sshTransferWindow = new SSHTransferWindow(); {
var connectionTreeWindow = new ConnectionTreeWindow(new DockContent(), _connectionInitiator, connectionsService); var connectionWindow = new ConnectionWindow(new DockContent());
Func<SecureString> encryptionKeySelectionFunc = () => connectionsService.EncryptionKey; return new InterfaceControl(connectionWindow, sut);
var connectionTree = connectionTreeWindow.ConnectionTree;
var export = new Export(new CredentialRepositoryList(), connectionsService, frmMain);
var connectionTreeContextMenu = new ConnectionContextMenu(connectionTree, _connectionInitiator, sshTransferWindow, export, _externalToolsService, import, connectionsService);
connectionTreeWindow.ConnectionTreeContextMenu = connectionTreeContextMenu;
var errorAndInfoWindow = new ErrorAndInfoWindow(new DockContent(), new DockPanel(), connectionTreeWindow);
var screenshotManagerWindow = new ScreenshotManagerWindow(new DockContent(), new DockPanel());
var shutdown = new Shutdown(new SettingsSaver(new ExternalToolsService()), new ConnectionsService(PuttySessionsManager.Instance, import, frmMain), frmMain);
var appUpdater = new AppUpdater(encryptionKeySelectionFunc);
Func<UpdateWindow> updateWindowBuilder = () => new UpdateWindow(new DockContent(), shutdown, appUpdater);
Func<NotificationAreaIcon> notificationAreaIconBuilder = () => new NotificationAreaIcon(frmMain, _connectionInitiator, shutdown, connectionsService);
Func<ExternalToolsWindow> externalToolsWindowBuilder = () => new ExternalToolsWindow(_connectionInitiator, _externalToolsService, () => connectionTree.SelectedNode, frmMain, connectionsService);
Func<PortScanWindow> portScanWindowBuilder = () => new PortScanWindow(connectionTreeWindow, import);
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder = () => new ActiveDirectoryImportWindow(() => connectionTreeWindow.SelectedNode, import, connectionsService);
var databaseConnectorFactory = new DatabaseConnectorFactory(encryptionKeySelectionFunc);
var windows = new Windows(_connectionInitiator, connectionTreeWindow, configWindow, errorAndInfoWindow, screenshotManagerWindow,
sshTransferWindow, updateWindowBuilder, notificationAreaIconBuilder, externalToolsWindowBuilder,
connectionsService, portScanWindowBuilder, activeDirectoryImportWindowBuilder, appUpdater, databaseConnectorFactory, frmMain);
var connectionWindow = new ConnectionWindow(new DockContent(), _connectionInitiator, windows, _externalToolsService, frmMain);
var connectionInfo = new ConnectionInfo {ExtApp = extAppName};
return new InterfaceControl(connectionWindow, sut, connectionInfo);
} }
} }
} }

View File

@@ -1,12 +1,10 @@
using System.Collections; using System.Collections;
using System.Collections.Specialized; using System.Collections.Specialized;
using mRemoteNG.Config.Putty;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.SSH; using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Connection.Protocol.Telnet; using mRemoteNG.Connection.Protocol.Telnet;
using mRemoteNG.Connection.Protocol.VNC; using mRemoteNG.Connection.Protocol.VNC;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@@ -23,11 +21,10 @@ namespace mRemoteNGTests.Connection.Protocol
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
var connectionService = Substitute.For<IConnectionsService>();
_protocolList = new ProtocolList(); _protocolList = new ProtocolList();
_protocol1 = new ProtocolTelnet(connectionService); _protocol1 = new ProtocolTelnet(new ConnectionInfo());
_protocol2 = new ProtocolSSH2(connectionService); _protocol2 = new ProtocolSSH2(new ConnectionInfo());
_protocol3 = new ProtocolVNC(); _protocol3 = new ProtocolVNC(new ConnectionInfo());
} }
[TearDown] [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,16 +1,11 @@
using System; using System.Linq;
using System.Linq; using mRemoteNG.Config.Serializers;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Security.Factories; using mRemoteNG.Security.Factories;
using mRemoteNG.Tree; using mRemoteNG.Tree;
using mRemoteNG.Tree.Root; using mRemoteNG.Tree.Root;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@@ -33,20 +28,20 @@ namespace mRemoteNGTests.IntegrationTests
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(), _originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
new SaveFilter()); new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer); _serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
var mockWindow = Substitute.For<IWin32Window>();
_deserializer = new XmlConnectionsDeserializer(new ConnectionsService(PuttySessionsManager.Instance, new Import(mockWindow), mockWindow), mockWindow);
} }
[TearDown] [TearDown]
public void Teardown() public void Teardown()
{ {
_serializer = null; _serializer = null;
_deserializer = null;
} }
[Test] [Test]
public void SerializeThenDeserialize() public void SerializeThenDeserialize()
{ {
var serializedContent = _serializer.Serialize(_originalModel); var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent); var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name); var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name); var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
@@ -58,6 +53,7 @@ namespace mRemoteNGTests.IntegrationTests
{ {
_serializer.UseFullEncryption = true; _serializer.UseFullEncryption = true;
var serializedContent = _serializer.Serialize(_originalModel); var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent); var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name); var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name); var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
@@ -69,6 +65,7 @@ namespace mRemoteNGTests.IntegrationTests
{ {
var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" }; var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" };
var serializedContent = _serializer.Serialize(originalConnectionInfo); var serializedContent = _serializer.Serialize(originalConnectionInfo);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent); var deserializedModel = _deserializer.Deserialize(serializedContent);
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name); var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description)); Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description));
@@ -86,26 +83,13 @@ namespace mRemoteNGTests.IntegrationTests
new SaveFilter()); new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer); _serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
var serializedContent = _serializer.Serialize(_originalModel); var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent); var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name); var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name); var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel)); 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() private ConnectionTreeModel SetupConnectionTreeModel()
{ {
@@ -142,4 +126,4 @@ namespace mRemoteNGTests.IntegrationTests
return connectionTreeModel; return connectionTreeModel;
} }
} }
} }

View File

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

View File

@@ -2,7 +2,6 @@
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Security.Authentication; using mRemoteNG.Security.Authentication;
using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
using NUnit.Framework; using NUnit.Framework;
@@ -10,31 +9,35 @@ namespace mRemoteNGTests.Security.Authentication
{ {
public class PasswordAuthenticatorTests public class PasswordAuthenticatorTests
{ {
private ICryptographyProvider _cryptographyProvider; private PasswordAuthenticator _authenticator;
private string _cipherText;
private readonly SecureString _correctPassword = "9theCorrectPass#5".ConvertToSecureString(); private readonly SecureString _correctPassword = "9theCorrectPass#5".ConvertToSecureString();
private readonly SecureString _wrongPassword = "wrongPassword".ConvertToSecureString(); private readonly SecureString _wrongPassword = "wrongPassword".ConvertToSecureString();
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_cryptographyProvider = new AeadCryptographyProvider {KeyDerivationIterations = 10000}; var cryptoProvider = new AeadCryptographyProvider {KeyDerivationIterations = 10000};
_cipherText = "MPELiwk7+xeNlruIyt5uxTvVB+/RLVoLdUGnwY4CWCqwKe7T2IBwWo4oaKum5hdv7447g5m2nZsYPrfARSlotQB4r1KZQg=="; const string cipherText = "MPELiwk7+xeNlruIyt5uxTvVB+/RLVoLdUGnwY4CWCqwKe7T2IBwWo4oaKum5hdv7447g5m2nZsYPrfARSlotQB4r1KZQg==";
_authenticator = new PasswordAuthenticator(cryptoProvider, cipherText);
}
[TearDown]
public void Teardown()
{
_authenticator = null;
} }
[Test] [Test]
public void AuthenticatingWithCorrectPasswordReturnsTrue() 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); Assert.That(authenticated);
} }
[Test] [Test]
public void AuthenticatingWithWrongPasswordReturnsFalse() 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); Assert.That(!authenticated);
} }
@@ -42,15 +45,12 @@ namespace mRemoteNGTests.Security.Authentication
public void AuthenticationRequestorIsCalledWhenInitialPasswordIsWrong() public void AuthenticationRequestorIsCalledWhenInitialPasswordIsWrong()
{ {
var wasCalled = false; var wasCalled = false;
_authenticator.AuthenticationRequestor = () =>
Optional<SecureString> AuthenticationRequestor()
{ {
wasCalled = true; wasCalled = true;
return _correctPassword; return _correctPassword;
} };
_authenticator.Authenticate(_wrongPassword);
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor);
authenticator.Authenticate(_wrongPassword);
Assert.That(wasCalled); Assert.That(wasCalled);
} }
@@ -58,30 +58,28 @@ namespace mRemoteNGTests.Security.Authentication
public void AuthenticationRequestorNotCalledWhenInitialPasswordIsCorrect() public void AuthenticationRequestorNotCalledWhenInitialPasswordIsCorrect()
{ {
var wasCalled = false; var wasCalled = false;
Optional<SecureString> AuthenticationRequestor() _authenticator.AuthenticationRequestor = () =>
{ {
wasCalled = true; wasCalled = true;
return _correctPassword; return _correctPassword;
} };
_authenticator.Authenticate(_correctPassword);
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor);
authenticator.Authenticate(_correctPassword);
Assert.That(!wasCalled); Assert.That(!wasCalled);
} }
[Test] [Test]
public void ProvidingCorrectPasswordToTheAuthenticationRequestorReturnsTrue() public void ProvidingCorrectPasswordToTheAuthenticationRequestorReturnsTrue()
{ {
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, () => _correctPassword); _authenticator.AuthenticationRequestor = () => _correctPassword;
var authenticated = authenticator.Authenticate(_wrongPassword); var authenticated = _authenticator.Authenticate(_wrongPassword);
Assert.That(authenticated); Assert.That(authenticated);
} }
[Test] [Test]
public void AuthenticationFailsWhenAuthenticationRequestorGivenEmptyPassword() public void AuthenticationFailsWhenAuthenticationRequestorGivenEmptyPassword()
{ {
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, () => new SecureString()); _authenticator.AuthenticationRequestor = () => new SecureString();
var authenticated = authenticator.Authenticate(_wrongPassword); var authenticated = _authenticator.Authenticate(_wrongPassword);
Assert.That(!authenticated); Assert.That(!authenticated);
} }
@@ -89,34 +87,27 @@ namespace mRemoteNGTests.Security.Authentication
public void AuthenticatorRespectsMaxAttempts() public void AuthenticatorRespectsMaxAttempts()
{ {
var authAttempts = 0; var authAttempts = 0;
Optional<SecureString> AuthenticationRequestor() _authenticator.AuthenticationRequestor = () =>
{ {
authAttempts++; authAttempts++;
return _wrongPassword; return _wrongPassword;
} };
_authenticator.Authenticate(_wrongPassword);
var authenticator = new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor); Assert.That(authAttempts == _authenticator.MaxAttempts);
authenticator.Authenticate(_wrongPassword);
Assert.That(authAttempts == authenticator.MaxAttempts);
} }
[Test] [Test]
public void AuthenticatorRespectsMaxAttemptsCustomValue() public void AuthenticatorRespectsMaxAttemptsCustomValue()
{ {
const int customMaxAttempts = 5; const int customMaxAttempts = 5;
_authenticator.MaxAttempts = customMaxAttempts;
var authAttempts = 0; var authAttempts = 0;
Optional<SecureString> AuthenticationRequestor() _authenticator.AuthenticationRequestor = () =>
{ {
authAttempts++; authAttempts++;
return _wrongPassword; return _wrongPassword;
} };
_authenticator.Authenticate(_wrongPassword);
var authenticator =
new PasswordAuthenticator(_cryptographyProvider, _cipherText, AuthenticationRequestor)
{
MaxAttempts = customMaxAttempts
};
authenticator.Authenticate(_wrongPassword);
Assert.That(authAttempts == customMaxAttempts); 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 public class ConnectionTreeModelBuilder
{ {
/// <summary>
/// Builds a tree which looks like:
/// Root
/// |- folder1
/// | |- con1
/// |- con2
/// |- folder2
/// |- folder3
/// |- con3
/// </summary>
/// <returns></returns>
public ConnectionTreeModel Build() public ConnectionTreeModel Build()
{ {
var model = new ConnectionTreeModel(); var model = new ConnectionTreeModel();
var root = new RootNodeInfo(RootNodeType.Connection); var root = new RootNodeInfo(RootNodeType.Connection);
var folder1 = new ContainerInfo { Name = "folder1", Username = "user1", Domain = "domain1", Password = "password1" }; 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 con1 = new ConnectionInfo { Name = "Con1", Username = "user1", Domain = "domain1", Password = "password1" };
var con2 = new ConnectionInfo { Name = "Con2", Username = "user2", Domain = "domain2", Password = "password2" }; 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(folder1);
root.AddChild(con2); root.AddChild(con2);
folder1.AddChild(con1); folder1.AddChild(con1);
root.AddChild(folder2);
folder2.AddChild(folder3);
folder3.AddChild(con3);
model.AddRootNode(root); model.AddRootNode(root);
return model; return model;
} }

View File

@@ -1,64 +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 RedirectClipboard { 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

@@ -2,7 +2,6 @@
using System.Collections; using System.Collections;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Tools; using mRemoteNG.Tools;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@@ -35,7 +34,7 @@ namespace mRemoteNGTests.Tools
MacAddress = TestString, MacAddress = TestString,
UserField = TestString UserField = TestString
}; };
_argumentParser = new ExternalToolArgumentParser(connectionInfo, Substitute.For<IConnectionsService>()); _argumentParser = new ExternalToolArgumentParser(connectionInfo);
} }
[OneTimeTearDown] [OneTimeTearDown]
@@ -53,7 +52,7 @@ namespace mRemoteNGTests.Tools
[Test] [Test]
public void NullConnectionInfoResultsInEmptyVariables() public void NullConnectionInfoResultsInEmptyVariables()
{ {
var parser = new ExternalToolArgumentParser(null, Substitute.For<IConnectionsService>()); var parser = new ExternalToolArgumentParser(null);
var parsedText = parser.ParseArguments("test %USERNAME% test"); var parsedText = parser.ParseArguments("test %USERNAME% test");
Assert.That(parsedText, Is.EqualTo("test test")); Assert.That(parsedText, Is.EqualTo("test test"));
} }

View File

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

View File

@@ -1,50 +0,0 @@
using System;
using System.Linq;
using mRemoteNG.Tools.WindowsRegistry;
using NUnit.Framework;
namespace mRemoteNGTests.Tools.Registry
{
public class WindowsRegistryTests
{
private WindowsRegistry _registry;
[SetUp]
public void Setup()
{
_registry = new WindowsRegistry();
}
[Test]
public void CanGetSubkeyNames()
{
var subKeyNames = _registry.GetSubKeyNames(RegistryHive.CurrentUser, "Software");
Assert.That(subKeyNames, Does.Contain("Microsoft"));
}
[Test]
public void GetSubkeyNamesThrowsIfGivenNullKeyPath()
{
Assert.Throws<ArgumentNullException>(() => _registry.GetSubKeyNames(RegistryHive.CurrentUser, null));
}
[Test]
public void CanGetKeyValue()
{
var keyValue = _registry.GetKeyValue(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
Assert.That(keyValue.FirstOrDefault(), Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
}
[Test]
public void GetKeyValueThrowsIfGivenNullKeyPath()
{
Assert.Throws<ArgumentNullException>(() => _registry.GetKeyValue(RegistryHive.CurrentUser, null, ""));
}
[Test]
public void GetKeyValueThrowsIfGivenNullPropertyName()
{
Assert.Throws<ArgumentNullException>(() => _registry.GetKeyValue(RegistryHive.CurrentUser, "", null));
}
}
}

View File

@@ -8,7 +8,7 @@ using NUnit.Framework;
namespace mRemoteNGTests.Tree namespace mRemoteNGTests.Tree
{ {
public class NodeSearcherTests public class NodeSearcherTests
{ {
private NodeSearcher _nodeSearcher; private NodeSearcher _nodeSearcher;
private ContainerInfo _folder1; private ContainerInfo _folder1;
@@ -104,14 +104,6 @@ namespace mRemoteNGTests.Tree
_con4 = new ConnectionInfo { Name = "con4", Description="description6", Hostname="hostname6" }; _con4 = new ConnectionInfo { Name = "con4", Description="description6", Hostname="hostname6" };
_con5 = new ConnectionInfo { Name = "con5", Description="description7", Hostname="hostname7" }; _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); connectionTreeModel.AddRootNode(root);
root.AddChildRange(new [] { _folder1, _folder2, _con5 }); root.AddChildRange(new [] { _folder1, _folder2, _con5 });
_folder1.AddChildRange(new [] { _con1, _con2 }); _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; using NUnit.Framework;
@@ -47,13 +46,5 @@ namespace mRemoteNGTests.Tree
_rootNodeInfo.PasswordString = password; _rootNodeInfo.PasswordString = password;
Assert.That(_rootNodeInfo.PasswordString, Is.EqualTo(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,49 +0,0 @@
using System;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Controls
{
public class ExternalToolsToolStripTests
{
private ExternalToolsToolStrip _externalToolsToolStrip;
[SetUp]
public void Setup()
{
_externalToolsToolStrip = new ExternalToolsToolStrip();
}
[TearDown]
public void Teardown()
{
_externalToolsToolStrip.Dispose();
}
[Test]
public void SettingExternalToolsServiceToNullThrowsException()
{
Assert.Throws<ArgumentNullException>(() => _externalToolsToolStrip.ExternalToolsService = null);
}
[Test]
public void AddExternalToolsToToolBarCreatesControlsForAllExternalTools()
{
var externaltoolsService = new ExternalToolsService();
externaltoolsService.ExternalTools.Add(BuildExternalTool());
externaltoolsService.ExternalTools.Add(BuildExternalTool());
_externalToolsToolStrip.ExternalToolsService = externaltoolsService;
_externalToolsToolStrip.AddExternalToolsToToolBar();
Assert.That(_externalToolsToolStrip.Items.Count, Is.EqualTo(2));
}
private ExternalTool BuildExternalTool()
{
return new ExternalTool(Substitute.For<IConnectionInitiator>(), Substitute.For<IConnectionsService>());
}
}
}

View File

@@ -6,6 +6,7 @@ namespace mRemoteNGTests.UI.Controls
{ {
public TextBoxExtensionsTestForm() public TextBoxExtensionsTestForm()
{ {
Application.EnableVisualStyles();
InitializeComponent(); InitializeComponent();
} }
} }

View File

@@ -30,8 +30,7 @@ namespace mRemoteNGTests.UI.Controls
{ {
const string text = "Type Here"; const string text = "Type Here";
var textBox = new TextBoxTester(_textBoxExtensionsTestForm.textBox1.Name); var textBox = new TextBoxTester(_textBoxExtensionsTestForm.textBox1.Name);
var textWasSet = textBox.Properties.SetCueBannerText(text); Assert.That(textBox.Properties.SetCueBannerText(text), Is.True);
Assert.That(textWasSet, Is.True);
} }
[Test] [Test]

View File

@@ -1,16 +0,0 @@
using System.Threading;
using mRemoteNG.UI.Forms;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Forms
{
public class FrmMainTests
{
[Test]
[Apartment(ApartmentState.STA)]
public void CanCreateFrmMain()
{
var frmMain = new FrmMain();
}
}
}

View File

@@ -1,24 +1,9 @@
using System; using NUnit.Framework;
using System.Security;
using System.Windows.Forms;
using System.Xml.Linq;
using mRemoteNG.App;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms; using mRemoteNG.UI.Forms;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Forms namespace mRemoteNGTests.UI.Forms
{ {
public class OptionsFormSetupAndTeardown public class OptionsFormSetupAndTeardown
{ {
protected frmOptions _optionsForm; protected frmOptions _optionsForm;
@@ -30,16 +15,7 @@ namespace mRemoteNGTests.UI.Forms
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
var frmMain = new FrmMain(); _optionsForm = new frmOptions();
var connectionInitiator = Substitute.For<IConnectionInitiator>();
var import = new Import(Substitute.For<IWin32Window>());
var shutdown = new Shutdown(new SettingsSaver(new ExternalToolsService()), new ConnectionsService(PuttySessionsManager.Instance, import, frmMain), frmMain);
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, import, frmMain);
Func<NotificationAreaIcon> notificationIconBuilder = () => new NotificationAreaIcon(frmMain, connectionInitiator, shutdown, connectionsService);
Func<SecureString> encryptionKeySelectionFunc = () => connectionsService.EncryptionKey;
var databaseConnectorFactory = new DatabaseConnectorFactory(encryptionKeySelectionFunc);
var appUpdater = new AppUpdater(encryptionKeySelectionFunc);
_optionsForm = new frmOptions(connectionInitiator, type => {}, notificationIconBuilder, connectionsService, appUpdater, databaseConnectorFactory, frmMain);
_optionsForm.Show(); _optionsForm.Show();
} }

View File

@@ -1,227 +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 NSubstitute;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
public class ConfigWindowGeneralTests
{
private ConfigWindow _configWindow;
[SetUp]
public void Setup()
{
_configWindow = new ConfigWindow(new DockContent(), Substitute.For<IConnectionsService>())
{
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.RedirectClipboard),
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,39 +0,0 @@
using System.Collections.Generic;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
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(new DockContent(), Substitute.For<IConnectionsService>())
{
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

@@ -1,38 +1,19 @@
using System.Security; using System.Threading;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Security;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Window; using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking; using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.UI.Window namespace mRemoteNGTests.UI.Window
{ {
public class ConnectionTreeWindowTests public class ConnectionTreeWindowTests
{ {
private ConnectionTreeWindow _connectionTreeWindow; private ConnectionTreeWindow _connectionTreeWindow;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
var connectionInitiator = Substitute.For<IConnectionInitiator>(); _connectionTreeWindow = new ConnectionTreeWindow(new DockContent());
var connectionTree = new ConnectionTree();
var sshTransferWindow = new SSHTransferWindow();
var externalToolsService = new ExternalToolsService();
var import = new Import(Substitute.For<IWin32Window>());
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, import, connectionTree);
var export = new Export(new CredentialRepositoryList(), connectionsService, connectionTree);
var connectionContextMenu = new ConnectionContextMenu(connectionTree, connectionInitiator, sshTransferWindow, export, externalToolsService, import, connectionsService);
_connectionTreeWindow = new ConnectionTreeWindow(new DockContent(), connectionInitiator, connectionsService) {ConnectionTreeContextMenu = connectionContextMenu};
} }
[TearDown] [TearDown]

View File

@@ -109,13 +109,11 @@
</Choose> </Choose>
<ItemGroup> <ItemGroup>
<Compile Include="App\UpdaterTests.cs" /> <Compile Include="App\UpdaterTests.cs" />
<Compile Include="AssemblyTestSetup.cs" />
<Compile Include="BinaryFileTests.cs" /> <Compile Include="BinaryFileTests.cs" />
<Compile Include="Config\Connections\Multiuser\ConnectionsUpdateAvailableEventArgsTests.cs" /> <Compile Include="Config\Connections\Multiuser\ConnectionsUpdateAvailableEventArgsTests.cs" />
<Compile Include="Config\DataProviders\FileBackupCreatorTests.cs" /> <Compile Include="Config\DataProviders\FileBackupCreatorTests.cs" />
<Compile Include="Config\DataProviders\FileDataProviderTests.cs" /> <Compile Include="Config\DataProviders\FileDataProviderTests.cs" />
<Compile Include="Config\DataProviders\FileDataProviderWithRollingBackupTests.cs" /> <Compile Include="Config\DataProviders\FileDataProviderWithRollingBackupTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\ValidateXmlSchemas.cs" />
<Compile Include="Config\Serializers\DataTableDeserializerTests.cs" /> <Compile Include="Config\Serializers\DataTableDeserializerTests.cs" />
<Compile Include="Config\CredentialHarvesterTests.cs" /> <Compile Include="Config\CredentialHarvesterTests.cs" />
<Compile Include="Config\CredentialRecordLoaderTests.cs" /> <Compile Include="Config\CredentialRecordLoaderTests.cs" />
@@ -123,21 +121,21 @@
<Compile Include="Config\Serializers\CredentialProviderSerializerTests.cs" /> <Compile Include="Config\Serializers\CredentialProviderSerializerTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialPasswordDecryptorDecoratorTests.cs" /> <Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialPasswordDecryptorDecoratorTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialPasswordEncryptorDecoratorTests.cs" /> <Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialPasswordEncryptorDecoratorTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Csv\CsvConnectionsDeserializerMremotengFormatTests.cs" /> <Compile Include="Config\Serializers\MiscSerializers\CsvConnectionsDeserializerMremotengFormatTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Csv\CsvConnectionsSerializerMremotengFormatTests.cs" /> <Compile Include="Config\Serializers\MiscSerializers\CsvConnectionsSerializerMremotengFormatTests.cs" />
<Compile Include="Config\Serializers\DataTableSerializerTests.cs" /> <Compile Include="Config\Serializers\DataTableSerializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\PortScanDeserializerTests.cs" /> <Compile Include="Config\Serializers\MiscSerializers\PortScanDeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\PuttyConnectionManagerDeserializerTests.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\RemoteDesktopConnectionDeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManager27DeserializerTests.cs" /> <Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManager27DeserializerTests.cs" />
<Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManagerDeserializerTests.cs" /> <Compile Include="Config\Serializers\MiscSerializers\RemoteDesktopConnectionManagerDeserializerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsDocumentCompilerTests.cs" /> <Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsDocumentCompilerTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsDocumentEncryptorTests.cs" /> <Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsDocumentEncryptorTests.cs" />
<Compile Include="Config\Serializers\ConnectionSerializers\Xml\XmlConnectionsSerializerTests.cs" /> <Compile Include="Config\Serializers\ConnectionSerializers\XmlConnectionsSerializerTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialRecordDeserializerTests.cs" /> <Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialRecordDeserializerTests.cs" />
<Compile Include="Config\Serializers\CredentialSerializers\XmlCredentialSerializerTests.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\SqlVersion22To23UpgraderTests.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion23To24UpgraderTests.cs" /> <Compile Include="Config\Serializers\Versioning\SqlVersion23To24UpgraderTests.cs" />
<Compile Include="Config\Serializers\Versioning\SqlVersion24To25UpgraderTests.cs" /> <Compile Include="Config\Serializers\Versioning\SqlVersion24To25UpgraderTests.cs" />
@@ -147,7 +145,6 @@
<Compile Include="Connection\ConnectionInfoComparerTests.cs" /> <Compile Include="Connection\ConnectionInfoComparerTests.cs" />
<Compile Include="Connection\Protocol\IntegratedProgramTests.cs" /> <Compile Include="Connection\Protocol\IntegratedProgramTests.cs" />
<Compile Include="Connection\Protocol\ProtocolListTests.cs" /> <Compile Include="Connection\Protocol\ProtocolListTests.cs" />
<Compile Include="Container\RootNodeInfoTests.cs" />
<Compile Include="Credential\CompositeRepositoryUnlockerTests.cs" /> <Compile Include="Credential\CompositeRepositoryUnlockerTests.cs" />
<Compile Include="Credential\CredentialChangedEventArgsTests.cs" /> <Compile Include="Credential\CredentialChangedEventArgsTests.cs" />
<Compile Include="Credential\CredentialDeletionMsgBoxConfirmerTests.cs" /> <Compile Include="Credential\CredentialDeletionMsgBoxConfirmerTests.cs" />
@@ -171,15 +168,12 @@
<Compile Include="Security\PasswordCreation\PasswordLengthConstraintTests.cs" /> <Compile Include="Security\PasswordCreation\PasswordLengthConstraintTests.cs" />
<Compile Include="Security\RandomGeneratorTests.cs" /> <Compile Include="Security\RandomGeneratorTests.cs" />
<Compile Include="Security\SecureStringExtensionsTests.cs" /> <Compile Include="Security\SecureStringExtensionsTests.cs" />
<Compile Include="TestHelpers\ConnectionInfoHelpers.cs" />
<Compile Include="TestHelpers\ConnectionTreeModelBuilder.cs" /> <Compile Include="TestHelpers\ConnectionTreeModelBuilder.cs" />
<Compile Include="Security\XmlCryptoProviderBuilderTests.cs" /> <Compile Include="Security\XmlCryptoProviderBuilderTests.cs" />
<Compile Include="TestHelpers\FileTestHelpers.cs" /> <Compile Include="TestHelpers\FileTestHelpers.cs" />
<Compile Include="TestHelpers\SerializableConnectionInfoAllPropertiesOfType.cs" />
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" /> <Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
<Compile Include="Tools\FullyObservableCollectionTests.cs" /> <Compile Include="Tools\FullyObservableCollectionTests.cs" />
<Compile Include="Tools\OptionalTests.cs" /> <Compile Include="Tools\MaybeTests.cs" />
<Compile Include="Tools\Registry\WindowsRegistryTests.cs" />
<Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" /> <Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" />
<Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" /> <Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" />
<Compile Include="Tree\ConnectionTreeModelTests.cs" /> <Compile Include="Tree\ConnectionTreeModelTests.cs" />
@@ -209,8 +203,6 @@
<Compile Include="Tree\RootNodeInfoTests.cs" /> <Compile Include="Tree\RootNodeInfoTests.cs" />
<Compile Include="Tree\ClickHandlers\SwitchToConnectionClickHandlerTests.cs" /> <Compile Include="Tree\ClickHandlers\SwitchToConnectionClickHandlerTests.cs" />
<Compile Include="Tree\SelectedConnectionDeletionConfirmerTests.cs" /> <Compile Include="Tree\SelectedConnectionDeletionConfirmerTests.cs" />
<Compile Include="UI\Controls\ExternalToolsToolStripTests.cs" />
<Compile Include="UI\Controls\ConnectionTreeTests.cs" />
<Compile Include="UI\Controls\PageSequenceTests.cs" /> <Compile Include="UI\Controls\PageSequenceTests.cs" />
<Compile Include="UI\Controls\SecureTextBoxTestForm.cs"> <Compile Include="UI\Controls\SecureTextBoxTestForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
@@ -232,14 +224,9 @@
<DependentUpon>TextBoxExtensionsTestForm.cs</DependentUpon> <DependentUpon>TextBoxExtensionsTestForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="UI\Controls\TextBoxExtensionsTests.cs" /> <Compile Include="UI\Controls\TextBoxExtensionsTests.cs" />
<Compile Include="UI\Forms\FrmMainTests.cs" />
<Compile Include="UI\Forms\OptionsFormSetupAndTeardown.cs" /> <Compile Include="UI\Forms\OptionsFormSetupAndTeardown.cs" />
<Compile Include="UI\Forms\PasswordFormTests.cs" /> <Compile Include="UI\Forms\PasswordFormTests.cs" />
<Compile Include="UI\WindowListTests.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" /> <Compile Include="UI\Window\ConnectionTreeWindowTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -33,19 +33,16 @@ Global
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution 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.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.ActiveCfg = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.Build.0 = 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.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.ActiveCfg = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.Build.0 = 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.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.Build.0 = Release|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.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.Build.0 = 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.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.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.Build.0 = 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 {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.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.Build.0 = 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.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.ActiveCfg = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.Build.0 = 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.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.ActiveCfg = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.Build.0 = 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.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.Build.0 = Release|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.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.Build.0 = 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.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.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.Build.0 = 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.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.Build.0 = 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.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.Build.0 = 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 Portable|x86.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|Any CPU.ActiveCfg = Debug|x86 {5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|Any CPU.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.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.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|x86.Build.0 = 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.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 Portable|x86.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|Any CPU.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 {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 Portable|x86.ActiveCfg = Debug Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|Any CPU.ActiveCfg = Debug|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}.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.ActiveCfg = Release Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.Build.0 = Release|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.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.Build.0 = 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 {F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86

View File

@@ -6,35 +6,25 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Forms; using System.Windows.Forms;
using mRemoteNG.Messages; using mRemoteNG.Messages;
using mRemoteNG.Tools;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class CompatibilityChecker public static class CompatibilityChecker
{ {
private readonly MessageCollector _messageCollector; public static void CheckCompatibility(MessageCollector messageCollector)
private readonly IWin32Window _dialogWindowParent;
public CompatibilityChecker(MessageCollector messageCollector, IWin32Window dialogWindowParent)
{ {
_messageCollector = messageCollector.ThrowIfNull(nameof(messageCollector)); CheckFipsPolicy(messageCollector);
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent)); CheckLenovoAutoScrollUtility(messageCollector);
} }
public void CheckCompatibility() private static void CheckFipsPolicy(MessageCollector messageCollector)
{ {
CheckFipsPolicy(); messageCollector.AddMessage(MessageClass.InformationMsg, "Checking FIPS Policy...", true);
CheckLenovoAutoScrollUtility();
}
private void CheckFipsPolicy()
{
_messageCollector.AddMessage(MessageClass.InformationMsg, "Checking FIPS Policy...", true);
if (!FipsPolicyEnabledForServer2003() && !FipsPolicyEnabledForServer2008AndNewer()) return; if (!FipsPolicyEnabledForServer2003() && !FipsPolicyEnabledForServer2008AndNewer()) return;
var errorText = string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName, var errorText = string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName,
GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
_messageCollector.AddMessage(MessageClass.ErrorMsg, errorText, true); messageCollector.AddMessage(MessageClass.ErrorMsg, errorText, true);
MessageBox.Show(_dialogWindowParent, errorText); MessageBox.Show(FrmMain.Default, errorText);
Environment.Exit(1); Environment.Exit(1);
} }
@@ -56,9 +46,9 @@ namespace mRemoteNG.App
return (int)fipsPolicy != 0; return (int)fipsPolicy != 0;
} }
private void CheckLenovoAutoScrollUtility() private static void CheckLenovoAutoScrollUtility(MessageCollector messageCollector)
{ {
_messageCollector.AddMessage(MessageClass.InformationMsg, "Checking Lenovo AutoScroll Utility...", true); messageCollector.AddMessage(MessageClass.InformationMsg, "Checking Lenovo AutoScroll Utility...", true);
if (!Settings.Default.CompatibilityWarnLenovoAutoScrollUtility) if (!Settings.Default.CompatibilityWarnLenovoAutoScrollUtility)
return; return;
@@ -70,7 +60,7 @@ namespace mRemoteNG.App
} }
catch (InvalidOperationException ex) catch (InvalidOperationException ex)
{ {
_messageCollector.AddExceptionMessage("Error in CheckLenovoAutoScrollUtility", ex); messageCollector.AddExceptionMessage("Error in CheckLenovoAutoScrollUtility", ex);
} }
if (proccesses.Length <= 0) return; if (proccesses.Length <= 0) return;

View File

@@ -4,14 +4,10 @@ using System.Windows.Forms;
using mRemoteNG.Config.Connections; using mRemoteNG.Config.Connections;
using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Credential;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Security.Factories; using mRemoteNG.Security.Factories;
using mRemoteNG.Tools;
using mRemoteNG.Tree; using mRemoteNG.Tree;
using mRemoteNG.Tree.Root; using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Forms; using mRemoteNG.UI.Forms;
@@ -19,20 +15,9 @@ using mRemoteNG.UI.Forms;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Export public static class Export
{ {
private readonly IConnectionsService _connectionsService; public static void ExportToFile(ConnectionInfo selectedNode, ConnectionTreeModel connectionTreeModel)
private readonly ICredentialRepositoryList _credentialRepositoryList;
private readonly IWin32Window _dialogWindowParent;
public Export(ICredentialRepositoryList credentialRepositoryList, IConnectionsService connectionsService, IWin32Window dialogWindowParent)
{
_credentialRepositoryList = credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
public void ExportToFile(ConnectionInfo selectedNode, ConnectionTreeModel connectionTreeModel)
{ {
try try
{ {
@@ -49,7 +34,7 @@ namespace mRemoteNG.App
exportForm.SelectedConnection = selectedNode; exportForm.SelectedConnection = selectedNode;
} }
if (exportForm.ShowDialog(_dialogWindowParent) != DialogResult.OK) if (exportForm.ShowDialog(FrmMain.Default) != DialogResult.OK)
return; return;
ConnectionInfo exportTarget; ConnectionInfo exportTarget;
@@ -82,7 +67,7 @@ namespace mRemoteNG.App
} }
} }
private void SaveExportFile(string fileName, SaveFormat saveFormat, SaveFilter saveFilter, ConnectionInfo exportTarget) private static void SaveExportFile(string fileName, SaveFormat saveFormat, SaveFilter saveFilter, ConnectionInfo exportTarget)
{ {
try try
{ {
@@ -92,14 +77,14 @@ namespace mRemoteNG.App
case SaveFormat.mRXML: case SaveFormat.mRXML:
var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build(); var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
var rootNode = exportTarget.GetRootParent() as RootNodeInfo; var rootNode = exportTarget.GetRootParent() as RootNodeInfo;
var connectionNodeSerializer = new XmlConnectionNodeSerializer27( var connectionNodeSerializer = new XmlConnectionNodeSerializer26(
cryptographyProvider, cryptographyProvider,
rootNode?.PasswordString.ConvertToSecureString() ?? new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString(), rootNode?.PasswordString.ConvertToSecureString() ?? new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString(),
saveFilter); saveFilter);
serializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer); serializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer);
break; break;
case SaveFormat.mRCSV: case SaveFormat.mRCSV:
serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, _credentialRepositoryList); serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, Runtime.CredentialProviderCatalog);
break; break;
default: default:
throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null); throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null);
@@ -114,7 +99,7 @@ namespace mRemoteNG.App
} }
finally finally
{ {
_connectionsService.RemoteConnectionsSyncronizer?.Enable(); Runtime.ConnectionsService.RemoteConnectionsSyncronizer?.Enable();
} }
} }
} }

View File

@@ -3,26 +3,15 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using mRemoteNG.Config.Import; using mRemoteNG.Config.Import;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Tools; using mRemoteNG.Tools;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Import public static class Import
{ {
private readonly IWin32Window _dialogWindowParent; public static void ImportFromFile(ContainerInfo importDestinationContainer)
public Import(IWin32Window dialogWindowParent)
{
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
// TODO - this is only a property to break up a circular dependency. move this to ctor when able
public IConnectionsService ConnectionsService { get; set; }
public void ImportFromFile(ContainerInfo importDestinationContainer)
{ {
try try
{ {
@@ -61,7 +50,7 @@ namespace mRemoteNG.App
} }
} }
ConnectionsService.SaveConnectionsAsync(); Runtime.ConnectionsService.SaveConnectionsAsync();
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -70,12 +59,12 @@ namespace mRemoteNG.App
} }
} }
public void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer, bool importSubOu) public static void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer, bool importSubOu)
{ {
try try
{ {
ActiveDirectoryImporter.Import(ldapPath, importDestinationContainer, importSubOu); ActiveDirectoryImporter.Import(ldapPath, importDestinationContainer, importSubOu);
ConnectionsService.SaveConnectionsAsync(); Runtime.ConnectionsService.SaveConnectionsAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -83,13 +72,13 @@ namespace mRemoteNG.App
} }
} }
public void ImportFromPortScan(IEnumerable<ScanHost> hosts, ProtocolType protocol, ContainerInfo importDestinationContainer) public static void ImportFromPortScan(IEnumerable<ScanHost> hosts, ProtocolType protocol, ContainerInfo importDestinationContainer)
{ {
try try
{ {
var importer = new PortScanImporter(protocol); var importer = new PortScanImporter(protocol);
importer.Import(hosts, importDestinationContainer); importer.Import(hosts, importDestinationContainer);
ConnectionsService.SaveConnectionsAsync(); Runtime.ConnectionsService.SaveConnectionsAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -97,14 +86,14 @@ namespace mRemoteNG.App
} }
} }
private IConnectionImporter<string> BuildConnectionImporterFromFileExtension(string fileName) private static IConnectionImporter<string> BuildConnectionImporterFromFileExtension(string fileName)
{ {
// TODO: Use the file contents to determine the file type instead of trusting the extension // TODO: Use the file contents to determine the file type instead of trusting the extension
var extension = Path.GetExtension(fileName) ?? ""; var extension = Path.GetExtension(fileName) ?? "";
switch (extension.ToLowerInvariant()) switch (extension.ToLowerInvariant())
{ {
case ".xml": case ".xml":
return new MRemoteNGXmlImporter(ConnectionsService, _dialogWindowParent); return new MRemoteNGXmlImporter();
case ".csv": case ".csv":
return new MRemoteNGCsvImporter(); return new MRemoteNGCsvImporter();
case ".rdp": case ".rdp":

View File

@@ -1,24 +1,18 @@
using mRemoteNG.Connection; using System.IO;
using mRemoteNG.Tools; using mRemoteNG.Config.Connections;
using System.IO;
namespace mRemoteNG.App.Initialization namespace mRemoteNG.App.Initialization
{ {
public class CredsAndConsSetup public class CredsAndConsSetup
{ {
private readonly IConnectionsService _connectionsService; public void LoadCredsAndCons()
public CredsAndConsSetup(IConnectionsService connectionsService)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public void LoadCredsAndCons()
{ {
if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(_connectionsService.GetStartupConnectionFileName())) new SaveConnectionsOnEdit(Runtime.ConnectionsService);
_connectionsService.NewConnectionsFile(_connectionsService.GetStartupConnectionFileName());
_connectionsService.LoadConnections(); if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(Runtime.ConnectionsService.GetStartupConnectionFileName()))
Runtime.ConnectionsService.NewConnectionsFile(Runtime.ConnectionsService.GetStartupConnectionFileName());
Runtime.LoadConnections();
} }
} }
} }

View File

@@ -3,13 +3,10 @@ using System.Linq;
using mRemoteNG.Messages; using mRemoteNG.Messages;
using mRemoteNG.Messages.MessageWriters; using mRemoteNG.Messages.MessageWriters;
using mRemoteNG.Messages.WriterDecorators; using mRemoteNG.Messages.WriterDecorators;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
namespace mRemoteNG.App.Initialization namespace mRemoteNG.App.Initialization
{ {
public class MessageCollectorSetup public class MessageCollectorSetup
{ {
public static void SetupMessageCollector(MessageCollector messageCollector, IList<IMessageWriter> messageWriterList) public static void SetupMessageCollector(MessageCollector messageCollector, IList<IMessageWriter> messageWriterList)
{ {
@@ -22,13 +19,13 @@ namespace mRemoteNG.App.Initialization
}; };
} }
public static void BuildMessageWritersFromSettings(IList<IMessageWriter> messageWriterList, FrmMain frmMain, ErrorAndInfoWindow errorAndInfoWindow) public static void BuildMessageWritersFromSettings(IList<IMessageWriter> messageWriterList)
{ {
#if DEBUG #if DEBUG
messageWriterList.Add(BuildDebugConsoleWriter()); messageWriterList.Add(BuildDebugConsoleWriter());
#endif #endif
messageWriterList.Add(BuildTextLogMessageWriter()); messageWriterList.Add(BuildTextLogMessageWriter());
messageWriterList.Add(BuildNotificationPanelMessageWriter(frmMain, errorAndInfoWindow)); messageWriterList.Add(BuildNotificationPanelMessageWriter());
messageWriterList.Add(BuildPopupMessageWriter()); messageWriterList.Add(BuildPopupMessageWriter());
} }
@@ -45,17 +42,16 @@ namespace mRemoteNG.App.Initialization
); );
} }
private static IMessageWriter BuildNotificationPanelMessageWriter(FrmMain frmMain, ErrorAndInfoWindow errorAndInfoWindow) private static IMessageWriter BuildNotificationPanelMessageWriter()
{ {
errorAndInfoWindow.ThrowIfNull(nameof(errorAndInfoWindow));
return new OnlyLogMessageFilter( return new OnlyLogMessageFilter(
new MessageTypeFilterDecorator( new MessageTypeFilterDecorator(
new NotificationPanelMessageFilteringOptions(), new NotificationPanelMessageFilteringOptions(),
new MessageFocusDecorator( new MessageFocusDecorator(
frmMain, Windows.ErrorsForm,
errorAndInfoWindow,
new NotificationPanelSwitchOnMessageFilteringOptions(), new NotificationPanelSwitchOnMessageFilteringOptions(),
new NotificationPanelMessageWriter(errorAndInfoWindow) new NotificationPanelMessageWriter(Windows.ErrorsForm)
) )
) )
); );

View File

@@ -26,8 +26,7 @@ namespace mRemoteNG.App
{ {
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);
var frmMain = new FrmMain(); Application.Run(FrmMain.Default);
Application.Run(frmMain);
} }
public static void CloseSingletonInstanceMutex() public static void CloseSingletonInstanceMutex()

View File

@@ -1,11 +1,26 @@
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.Config.Putty;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Credential;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Messages; using mRemoteNG.Messages;
using mRemoteNG.Security;
using mRemoteNG.Tools; using mRemoteNG.Tools;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.TaskDialog;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Runtime public static class Runtime
{ {
public static bool IsPortableEdition public static bool IsPortableEdition
{ {
@@ -19,7 +34,171 @@ namespace mRemoteNG.App
} }
} }
public static WindowList WindowList { get; set; }
public static MessageCollector MessageCollector { get; } = new MessageCollector(); public static MessageCollector MessageCollector { get; } = new MessageCollector();
public static NotificationAreaIcon NotificationAreaIcon { get; set; } public static NotificationAreaIcon NotificationAreaIcon { get; set; }
public static ExternalToolsService ExternalToolsService { get; } = new ExternalToolsService();
public static SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString();
public static ICredentialRepositoryList CredentialProviderCatalog { get; } = new CredentialRepositoryList();
public static ConnectionsService ConnectionsService { get; } = new ConnectionsService(PuttySessionsManager.Instance);
#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(_withDialog);
}
public static void LoadConnections(bool withDialog = false)
{
var connectionFileName = "";
try
{
// disable sql update checking while we are loading updates
ConnectionsService.RemoteConnectionsSyncronizer?.Disable();
if (!Settings.Default.UseSQLServer)
{
if (withDialog)
{
var loadDialog = DialogFactory.BuildLoadConnectionsDialog();
if (loadDialog.ShowDialog() != DialogResult.OK) return;
connectionFileName = loadDialog.FileName;
}
else
{
connectionFileName = ConnectionsService.GetStartupConnectionFileName();
}
var backupFileCreator = new FileBackupCreator();
backupFileCreator.CreateBackupFile(connectionFileName);
var backupPruner = new FileBackupPruner();
backupPruner.PruneBackupFiles(connectionFileName);
}
ConnectionsService.LoadConnections(Settings.Default.UseSQLServer, false, connectionFileName);
if (Settings.Default.UseSQLServer)
{
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();
}
catch (Exception ex)
{
if (Settings.Default.UseSQLServer)
{
MessageCollector.AddExceptionMessage(Language.strLoadFromSqlFailed, ex);
var commandButtons = string.Join("|", Language.strCommandTryAgain, Language.strCommandOpenConnectionFile, string.Format(Language.strCommandExitProgram, Application.ProductName));
CTaskDialog.ShowCommandBox(Application.ProductName, Language.strLoadFromSqlFailed, Language.strLoadFromSqlFailedContent, MiscTools.GetExceptionMessageRecursive(ex), "", "", commandButtons, false, ESysIcons.Error, ESysIcons.Error);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
LoadConnections(withDialog);
return;
case 1:
Settings.Default.UseSQLServer = false;
LoadConnections(true);
return;
default:
Application.Exit();
return;
}
}
if (ex is FileNotFoundException && !withDialog)
{
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), ex, MessageClass.InformationMsg);
string[] commandButtons =
{
Language.ConfigurationCreateNew,
Language.ConfigurationCustomPath,
Language.ConfigurationImportFile,
Language.strMenuExit
};
var answered = false;
while (!answered)
{
try
{
CTaskDialog.ShowTaskDialogBox(
GeneralAppInfo.ProductName,
Language.ConnectionFileNotFound,
"", "", "", "", "",
string.Join(" | ", commandButtons),
ETaskDialogButtons.None,
ESysIcons.Question,
ESysIcons.Question);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
ConnectionsService.NewConnectionsFile(connectionFileName);
answered = true;
break;
case 1:
LoadConnections(true);
answered = true;
break;
case 2:
ConnectionsService.NewConnectionsFile(connectionFileName);
Import.ImportFromFile(ConnectionsService.ConnectionTreeModel.RootNodes[0]);
answered = true;
break;
case 3:
Application.Exit();
answered = true;
break;
}
}
catch (Exception exc)
{
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), exc, MessageClass.InformationMsg);
}
}
return;
}
MessageCollector.AddExceptionStackTrace(string.Format(Language.strConnectionsFileCouldNotBeLoaded, connectionFileName), ex);
if (connectionFileName != ConnectionsService.GetStartupConnectionFileName())
{
LoadConnections(withDialog);
}
else
{
MessageBox.Show(FrmMain.Default,
string.Format(Language.strErrorStartupConnectionFileLoad, Environment.NewLine, Application.ProductName, ConnectionsService.GetStartupConnectionFileName(), MiscTools.GetExceptionMessageRecursive(ex)),
@"Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
}
#endregion
} }
} }

View File

@@ -1,38 +1,31 @@
using System.Windows.Forms; using System.Windows.Forms;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms; using mRemoteNG.UI.Forms;
using WeifenLuo.WinFormsUI.Docking; using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Screens public static class Screens
{ {
private readonly FrmMain _frmMain; public static void SendFormToScreen(Screen screen)
public Screens(FrmMain frmMain)
{
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
}
public void SendFormToScreen(Screen screen)
{ {
var frmMain = FrmMain.Default;
var wasMax = false; var wasMax = false;
if (_frmMain.WindowState == FormWindowState.Maximized) if (frmMain.WindowState == FormWindowState.Maximized)
{ {
wasMax = true; wasMax = true;
_frmMain.WindowState = FormWindowState.Normal; frmMain.WindowState = FormWindowState.Normal;
} }
_frmMain.Location = screen.Bounds.Location; frmMain.Location = screen.Bounds.Location;
if (wasMax) if (wasMax)
{ {
_frmMain.WindowState = FormWindowState.Maximized; frmMain.WindowState = FormWindowState.Maximized;
} }
} }
public void SendPanelToScreen(DockContent panel, Screen screen) public static void SendPanelToScreen(DockContent panel, Screen screen)
{ {
panel.DockState = DockState.Float; panel.DockState = DockState.Float;
if (panel.ParentForm == null) return; if (panel.ParentForm == null) return;

View File

@@ -3,41 +3,29 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Forms; using System.Windows.Forms;
using mRemoteNG.Config.Putty; using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.UI.Controls; using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Forms; using mRemoteNG.UI.Forms;
// ReSharper disable ArrangeAccessorOwnerBody // ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Shutdown public static class Shutdown
{ {
private readonly SettingsSaver _settingsSaver;
private readonly IConnectionsService _connectionsService;
private readonly FrmMain _frmMain;
private static string _updateFilePath; private static string _updateFilePath;
public Shutdown(SettingsSaver settingsSaver, IConnectionsService connectionsService, FrmMain frmMain)
{
_settingsSaver = settingsSaver.ThrowIfNull(nameof(settingsSaver));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
}
private static bool UpdatePending private static bool UpdatePending
{ {
get { return !string.IsNullOrEmpty(_updateFilePath); } get { return !string.IsNullOrEmpty(_updateFilePath); }
} }
public void Quit(string updateFilePath = null) public static void Quit(string updateFilePath = null)
{ {
_updateFilePath = updateFilePath; _updateFilePath = updateFilePath;
_frmMain.Close(); FrmMain.Default.Close();
ProgramRoot.CloseSingletonInstanceMutex(); ProgramRoot.CloseSingletonInstanceMutex();
} }
public void Cleanup(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain) public static void Cleanup(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain)
{ {
try try
{ {
@@ -53,34 +41,34 @@ namespace mRemoteNG.App
} }
} }
private void StopPuttySessionWatcher() private static void StopPuttySessionWatcher()
{ {
PuttySessionsManager.Instance.StopWatcher(); PuttySessionsManager.Instance.StopWatcher();
} }
private void DisposeNotificationAreaIcon() private static void DisposeNotificationAreaIcon()
{ {
if (Runtime.NotificationAreaIcon != null && Runtime.NotificationAreaIcon.Disposed == false) if (Runtime.NotificationAreaIcon != null && Runtime.NotificationAreaIcon.Disposed == false)
Runtime.NotificationAreaIcon.Dispose(); Runtime.NotificationAreaIcon.Dispose();
} }
private void SaveConnections() private static void SaveConnections()
{ {
if (Settings.Default.SaveConsOnExit) if (Settings.Default.SaveConsOnExit)
_connectionsService.SaveConnections(); Runtime.ConnectionsService.SaveConnections();
} }
private void SaveSettings(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain) private static void SaveSettings(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain)
{ {
_settingsSaver.SaveSettings(quickConnectToolStrip, externalToolsToolStrip, multiSshToolStrip, frmMain); Config.Settings.SettingsSaver.SaveSettings(quickConnectToolStrip, externalToolsToolStrip, multiSshToolStrip, frmMain);
} }
private void UnregisterBrowsers() private static void UnregisterBrowsers()
{ {
IeBrowserEmulation.Unregister(); IeBrowserEmulation.Unregister();
} }
public void StartUpdate() public static void StartUpdate()
{ {
try try
{ {
@@ -92,7 +80,7 @@ namespace mRemoteNG.App
} }
} }
private void RunUpdateFile() private static void RunUpdateFile()
{ {
if (UpdatePending) if (UpdatePending)
Process.Start(_updateFilePath); Process.Start(_updateFilePath);

View File

@@ -7,7 +7,6 @@ using mRemoteNG.App.Initialization;
using mRemoteNG.App.Update; using mRemoteNG.App.Update;
using mRemoteNG.Config.Connections; using mRemoteNG.Config.Connections;
using mRemoteNG.Config.Connections.Multiuser; using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection; using mRemoteNG.Connection;
using mRemoteNG.Messages; using mRemoteNG.Messages;
using mRemoteNG.Tools; using mRemoteNG.Tools;
@@ -18,34 +17,30 @@ using mRemoteNG.UI.Forms;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Startup public class Startup
{ {
private readonly AppUpdater _appUpdate; private AppUpdater _appUpdate;
private readonly ConnectionIconLoader _connectionIconLoader; private readonly ConnectionIconLoader _connectionIconLoader;
private readonly FrmMain _frmMain; private readonly FrmMain _frmMain = FrmMain.Default;
private readonly Windows _windows;
private readonly IConnectionsService _connectionsService;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly CompatibilityChecker _compatibilityChecker;
public Startup(FrmMain frmMain, Windows windows, IConnectionsService connectionsService, public static Startup Instance { get; } = new Startup();
AppUpdater appUpdate, DatabaseConnectorFactory databaseConnectorFactory, CompatibilityChecker compatibilityChecker)
private Startup()
{ {
_frmMain = frmMain.ThrowIfNull(nameof(frmMain)); _appUpdate = new AppUpdater();
_windows = windows.ThrowIfNull(nameof(windows));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_appUpdate = appUpdate.ThrowIfNull(nameof(appUpdate));
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_compatibilityChecker = compatibilityChecker.ThrowIfNull(nameof(compatibilityChecker));
_connectionIconLoader = new ConnectionIconLoader(GeneralAppInfo.HomePath + "\\Icons\\"); _connectionIconLoader = new ConnectionIconLoader(GeneralAppInfo.HomePath + "\\Icons\\");
} }
static Startup()
{
}
public void InitializeProgram(MessageCollector messageCollector) public void InitializeProgram(MessageCollector messageCollector)
{ {
Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture)); Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture));
var startupLogger = new StartupDataLogger(messageCollector); var startupLogger = new StartupDataLogger(messageCollector);
startupLogger.LogStartupData(); startupLogger.LogStartupData();
_compatibilityChecker.CheckCompatibility(); CompatibilityChecker.CheckCompatibility(messageCollector);
ParseCommandLineArgs(messageCollector); ParseCommandLineArgs(messageCollector);
IeBrowserEmulation.Register(); IeBrowserEmulation.Register();
_connectionIconLoader.GetConnectionIcons(); _connectionIconLoader.GetConnectionIcons();
@@ -64,14 +59,17 @@ namespace mRemoteNG.App
messageCollector.AddMessage(MessageClass.DebugMsg, "Determining if we need a database syncronizer"); messageCollector.AddMessage(MessageClass.DebugMsg, "Determining if we need a database syncronizer");
if (!Settings.Default.UseSQLServer) return; if (!Settings.Default.UseSQLServer) return;
messageCollector.AddMessage(MessageClass.DebugMsg, "Creating database syncronizer"); messageCollector.AddMessage(MessageClass.DebugMsg, "Creating database syncronizer");
var sqlConnectionsUpdateChecker = new SqlConnectionsUpdateChecker(_connectionsService, _databaseConnectorFactory); Runtime.ConnectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker());
_connectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(sqlConnectionsUpdateChecker, _connectionsService); Runtime.ConnectionsService.RemoteConnectionsSyncronizer.Enable();
_connectionsService.RemoteConnectionsSyncronizer.Enable();
} }
public void CheckForUpdate() public void CheckForUpdate()
{ {
if (_appUpdate.IsGetUpdateInfoRunning) if (_appUpdate == null)
{
_appUpdate = new AppUpdater();
}
else if (_appUpdate.IsGetUpdateInfoRunning)
{ {
return; return;
} }
@@ -109,7 +107,7 @@ namespace mRemoteNG.App
if (_appUpdate.IsUpdateAvailable()) if (_appUpdate.IsUpdateAvailable())
{ {
_windows.Show(WindowType.Update); Windows.Show(WindowType.Update);
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -4,7 +4,6 @@ using System.Net;
using System.ComponentModel; using System.ComponentModel;
using System.Threading; using System.Threading;
using System.Reflection; using System.Reflection;
using System.Security;
using mRemoteNG.App.Info; using mRemoteNG.App.Info;
using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Security.SymmetricEncryption;
using System.Security.Cryptography; using System.Security.Cryptography;
@@ -23,7 +22,6 @@ namespace mRemoteNG.App.Update
private WebProxy _webProxy; private WebProxy _webProxy;
private Thread _getUpdateInfoThread; private Thread _getUpdateInfoThread;
private Thread _getChangeLogThread; private Thread _getChangeLogThread;
private readonly Func<SecureString> _encryptionKeyRetrievalFunc;
#region Public Properties #region Public Properties
@@ -50,9 +48,8 @@ namespace mRemoteNG.App.Update
#region Public Methods #region Public Methods
public AppUpdater(Func<SecureString> encryptionKeyRetrievalFunc) public AppUpdater()
{ {
_encryptionKeyRetrievalFunc = encryptionKeyRetrievalFunc;
SetProxySettings(); SetProxySettings();
} }
@@ -64,7 +61,7 @@ namespace mRemoteNG.App.Update
var useAuthentication = Settings.Default.UpdateProxyUseAuthentication; var useAuthentication = Settings.Default.UpdateProxyUseAuthentication;
var username = Settings.Default.UpdateProxyAuthUser; var username = Settings.Default.UpdateProxyAuthUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, _encryptionKeyRetrievalFunc()); var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
SetProxySettings(shouldWeUseProxy, proxyAddress, port, useAuthentication, username, password); SetProxySettings(shouldWeUseProxy, proxyAddress, port, useAuthentication, username, password);
} }

View File

@@ -1,134 +1,88 @@
using System; using mRemoteNG.UI.Forms;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window; using mRemoteNG.UI.Window;
using WeifenLuo.WinFormsUI.Docking; using System;
using mRemoteNG.Messages;
using mRemoteNG.UI;
namespace mRemoteNG.App namespace mRemoteNG.App
{ {
public class Windows public static class Windows
{ {
private readonly IConnectionInitiator _connectionInitiator; private static AboutWindow _aboutForm;
private AboutWindow _aboutForm; private static ActiveDirectoryImportWindow _adimportForm;
private ActiveDirectoryImportWindow _adimportForm; private static HelpWindow _helpForm;
private HelpWindow _helpForm; private static ExternalToolsWindow _externalappsForm;
private ExternalToolsWindow _externalappsForm; private static PortScanWindow _portscanForm;
private PortScanWindow _portscanForm; private static UltraVNCWindow _ultravncscForm;
private UltraVNCWindow _ultravncscForm; private static ComponentsCheckWindow _componentscheckForm;
private ComponentsCheckWindow _componentscheckForm;
private UpdateWindow _updateForm;
private readonly Func<UpdateWindow> _updateWindowBuilder;
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
private readonly Func<ExternalToolsWindow> _externalToolsWindowBuilder;
private readonly Func<PortScanWindow> _portScanWindowBuilder;
private readonly Func<ActiveDirectoryImportWindow> _activeDirectoryImportWindowBuilder;
private readonly IConnectionsService _connectionsService;
private readonly AppUpdater _appUpdater;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly FrmMain _frmMain;
internal ConnectionTreeWindow TreeForm { get; } internal static ConnectionTreeWindow TreeForm { get; set; } = new ConnectionTreeWindow();
internal ConfigWindow ConfigForm { get; } internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
internal ErrorAndInfoWindow ErrorsForm { get; } internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
internal ScreenshotManagerWindow ScreenshotForm { get; } internal static ScreenshotManagerWindow ScreenshotForm { get; set; } = new ScreenshotManagerWindow();
internal SSHTransferWindow SshtransferForm { get; private set; } private static UpdateWindow UpdateForm { get; set; } = new UpdateWindow();
internal static SSHTransferWindow SshtransferForm { get; private set; } = new SSHTransferWindow();
public Windows(
IConnectionInitiator connectionInitiator,
ConnectionTreeWindow treeForm,
ConfigWindow configForm,
ErrorAndInfoWindow errorAndInfoWindow,
ScreenshotManagerWindow screenshotForm,
SSHTransferWindow sshtransferForm,
Func<UpdateWindow> updateWindowBuilder,
Func<NotificationAreaIcon> notificationAreaIconBuilder,
Func<ExternalToolsWindow> externalToolsWindowBuilder,
IConnectionsService connectionsService,
Func<PortScanWindow> portScanWindowBuilder,
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder,
AppUpdater appUpdater,
DatabaseConnectorFactory databaseConnectorFactory,
FrmMain frmMain)
{
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
TreeForm = treeForm.ThrowIfNull(nameof(treeForm));
ConfigForm = configForm.ThrowIfNull(nameof(configForm));
ErrorsForm = errorAndInfoWindow.ThrowIfNull(nameof(errorAndInfoWindow));
ScreenshotForm = screenshotForm.ThrowIfNull(nameof(screenshotForm));
SshtransferForm = sshtransferForm.ThrowIfNull(nameof(sshtransferForm));
_updateWindowBuilder = updateWindowBuilder;
_notificationAreaIconBuilder = notificationAreaIconBuilder;
_externalToolsWindowBuilder = externalToolsWindowBuilder;
_portScanWindowBuilder = portScanWindowBuilder;
_activeDirectoryImportWindowBuilder = activeDirectoryImportWindowBuilder;
_frmMain = frmMain;
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_appUpdater = appUpdater.ThrowIfNull(nameof(appUpdater));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public void Show(WindowType windowType)
public static void Show(WindowType windowType)
{ {
try try
{ {
var dockPanel = FrmMain.Default.pnlDock;
// ReSharper disable once SwitchStatementMissingSomeCases // ReSharper disable once SwitchStatementMissingSomeCases
switch (windowType) switch (windowType)
{ {
case WindowType.About: case WindowType.About:
if (_aboutForm == null || _aboutForm.IsDisposed) if (_aboutForm == null || _aboutForm.IsDisposed)
_aboutForm = new AboutWindow(); _aboutForm = new AboutWindow();
_aboutForm.Show(_frmMain.pnlDock); _aboutForm.Show(dockPanel);
break; break;
case WindowType.ActiveDirectoryImport: case WindowType.ActiveDirectoryImport:
if (_adimportForm == null || _adimportForm.IsDisposed) if (_adimportForm == null || _adimportForm.IsDisposed)
_adimportForm = _activeDirectoryImportWindowBuilder(); _adimportForm = new ActiveDirectoryImportWindow();
_adimportForm.Show(_frmMain.pnlDock); _adimportForm.Show(dockPanel);
break; break;
case WindowType.Options: case WindowType.Options:
using (var optionsForm = new frmOptions(_connectionInitiator, Show, _notificationAreaIconBuilder, _connectionsService, _appUpdater, _databaseConnectorFactory, _frmMain)) using (var optionsForm = new frmOptions())
{ {
optionsForm.ShowDialog(_frmMain); optionsForm.ShowDialog(dockPanel);
} }
break; break;
case WindowType.SSHTransfer: case WindowType.SSHTransfer:
if (SshtransferForm == null || SshtransferForm.IsDisposed) if (SshtransferForm == null || SshtransferForm.IsDisposed)
SshtransferForm = new SSHTransferWindow(_frmMain); SshtransferForm = new SSHTransferWindow();
SshtransferForm.Show(_frmMain.pnlDock); SshtransferForm.Show(dockPanel);
break; break;
case WindowType.Update: case WindowType.Update:
if (_updateForm == null || _updateForm.IsDisposed) if (UpdateForm == null || UpdateForm.IsDisposed)
_updateForm = _updateWindowBuilder(); UpdateForm = new UpdateWindow();
_updateForm.Show(_frmMain.pnlDock); UpdateForm.Show(dockPanel);
break; break;
case WindowType.Help: case WindowType.Help:
if (_helpForm == null || _helpForm.IsDisposed) if (_helpForm == null || _helpForm.IsDisposed)
_helpForm = new HelpWindow(); _helpForm = new HelpWindow();
_helpForm.Show(_frmMain.pnlDock); _helpForm.Show(dockPanel);
break; break;
case WindowType.ExternalApps: case WindowType.ExternalApps:
if (_externalappsForm == null || _externalappsForm.IsDisposed) if (_externalappsForm == null || _externalappsForm.IsDisposed)
_externalappsForm = _externalToolsWindowBuilder(); _externalappsForm = new ExternalToolsWindow();
_externalappsForm.Show(_frmMain.pnlDock); _externalappsForm.Show(dockPanel);
break; break;
case WindowType.PortScan: case WindowType.PortScan:
_portscanForm = _portScanWindowBuilder(); _portscanForm = new PortScanWindow();
_portscanForm.Show(_frmMain.pnlDock); _portscanForm.Show(dockPanel);
break; break;
case WindowType.UltraVNCSC: case WindowType.UltraVNCSC:
if (_ultravncscForm == null || _ultravncscForm.IsDisposed) if (_ultravncscForm == null || _ultravncscForm.IsDisposed)
_ultravncscForm = new UltraVNCWindow(Show); _ultravncscForm = new UltraVNCWindow();
_ultravncscForm.Show(_frmMain.pnlDock); _ultravncscForm.Show(dockPanel);
break; break;
case WindowType.ComponentsCheck: case WindowType.ComponentsCheck:
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Showing ComponentsCheck window", true); Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Showing ComponentsCheck window", true);
if (_componentscheckForm == null || _componentscheckForm.IsDisposed) if (_componentscheckForm == null || _componentscheckForm.IsDisposed)
_componentscheckForm = new ComponentsCheckWindow(); _componentscheckForm = new ComponentsCheckWindow();
_componentscheckForm.Show(_frmMain.pnlDock); _componentscheckForm.Show(dockPanel);
break; break;
} }
} }
@@ -138,4 +92,4 @@ namespace mRemoteNG.App
} }
} }
} }
} }

View File

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

View File

@@ -1,8 +1,8 @@
using mRemoteNG.Config.DataProviders; using System;
using mRemoteNG.Config.Serializers.Csv; using mRemoteNG.App;
using mRemoteNG.Credential; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.Tree; using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections namespace mRemoteNG.Config.Connections
@@ -11,18 +11,21 @@ namespace mRemoteNG.Config.Connections
{ {
private readonly string _connectionFileName; private readonly string _connectionFileName;
private readonly SaveFilter _saveFilter; private readonly SaveFilter _saveFilter;
private readonly ICredentialRepositoryList _credentialRepositoryList;
public CsvConnectionsSaver(string connectionFileName, SaveFilter saveFilter, ICredentialRepositoryList credentialRepositoryList) public CsvConnectionsSaver(string connectionFileName, SaveFilter saveFilter)
{ {
_connectionFileName = connectionFileName.ThrowIfNullOrEmpty(nameof(connectionFileName)); if (string.IsNullOrEmpty(connectionFileName))
_saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter)); throw new ArgumentException($"Argument '{nameof(connectionFileName)}' cannot be null or empty");
_credentialRepositoryList = credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList)); if (saveFilter == null)
throw new ArgumentNullException(nameof(saveFilter));
_connectionFileName = connectionFileName;
_saveFilter = saveFilter;
} }
public void Save(ConnectionTreeModel connectionTreeModel) public void Save(ConnectionTreeModel connectionTreeModel)
{ {
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, _credentialRepositoryList); var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, Runtime.CredentialProviderCatalog);
var dataProvider = new FileDataProvider(_connectionFileName); var dataProvider = new FileDataProvider(_connectionFileName);
var csvContent = csvConnectionsSerializer.Serialize(connectionTreeModel); var csvContent = csvConnectionsSerializer.Serialize(connectionTreeModel);
dataProvider.Save(csvContent); dataProvider.Save(csvContent);

View File

@@ -1,8 +1,6 @@
using System; using System;
using System.Timers; using System.Timers;
using mRemoteNG.Connection; using mRemoteNG.App;
using mRemoteNG.Tools;
// ReSharper disable ArrangeAccessorOwnerBody // ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Config.Connections.Multiuser namespace mRemoteNG.Config.Connections.Multiuser
@@ -11,17 +9,15 @@ namespace mRemoteNG.Config.Connections.Multiuser
{ {
private readonly Timer _updateTimer; private readonly Timer _updateTimer;
private readonly IConnectionsUpdateChecker _updateChecker; private readonly IConnectionsUpdateChecker _updateChecker;
private readonly IConnectionsService _connectionsService;
public double TimerIntervalInMilliseconds public double TimerIntervalInMilliseconds
{ {
get { return _updateTimer.Interval; } get { return _updateTimer.Interval; }
} }
public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker, IConnectionsService connectionsService) public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker)
{ {
_updateChecker = updateChecker.ThrowIfNull(nameof(updateChecker)); _updateChecker = updateChecker;
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_updateTimer = new Timer(3000); _updateTimer = new Timer(3000);
SetEventListeners(); SetEventListeners();
} }
@@ -37,7 +33,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
private void Load(object sender, ConnectionsUpdateAvailableEventArgs args) private void Load(object sender, ConnectionsUpdateAvailableEventArgs args)
{ {
_connectionsService.LoadConnections(true, false, ""); Runtime.ConnectionsService.LoadConnections(true, false, "");
args.Handled = true; args.Handled = true;
} }

View File

@@ -6,8 +6,6 @@ using System.Data.SqlClient;
using System.Threading; using System.Threading;
using mRemoteNG.Config.Connections.Multiuser; using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors; using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Connections namespace mRemoteNG.Config.Connections
{ {
@@ -15,15 +13,13 @@ namespace mRemoteNG.Config.Connections
{ {
private readonly SqlDatabaseConnector _sqlConnector; private readonly SqlDatabaseConnector _sqlConnector;
private readonly SqlCommand _sqlQuery; private readonly SqlCommand _sqlQuery;
private readonly IConnectionsService _connectionsService;
private DateTime _lastUpdateTime; private DateTime _lastUpdateTime;
private DateTime _lastDatabaseUpdateTime; private DateTime _lastDatabaseUpdateTime;
public SqlConnectionsUpdateChecker(IConnectionsService connectionsService, DatabaseConnectorFactory databaseConnectorFactory)
public SqlConnectionsUpdateChecker()
{ {
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService)); _sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_sqlConnector = databaseConnectorFactory.SqlDatabaseConnectorFromSettings();
_sqlQuery = new SqlCommand("SELECT * FROM tblUpdate", _sqlConnector.SqlConnection); _sqlQuery = new SqlCommand("SELECT * FROM tblUpdate", _sqlConnector.SqlConnection);
_lastUpdateTime = default(DateTime); _lastUpdateTime = default(DateTime);
_lastDatabaseUpdateTime = default(DateTime); _lastDatabaseUpdateTime = default(DateTime);
@@ -68,7 +64,7 @@ namespace mRemoteNG.Config.Connections
private bool CheckIfIAmTheLastOneUpdated(DateTime lastUpdateInDb) private bool CheckIfIAmTheLastOneUpdated(DateTime lastUpdateInDb)
{ {
DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(_connectionsService.LastSqlUpdate.Ticks - (_connectionsService.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), _connectionsService.LastSqlUpdate.Kind); DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(Runtime.ConnectionsService.LastSqlUpdate.Ticks - (Runtime.ConnectionsService.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), Runtime.ConnectionsService.LastSqlUpdate.Kind);
return lastUpdateInDb == LastSqlUpdateWithoutMilliseconds; return lastUpdateInDb == LastSqlUpdateWithoutMilliseconds;
} }

View File

@@ -1,17 +1,15 @@
using mRemoteNG.Connection; using System;
using System;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using mRemoteNG.Connection;
namespace mRemoteNG.Config.Connections namespace mRemoteNG.Config.Connections
{ {
public class SaveConnectionsOnEdit public class SaveConnectionsOnEdit
{ {
private readonly IConnectionsService _connectionsService; private readonly ConnectionsService _connectionsService;
public bool Enabled { get; set; } = true; public SaveConnectionsOnEdit(ConnectionsService connectionsService)
public SaveConnectionsOnEdit(IConnectionsService connectionsService)
{ {
if (connectionsService == null) if (connectionsService == null)
throw new ArgumentNullException(nameof(connectionsService)); throw new ArgumentNullException(nameof(connectionsService));
@@ -22,9 +20,10 @@ namespace mRemoteNG.Config.Connections
private void ConnectionsServiceOnConnectionsLoaded(object sender, ConnectionsLoadedEventArgs connectionsLoadedEventArgs) private void ConnectionsServiceOnConnectionsLoaded(object sender, ConnectionsLoadedEventArgs connectionsLoadedEventArgs)
{ {
connectionsLoadedEventArgs.NewConnectionTreeModel.CollectionChanged += ConnectionTreeModelOnCollectionChanged; connectionsLoadedEventArgs.NewConnectionTreeModel.CollectionChanged += ConnectionTreeModelOnCollectionChanged;
connectionsLoadedEventArgs.NewConnectionTreeModel.PropertyChanged += ConnectionTreeModelOnPropertyChanged; connectionsLoadedEventArgs.NewConnectionTreeModel.PropertyChanged += ConnectionTreeModelOnPropertyChanged;
foreach (var oldTree in connectionsLoadedEventArgs.PreviousConnectionTreeModel) foreach (var oldTree in connectionsLoadedEventArgs.PreviousConnectionTreeModel)
{ {
oldTree.CollectionChanged -= ConnectionTreeModelOnCollectionChanged; oldTree.CollectionChanged -= ConnectionTreeModelOnCollectionChanged;
@@ -46,11 +45,7 @@ namespace mRemoteNG.Config.Connections
{ {
if (!mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit) if (!mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit)
return; return;
_connectionsService.SaveConnections();
if (!Enabled)
return;
_connectionsService.SaveConnectionsAsync();
} }
} }
} }

View File

@@ -2,31 +2,20 @@
using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Versioning; using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using mRemoteNG.Tree; using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections namespace mRemoteNG.Config.Connections
{ {
public class SqlConnectionsLoader public class SqlConnectionsLoader
{ {
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly IConnectionsService _connectionsService;
public SqlConnectionsLoader(DatabaseConnectorFactory databaseConnectorFactory, IConnectionsService connectionsService)
{
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public ConnectionTreeModel Load() public ConnectionTreeModel Load()
{ {
var connector = _databaseConnectorFactory.SqlDatabaseConnectorFromSettings(); var connector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
var dataProvider = new SqlDataProvider(connector); var dataProvider = new SqlDataProvider(connector);
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector); var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
databaseVersionVerifier.VerifyDatabaseVersion(); databaseVersionVerifier.VerifyDatabaseVersion();
var dataTable = dataProvider.Load(); var dataTable = dataProvider.Load();
var deserializer = new DataTableDeserializer(_connectionsService); var deserializer = new DataTableDeserializer();
return deserializer.Deserialize(dataTable); return deserializer.Deserialize(dataTable);
} }
} }

View File

@@ -2,13 +2,13 @@
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Security;
using mRemoteNG.App; using mRemoteNG.App;
using mRemoteNG.App.Info; using mRemoteNG.App.Info;
using mRemoteNG.Config.DatabaseConnectors; using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Versioning; using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Messages; using mRemoteNG.Messages;
using mRemoteNG.Security; using mRemoteNG.Security;
@@ -21,15 +21,14 @@ namespace mRemoteNG.Config.Connections
{ {
public class SqlConnectionsSaver : ISaver<ConnectionTreeModel> public class SqlConnectionsSaver : ISaver<ConnectionTreeModel>
{ {
private readonly IConnectionsService _connectionsService; private SecureString _password = Runtime.EncryptionKey;
private readonly SaveFilter _saveFilter; private readonly SaveFilter _saveFilter;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
public SqlConnectionsSaver(SaveFilter saveFilter, IConnectionsService connectionsService, DatabaseConnectorFactory databaseConnectorFactory) public SqlConnectionsSaver(SaveFilter saveFilter)
{ {
_saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter)); if (saveFilter == null)
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory)); throw new ArgumentNullException(nameof(saveFilter));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService)); _saveFilter = saveFilter;
} }
public void Save(ConnectionTreeModel connectionTreeModel) public void Save(ConnectionTreeModel connectionTreeModel)
@@ -41,7 +40,7 @@ namespace mRemoteNG.Config.Connections
} }
using (var sqlConnector = _databaseConnectorFactory.SqlDatabaseConnectorFromSettings()) using (var sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings())
{ {
sqlConnector.Connect(); sqlConnector.Connect();
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector); var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector);
@@ -68,17 +67,17 @@ namespace mRemoteNG.Config.Connections
{ {
if (rootTreeNode.Password) if (rootTreeNode.Password)
{ {
_connectionsService.EncryptionKey = rootTreeNode.PasswordString.ConvertToSecureString(); _password = rootTreeNode.PasswordString.ConvertToSecureString();
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _connectionsService.EncryptionKey); strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password);
} }
else else
{ {
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _connectionsService.EncryptionKey); strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
} }
} }
else else
{ {
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _connectionsService.EncryptionKey); strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
} }
var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection); var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection);

View File

@@ -1,37 +1,40 @@
using System.Security; using System;
using System.Windows.Forms; using System.Security;
using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Config.Serializers;
using mRemoteNG.Connection;
using mRemoteNG.Tools; using mRemoteNG.Tools;
using mRemoteNG.Tree; using mRemoteNG.Tree;
using System.IO;
namespace mRemoteNG.Config.Connections namespace mRemoteNG.Config.Connections
{ {
public class XmlConnectionsLoader public class XmlConnectionsLoader
{ {
private readonly IConnectionsService _connectionsService;
private readonly string _connectionFilePath; private readonly string _connectionFilePath;
private readonly IWin32Window _dialogWindowParent;
public XmlConnectionsLoader(string connectionFilePath, IConnectionsService connectionsService, IWin32Window dialogWindowParent) public XmlConnectionsLoader(string connectionFilePath)
{ {
_dialogWindowParent = dialogWindowParent; if (string.IsNullOrEmpty(connectionFilePath))
_connectionFilePath = connectionFilePath.ThrowIfNullOrEmpty(nameof(connectionFilePath)); throw new ArgumentException($"{nameof(connectionFilePath)} cannot be null or empty");
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
if (!File.Exists(connectionFilePath))
throw new FileNotFoundException($"{connectionFilePath} does not exist");
_connectionFilePath = connectionFilePath;
} }
public ConnectionTreeModel Load() public ConnectionTreeModel Load()
{ {
var dataProvider = new FileDataProvider(_connectionFilePath); var dataProvider = new FileDataProvider(_connectionFilePath);
var xmlString = dataProvider.Load(); var xmlString = dataProvider.Load();
var deserializer = new XmlConnectionsDeserializer(_connectionsService, _dialogWindowParent, PromptForPassword); var deserializer = new XmlConnectionsDeserializer(PromptForPassword);
return deserializer.Deserialize(xmlString); return deserializer.Deserialize(xmlString);
} }
private Optional<SecureString> PromptForPassword() private SecureString PromptForPassword()
{ {
return MiscTools.PasswordDialog("", false); var password = MiscTools.PasswordDialog("", false);
return password;
} }
} }
} }

View File

@@ -3,7 +3,6 @@ using System.Linq;
using mRemoteNG.App; using mRemoteNG.App;
using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Security; using mRemoteNG.Security;
using mRemoteNG.Security.Factories; using mRemoteNG.Security.Factories;
using mRemoteNG.Tree; using mRemoteNG.Tree;
@@ -32,7 +31,7 @@ namespace mRemoteNG.Config.Connections
try try
{ {
var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build(); var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
var connectionNodeSerializer = new XmlConnectionNodeSerializer27( var connectionNodeSerializer = new XmlConnectionNodeSerializer26(
cryptographyProvider, cryptographyProvider,
connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(), connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
_saveFilter); _saveFilter);

View File

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

View File

@@ -1,26 +1,17 @@
using System; using mRemoteNG.App;
using System.Security;
using mRemoteNG.App;
using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Security.SymmetricEncryption;
namespace mRemoteNG.Config.DatabaseConnectors namespace mRemoteNG.Config.DatabaseConnectors
{ {
public class DatabaseConnectorFactory public class DatabaseConnectorFactory
{ {
private readonly Func<SecureString> _decryptionKeyRetrievalFun; public static SqlDatabaseConnector SqlDatabaseConnectorFromSettings()
public DatabaseConnectorFactory(Func<SecureString> decryptionKeyRetrievalFun)
{
_decryptionKeyRetrievalFun = decryptionKeyRetrievalFun;
}
public SqlDatabaseConnector SqlDatabaseConnectorFromSettings()
{ {
var sqlHost = mRemoteNG.Settings.Default.SQLHost; var sqlHost = mRemoteNG.Settings.Default.SQLHost;
var sqlCatalog = mRemoteNG.Settings.Default.SQLDatabaseName; var sqlCatalog = mRemoteNG.Settings.Default.SQLDatabaseName;
var sqlUsername = mRemoteNG.Settings.Default.SQLUser; var sqlUsername = mRemoteNG.Settings.Default.SQLUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var sqlPassword = cryptographyProvider.Decrypt(mRemoteNG.Settings.Default.SQLPass, _decryptionKeyRetrievalFun()); var sqlPassword = cryptographyProvider.Decrypt(mRemoteNG.Settings.Default.SQLPass, Runtime.EncryptionKey);
return new SqlDatabaseConnector(sqlHost, sqlCatalog, sqlUsername, sqlPassword); return new SqlDatabaseConnector(sqlHost, sqlCatalog, sqlUsername, sqlPassword);
} }
} }

View File

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

View File

@@ -1,13 +1,10 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Windows.Forms;
using mRemoteNG.App; using mRemoteNG.App;
using mRemoteNG.Config.DataProviders; using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.Xml; using mRemoteNG.Config.Serializers;
using mRemoteNG.Connection;
using mRemoteNG.Container; using mRemoteNG.Container;
using mRemoteNG.Messages; using mRemoteNG.Messages;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Import namespace mRemoteNG.Config.Import
@@ -15,15 +12,6 @@ namespace mRemoteNG.Config.Import
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public class MRemoteNGXmlImporter : IConnectionImporter<string> public class MRemoteNGXmlImporter : IConnectionImporter<string>
{ {
private readonly IConnectionsService _connectionsService;
private readonly IWin32Window _dialogWindowParent;
public MRemoteNGXmlImporter(IConnectionsService connectionsService, IWin32Window dialogWindowParent)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
public void Import(string fileName, ContainerInfo destinationContainer) public void Import(string fileName, ContainerInfo destinationContainer)
{ {
if (fileName == null) if (fileName == null)
@@ -37,7 +25,7 @@ namespace mRemoteNG.Config.Import
var dataProvider = new FileDataProvider(fileName); var dataProvider = new FileDataProvider(fileName);
var xmlString = dataProvider.Load(); var xmlString = dataProvider.Load();
var xmlConnectionsDeserializer = new XmlConnectionsDeserializer(_connectionsService, _dialogWindowParent); var xmlConnectionsDeserializer = new XmlConnectionsDeserializer();
var connectionTreeModel = xmlConnectionsDeserializer.Deserialize(xmlString, true); var connectionTreeModel = xmlConnectionsDeserializer.Deserialize(xmlString, true);
var rootImportContainer = new ContainerInfo { Name = Path.GetFileNameWithoutExtension(fileName) }; var rootImportContainer = new ContainerInfo { Name = Path.GetFileNameWithoutExtension(fileName) };

View File

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

View File

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

View File

@@ -1,213 +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;RedirectClipboard;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;InheritRedirectClipboard;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.RedirectClipboard))
.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.RedirectClipboard))
.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 + ";";
}
}
}

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