Compare commits

..

885 Commits

Author SHA1 Message Date
Dimitrij
a908a783be lib update 2025-01-24 13:25:58 +00:00
Dimitrij
1ae9960e82 lib update 2025-01-14 14:54:54 +00:00
Dimitrij
5aa8425209 Lib updates 2024-12-23 14:27:58 +00:00
Dimitrij
b794aa8089 update puttyng to ver. 0.82 2024-12-23 14:09:07 +00:00
Dimitrij
e8bb0bffaa lib upgrade + update
Some version should be not upgraded due .net limitation, what will be done once .net will be upgraded
2024-11-23 15:51:32 +00:00
Dimitrij
e1e0661f25 lib upgrade 2024-11-23 13:12:36 +00:00
Dimitrij
7848c83c72 lib updates 2024-11-23 12:50:16 +00:00
Dimitrij
2de37ed9c7 Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2024-11-21 11:17:24 +00:00
Dimitrij
425b433cd2 lib updates 2024-11-21 11:17:15 +00:00
Dimitrij
44e07e3cdb Merge pull request #2652 from kursataktas/mremoteng-guru
Introducing mRemoteNG Guru on Gurubase.io
2024-11-12 21:46:23 +00:00
Kursat Aktas
689f882104 Introducing mRemoteNG Guru on Gurubase.io
Signed-off-by: Kursat Aktas <kursat.ce@gmail.com>
2024-11-13 00:17:19 +03:00
Dimitrij
207beaee12 Lib updates + small changes 2024-11-12 11:47:47 +00:00
Dimitrij
bd21b85de7 Lib update 2024-11-01 11:17:54 +00:00
Dimitrij
2e7579cac5 Moved all language files into Language folder. To keep root folder clean
On language change new language will not apply, need more work on that later
2024-10-18 15:40:50 +01:00
Dimitrij
ec63812af0 lib update 2024-10-18 11:02:27 +01:00
Dimitrij
8dfe1a22c9 Moved packages dll's into Assembly folder to keep root folder cleaner 2024-10-18 10:58:49 +01:00
Dimitrij
c0e3f547ec Introducing Local settings manager class and example of default settings json schema
Idea to create json file with defaults settings, what will be automatically loaded into new local settings db at creating process.
Group 'default' means its comes from json file and if user change it later - we will have user id there, that allow us to have different settings for different users but at same time keeping "original" ones in case user decide to reset.

What one of the basic steps of transition all settings into local db. Once application is running - will be possible to import already existing settings into local db, as well as switch where to have save them: to windows registery or to local db.

Settings file also could be encrypted, and file will be locked on current machine, that allow all users to use it, but not allow to transfer it to another machine. (If they do it will not work)
mR don't use any hard-coded passwords for such, only hdd id + machine name (what is hashed by SHA256) so couldn't be traceable from memory dump. Later will be possible to lock by user with own password, but that will required to enter on every start as mR will not save it.
2024-10-16 11:37:31 +01:00
Dimitrij
dafb1b364c lib updates 2024-10-15 13:41:41 +01:00
Dimitrij
7d1b9d8635 Merge pull request #2643 from xRushG/asyncRegSetting
Registry Settings: enhancements and new settings implementation
2024-10-01 22:51:52 +01:00
xRushG
8041f58ffd feat: Add registry settings for Security Page and encryption key generator
- Added new registry settings for managing security-related configurations on the Security Page.
- Implemented an encryption key generator to securely generate a password for store in the registry.
- Passwords are placed encrypted on the clipboard for 30 seconds.
- Update documents and finalize comments
2024-10-01 16:02:59 +02:00
xRushG
d018fdbace feat: Add registry settings for Connections and SQL Server settings
- Added registry settings for the Connection Page.
- Added registry settings for the SQL Serverl Page.
- All settings implemented with async registry logic
- Comment unused settings for Connection Page
- Update documents
2024-10-01 12:35:34 +02:00
xRushG
489602ffb3 feat: Add registry settings forTabs and Panel settings
- Added registry settings for the Tabs and Panel Page.
- All settings implemented with async registry logic
- Comment unused settings
- Update documents
2024-10-01 12:32:16 +02:00
xRushG
600ba73f5f Removed the deprecated SaveConnectionsOnExit option from the registry settings related to startup and exit. 2024-10-01 12:29:01 +02:00
xRushG
88600ae6df feat: Add registry settings for Notification Page, Appearance Page, and Startup and Exit Page with async logic
- Added registry settings for the Notification Page.
- Added registry settings for the Appearance Page.
- Added registry settings for the Startup and Exit Page.
- All settings implemented with async registry logic
2024-10-01 12:27:33 +02:00
xRushG
5e3bce9a92 refactor: Apply the async logic for Credentials and Updates registry settings, remove obsolete code
- Moved async registry loading logic to OptRegistryCredentialsPage and OptRegistryUpdatesPage to improve structure and maintainability.
- Removed obsolete logic and redundant code that is no longer needed due to the new asynchronous architecture.
- Enhanced settings management to take advantage of the just-in-time loading mechanism.
- Improved performance by ensuring registry settings are loaded asynchronously right before they are needed by the UI or application logic, minimizing unnecessary loads.
- Update documents
2024-10-01 12:19:41 +02:00
xRushG
9b28b7057d feat: Introduce RegistryLoader class with Lazy<T> and async registry settings loading
- Added the RegistryLoader class to handle loading of registry settings.
- Implemented Lazy<T> for singleton pattern to ensure only one instance of RegistryLoader is created.
- Added support for asynchronous loading of registry settings to improve performance in async workflows.
- Designed the class with thread safety in mind, leveraging ConcurrentDictionary for storage.
- Included logging of debug messages to track the load process and timing.
2024-10-01 12:08:52 +02:00
Dimitrij
0a17220446 lib updates 2024-09-29 17:05:51 +01:00
Dimitrij
7684b19d13 lib updates 2024-09-18 10:32:34 +01:00
Dimitrij
47baf3b662 fix case 2024-08-28 11:35:56 +01:00
Dimitrij
bc5e2b9437 add project line name 2024-08-28 11:29:40 +01:00
Dimitrij
cf0ef6d9d0 remove older schemes from distribution 2024-08-28 09:54:49 +01:00
Dimitrij
b6f3047f82 lib updates 2024-08-28 09:39:02 +01:00
Dimitrij
0a418561d7 Merge pull request #2629 from ianselmi/v1.77.3-dev
Made the specflow compatible with net6
2024-08-27 11:29:10 +01:00
ianselmi
6da79a41df made the specflow compatible with net6 2024-08-18 10:12:16 +02:00
Dimitrij
3ddeac6c74 lib update 2024-08-05 13:35:58 +01:00
Dimitrij
98f97c442d fix build number calculation 2024-08-05 13:33:50 +01:00
Dimitrij
472d33ba12 Merge pull request #2550 from Risae/v1.77.3-dev
CI: Add GitHub Actions workflow
2024-08-01 16:08:44 +01:00
Dimitrij
d906cfcc1e lib updates 2024-07-31 10:24:44 +01:00
Dimitrij
0f0d8bdcdb Merge pull request #2623 from magriggs/issue-2622
issue-2622: mRemoteNGInstaller - remove explicit PuTTyNG fragment, as…
2024-07-30 13:09:31 +01:00
23439176+magriggs@users.noreply.github.com
005b2485f6 issue-2622: mRemoteNGInstaller - remove explicit PuTTyNG fragment, as PuttyNG is copied implicitly by FilesFragment. Fixes #2622. 2024-07-30 09:07:55 +08:00
Dimitrij
ffd90bed70 Merge pull request #2621 from magriggs/issue-726
Issue 726 - SecureString for ConnectionInfo.Password
2024-07-29 09:05:05 +01:00
23439176+magriggs@users.noreply.github.com
70264a24ab Fix null password handling 2024-07-28 21:30:10 +08:00
23439176+magriggs@users.noreply.github.com
ad3a37fde3 Move ConnectionInfo.Password to use SecureString. Only decrypt when required for connecting. Update tests to skip tests of password values where necessary. 2024-07-28 19:56:36 +08:00
Dimitrij
9dac0eeaac Updating due https://github.com/mRemoteNG/mRemoteNG/issues/243 2024-07-16 20:55:18 +01:00
Dimitrij
8dac393bb4 libs update 2024-07-10 10:26:50 +01:00
Dimitrij
287d1a5575 Merge pull request #2611 from Wolvverine/v1.77.3-dev
correct registry path
2024-07-05 22:31:42 +01:00
Michał Panasiewicz
20278e0e53 correct registry path 2024-07-05 20:50:41 +02:00
Dimitrij
a3c3ec8c5c lib updates 2024-06-20 10:22:13 +01:00
Dimitrij
3039b25a66 versioning fix 2024-06-11 14:11:52 +01:00
Dimitrij
0b7ce92af8 libs update 2024-06-11 11:36:17 +01:00
Dimitrij
e3ec521a1d Merge pull request #2601 from xRushG/RegSettings
Enhancement of Registry Settings capabilities
2024-06-11 11:21:39 +01:00
xRushG
88999263a7 Finalize Update Options Page
This commit finalizes the Update Options Page with the following changes:
- Removed unnecessary methods due to new features of the registry handler class.
- Updated and added comments to improve code readability and understanding.
- Implemented UI optimizations such as disabling the frequency control and showing "Never" in the combobox.
- Enabled the password storing ability, making it functional but not yet usable.
- Applied some code optimizations for improved efficiency.
2024-06-11 10:07:33 +02:00
xRushG
9687ccd01d Finalize Credentials Options Page
This commit finalizes the Credentials Options Page with the following changes:
- Updated and added comments to improve code readability and understanding.
- Enabled the password storing ability, making it functional but not yet usable.
- Applied some code optimizations for improved efficiency.
2024-06-11 09:44:20 +02:00
xRushG
ca62502499 Update dependent registry options settings to use new WindowsRegistryEntry class. 2024-06-11 09:08:37 +02:00
xRushG
8b3a68f58e Removing all unnecessary old files 2024-06-11 09:07:04 +02:00
xRushG
08eb35a360 Refactor registry settings interaction classes.
This commit refactors the registry settings interaction classes by consolidating the multiple entry classes for int, string, bool, etc., into a single class that supports multiple data types. This change simplifies the code and enhances readability.

- Consolidate multiple entry classes (int, string, bool, etc.) into a single class
- Introduce WindowsRegistryEntry<T> to support multiple data types
2024-06-11 09:03:34 +02:00
Dimitrij
dec82b41f2 lib update 2024-06-10 21:14:52 +01:00
Dimitrij
b9ab5c76f7 Merge pull request #2597 from CodeCasterNL/v1.77.3-dev
Remember the opened connection file on relaunch
2024-06-07 13:33:53 +01:00
Dimitrij
6de0c536e8 Merge pull request #2591 from tecxx/develop-orig
add Clickstudios Passwordstate API connector
2024-06-07 13:32:56 +01:00
tecxx
3f0aca97bf Merge branch 'mRemoteNG:v1.77.3-dev' into develop-orig 2024-06-06 09:17:37 +02:00
Dimitrij
ccb51a2603 Merge pull request #2599 from xRushG/fix2592
Fix for #2592 compiler issue
2024-05-30 10:03:35 +01:00
xRushG
99d9e70921 Fix #2592: Prevent GeneralAppInfo.ApplicationVersion from being set in Unit Tests. Not needed for tests. 2024-05-29 15:20:56 +02:00
CodeCasterNL
b8b54271dd Save ConnectionFilePath, fix typo in identifier 2024-05-25 17:13:11 +02:00
Dimitrij
49a1549e5a Merge pull request #2596 from xRushG/OpenLogBug
Log File Opening Fails on Notification Settings Page
2024-05-24 09:12:38 +01:00
xRushG
b3f936c194 - Added my missed comment for outlined LocalSettingsManager
- Fixed a bug that occurred when trying to open the log file on the Notification settings page.
- Removed unnecessary file association when user tries to open the log file on the Notification page. The "choose file" dialog handles the extension as it is fixed on .log
- Implemented fallback to open file explorer to the specified file location if mRem fails to open the log file.
2024-05-23 21:29:35 +02:00
Robert Rostek
f3b10d4c20 update credential vault documentation 2024-05-04 18:05:28 +02:00
Robert Rostek
94b17037d0 add Clickstudios Passwordstate API connector 2024-05-04 13:49:17 +02:00
Dimitrij
83f3846ce6 lib updates
correct build number calculations - now its days from last release + hour + minute of build
some changes to migrate to json schema + preparation of using db to save settings
2024-05-03 14:40:52 +01:00
Dimitrij
711a751117 Merge pull request #2589 from xRushG/Fix-2540
LocalSettingsManager class implementation is missing (#2540)
2024-04-29 13:56:53 +01:00
xRushG
e013e32792 Fix #2540
LocalSettingsManager class implementation is missing
2024-04-29 14:34:36 +02:00
Dimitrij
6e64b09256 Merge pull request #2571 from mRemoteNG/dependabot/nuget/mRemoteNG/System.Data.SqlClient-4.8.6
Bump System.Data.SqlClient from 4.8.5 to 4.8.6 in /mRemoteNG
2024-03-11 14:31:41 +00:00
dependabot[bot]
e32d268587 Bump System.Data.SqlClient from 4.8.5 to 4.8.6 in /mRemoteNG
Bumps [System.Data.SqlClient](https://github.com/dotnet/corefx) from 4.8.5 to 4.8.6.
- [Release notes](https://github.com/dotnet/corefx/releases)
- [Commits](https://github.com/dotnet/corefx/commits)

---
updated-dependencies:
- dependency-name: System.Data.SqlClient
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 14:30:32 +00:00
Dimitrij
05635dec93 Merge pull request #2559 from xRushG/v1.77.3-dev
Configuration via windows registry (updates and credentials)
2024-02-19 18:20:44 +00:00
Schmitti91
e694923d33 Merge branch 'v1.77.3-dev' of https://github.com/xRushG/mRemoteNG into v1.77.3-dev 2024-01-28 10:16:30 +01:00
Schmitti91
7322683465 Fix AppVeyor CA2200 and optimize CreateOrSetRegistryValue method 2024-01-28 10:15:34 +01:00
Schmitti91
64688f3512 Add documentation page for registry settings (credentials) 2024-01-27 21:01:38 +01:00
Schmitti91
762760af2f Adding the configuration capability for the Credentials page through the Windows Registry. 2024-01-27 20:55:12 +01:00
Schmitti91
48e6881401 Merge branch 'v1.77.3-dev' of https://github.com/xRushG/mRemoteNG into v1.77.3-dev 2024-01-26 21:13:22 +01:00
Schmitti91
95c958136f Add Dokupage for registry settings (update) 2024-01-26 21:12:24 +01:00
Schmitti91
53a6be0f82 remove placeholder code by commenting it out in its current state. (needed for later commit) 2024-01-26 21:07:04 +01:00
Schmitti91
0b4d95be1c Renameing the common setting name "CheckForUpdate Asked" to "AllowPromptForUpdates Preference" for consistency in naming conventions. 2024-01-23 21:43:29 +01:00
Schmitti91
aad3948475 make ProxyAuthPass not usable, placeholder code 2024-01-23 16:24:28 +01:00
Schmitti91
093370081e Add capability to set Update Settings via Registry
This commit enhances the functionality of the WindowsRegistryAdvanced class to provide the capability to set up Update Settings through the Windows Registry. The changes include the addition of methods or modifications that allow users to configure update-related settings using the Registry.
2024-01-23 16:14:36 +01:00
Schmitti91
33426ceee9 Add GetDwordValue method to WindowsRegistryAdvanced
This commit introduces the GetDwordValue method in the WindowsRegistryAdvanced class, allowing the retrieval of DWORD values from the Windows Registry. The implementation uses int.TryParse for efficient parsing and handles default values gracefully.
2024-01-23 14:29:07 +01:00
Schmitti91
5f5700b948 extend Registry handling capabilities in preparation for Registry settings
Enhanced the functionality of Registry handling in preparation for managing Registry settings
2024-01-23 12:54:43 +01:00
Risae
802e9abfef CI: Create build-x86_64.yml 2024-01-11 17:46:08 +01:00
Dimitrij
45149d6547 Merge pull request #2549 from magriggs/issue-2487
Issue 2487
2024-01-05 12:07:05 +00:00
23439176+magriggs@users.noreply.github.com
595681a982 Remove boilerplate code 2024-01-05 14:28:33 +08:00
23439176+magriggs@users.noreply.github.com
e1cac723d6 First commit of SecureCRT import functionality. 2024-01-05 13:59:36 +08:00
Dimitrij
683f84f053 Merge pull request #2545 from magriggs/issue-1308
Some fixes for issue mRemoteNG#1308. Inspired by dockpanelsuite/dockp…
2024-01-03 13:15:15 +00:00
23439176+magriggs@users.noreply.github.com
b6d882a06f Some fixes for issue mRemoteNG#1308. Inspired by dockpanelsuite/dockpanelsuite#526 (comment). Main change is to enable minimize and close buttons 2024-01-03 20:39:36 +08:00
Dimitrij
9d4bfbcb1c lib updates 2023-12-13 21:56:25 +00:00
Dimitrij
b563747046 Merge pull request #2534 from jcefoli/v1.77.3-dev
Handle case where COM object becomes separated from RCW
2023-12-13 21:47:47 +00:00
Joe Cefoli
1ebd0a430f Remove unnecessary line break 2023-12-13 14:42:13 -05:00
Joe Cefoli
ef4366be4d Handle case where COM object becomes sepatated from Runtime Callable Wrapper (resizing main window after disconnecting from fit to panel session) 2023-12-13 14:34:33 -05:00
Dimitrij
484283fef8 Merge pull request #2533 from tommwq/v1.77.3-dev
support local PowerShell connection
2023-12-13 11:02:10 +00:00
tommwq
b546a48a5f support local PowerShell connection 2023-12-12 23:26:58 +08:00
Dimitrij
51bd64d005 Merge pull request #2530 from BestiaPL/v1.77.3-dev
Update Language.pl.resx
2023-12-11 10:32:02 +00:00
Andrzej Rudnik
2c65d12b92 Update Language.pl.resx 2023-12-05 21:17:59 +01:00
Dimitrij
c43a3b5115 Merge pull request #2529 from xRushG/v1.77.3-dev
Pre-build event powershell code update #2524
2023-12-04 17:47:04 +00:00
Schmitti91
515778b13d Pre-build event powershell code update/fix 2023-12-02 21:59:56 +01:00
Dimitrij
bb4b9ce9e7 Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2023-11-29 09:42:06 +00:00
Dimitrij
1d6707fecd #2528
fix typo
2023-11-29 09:41:56 +00:00
Dimitrij
5b2a46ed91 Merge pull request #2523 from zeze0556/v1.77.3-dev
fixed mysql error
2023-11-20 09:27:46 +00:00
unknown
24fa97da4c fixed mysql error 2023-11-20 10:21:59 +08:00
Dimitrij
b0109c2581 lib update 2023-11-10 11:29:18 +00:00
Dimitrij
20f237ec4c Merge pull request #2519 from BestiaPL/v1.77.3-dev
Update Language.pl.resx
2023-11-04 23:38:09 +00:00
Andrzej Rudnik
6ea535ae29 Update Language.pl.resx 2023-11-04 16:59:46 +01:00
Dimitrij
57ca8a3eee Merge pull request #2514 from Schmitti91/v1.77.3-dev
Update Registry interaction capabilities.
2023-10-24 13:33:12 +01:00
Schmitti91
307ea42a0f Cleanup of references and correction of comments. 2023-10-23 07:58:13 +02:00
Schmitti91
ac41c04f67 mRemoteNG tools WindowsRegistry has been revised and the Windows Registry reading capabilities have been expanded in preparation for working with Registry Keys options. The "RegistryHive" enum was deleted because it is contained in "Microsoft.Win32". 2023-10-22 12:18:42 +02:00
Dimitrij
b3496e79de lib update 2023-10-17 16:05:09 +01:00
Dimitrij
4f7aa755e3 Merge pull request #2508 from RFC1920/v1.77.3-dev-putty
bugfix for Putty import
2023-10-17 09:30:56 +01:00
Dimitrij
d3af50f009 lib updates 2023-10-16 13:59:04 +01:00
RFC1920
ba77a7b7c0 Update Putty registry import to fix connection name, username, and port setting 2023-10-16 05:32:34 -05:00
Dimitrij
666a0e1537 Merge pull request #2507 from RFC1920/v1.77.3-dev-putty
Add Putty registry import
2023-10-16 11:32:21 +01:00
RFC1920
96f4307910 Add Putty registry import 2023-10-16 04:50:35 -05:00
Dimitrij
81e997eb60 Merge pull request #2506 from Schmitti91/v1.77.3-dev
Enhancing the PowerShell Connection.
2023-10-16 09:56:50 +01:00
Schmitti91
7132c6e7c2 Removing the "-NoProfile" option from PowerShell.exe parameters. 2023-10-15 21:48:01 +02:00
Schmitti91
cb01e92fe2 Enhancing the PowerShell Connection. The PowerShell script is designed to simplify multiple login attempts to a remote host using user-provided credentials, or not. In addition, granular error handling has been added to prevent errors, such as the conversion of empty or null strings to SecureString. Furthermore, hostname, username, and password are now passed as parameters in the PowerShell script block (#2195). 2023-10-15 21:13:36 +02:00
Dimitrij
2c9c512d74 Merge pull request #2503 from WojciechNagorski/new-sshnet
Update SSH.NET to 2023.0.0
2023-10-11 13:55:07 +01:00
Wojciech Nagórski
8d05c9040b Update SSH.NET to 2023.0.0 2023-10-11 14:45:01 +02:00
Dimitrij
4e994fb202 Merge pull request #2502 from BestiaPL/v1.77.3-dev
Updated Polish translation
2023-10-09 16:45:55 +01:00
Dimitrij
ab2a778694 Merge pull request #2496 from tecxx/develop-orig
use pwfile instead of cleartext password for putty connections
2023-10-09 09:27:00 +01:00
Andrzej Rudnik
115375820d Update Language.pl.resx 2023-10-08 20:51:22 +02:00
Andrzej Rudnik
8cb753916b Update Language.pl.resx 2023-10-05 23:36:45 +02:00
Robert Rostek
ec3a0cee9b remove unnecessary usings 2023-10-03 10:55:27 +02:00
Robert Rostek
13f8f82537 update changelog 2023-10-03 10:53:34 +02:00
Robert Rostek
54544dd2aa use pwfile instead of pw for puttyng 2023-10-03 10:52:41 +02:00
Dimitrij
ac99115424 Merge pull request #2482 from simonai1254/fix-2195
Fix 2195
2023-08-31 16:37:41 +01:00
Simon Monai
d6c6038193 Update CHANGELOG.md 2023-08-30 23:55:40 +02:00
Simon Monai
c97b84e4a2 Quote variable for #2195
In order to interpret variable as string and not arbitrary code
2023-08-30 23:46:42 +02:00
Dimitrij
6698ec0b06 Update README.md 2023-08-02 13:14:28 +01:00
Dimitrij
290b1c4de5 Update README.md 2023-08-02 13:14:02 +01:00
Dimitrij
d497a50727 Update README.md 2023-08-02 13:13:23 +01:00
Dimitrij
2837c91f5e Update README.md 2023-08-02 13:12:34 +01:00
Dimitrij
9a717f28c6 upd 2023-08-02 13:03:14 +01:00
Dimitrij
e416c2c9c9 upd 2023-08-02 13:01:21 +01:00
Dimitrij
331cdaa6ce upd 2023-08-02 12:54:27 +01:00
Dimitrij
aa329b1a9a upd 2023-08-02 12:51:30 +01:00
Dimitrij
16c080942d upd table 2023-08-02 12:47:15 +01:00
Dimitrij
4acc111b3d upd 2023-08-02 12:39:29 +01:00
Dimitrij
afe453d371 upd 2023-08-02 12:37:25 +01:00
Dimitrij
e93c120dac update table 2023-08-02 12:34:16 +01:00
Dimitrij
2f701458f4 mistype fix 2023-08-02 12:27:30 +01:00
Dimitrij
6a35961dfb Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2023-08-02 12:24:16 +01:00
Dimitrij
1a90095ba3 add add-ons list 2023-08-02 12:24:05 +01:00
Dimitrij
5dc87213b5 Merge pull request #2462 from jurepurgar/rdgw-access-token
Support for gatewayaccesstoken
2023-07-18 16:24:49 +01:00
Jure Purgar
ff8044b09b Delete resx 2023-07-18 16:23:48 +02:00
Jure Purgar
f1fa40f6fd Initial implementation of gatewayaccesstoken support 2023-07-18 16:07:06 +02:00
Dimitrij
9bc5b62828 enable signing 2023-07-15 22:44:26 +01:00
Dimitrij
5aae586812 lib update 2023-07-15 22:11:03 +01:00
Dimitrij
bc5e5be42e update cert 2023-07-15 22:06:47 +01:00
Dimitrij
be68573378 lib updates 2023-07-05 14:33:39 +01:00
Dimitrij
cf0bc3d270 fix links 2023-07-05 12:00:14 +01:00
Dimitrij
d5773eb2e9 doc update
adding image, fix link
2023-07-05 09:29:19 +01:00
Dimitrij
50523e5b67 update docs 2023-07-04 15:59:48 +01:00
Dimitrij
feeca86c6a small fix 2023-06-21 21:03:57 +01:00
Dimitrij
a2e2671483 update links 2023-06-21 20:55:35 +01:00
Dimitrij
0b4d6ef8ef update index 2023-06-21 20:48:23 +01:00
Dimitrij
bdf0e532a5 #2447
add screenshots for themes
2023-06-21 20:46:37 +01:00
Dimitrij
d8cf72d09b Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2023-06-21 12:08:25 +01:00
Dimitrij
6c3ec8f058 update puttyng to actual version 2023-06-21 12:08:07 +01:00
Dimitrij
fbd9b76a09 Merge pull request #2449 from simonai1254/update_documentation
Improve PuttyNG Issue Description
2023-06-21 09:41:55 +01:00
Simon Monai
bee216220a Improve PuttyNG Issue Description
Update PuttyNG Documentation
Do not recommend insecure changes
2023-06-21 09:29:05 +02:00
Dimitrij
4ca7f34989 code corrections 2023-06-16 19:24:33 +01:00
Dimitrij
51015e6b51 lib update 2023-06-16 19:24:00 +01:00
Dimitrij
46100d6d94 lib update 2023-06-08 10:58:05 +01:00
Dimitrij
c94eac3863 Merge pull request #2416 from BlueBlock/streamline_build_scripts_for_appveyor
modify build scripts for appveyor
2023-04-07 15:19:44 +01:00
BlueBlock
965b0e5b6d Update update_and_upload_assemblyinfocs.ps1
enable assemblyinfo.cs update when not (CI)
2023-03-31 11:27:49 -04:00
BlueBlock
000cea1dda test repo name 2023-03-31 11:16:40 -04:00
BlueBlock
6d4d60e3b1 Update postbuild.ps1
fix if matching
2023-03-31 11:02:49 -04:00
BlueBlock
9957282bfa Update postbuild_installer.ps1
disable assemblyinfo.cs update temporarily
2023-03-31 11:01:48 -04:00
BlueBlock
9b603dd956 Update postbuild.ps1
check variables
2023-03-31 10:10:10 -04:00
BlueBlock
759ee55780 modify build scripts for appveyor 2023-03-31 09:14:35 -04:00
Dimitrij
93b2edb5a5 Merge pull request #2415 from BlueBlock/fix_window_restore_resize
Update RdpProtocol8.cs
2023-03-28 14:59:36 +01:00
BlueBlock
4d49c14bb9 Update RdpProtocol8.cs
resize when restored from minimize
2023-03-28 08:49:52 -04:00
Dimitrij
6398808a0a corrected slashes 2023-03-25 22:29:53 +00:00
Dimitrij
64e20f3665 update 2023-03-25 21:45:22 +00:00
Dimitrij
3b542d8868 excluding AssemblyInfo from accidental update in repo 2023-03-25 21:40:42 +00:00
Dimitrij
d5af0e43a5 add condition 2023-03-25 18:44:40 +00:00
Dimitrij
7a8ef87dc7 run string as a command 2023-03-25 18:33:50 +00:00
Dimitrij
7a5293cde3 add wrapping ' 2023-03-25 18:24:08 +00:00
Dimitrij
26400631a0 replace " by ' to avoid path brake 2023-03-25 18:20:46 +00:00
Dimitrij
97a5c584be increase build number only then release in appveyor 2023-03-25 18:16:03 +00:00
Dimitrij
0700b6573c Merge pull request #2413 from BlueBlock/fix_running_of_unit_tests
Fix running of unit tests
2023-03-25 17:17:32 +00:00
Dimitrij
d8f66a4188 Merge pull request #2412 from BlueBlock/update_build_script
Update find_vstool.ps1
2023-03-25 16:39:49 +00:00
BlueBlock
c22971cf54 add unit test references
unit tests were not able to run since the refs were missing
2023-03-25 12:08:52 -04:00
BlueBlock
9d2dd5dd93 remove variable not used 2023-03-25 12:08:02 -04:00
BlueBlock
c19d512631 Update Logger.cs
code formatting and using adjustment
2023-03-25 12:07:28 -04:00
BlueBlock
9efda5fef3 lib update 2023-03-25 12:06:53 -04:00
BlueBlock
a27cdcfdb5 Update find_vstool.ps1
Do not attempt to verify the fingerprint since it changes often. It seems to be overkill to check it.
2023-03-25 12:03:37 -04:00
Dimitrij
5667a07b25 Merge pull request #2411 from BlueBlock/fix_log4net_logging
fix log4net logging
2023-03-25 07:04:21 +00:00
BlueBlock
7d0bd85466 fix log4net logging 2023-03-24 14:49:27 -04:00
Dimitrij
4f269442a6 Merge pull request #2410 from BlueBlock/fix_notificiation_bug_introduced
Fix notification bug introduced
2023-03-24 18:09:14 +00:00
BlueBlock
16d182fca2 Update NotificationPanelMessageWriter.cs
fix notification bug, text not displaying
2023-03-24 11:53:05 -04:00
BlueBlock
6d1a206cc9 code formatting 2023-03-24 11:51:33 -04:00
Dimitrij
d8a7fdbf4f lib update 2023-03-24 15:22:10 +00:00
Dimitrij
516b365ebc Merge pull request #2401 from BlueBlock/fix_options_ui_sizing
options pages size and position fixes
2023-03-24 07:16:15 +00:00
BlueBlock
6da6a5ede9 options pages size and position fixes
- options page was too small
- some tabs needed adjustment for spacing
2023-03-24 03:02:27 -04:00
Dimitrij
67244f1957 Merge pull request #2400 from BlueBlock/fix_database_columns_and_some_tests
Fix database columns and some tests
2023-03-24 06:08:48 +00:00
BlueBlock
0a304e9a03 add missing objects needed in tests 2023-03-24 01:35:37 -04:00
BlueBlock
05154af606 code formatting 2023-03-24 01:34:51 -04:00
BlueBlock
7454b15ec9 adjust app to use 2.8 xsd schema 2023-03-24 01:33:30 -04:00
BlueBlock
38f435f639 Update RemoteDesktopConnectionDeserializer.cs
add missing serializer
2023-03-24 01:32:21 -04:00
BlueBlock
5f38ec7210 Update SqlVersion29To30Upgrader.cs
add missing DB column UserViaAPI
2023-03-24 01:31:41 -04:00
BlueBlock
ca143bf969 Update mremoteng_confcons_v2_8.xsd
inherit should be boolean
2023-03-24 01:29:39 -04:00
BlueBlock
402e5c3665 Create mRemoteNG.lutconfig
live test runner config file
2023-03-24 01:27:52 -04:00
BlueBlock
290dbcc3ed Update SqlDatabaseMetaDataRetriever.cs
- add missing db column UserViaAPI
- formatting and remove commented code
2023-03-24 01:26:44 -04:00
Dimitrij
a7749c70e7 Merge pull request #2399 from BlueBlock/fix_database_use
Fix database use
2023-03-23 22:01:40 +00:00
BlueBlock
9f0cfd5f22 Update CsvConnectionsDeserializerMremotengFormatTests.cs
fix test
2023-03-23 17:47:27 -04:00
BlueBlock
f47434c09e Merge remote-tracking branch 'upstream/v1.77.3-dev' into fix_database_use 2023-03-23 17:44:39 -04:00
BlueBlock
795a4b571e Update AbstractConnectionRecord.cs
defaults set not needed
2023-03-23 17:26:11 -04:00
BlueBlock
f71727e05e Update SqlConnectionsUpdateChecker.cs
code formatting
2023-03-23 16:34:37 -04:00
BlueBlock
d2fa8e86b1 Update DatabaseConnectorFactory.cs
add TODO
2023-03-23 16:34:15 -04:00
BlueBlock
23dcd9d30f Update MySqlDatabaseConnector.cs
add TODO
2023-03-23 16:33:55 -04:00
BlueBlock
d6890c6ecd refactor to newer c# code statements 2023-03-23 16:32:14 -04:00
BlueBlock
b1a6ba78d4 fix database upgrades
- fix tested db upgrading for each version
- fix version check for 3.0
2023-03-23 16:31:28 -04:00
BlueBlock
e6abe3f3a1 simple code reformatting 2023-03-23 16:30:04 -04:00
BlueBlock
6c32540ecb refactor class mssql to sql
refactor class mssql to sql
code formatting
refactor null check
use db TRUNCATE instead of DELETE (mysql warns about mass DELETE)
2023-03-23 16:27:17 -04:00
BlueBlock
951ad5cd0a Update ConnectionsService.cs
use universal time for db time
2023-03-23 16:23:45 -04:00
BlueBlock
5f56477123 Update MiscTools.cs
- add GetBooleanValue method for getting bool from databases
- use universal time for db time
2023-03-23 16:22:38 -04:00
BlueBlock
3180f38a1d Update AbstractConnectionRecord.cs
fix to add redirectdiskdrives default value
2023-03-23 16:21:34 -04:00
BlueBlock
07f15993e5 Update SettingsLoader.cs
refactor null check
2023-03-23 16:20:55 -04:00
BlueBlock
fc8e9c7689 rename class from mssql to sql
This class is not dedicated to mssql but is used by all sql databases. Rename to reflect this.
2023-03-23 16:20:01 -04:00
BlueBlock
7cb20b9e28 Update Runtime.cs
use universal time for stored DB time since users can span time zones
2023-03-23 15:16:28 -04:00
BlueBlock
ffc2351d64 Update ConnectionsFileInfo.cs
latest db version should be 3.0
2023-03-23 15:15:36 -04:00
Dimitrij
f10fec61ac Merge pull request #2398 from BlueBlock/fix_deserializer_test
Update CsvConnectionsDeserializerMremotengFormatTests.cs
2023-03-23 16:39:01 +00:00
BlueBlock
e41200067c Update CsvConnectionsDeserializerMremotengFormatTests.cs
fix test, missing changes needed for RedirectDrives PR
2023-03-23 12:18:28 -04:00
Dimitrij
30f6d3dde7 Merge pull request #2397 from BlueBlock/fix_remove_exception_test
Update ProgramRoot.cs
2023-03-21 20:59:32 +00:00
BlueBlock
7f9dcb11f0 Update ProgramRoot.cs
remove exception test
2023-03-21 16:49:59 -04:00
Dimitrij
d5fa2f62c0 Merge pull request #2396 from BlueBlock/fix_load_misssing_localconnectionproperties_xml_file
Fix load misssing localconnectionproperties xml file
2023-03-21 20:44:59 +00:00
Dimitrij
fa7967190d Merge pull request #2395 from integratorbit/v1.77.3-dev
Improve Disk Drive Redirection
2023-03-21 20:33:33 +00:00
BlueBlock
20e04c0d75 resolve conflicts 2023-03-21 16:04:32 -04:00
BlueBlock
d5eea9db20 Merge remote-tracking branch 'upstream/v1.77.3-dev' into pr/2395 2023-03-21 16:00:50 -04:00
BlueBlock
8cb598ce25 Update FileDataProvider.cs
fix creation of file LocalConnectionProperties.xml if it does not exist
2023-03-21 15:26:01 -04:00
BlueBlock
f3a57d7f23 move filename value LocalConnectionProperties.xml into settings file 2023-03-21 15:25:32 -04:00
BlueBlock
14e47def9d Update SqlDatabaseMetaDataRetriever.cs
fix exception casting int64 to int32, unbox and cast to int
2023-03-21 15:24:49 -04:00
Dimitrij
7573081d7a Merge pull request #2394 from BlueBlock/fix_rdp_operation
Fix RDP operation
2023-03-21 18:48:56 +00:00
Dimitrij
aaca581324 Merge pull request #2393 from BlueBlock/do_not_display_splash_on_taskbar
Do not show splash on taskbar
2023-03-21 18:06:52 +00:00
BlueBlock
43c2797a51 Update ProgramRoot.cs
do not show splash on taskbar
2023-03-21 13:56:55 -04:00
integratorbit
da6bbf65f0 Improve Disk Drive Redirection 2023-03-21 14:31:15 -03:00
BlueBlock
7d0cbf423e add resize fallback
Add resize fallback if the target OS fails to resize using the most current method. (for example, this occurs with Server2008R2)
2023-03-21 13:03:21 -04:00
BlueBlock
d94eab71da Update RdpProtocol8.cs
remove test code
2023-03-21 12:58:58 -04:00
BlueBlock
b0a8ccc5b6 multiple RDP issues fixed
- fix scale of RDP session when moving between 4k and 1080 monitors etc.
- fix inefficient continuous RDP screen resizing while the window size is changed
- add a RDP version check before attempting to use each RDP version and properties
2023-03-21 12:23:59 -04:00
BlueBlock
5cbf1f1568 adjust method access level of common protocol methods 2023-03-21 12:22:20 -04:00
BlueBlock
22cde74db2 Delete RdpProtocol6.cs
class renamed to RdpProtocol
2023-03-21 12:07:18 -04:00
BlueBlock
cdc3759c04 Update Optional.cs
- use more efficient empty assignments
- use string interpolation
- adjust method access to minimal needed
2023-03-21 12:06:38 -04:00
BlueBlock
38abc8a167 Update NotificationPanelMessageWriter.cs
check for object _messageWindow before using it to avoid an exception
2023-03-21 12:04:52 -04:00
BlueBlock
7c7c7086ce Update RdpProtocolFactory.cs
class RdpProtocol6 renamed to RdpProtocol
2023-03-21 12:04:03 -04:00
BlueBlock
50daf64025 Update ProtocolBase.cs
- add check for object _interfaceControl before using it
- adjust methods to protected where appropriate
- remove unused using
2023-03-21 12:03:28 -04:00
BlueBlock
dc38df5389 Update ConnectionsService.cs
use object initializer and remove unused using
2023-03-21 12:00:54 -04:00
BlueBlock
a46b2c9d98 Update ProtocolFactory.cs
remove unused usings
2023-03-21 11:57:34 -04:00
BlueBlock
200756361c rename base class of RDP
So it is consistent with other protocols, rename the RDP base class to not reflect a version.
2023-03-21 11:55:17 -04:00
Dimitrij
877a1e4cd0 Merge pull request #2391 from BlueBlock/add_set_devenvdir_to_prebuild
Update mRemoteNG.csproj
2023-03-20 21:16:18 +00:00
BlueBlock
a382206f5a Update mRemoteNG.csproj
add setting of DevEnvDir in prebuild
2023-03-20 16:31:22 -04:00
Dimitrij
1af7a622a6 Merge pull request #2388 from BlueBlock/fix_remove_unsused_class
Delete RDPVersions.cs
2023-03-17 17:54:50 +00:00
Dimitrij
3f95b2aa7e Merge pull request #2387 from BlueBlock/fix_exception_in_disposeinterface
Update ProtocolBase.cs
2023-03-17 17:48:43 +00:00
BlueBlock
b7871e2e04 Delete RDPVersions.cs
Class is unused and not needed.
2023-03-17 13:18:14 -04:00
BlueBlock
6b6ceda497 Update ProtocolBase.cs
check if object is disposed before working with it
2023-03-17 13:07:58 -04:00
Dimitrij
b01b8e4bc8 adjust installer script 2023-03-17 00:42:46 +00:00
Dimitrij
20f7cb1cd0 update move installer 2023-03-17 00:17:52 +00:00
Dimitrij
3e1ee0056d small amendments 2023-03-16 23:01:06 +00:00
Dimitrij
a3a851e57f Merge pull request #2383 from BlueBlock/fix_null_check_not_needed
Update PuttySessionsRegistryProvider.cs
2023-03-16 20:10:57 +00:00
BlueBlock
cf650d4318 use more efficient array 2023-03-16 16:10:01 -04:00
Dimitrij
58e7420f04 Merge pull request #2386 from BlueBlock/fix_suppress_com_warnings_on_release_build
Update mRemoteNG.csproj
2023-03-16 19:24:18 +00:00
Dimitrij
aedaf084d9 Merge pull request #2382 from BlueBlock/fix_more_CA1416_warnings
fix more CA1416 warnings
2023-03-16 19:04:47 +00:00
BlueBlock
c18f638989 Update mRemoteNG.csproj
suppress com warnings on release build, but display warnings on debug builds
2023-03-16 15:00:46 -04:00
BlueBlock
fb50cdc058 Update PuttySessionsRegistryProvider.cs
remove unreachable code
- no need to test for null, PuttySessionsKey is a const with a value set on instantiation
2023-03-16 14:35:39 -04:00
BlueBlock
68e702c344 fix more CA1416 warnings 2023-03-16 14:15:44 -04:00
Dimitrij
651b18a8b3 Merge pull request #2381 from BlueBlock/fix_obsolete_SHA1CryptoServiceProvider
Update PuttyKeyFileGenerator.cs
2023-03-16 17:11:53 +00:00
BlueBlock
2174e56407 Update PuttyKeyFileGenerator.cs
Replace use of obsolete SHA1CryptoServiceProvider with replacement call.
2023-03-16 12:59:28 -04:00
Dimitrij
ea27a4da02 Merge pull request #2380 from BlueBlock/fix_appveyor_bulk_of_changes
appveyor build automation
2023-03-16 16:50:53 +00:00
BlueBlock
321fd1162b appveyor build automation
bulk of the changes for appveyor automation
2023-03-16 11:08:27 -04:00
Dimitrij
c51f38ddc7 Merge pull request #2379 from BlueBlock/fix_appveyor
additional appveyor change
2023-03-15 19:05:36 +00:00
BlueBlock
b34cd1acc5 additional appveyor change 2023-03-15 14:51:04 -04:00
Dimitrij
43f20bb83a Merge pull request #2378 from BlueBlock/fix_adj_appveyor_build
appveyor build adjustment
2023-03-15 16:57:16 +00:00
Dimitrij
79b8ddef15 Merge pull request #2377 from BlueBlock/fix_putty_registry_watcher
Fix putty registry watcher
2023-03-15 16:49:29 +00:00
BlueBlock
2642ea0601 appveyor build adjustment
Further work to test appveyor builds
2023-03-15 12:46:37 -04:00
Dimitrij
7a2f934f6a Merge pull request #2376 from BlueBlock/add_rdp_protocol_rdc11
add rdp protocol rdc11
2023-03-15 12:49:03 +00:00
BlueBlock
f299fefcdc Update PuttySessionsRegistryProvider.cs
Remove previous fixes return statement
2023-03-15 08:22:29 -04:00
BlueBlock
209319f460 Update PuttySessionsRegistryProvider.cs
Update the latest fix for the putty registry watcher, to create the registry path if it does not exist, so the watcher is able to always run.
2023-03-15 08:14:52 -04:00
BlueBlock
5ec4f4dcea add rdp rdc11 2023-03-15 08:04:01 -04:00
Dimitrij
16f67d58d1 Merge pull request #2372 from BlueBlock/fix_exception_when_no_putty_sessions_exist
fix exception when no putty sessions exist
2023-03-14 19:32:10 +00:00
Dimitrij
542d794ab4 Merge pull request #2373 from BlueBlock/fix_exception_with_notification_on_app_closing
Update MessageFocusDecorator.cs
2023-03-14 17:03:33 +00:00
Dimitrij
ede1573b56 Merge pull request #2375 from BlueBlock/fix_exception_for_protocolbase_when_closing_app
Update ProtocolBase.cs
2023-03-14 16:24:43 +00:00
Dimitrij
bc8eec8887 Merge pull request #2374 from BlueBlock/add_rdp_protocol_rdc10
add rdc10 protocol
2023-03-14 15:35:38 +00:00
Dimitrij
59b0654b95 Merge pull request #2371 from BlueBlock/fix_installer_build_order
Update mRemoteNG.sln
2023-03-14 15:24:05 +00:00
Dimitrij
cae3477591 Merge pull request #2370 from BlueBlock/fix_file_fragments
Update FilesFragment.wxs
2023-03-14 15:22:30 +00:00
BlueBlock
6a3115b80a Update ProtocolBase.cs
Do not attempt to dispose the control if the control is already closed, closing or disposed.
2023-03-14 04:44:42 -04:00
BlueBlock
1232d7c288 add rdc10 protocol 2023-03-13 22:38:13 -04:00
BlueBlock
8e1b4c9271 Update MessageFocusDecorator.cs
do not attempt to focus the notification panel if the application is closing, otherwise exceptions will occur since _frmMain is closing
2023-03-13 20:08:48 -04:00
BlueBlock
0f8810e22a fix exception when no putty sessions exist
When putty is not installed or no sessions exist in the registry, an exception is thrown when starting the eventwatcher. Only start the eventwatcher if sessions registry path exists.
2023-03-13 18:53:00 -04:00
BlueBlock
7bbff38b6b Update mRemoteNG.sln
fix install build order by also including building mremoteng
2023-03-13 18:47:14 -04:00
BlueBlock
4a7b8fa250 Update FilesFragment.wxs
fix some dll paths and remove unused dll
2023-03-13 18:44:26 -04:00
Dimitrij
53acc94976 Merge pull request #2369 from BlueBlock/fix_find_vstool.ps1
Update find_vstool.ps1
2023-03-13 14:11:00 +00:00
BlueBlock
ab8d83b12d Update find_vstool.ps1
add vs2022 cert thunbprint
fix function which tests if a file is executable
2023-03-13 09:46:27 -04:00
Dimitrij
713a0a6174 more fixes for CA1416 2023-03-11 13:13:19 +00:00
Dimitrij
a3b9695b81 lib replace 2023-03-11 12:38:53 +00:00
Dimitrij
85dd381bd9 lib update 2023-03-11 12:21:17 +00:00
Dimitrij
05b418e9b6 more fix for Warning CA1416 2023-03-11 12:20:19 +00:00
Dimitrij
40af584afe fix for Warning CA1416 2023-03-11 01:46:11 +00:00
Dimitrij
93fe32491b couple of fixes 2023-03-10 23:00:05 +00:00
Dimitrij
4b67fcb0d4 fix splash screen version logo 2023-03-09 09:12:40 +00:00
Dimitrij
0b0c92717d fix format to avoid error on file name 2023-03-08 22:15:25 +00:00
Dimitrij
4564cafa85 more fixes for CA1416 2023-03-08 21:50:23 +00:00
Dimitrij
2e21f8d03a add form 2023-03-08 20:51:58 +00:00
Dimitrij
4336254d56 fix naming after rename 2023-03-08 20:36:00 +00:00
Dimitrij
bc5e9279a5 fix naming to be inline with Others 2023-03-08 20:28:31 +00:00
Dimitrij
1bfbb956c2 fix CA1416: Validate platform compatibility
https://learn.microsoft.com/en-gb/dotnet/fundamentals/code-analysis/quality-rules/ca1416
2023-03-08 20:23:38 +00:00
Dimitrij
b336db773c Merge pull request #2367 from BlueBlock/update_build_scripts
Update build scripts
2023-03-08 19:32:06 +00:00
BlueBlock
30e7d2424c Merge remote-tracking branch 'upstream/v1.77.3-dev' into update_build_scripts 2023-03-08 14:08:46 -05:00
kmscode
cbb8c0234d fixed a few warnings 2023-03-05 20:10:32 -05:00
kmscode
95469107fd don't need to manually editbin for large address aware on x64 targets 2023-03-05 15:37:49 -05:00
Dimitrij
ba0058c0b9 fix installer paths 2023-03-04 22:49:23 +00:00
Dimitrij
8f35afe353 fix for portable version 2023-03-04 21:02:19 +00:00
Dimitrij
aaf219eb90 revert check due set variable explicitly in appveyor 2023-03-04 20:32:22 +00:00
Dimitrij
1167794d58 fix condition to work in appveyor env. 2023-03-04 18:38:12 +00:00
Dimitrij
929babd69a Update change log 2023-03-04 00:35:35 +00:00
Dimitrij
870b7c1ffd update links 2023-03-04 00:07:19 +00:00
Dimitrij
9ed9d835b9 file harvester update 2023-03-04 00:06:55 +00:00
Dimitrij
985feb4b91 name space sync 2023-03-03 23:25:18 +00:00
Dimitrij
c43c85bb21 lib Update
correction for update window
2023-03-03 22:19:38 +00:00
Dimitrij
038074131c add template for build versioning 2023-03-03 20:45:40 +00:00
Dimitrij
ab9156a7d3 Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2023-03-03 15:44:34 +00:00
Dimitrij
f4b76818e8 lib update 2023-03-03 15:42:33 +00:00
Dimitrij
12a399a354 Merge pull request #2364 from BlueBlock/update_sql_usage_instructions
update sql usage doc
2023-03-02 13:55:24 +00:00
BlueBlock
dfdbbea85c sql usage doc updated 2023-03-02 08:32:07 -05:00
BlueBlock
5fad5ec4c7 Merge remote-tracking branch 'upstream/v1.77.3-dev' into update_build_scripts 2023-03-02 08:28:10 -05:00
Dimitrij
fe94da4727 lib update 2023-03-02 09:42:43 +00:00
Dimitrij
361ae3af50 Merge pull request #2362 from BlueBlock/fix_use_of_sql_database
Fix use of sql database
2023-03-02 09:34:06 +00:00
BlueBlock
a2e302ebfa add check for appveyor only actions in scripts 2023-03-01 15:31:54 -05:00
BlueBlock
186ab9c00e Merge remote-tracking branch 'upstream/v1.77.3-dev' into update_build_scripts 2023-03-01 14:50:49 -05:00
BlueBlock
9a2453524a update db to 2.9 2023-03-01 14:19:41 -05:00
BlueBlock
3a2e128e98 add missing columns to serializer 2023-03-01 11:22:18 -05:00
BlueBlock
1bd2dbf9f0 modify schema to be consistent 2023-03-01 11:21:55 -05:00
BlueBlock
b7f880e7f8 modify sql bit columns to be consistent 2023-03-01 11:21:26 -05:00
BlueBlock
13cd926b4f add missing columns 2023-03-01 09:37:10 -05:00
BlueBlock
6fb7b1c6e4 update docs to reflect auto-schema generation 2023-03-01 07:29:31 -05:00
BlueBlock
8f35015a6c fix db upgrade
fix db upgrade 2.8->2.9
2023-03-01 07:11:45 -05:00
BlueBlock
a926bccb97 fix db upgrade
fix db upgrade 2.7->2.8
2023-03-01 07:11:30 -05:00
BlueBlock
b9f2abf5eb add db schema initialization on a new empty database 2023-03-01 07:10:29 -05:00
BlueBlock
8dc5bda171 Update SqlDatabaseVersionVerifier.cs
fix CRLF of file
2023-03-01 07:09:33 -05:00
Dimitrij
d24bdb543b lib update 2023-02-26 21:40:14 +00:00
BlueBlock
dc921161e4 Merge remote-tracking branch 'upstream/v1.77.3-dev' into update_build_scripts 2023-02-25 17:37:58 -05:00
Dimitrij
8e248cb545 lib update 2023-02-21 21:48:20 +00:00
BlueBlock
ae93be4cfb make website update optional 2023-02-20 12:39:29 -05:00
BlueBlock
42949fbe91 update build scripts to create update files 2023-02-20 05:21:11 -05:00
Dimitrij
21dd175456 lib update 2023-02-17 19:49:47 +00:00
BlueBlock
a3df0da26b widen the version label further 2023-02-16 16:55:40 -05:00
BlueBlock
6b9d4fd107 increase label width for version on splashscreen
Widen to support longer version numbers such as 1.77.3.1234
2023-02-16 16:27:17 -05:00
BlueBlock
fac2ae6399 Merge remote-tracking branch 'upstream/v1.77.3-dev' into update_build_scripts 2023-02-16 15:47:57 -05:00
Dimitrij
46732803c3 Merge pull request #2356 from BlueBlock/improve_options_page_speed
improve speed for the display of the options page
2023-02-16 20:16:47 +00:00
BlueBlock
39d205bd4d improve speed for the display of the options page
rather than create the options page on demand, instantiate the options page immediately upon app start though in the background using idle time.
2023-02-16 14:57:11 -05:00
Dimitrij
8e2bd7997e update "Known Issues" regarding how-to update PuttyNG to latest 2023-02-16 11:12:44 +00:00
Dimitrij
76db9a6c62 Merge pull request #2352 from pakass/SSH.NET-update
SSH.NET Update
2023-02-16 09:45:30 +00:00
pakass
c03d5e891d update Changelog 2023-02-15 15:15:55 +01:00
pakass
b21f6e8ce7 update SSH.NET 2023-02-15 15:11:22 +01:00
BlueBlock
4b916f1888 update build scripts 2023-02-14 19:38:08 -05:00
Dimitrij
1f80e5339b Merge pull request #2348 from BlueBlock/remove_mat_kit
Remove mat kit included unintentionally
2023-02-13 09:30:48 +00:00
BlueBlock
dc616f8ea1 remove mat kit included unintentionally
It appears the mat kit config was included along with some .xlf definitions on the csproj

Remove th mat kit and references
2023-02-12 16:39:30 -05:00
Dimitrij
dc6588243f libs update 2023-02-11 21:31:12 +00:00
Dimitrij
690d3b0d4e Merge pull request #2347 from savornicesei/simo/gh-2344-docs-log4net-patching
Documented manual patching of  log4net CVE-2018-1285 vulnerability #2344
2023-02-11 12:41:09 +00:00
Dimitrij
4bc5dffabb Merge pull request #2346 from BlueBlock/add_feature_to_auto_reconnect_without_clicking_check
Modify "auto reconnect" to have the ability to really auto-reconnect
2023-02-11 12:35:02 +00:00
Simona Avornicesei
55a1e4a544 Documented manual patching of log4net CVE-2018-1285 vulnerability #2344 2023-02-10 21:17:26 +02:00
BlueBlock
5cb32dd75a change reconnect timer from 2s to 5s
Change and increase the reconnect timer to avoid too frequent connection attempts.
2023-02-10 04:40:55 -05:00
BlueBlock
f858c9fe48 fix checkbox state 2023-02-10 04:39:13 -05:00
BlueBlock
0ac39af404 modify "auto reconnect" to really auto-reconnect
The auto-reconnect does not automatically reconnect but instead displays a reconnect dialog. A second Options checkbox is added to allow true auto-reconnect.
2023-02-09 13:41:31 -05:00
Dimitrij
fc757b236f lib update 2023-02-04 16:42:12 +00:00
Dimitrij
a921e6e3d4 Merge pull request #2340 from BlueBlock/set_default_theme_on_first_run
set the default theme setting
2023-02-04 16:28:34 +00:00
Dimitrij
8cf0f50565 Merge pull request #2341 from BlueBlock/fix_broken_tests
Fix broken tests
2023-02-04 16:26:34 +00:00
Dimitrij
575ad7664f Merge pull request #2343 from savornicesei/simo/gh-2342-installer-in-debug-mode
Build installer in Debug mode #2342
2023-02-04 16:23:51 +00:00
Dimitrij
be17488070 Merge pull request #2339 from BlueBlock/add_missing_settings
Add 2 missing settings
2023-02-04 16:23:07 +00:00
Simona Avornicesei
f504107928 Build installer in Debug mode #2342 2023-02-04 10:10:51 +02:00
BlueBlock
0113f549c5 fix remaining unit tests 2023-02-03 17:35:09 -05:00
BlueBlock
9ff831faab fix additional tests 2023-02-03 17:05:36 -05:00
BlueBlock
a9ca243c0b fix protocol config unit tests 2023-02-03 16:53:29 -05:00
BlueBlock
553bbef45f set the default theme setting
On the initial start of a fresh install, if the options are opened the theme is then set from an empty string to the default. This causes the user to see the "must restart app" dialog when closing the options.

This only occurs on the initial run of the app. If the app is closed and run again, the theme will have been set.
2023-02-03 14:34:38 -05:00
BlueBlock
8f713f861b Add 2 missing settings
Two settings are missing in the settings but do exist in the Designer class.  These settings are used in code so they do need to exist.
ConDefaultRDGatewayUserViaAPI
ConDefaultRDGatewayExternalCredentialProvider
2023-02-03 14:12:02 -05:00
Dimitrij
324054b9d7 Merge pull request #2337 from BlueBlock/set_language_resx_to_autogen_language_class
set language.resx to auto generate the designer class
2023-02-03 10:10:20 +00:00
BlueBlock
d3fc9404ee set language.resx to auto generate the designer class
This avoids the need to manually regenerate the Language.Designer.cs file.

Note that in VS the file Language.Designer.cs will appear under Language.resx but the actual file locations have not changed.
2023-02-02 10:25:27 -05:00
Dimitrij
5bb780439b add autodate as was suggested by @savornicese 2023-02-01 12:56:43 +00:00
Dimitrij
f0e6008441 lib update 2023-02-01 12:44:37 +00:00
Dimitrij
39dd69f15e Merge pull request #2334 from BlueBlock/fix_build_order
Fix the dependencies for the Installer project build
2023-02-01 12:37:47 +00:00
Dimitrij
7b2e89df26 Merge pull request #2335 from BlueBlock/update_packages
Update project packages
2023-02-01 12:36:14 +00:00
BlueBlock
aa853f8481 Update project packages 2023-01-31 14:44:37 -05:00
BlueBlock
83bba75af6 Fix the dependencies for the Installer project build
The Installer project fails to build without also specifying the ExternalConnectors and mRemoteNG projects as dependencies.
2023-01-31 10:46:51 -05:00
Dimitrij
23889aa5b1 lib update 2023-01-08 11:57:03 +00:00
Dimitrij
5e6094fc42 lib update 2022-11-15 15:16:03 +00:00
Dimitrij
a4181cb6d6 Merge pull request #2301 from bartuszekj/splash_screen_fix
Fix for splash screen to appear on the primary screen.
2022-11-14 09:29:06 +00:00
Jerzy Bartuszek
88c49f0722 Fix for splash screen to appear on the primary screen. 2022-11-11 17:06:50 -06:00
Dimitrij
513d9e199c lib update 2022-11-09 14:34:02 +00:00
Dimitrij
e80975c56e lib update 2022-10-20 11:53:32 +01:00
Dimitrij
9051ac102c Merge pull request #2298 from SOlangsam/patch-2
Update mysql_db_setup.sql
2022-10-19 19:13:44 +01:00
SOlangsam
39a9b2e619 Update mysql_db_setup.sql
Added missing fields
Fix Issue for mysql #2292
2022-10-11 16:40:08 +02:00
Dimitrij
dbc55d248f add version color overwrite 2022-10-06 18:58:52 +01:00
Dimitrij
2b46180bfb clear inherited max-width 2022-10-06 18:41:31 +01:00
Dimitrij
5abe6c7e27 empty css 2022-10-06 18:30:31 +01:00
Dimitrij
4595ebeb9a next try to fix theme 2022-10-06 17:36:45 +01:00
Dimitrij
815c08e6d4 fix colors of sidebar 2022-10-05 21:31:30 +01:00
Dimitrij
a72ad218a0 fix for menu links color 2022-10-05 21:14:46 +01:00
Dimitrij
944ad1f769 Merge pull request #2295 from CrunchyBlue/v1.77.3-dev
*Updates hyperlink style to make links more visible to end users
2022-10-05 19:40:07 +01:00
PRINTABLE\dgagliardi
e17a68f61c *Updates hyperlink style to make links more visible to end users 2022-10-05 11:40:30 -05:00
Dimitrij
0b8196be68 Merge pull request #2285 from tecxx/develop-orig
support extraction of SSH private keys from external cred prov
2022-09-07 13:59:21 +01:00
tecxx
d9c01148b7 support extraction of SSH private keys from external credential provider (DSS)
supported formats: rsa, rsa with passphrase, putty private key
2022-09-07 14:08:29 +02:00
Dimitrij
2b3cfd992f Merge pull request #2275 from tecxx/develop-orig
external connectors improvement
2022-08-25 21:36:27 +01:00
tecxx
7e4bd7a6f3 add UI property selectors for external connectors
add support for external credential provider in remote desktop gateway
rename TSS to DSS
fix tests and property naming issues
2022-08-25 21:58:16 +02:00
Dimitrij
161e0ed637 fix for #2208 2022-08-22 10:31:54 +01:00
Dimitrij
1ee03e863c Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2022-07-29 23:26:59 +01:00
Dimitrij
2411481d8b lib upd 2022-07-29 23:26:14 +01:00
Dimitrij
0314a627ed Merge pull request #2259 from luciusagarthy/patch-1
Update Language.cs-CZ.resx
2022-07-27 23:39:09 +01:00
Dimitrij
4d339a0b09 Merge pull request #2261 from maxshlain/v1.77.3-hide-filemenu
Implement Show/Hide file menu in view menu
2022-07-27 23:38:37 +01:00
Dimitrij
c171e7f94b Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2022-07-17 23:14:21 +01:00
Dimitrij
eac4d966d9 remove not needed reference to old ObjectListView 2.7 2022-07-17 23:11:36 +01:00
Dimitrij
c20868c20c lib update 2022-07-17 22:42:17 +01:00
maxim-shlain
bb74d46f1f Implement Show/Hide file menu in view menu 2022-07-08 19:34:42 +03:00
luciusagarthy
152d48c583 Update Language.cs-CZ.resx
Thank you for a great app. I will contribute more. Here is some translation.
2022-07-07 16:19:48 +02:00
Dimitrij
b7a0155ba4 lib update 2022-06-25 06:39:19 +01:00
Dimitrij
0414724b21 update 2022-06-13 13:34:21 +01:00
Dimitrij
469f21db8d lib update 2022-06-13 10:35:41 +01:00
Dimitrij
b6c9d30195 Merge pull request #2244 from tecxx/develop-orig
save RCG and RestrictedAdmin fields correctly in connections file
2022-06-11 11:30:26 +01:00
tecxx
7b89430317 quickfix to save application settings correctly 2022-06-10 21:31:55 +02:00
tecxx
5bd854116a rcg/restrictedadmin fixes: schema file and defaults to false 2022-06-08 21:22:59 +02:00
tecxx
3fb7575529 save RCG and RestrictedAdmin fields correctly in connections file 2022-06-08 20:55:06 +02:00
Dimitrij
a3a868c2ce Merge pull request #2235 from jafin/fix/topmenu
fix (Toolbar): Remove unused `modeToolStripmenuItem` from Main toolbar
2022-06-03 09:59:26 +01:00
Jason Finch
1eb6fc2235 fix (Toolbar): Remove unused modeToolStripmenuItem from Main toolbar 2022-06-02 17:01:06 +10:00
Dimitrij
5ff4502f0a Merge pull request #2231 from simonai1254/patch-1
Specify "Desktop Runtime" in Requirements
2022-05-23 21:24:38 +01:00
Simon Monai
3126b8d4b0 Specify "Desktop Runtime" in Requirements 2022-05-23 22:15:00 +02:00
Dimitrij
dfb1d34b8a cleaning redundant blocks 2022-05-14 20:39:00 +01:00
Dimitrij
ace62c07be lib update 2022-05-13 01:55:18 +01:00
Dimitrij
ec2f3024b6 implement DPIAware, change splash screen to wpf 2022-05-13 01:39:00 +01:00
Dimitrij
25543f6561 Add acl controls to backupOptions 2022-05-02 00:31:00 +01:00
Dimitrij
3278657da7 fix missing values 2022-05-01 20:44:38 +01:00
Dimitrij
90c4d12688 lib updates 2022-05-01 20:10:22 +01:00
Dimitrij
4ceaea99f7 Merge pull request #2211 from nilsjonsson/new-lang
Add Swedish translation
2022-04-27 13:32:51 +01:00
Nils Jonsson
585de34ef1 Add Swedish translation 2022-04-27 14:18:53 +02:00
Dimitrij
60e1a3ce93 Merge pull request #2208 from Pwnoz0r/MR-887_rdm_import
Add Remote Desktop Manager (Devolutions) Importer
2022-04-23 21:02:32 +01:00
Jonathan Rainier
413d77ff1a Add Comments and Icon Support / Fix Unsorted
- Add Comments
- Add icon support for supported connection types
- Fix empty unsorted folder from being added
2022-04-23 15:53:25 -04:00
Jonathan Rainier
d8bb561063 Add Remote Desktop Manager (Devolutions) Importer
- Add RDM Importer mRemoteNG/mRemoteNG#887
2022-04-23 15:22:08 -04:00
Dimitrij
5dff2c20b2 Merge pull request #2204 from tecxx/develop-orig
fix for otp token renewal in TSS api
2022-04-19 12:53:06 +01:00
tecxx
27803e7787 fix for otp token renewal in TSS api 2022-04-19 11:44:12 +02:00
Dimitrij
58f9c1575f Merge pull request #2203 from tecxx/develop-orig
enable remote credential guard option
2022-04-15 16:45:33 +01:00
tecxx
7b909665b9 enable remote credential guard option
enable restricted admin mode option
2022-04-15 17:08:49 +02:00
Dimitrij
11eee991a1 fix visibility 2022-04-03 16:37:45 +01:00
Dimitrij
7056a859ef add acl for option pages 2022-04-03 16:25:04 +01:00
Dimitrij
2455f0d73e lib update 2022-04-03 15:35:56 +01:00
Dimitrij
943d36e23e add rbac to hide menu page + lang updates 2022-04-03 14:38:06 +01:00
Dimitrij
b563ac6e0c add basic rbac (acl) implementation as example for backup options + Language modification 2022-03-31 19:22:56 +01:00
Dimitrij
ed37a8ca2a fix #1015 2022-03-30 15:27:55 +01:00
Dimitrij
55bee8b0d8 add rbac settings 2022-03-30 12:30:59 +01:00
Dimitrij
6bd18c29e3 lib update 2022-03-29 10:38:27 +01:00
Dimitrij
37fc611767 Merge pull request #2188 from Trellmor/UpdateSessionDisplaySettings
Update session display settings
2022-03-19 12:57:09 +00:00
Daniel Triendl
f95fe351e2 Updated changelog and documentation 2022-03-18 20:27:54 +01:00
Daniel Triendl
2fb0ab1d91 Enable size change without reconnect
Use IMsRdpClient9::UpdateSessionDisplaySettings to dynamically update the
session display settings without reconnecting. RDP Version needs to be
Rdc9 or Highest for this to work.

Fixes #1546
2022-03-18 19:33:10 +01:00
Dimitrij
85f7be1d79 refactoring menu (preparation for RBAC) 2022-03-16 22:33:16 +00:00
Dimitrij
b3e5c1abc2 lib update 2022-03-16 09:55:34 +00:00
Dimitrij
9e216c0020 remove spaces 2022-03-11 17:53:05 +00:00
Dimitrij
a9f00b6a8c remove spaces 2022-03-11 17:04:51 +00:00
Dimitrij
46e7b02da2 lib update 2022-03-11 12:36:52 +00:00
Dimitrij
8db0bc6e6f refactoring options
each settings page from now will have separate options file, a bit later that helps to migrate into modular structure, then admin can control access to options and external modules may add may options independently
2022-03-10 13:48:39 +00:00
Dimitrij
1702b5867a update 2022-02-24 01:17:02 +00:00
Dimitrij
c03a6452ef update link 2022-02-24 01:14:14 +00:00
Dimitrij
69b840fb12 update 2022-02-24 01:11:44 +00:00
Dimitrij
9385ab287f update 2022-02-24 00:58:36 +00:00
Dimitrij
d2b2c39b97 fixing link 2022-02-24 00:54:01 +00:00
Dimitrij
f8ff978738 fix link 2022-02-24 00:49:43 +00:00
Dimitrij
d50b32236c update 2022-02-24 00:43:59 +00:00
Dimitrij
88d1db2840 Add howto for CyberArk psm 2022-02-24 00:35:00 +00:00
Dimitrij
b1dbe562d6 Merge pull request #2176 from AndyX90/sql-fix
Create missing columns
2022-02-23 23:56:56 +00:00
Andy Binder
e95b6f1b5d Update mysql_db_setup.sql 2022-02-23 21:57:24 +01:00
Andy Binder
1cbb7bb5dd Create missing columns 2022-02-23 21:46:10 +01:00
Dimitrij
34f3ffa129 Add version number to splash screen 2022-02-22 23:26:04 +00:00
Dimitrij
ecd25a673e lib updates 2022-02-15 17:27:57 +00:00
Dimitrij
58d0778c3d Merge pull request #2145 from jacko873/Dev
External Connectors, Default Options updated
2022-01-28 13:50:31 +00:00
Dimitrij
81a5422974 Merge pull request #2144 from tecxx/develop-orig
TSS improve refresh token / otp request handling
2022-01-28 13:04:40 +00:00
jacko873
eb859e5ede External Connectors, Default Options updated
Updated options form to fix UI bug where domain was pushout of range,
Added saving of  default User API ID
adjusted RDP and SHH to check for default User API ID,
also adjusted code here for consistancey
2022-01-28 13:50:13 +01:00
tecxx
c8035b5071 TSS improve refresh token / otp request handling 2022-01-28 11:18:44 +01:00
Dimitrij
a98a336e52 Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2022-01-21 23:58:25 +00:00
Dimitrij
d7f6535b85 update putty to v0.76 2022-01-21 23:54:28 +00:00
Faryan Rezagholi
f9d4e3152b Update README.md
Added  installation via winget
2022-01-19 23:49:16 +01:00
Dimitrij
69bd816aeb Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2022-01-19 19:44:19 +00:00
Dimitrij
783810749c change log update 2022-01-19 19:42:43 +00:00
Dimitrij
92c3c967ba Merge pull request #2138 from ThoGoetz/v1.77.3-dev
Improve compatibility with Remote Desktop Connection Manager v2.83
2022-01-19 19:41:05 +00:00
Thomas Götzinger
c632ba4306 Allow importing connections from Remote Desktop Connection Manager v2.83 2022-01-19 16:59:42 +01:00
Thomas Götzinger
e29d2c25ba Fixing Null value exception, when saving imported connections from Remote Desktop Connection Manager 2022-01-19 16:59:16 +01:00
Dimitrij
5cfdc96cd2 Merge pull request #2132 from tecxx/develop-orig
fix refresh token issue in TSS API
2022-01-18 15:48:20 +00:00
tecxx
a20e10b342 fix refresh token issue in TSS API 2022-01-18 16:28:03 +01:00
Dimitrij
39b7414553 correction 2022-01-18 10:50:09 +00:00
Dimitrij
0eef20caf6 Merge pull request #2131 from mRemoteNG/v1.77.2-dev
V1.77.2 dev
2022-01-18 10:44:50 +00:00
Dimitrij
859d12b450 Merge branch 'v1.77.3-dev' into v1.77.2-dev 2022-01-18 10:44:40 +00:00
Dimitrij
cd7c594b76 lib update 2022-01-18 10:38:14 +00:00
Dimitrij
39862e15f6 lib update 2022-01-18 10:37:49 +00:00
Dimitrij
87b0cf5c3f Merge pull request #2130 from simonai1254/patch-1
Patch 1
2022-01-18 10:35:37 +00:00
Simon Monai
a14219e1e2 Fix typo 2022-01-18 11:33:51 +01:00
Dimitrij
ee4660707c correction 2022-01-18 10:31:50 +00:00
Simon Monai
ccdf15c79c Update location for older versions
x64 and x86 builds behave differently on a x64 windows
2022-01-18 11:31:47 +01:00
Dimitrij
b31362afab correction 2022-01-18 10:30:49 +00:00
Dimitrij
74d6c88565 Merge branch 'v1.77.2-dev' into v1.77.3-dev 2022-01-18 10:24:33 +00:00
Dimitrij
638f64b888 Merge branch 'v1.77.3-dev' into v1.77.2-dev 2022-01-18 10:23:54 +00:00
Simon Monai
ffff9c1529 Add programm registry key 2022-01-18 11:23:26 +01:00
Dimitrij
39968c7c6e update changes 2022-01-18 10:16:42 +00:00
Simon Monai
2c3edf0ff2 Add Windows Desktop Runtime to removal list 2022-01-18 11:09:05 +01:00
Simon Monai
2c4445a2d9 Update wording 2022-01-18 10:59:06 +01:00
Simon Monai
09114a5ed3 Improve uninstall documentation
Addin AppData\Roaming as well as updating the Registry path for the new 64bit builds
2022-01-18 10:48:37 +01:00
Dimitrij
22e7825d65 Merge pull request #2126 from david-sway/v1.77.2-dev-RefactorConnectionInitiator
Combined instances of ConnectionInitiator to help with issue #2119
2022-01-18 09:47:36 +00:00
Dimitrij
62862141a8 update change log 2022-01-18 09:37:17 +00:00
Dimitrij
920461920c Merge pull request #2125 from david-sway/v1.77.2-dev
Fixed string parsing logic for Quick Connect toolbar.
2022-01-18 09:32:56 +00:00
david-sway
f5d0e93ecd Combined instances of ConnectionInitiator 2022-01-17 17:40:02 -05:00
david-sway
952a2f536b Fixed string parsing logic for Quick Connect toolbar. 2022-01-17 16:05:22 -05:00
Dimitrij
fbb9d849b4 update change log 2022-01-17 15:07:36 +00:00
Dimitrij
65a13dee68 fix tests 2022-01-17 15:01:35 +00:00
Dimitrij
09d26b37c7 fix year for copyright note 2022-01-17 14:54:12 +00:00
Dimitrij
47de6905df add check if xml return empty to address #2122 2022-01-17 14:53:38 +00:00
Dimitrij
c0cf316c16 update readme 2022-01-14 17:44:10 +00:00
Dimitrij
c055f8069d remove unnecessary files 2022-01-14 17:42:55 +00:00
Dimitrij
575356214f update readme 2022-01-14 17:42:16 +00:00
Dimitrij
4b5dc4152a Merge branch 'v1.77.3-dev' of https://github.com/mRemoteNG/mRemoteNG into v1.77.3-dev 2022-01-14 17:20:39 +00:00
Dimitrij
a023409fe9 update change log 2022-01-14 17:20:10 +00:00
Dimitrij
d36c59658d Merge pull request #2123 from jacko873/develop
Thycotic Secret Server -  Added 2FA OTP support
2022-01-14 17:14:37 +00:00
jacko873
4f832ee70b Added 2FA OTP support
Added support for 2FA OTP
token managment and use if refresh token
2022-01-14 17:29:07 +01:00
Dimitrij
7b97097515 Merge pull request #2121 from tecxx/develop-orig
update documentation regarding external connectors feature
2022-01-14 10:47:49 +00:00
tecxx
86b3cb8d5d update documentation regarding external connectors feature 2022-01-14 11:11:15 +01:00
Dimitrij
33e007ad48 update changelog 2022-01-12 16:44:49 +00:00
Dimitrij
efea9f0857 fix extensions (2 step) 2022-01-12 16:39:11 +00:00
Dimitrij
aa755a0093 fix normalize extension to lower case (1 step) 2022-01-12 16:38:11 +00:00
Dimitrij
807e80acbe Add missed credits file
Fix opening link in about form for .net 6
2022-01-12 16:32:40 +00:00
Dimitrij
4096247ee8 add default settings for channel
fix missing options
2022-01-12 16:29:16 +00:00
Dimitrij
782d09ddbc fix for ProgramWorkDir option name 2022-01-12 16:28:15 +00:00
Dimitrij
4c304e11f3 update version number to 1.77.3 2022-01-12 10:53:48 +00:00
Faryan Rezagholi
aee497de03 nuget updates 2022-01-11 23:31:13 +01:00
Dimitrij
823f8614e5 lib update 2022-01-11 21:04:53 +00:00
Dimitrij
b54afb8823 Merge pull request #2115 from Vest/fix_2100
Fix tests that were broken by PR #2100
2022-01-11 20:16:00 +00:00
Dimitrij
22e611c63b Update ConfigWindowGeneralTests.cs
add one more ','
2022-01-11 19:37:22 +00:00
Dimitrij
3deb01a65d Update ConfigWindowGeneralTests.cs
add ','
2022-01-11 19:23:52 +00:00
Dimitrij
6f24b0bb71 Update ConfigWindowGeneralTests.cs
add missing fileds
2022-01-11 19:07:29 +00:00
Dimitrij
9d7921f538 Update ConfigWindowGeneralTests.cs
fixes for username field add
2022-01-11 15:14:28 +00:00
Vest
a4e66b3d11 Fix tests that were broken by PR #2100.
Signed-off-by: Vest <Vest@users.noreply.github.com>
2022-01-11 15:47:18 +01:00
Faryan Rezagholi
3866ff76f9 Merge pull request #2114 from david-sway/fix_toolbar_toggles
Fixed behavior of toolbar visibility toggles in the View menu
2022-01-11 00:02:14 +01:00
david-sway
82f947abdd Fixed behavior of toolbar visibility toggles in the View menu 2022-01-10 13:06:18 -05:00
Dimitrij
47c6f53b43 fix image link 2022-01-07 16:57:13 +00:00
Dimitrij
606657524e update build badges, paypal 2022-01-07 16:33:23 +00:00
Dimitrij
168285944c fix path 2022-01-07 15:46:04 +00:00
Dimitrij
1746af927b lib updates 2022-01-07 09:46:31 +00:00
Dimitrij
2eca8ffba2 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2022-01-04 10:43:12 +00:00
Dimitrij
6ef0c06a19 lib updates 2022-01-04 10:43:00 +00:00
Faryan Rezagholi
af68f1a16e Merge pull request #2104 from tecxx/develop-orig
fix test cases caused by new fields
2021-12-26 13:11:03 +01:00
tecxx
f429839a17 fix test cases caused by new fields 2021-12-25 19:53:31 +01:00
Dimitrij
66770e602a Merge pull request #2103 from tecxx/develop-orig
improve SS api credential handling
2021-12-25 18:52:04 +00:00
tecxx
f760131cf5 remove dead function call 2021-12-25 18:55:59 +01:00
tecxx
cdc1d5064f improve handling of invalid api credentials 2021-12-25 18:52:54 +01:00
Faryan Rezagholi
3b707d29b9 Updated PuTTYNG to v0.76 (fixes #2012) 2021-12-25 16:11:22 +01:00
Dimitrij
df632bb1f0 Merge pull request #2102 from Vest/issue_2057
Extended the field [RenderingEngine] from 10 chars to 16
2021-12-25 13:12:22 +00:00
Vest
74cb453995 Updated changelog.md 2021-12-25 11:33:56 +01:00
Vest
f8eec94b04 Extended the field [RenderingEngine] from 10 chars to 16.
This is not the full fix of issue #2057, because the scripts are not "migration" scripts.
2021-12-25 11:31:05 +01:00
Faryan Rezagholi
697efacc58 Merge pull request #2101 from Vest/fix_mssql_type
Fix typo in mssql_db_setup.sql
2021-12-24 19:12:20 +01:00
Vest
ff9cff8f44 Fix typo in mssql_db_setup.sql
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-24 16:59:31 +01:00
Dimitrij
d78388646d Merge pull request #2100 from tecxx/develop
external connectors update #2
2021-12-23 17:42:49 +00:00
tecxx
05ffcdeef7 fix null object bug in ec2 connector 2021-12-23 16:54:54 +01:00
Dimitrij
3b8e347a9e Merge pull request #2098 from Vest/fix_large
Fix failed BinaryFileTest
2021-12-23 11:18:55 +00:00
Dimitrij
37f160f698 Merge branch 'develop' into fix_large 2021-12-23 11:18:46 +00:00
tecxx
6f1446339c new fields for external connectors
add ec2 instance connector
2021-12-23 09:59:29 +01:00
Dimitrij
fed44dc366 Merge pull request #2097 from Vest/fix_gui
Fix failed tests related to mRemoteNGTests.UI.Window.ConfigWindowTests
2021-12-23 02:36:17 +00:00
Vest
c71ec34998 Updated changelog
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-22 22:40:10 +01:00
Vest
157bda8f51 Fix BinaryFileTest
mRemoteNGTests doesn't define "DEBUG" and "PORTABLE", but defines "DEBUG_PORTABLE" macro.

Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-22 22:36:38 +01:00
Vest
d80e5bc792 Updated changelog.md
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-22 22:33:30 +01:00
Vest
f9669e8158 Fix failed tests related to mRemoteNGTests.UI.Window.ConfigWindowTests.
The menu item OpeningCommand is related to SSH1/SSH2. Previously it was tested for RDP.

Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-22 22:26:53 +01:00
Faryan Rezagholi
04c83c608b removed deprecated/unhandled features 2021-12-20 17:37:19 +01:00
Faryan Rezagholi
9f50037e11 Merge pull request #2096 from Vest/fix_2081
Fixed crypto provider test
2021-12-20 17:09:44 +01:00
Faryan Rezagholi
33fd741ba7 Merge branch 'develop' into fix_2081 2021-12-20 17:06:14 +01:00
Vest
035c3f9319 Updated changelog.md
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-20 16:21:43 +01:00
Vest
3df922340d Fixed the test that was broken with the PR #2081
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-20 16:17:39 +01:00
Dimitrij
72b9190e2f fix for failing tests due missing path to schema 2021-12-20 11:28:01 +00:00
Dimitrij
8fe1bdf39a Merge pull request #2089 from Vest/fix_help_menu
Fixes the exception thrown by menu buttons "Documentation" and "Website"
2021-12-17 10:14:57 +00:00
Vest
f78bf2bc8a Updated CHANGELOG.md
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 21:52:56 +01:00
Vest
a1f0a69874 Menu button "Documentation" and "Website" threw an exception.
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 21:46:10 +01:00
Faryan Rezagholi
8a26b2f433 Merge pull request #2088 from Vest/issue_2087
Launch updates from shell (fixes #2087)
2021-12-16 20:57:56 +01:00
Vest
a18784d2c7 Updated changelog.
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 19:04:49 +01:00
Vest
3c25a987fd Fix the issue #2087
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 19:02:25 +01:00
Dimitrij
7cebc4ef42 Merge pull request #2086 from Vest/refactor_webclient
Use async HttpClient instead of obsolete WebClient
2021-12-16 17:31:06 +00:00
Faryan Rezagholi
a8ab46d5c8 remove app.comfig 2021-12-16 17:09:03 +01:00
Vest
8bac5a8c54 Removed unused imports for UpdateWindow.cs 2021-12-16 17:05:05 +01:00
Faryan Rezagholi
801a41ae10 removed log4net leftover 2021-12-16 17:04:11 +01:00
Vest
47e37afe12 Removed unused imports for AppUpdater.cs
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 17:03:56 +01:00
Faryan Rezagholi
942bf7d8cb moved log4net config into its own file 2021-12-16 17:01:45 +01:00
Vest
0e8d573819 Updated changelog 2021-12-16 17:00:49 +01:00
Vest
2bdfd7401e Corrected warnings related to async event handlers
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 16:41:00 +01:00
Vest
68dd6b1e23 Removed unused code
Added the checksum verification.

Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 15:57:18 +01:00
Vest
2fe85ae0e5 Added the progress handling;
Now API (AppUpdater) is async.
Cancellation token hasn't been tested yet, because UI doesn't allow to cancel the update.

Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 15:37:56 +01:00
Vest
e9fa1c3b5e Added Initial async support for AppUpdater
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-16 12:30:12 +01:00
Faryan Rezagholi
f543b83cfc added missing issue (#870) 2021-12-16 00:41:57 +01:00
Faryan Rezagholi
2d917ca11a set lang version to latest 2021-12-15 22:54:08 +01:00
Faryan Rezagholi
2c830627ef removed orphaned paths, added missing ones 2021-12-15 21:11:22 +01:00
Faryan Rezagholi
46003a3509 removed orphaned path from harvest dir 2021-12-15 20:18:10 +01:00
Faryan Rezagholi
6b0412586e Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-15 19:50:03 +01:00
Faryan Rezagholi
36ca7ffbdb removed credits file from installer 2021-12-15 19:48:23 +01:00
Dimitrij
e5244f1fec Merge pull request #2085 from tecxx/develop
fix issue 2075
2021-12-15 18:41:57 +00:00
Faryan Rezagholi
359a7272e8 build external connectors on 'release portable' 2021-12-15 19:38:33 +01:00
Dimitrij
82cd3a7e56 swap runtime and configSections as per below https://stackoverflow.com/questions/13623896 2021-12-15 16:01:40 +00:00
tecxx
a2e78fd08a fix issue 2075 by standardizing "StartProgram" Property to "RDPStartProgram" and "StartProgramWorkDir" to "RDPStartProgramWorkDir" 2021-12-15 15:11:56 +01:00
Faryan Rezagholi
a48b5e9d65 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-15 02:42:00 +01:00
Faryan Rezagholi
f4c4d9ea8c removed 'en-US' specific translation in favor of default (en) 2021-12-15 02:41:50 +01:00
Dimitrij
02ed45fa61 added file exist check and null check 2021-12-15 01:31:26 +00:00
Dimitrij
ad227ea2ee add check if no removable files to don't throw null error 2021-12-15 01:02:13 +00:00
Dimitrij
d7e2358d3e Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-14 23:50:13 +00:00
Faryan Rezagholi
196e98e4a7 Merge pull request #2084 from tecxx/develop
fixed some tests around "StartProgramWorkDir"
2021-12-14 22:04:09 +01:00
tecxx
00bc45fba1 fix some more inconsistencies with "StartProgramWorkDir" 2021-12-14 21:45:39 +01:00
Dimitrij
62c0d3f07f Merge pull request #2083 from tecxx/develop
fix a test case caused by property named "Prop_StartProgram" instead …
2021-12-14 20:37:16 +00:00
Faryan Rezagholi
d42574a16c updated sql scripts (fixes #1436) 2021-12-14 21:36:14 +01:00
tecxx
a854b04293 fix a test case caused by property named "Prop_StartProgram" instead of "StartProgram" 2021-12-14 21:07:06 +01:00
Faryan Rezagholi
96632da4d7 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-14 20:00:10 +01:00
Faryan Rezagholi
cf18d6b1e9 reordered "added" section 2021-12-14 20:00:02 +01:00
Faryan Rezagholi
262e2e1b85 Merge pull request #1451 from mRemoteNG/push_settings_recursively
Added option to push inheritance settings to children recursively
2021-12-14 19:51:10 +01:00
Faryan Rezagholi
743c46de70 merge from develop 2021-12-14 19:48:10 +01:00
Faryan Rezagholi
9624bc96c9 Merge pull request #2081 from Vest/refactor_rijndael
Fixed compiler warning
2021-12-14 19:36:32 +01:00
Vest
1643bb7d59 Corrected "obsolete" warnings for objects RijndaelManaged and MD5CryptoServiceProvider
Added several "using" statements for all disposable objects.

Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-14 16:55:14 +01:00
Faryan Rezagholi
edad5a838f removed credits file 2021-12-14 13:40:35 +01:00
Faryan Rezagholi
fb35226e20 update nuget packages 2021-12-14 13:37:40 +01:00
Faryan Rezagholi
40605737b1 Merge pull request #2080 from Vest/issue_2079
Copy theme files to target dir
2021-12-14 13:31:13 +01:00
Faryan Rezagholi
01a62e099e updated changelog (#2079) 2021-12-14 13:27:23 +01:00
Faryan Rezagholi
80748bb66b copy theme files to output dir (fixes #2079) 2021-12-14 13:25:40 +01:00
Faryan Rezagholi
c6c77e9bc4 Revert "Solve issue #2079"
This reverts commit 1f462648c4.
2021-12-14 13:23:31 +01:00
Vest
1f462648c4 Solve issue #2079
Signed-off-by: Vest <Vest@users.noreply.github.com>
2021-12-14 13:10:02 +01:00
Faryan Rezagholi
099256e5d4 code cleanup 2021-12-14 01:14:51 +01:00
Dimitrij
8735d24122 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-12 19:37:12 +00:00
Dimitrij
b2fc3967d3 update to move dll and lang to subfolders, not supported fully in net 6.0 2021-12-12 19:36:47 +00:00
Faryan Rezagholi
0ec02cfa56 removed left over project files from #2076 2021-12-09 20:29:45 +01:00
Faryan Rezagholi
ade36d6876 re-add .net framework 2 as supported runtimefor installer 2021-12-09 20:25:48 +01:00
Faryan Rezagholi
73313d7dae fixes/simplified postbuild installer scripts 2021-12-09 20:11:45 +01:00
Faryan Rezagholi
7db9865ffa build installer for .net framework 4.8 only 2021-12-09 18:27:29 +01:00
Faryan Rezagholi
40656cb70b Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-09 18:20:27 +01:00
Faryan Rezagholi
b5a07f3e79 Update README.MD 2021-12-09 18:20:20 +01:00
Faryan Rezagholi
66877ce9b1 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-09 18:16:00 +01:00
Faryan Rezagholi
57b067b4e2 don't convert license file to rich text format on installer build 2021-12-09 18:14:35 +01:00
Faryan Rezagholi
74999e9394 removed obsolete files 2021-12-09 18:14:05 +01:00
Faryan Rezagholi
f4d6f1e5ee Condensed README.MD 2021-12-09 18:09:22 +01:00
Faryan Rezagholi
096f670eb3 hide disc cost button in installer (#1363) 2021-12-09 00:22:00 +01:00
Faryan Rezagholi
bceaca49bf imported templates from wix sources to be able to make modifications. 2021-12-09 00:21:04 +01:00
Faryan Rezagholi
5e94c84516 spelling fix 2021-12-08 23:08:35 +01:00
Faryan Rezagholi
28dc14e739 improved feature tree in installer 2021-12-08 23:06:56 +01:00
Faryan Rezagholi
d5d28e80cb removed any cpu configurations from solution file 2021-12-07 01:22:49 +01:00
Faryan Rezagholi
f1eea76249 added build configs for external conectors project 2021-12-07 01:12:20 +01:00
Faryan Rezagholi
0976404eda merged from develop 2021-12-07 01:10:02 +01:00
Faryan Rezagholi
8074c9a7c6 re 2021-12-07 01:06:31 +01:00
Dimitrij
513af43fca Merge pull request #2076 from tecxx/develop
rework TSS api to use .net6 compatible code
2021-12-06 21:59:58 +00:00
tecxx
afd5d76992 rework TSS api to use .net6 compatible code
rename dll to ExternalConnectors.dll for possible other future implementations
refactor namespaces in dll
2021-12-06 21:54:35 +01:00
Faryan Rezagholi
a31da5f880 update build configuration 2021-12-06 00:57:00 +01:00
Faryan Rezagholi
be470f50ec rounded corners 2021-12-04 15:17:24 +01:00
Faryan Rezagholi
a04494346e rounded corners 2021-12-04 15:15:25 +01:00
Faryan Rezagholi
797533459e Update README.MD
updated .net version requirement
2021-12-04 14:39:19 +01:00
Faryan Rezagholi
22e879ef18 Update README.MD
added server 2022
2021-12-04 14:37:19 +01:00
Faryan Rezagholi
dc6bc5b4d6 fixed appveyor badges 2021-12-04 14:34:07 +01:00
Faryan Rezagholi
a6c7457c59 updated VncSharp nuget 2021-12-02 23:20:20 +01:00
Dimitrij
b609cfba2a Merge pull request #1848 from johnwc/feature/RemoteDesktopServices
Feature/remote desktop services
2021-12-02 09:02:56 +00:00
John Carew
345980f457 Removed duplicate StartProgram property set 2021-12-02 01:27:27 -06:00
John Carew
5a86a0a8cb Merge from develop 2021-12-02 00:32:40 -06:00
John Carew
24c1ce3f4a Correct saving StartProgramWorkDir 2021-12-02 00:17:26 -06:00
Faryan Rezagholi
fc65c2583e hopefully fixed all installer build issues 2021-12-02 01:15:22 +01:00
Faryan Rezagholi
1df3c33f69 removed developer note from license file 2021-12-02 00:11:07 +01:00
Faryan Rezagholi
98a9cc7436 Update README.MD 2021-12-01 23:51:06 +01:00
Faryan Rezagholi
ff88d4649c more adjustments to the build configuration 2021-12-01 23:42:16 +01:00
Faryan Rezagholi
8c61306a8d Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-12-01 23:25:52 +01:00
Faryan Rezagholi
6496e34868 fixed installer paths 2021-12-01 23:25:42 +01:00
Faryan Rezagholi
7d6c9d517c unified different project configurations 2021-12-01 23:25:17 +01:00
Faryan Rezagholi
d918d8ffd1 Update README.MD 2021-12-01 22:53:18 +01:00
Dimitrij
ca61ea09d0 --update test libs 2021-12-01 20:55:15 +00:00
Faryan Rezagholi
faff230d42 applied fix from @reox22 2021-12-01 21:09:57 +01:00
Faryan Rezagholi
c288c3d071 fixed project style of pr 2021-12-01 21:07:18 +01:00
Faryan Rezagholi
500a22b0b6 merged from develop 2021-12-01 21:07:00 +01:00
Faryan Rezagholi
ba1317d245 replaced newly introduced backup icon with one that matches the programs ui 2021-12-01 20:25:00 +01:00
Dimitrij
5cfbfc5071 --correction
test cases
2021-12-01 10:04:38 +00:00
Dimitrij
bf4b9d5355 --lib updates 2021-11-26 09:41:32 +00:00
Dimitrij
904f0bc202 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-11-26 09:20:56 +00:00
Dimitrij
94c546bd0f -- fix for tests 2021-11-26 09:20:45 +00:00
Dimitrij
64f1e10a5e Merge pull request #2024 from mRemoteNG/dotnet
Migrate Project to .NET6
2021-11-26 09:14:55 +00:00
Faryan Rezagholi
8b20da78ff merge from develop 2021-11-25 22:40:32 +01:00
Faryan Rezagholi
1be4ef437d merged from develop 2021-11-25 22:40:20 +01:00
Dimitrij
76da9c3247 -fix
fix serializers for OpeningCommand
2021-11-17 23:30:57 +00:00
Dimitrij
1e4dcc23d7 -fix
more fix regarding adding new option
2021-11-17 11:41:06 +00:00
Dimitrij
9c95e7fd96 -fix after nunit update 2021-11-16 22:29:00 +00:00
Dimitrij
cea5f57c60 --fix
better way to set of defaults
2021-11-16 19:10:09 +00:00
Dimitrij
19e6d37b62 -- fix
Set CustomToolNamespace to avoid overwrite on change
2021-11-16 19:02:29 +00:00
Dimitrij
018979d17f #2064 fix, to avoid failure then null, set by default to be empty 2021-11-16 17:19:06 +00:00
Dimitrij
8bd398cbd6 update to VS 2022 2021-11-16 13:29:14 +00:00
Dimitrij
59872b14cf #1297
little fix of logic
2021-11-16 13:28:45 +00:00
Dimitrij
c5240d72e1 Merge pull request #2065 from merarischroeder/503_ssh-execute-single-command-after-login
Added Null/Empty check for OpeningCommand
2021-11-16 09:08:39 +00:00
Todd Hubers
77b54f9a10 Added Null/Empty check for OpeningCommand 2021-11-15 13:38:56 +11:00
Dimitrij
b5bcb5b3bb libupdate 2021-11-13 16:42:33 +00:00
Dimitrij
87c500138b update .net framework to version 4.8 2021-11-13 16:32:47 +00:00
Dimitrij
f3f384ebcc Merge pull request #2064 from merarischroeder/503_ssh-execute-single-command-after-login
503 SSH Execute a single command after login
2021-11-13 16:16:54 +00:00
Todd Hubers
08de2eacd6 Amended changelog 2021-11-13 03:25:03 +11:00
Todd Hubers
b763d968fe Support for saving OpeningCommand and the InheritedOpeningCommand. Tested for stock saving only. 2021-11-13 03:22:35 +11:00
Todd Hubers
3b05eba2e2 Use SendKeys to Execute the Opening Command on the Putty window after logged in + NEWLINE. Tested and working. 2021-11-13 03:05:02 +11:00
Todd Hubers
b6d2c72a40 Added new SSH Property "Opening Command" 2021-11-13 02:47:16 +11:00
Dimitrij
e6d2c9791d Merge pull request #2063 from tecxx/SecretServerInterface
Thycotic Secret Server Interface
2021-11-05 13:00:45 +00:00
tecxx
91a0eeb29a add changelog entry 2021-11-04 21:30:48 +01:00
tecxx
8c9c4865f2 add secret server handler to RDP and SSH 2021-11-04 21:13:37 +01:00
tecxx
6fbd4a7c88 add secret server interface library 2021-11-04 21:09:23 +01:00
Dimitrij
239adaa129 add 'Languages' folder as alternative for translation assemblies (to move from root all translations into it) 2021-11-02 23:08:09 +00:00
Dimitrij
9f8c82b649 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-11-02 22:53:56 +00:00
Dimitrij
7875bb6ebd lib update 2021-11-02 22:53:14 +00:00
Dimitrij
a33abf3f56 Merge pull request #2061 from horizontti/patch-1
Create Language.fi-FI.resx
2021-11-02 10:05:33 +00:00
horizontti
1fadadcdb5 Create Language.fi-FI.resx 2021-11-01 23:59:46 +02:00
Faryan Rezagholi
a294dec0dc merged from develop 2021-10-30 15:58:32 +02:00
Dimitrij
5de75e6a8a downgrade DockPanelSuite to 3.0.6 due reference error in 3.1.0 2021-10-30 01:04:39 +01:00
Dimitrij
4b44be2e54 libs update 2021-10-28 17:57:48 +01:00
Dimitrij
b5f1d63175 Merge pull request #2058 from LightningSt0rm/develop
Fix a break in the Windows Clipboard Chain
2021-10-28 17:24:33 +01:00
Adrian
1c5695df7e Update changelog 2021-10-20 17:52:50 -05:00
Adrian
1808ad9ad7 Correct issues with the Windows Clipboard Chain, where the chain was broken when messages to WM_CHANGECBCHAIN weren't handled appropriately as well unregister self from the clipboard chain when closing. 2021-10-20 17:10:24 -05:00
Dimitrij
8dc5e81374 Update French translation #2045 2021-09-21 22:46:49 +01:00
Dimitrij
b899056a8e lib update 2021-09-17 23:12:47 +01:00
Dimitrij
f884c47ad8 set Language as resource 2021-09-17 22:58:58 +01:00
Dimitrij
07eae639b6 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-09-14 12:13:58 +01:00
Dimitrij
d2349bd713 merge with new options 2021-09-14 12:03:01 +01:00
Faryan Rezagholi
28ee3c6e8f merged from develop 2021-08-30 00:36:28 +02:00
Faryan Rezagholi
4430f269f7 Merge pull request #2033 from IDDesigns/id/net5
Id/net5
2021-08-29 23:04:55 +02:00
Faryan Rezagholi
a72f7d63f6 Added <LangVersion>preview</LangVersion> to test project 2021-08-29 22:59:38 +02:00
Faryan Rezagholi
859b6f8ac5 set target framework to "net6.0-windows" instead of "net6.0-windows7.0" 2021-08-29 22:55:19 +02:00
Faryan Rezagholi
a7f238aba3 merge from dotnet 2021-08-29 22:51:29 +02:00
Faryan Rezagholi
e0cff27aae addded <LangVersion>preview</LangVersion> to project file 2021-08-29 18:55:21 +02:00
Faryan Rezagholi
d9c4a6ec76 Merge branch 'dotnet' into dotnet6 2021-08-29 18:45:29 +02:00
Faryan Rezagholi
4d95bc4255 merge from develop 2021-08-29 18:45:02 +02:00
Faryan Rezagholi
fdea0144b0 removed test output from script 2021-08-29 18:44:08 +02:00
Faryan Rezagholi
7398a373c2 Squashed commit of the following:
commit 84b28316d01d158891d909e90fe428e48d5566e3
Author: Faryan Rezagholi <faryan.rezagholi@siedle.de>
Date:   Sun Aug 29 13:08:31 2021 +0200

    r

commit 7375b4a5456a615b36c4fbf0eda7a8d56762de85
Author: Faryan Rezagholi <faryan.rezagholi@siedle.de>
Date:   Sun Aug 29 12:54:40 2021 +0200

    ...

commit 96aa9d809131c8277bd62cb90fdfa4fd07f1940e
Author: Faryan Rezagholi <faryan.rezagholi@siedle.de>
Date:   Fri Aug 20 15:12:03 2021 +0200

    j
2021-08-29 18:41:50 +02:00
Faryan Rezagholi
c88e45cde8 fixed app.config for dotnet6 2021-08-29 12:47:31 +02:00
Ian Dunkerly
f77848e3d9 Fixing up unit tests 2021-08-27 21:20:50 +01:00
Ian Dunkerly
5ed78cc3b6 Swapped BouncyCastle for Portable.BouncyCastle which support .net standard 2.0 2021-08-22 17:25:55 +01:00
Ian Dunkerly
1b4593bb62 Removed system.web reference - these are not supported in .Net 5 2021-08-22 15:28:47 +01:00
Ian Dunkerly
c620e26644 Import MSTC as ActiveX control removing need for dependency on Windows Simulator 2021-08-22 14:27:58 +01:00
Faryan Rezagholi
74af24c3db appveyor test 2021-08-20 13:14:16 +02:00
Faryan Rezagholi
ac1f32f773 setting workdir for 7z 2021-08-20 13:03:22 +02:00
Faryan Rezagholi
99c7dbb332 trying -sfp2 option on 7z for appveyor 2021-08-20 12:17:14 +02:00
Faryan Rezagholi
b0632b8910 trying to fix appveyor no 7z-ing portable release 2021-08-20 00:36:09 +02:00
Faryan Rezagholi
d26a9615c0 updated nuget 2021-08-19 23:47:46 +02:00
Faryan Rezagholi
f609d6e0b2 removed cefsharp nuget 2021-08-19 23:47:37 +02:00
Faryan Rezagholi
e5042712b6 nuget update 2021-08-19 23:29:13 +02:00
Faryan Rezagholi
bf93d3af04 fixed ambigous call 2021-08-19 22:36:41 +02:00
Faryan Rezagholi
ea43abe392 updated projects to .net6 2021-08-19 22:36:32 +02:00
Faryan Rezagholi
0e74314ddc fixed port scan and external tools window not showing 2021-08-15 21:53:10 +02:00
Faryan Rezagholi
54eabd6a74 some property display names were not showing, fixes #1990 2021-08-15 20:53:52 +02:00
Faryan Rezagholi
2f52473566 Allow setting Port when using MSSQL, fixes #1884 2021-08-15 20:13:59 +02:00
Faryan Rezagholi
98e7250b3c trying to fix 7z creating archives wrong on appveyor 2021-08-15 19:51:25 +02:00
Faryan Rezagholi
882438f5e0 replaced logo in readme 2021-08-15 19:16:17 +02:00
Faryan Rezagholi
bb93dddd39 copy PUTTYNG.exe to output dir 2021-08-15 17:05:13 +02:00
Faryan Rezagholi
59f6a8a933 fixed wix installer 2021-08-15 16:36:55 +02:00
Faryan Rezagholi
8ce83f3cd0 removed orphaned path from project 2021-08-15 16:32:50 +02:00
Faryan Rezagholi
745e402da9 Removed VNC Smart Size feature. This allows the use of VNCSharp via nuget instead of distributing our own version of it) 2021-08-15 16:32:31 +02:00
Faryan Rezagholi
6cbe1c92d5 fix for Proces.Start() on .net5 2021-08-15 16:28:38 +02:00
Faryan Rezagholi
54fc2fb4c6 updated readme 2021-08-15 16:20:23 +02:00
Faryan Rezagholi
adc2815ab5 fixed some failing tests 2021-08-15 16:20:09 +02:00
Faryan Rezagholi
75f9f647ee migrated projects to .net5 2021-08-15 16:16:30 +02:00
Faryan Rezagholi
f14f7dbb72 removed assembly info classes as they are no longer needed 2021-08-15 16:15:34 +02:00
Faryan Rezagholi
4978618e9a merged from develp 2021-08-15 14:08:40 +02:00
Faryan Rezagholi
59b9f4f15b moved resharper logo 2021-08-15 02:17:40 +02:00
Faryan Rezagholi
7ff0ce5369 tring to fix 7z duplicate file error on appveyor builds 2021-08-15 00:41:59 +02:00
Faryan Rezagholi
93bd278819 removed assembly bindings 2021-08-14 18:30:49 +02:00
Faryan Rezagholi
b97b1f3690 added sigcheck back 2021-08-14 18:24:36 +02:00
Faryan Rezagholi
307f374be1 fixed renaming of installer not working 2021-08-14 18:17:17 +02:00
Faryan Rezagholi
17f701824e encore un test 2021-08-14 17:05:21 +02:00
Faryan Rezagholi
c7b89dcf71 another test 2021-08-14 16:57:42 +02:00
Faryan Rezagholi
fc527a947f appveyor build script fixes 2021-08-14 16:49:23 +02:00
Faryan Rezagholi
d0520690a2 appveyor build script fixes 2021-08-14 16:45:06 +02:00
Faryan Rezagholi
315d020b6f appveyor build script fixes 2021-08-14 13:55:42 +02:00
Faryan Rezagholi
8a4bcdef52 appveyor build script fixes 2021-08-14 13:48:38 +02:00
Faryan Rezagholi
727ef34c6d appveyor build script fixes 2021-08-14 13:46:43 +02:00
Faryan Rezagholi
d8bc06d05d ? 2021-08-14 13:41:09 +02:00
Faryan Rezagholi
def214dde2 maybe this time 2021-08-14 13:39:10 +02:00
Faryan Rezagholi
219f948c4a again... 2021-08-14 13:35:13 +02:00
Faryan Rezagholi
72193eccf0 appveyor fix 2021-08-14 13:30:54 +02:00
Faryan Rezagholi
7eb85c6a3d trying to fix appveyor not zipping 2021-08-14 13:26:35 +02:00
Faryan Rezagholi
954c667173 cleanup 2021-08-14 13:16:09 +02:00
Faryan Rezagholi
33c738df5f unified/simplified/accelerated zip file creation 2021-08-14 13:07:14 +02:00
Faryan Rezagholi
2141fe298f let appveyor use project scripts 2021-08-14 12:15:13 +02:00
Faryan Rezagholi
8e73f512b4 moved puttyng.exe to project root 2021-08-14 01:55:51 +02:00
Faryan Rezagholi
92dddb8fd8 removed unused scripts 2021-08-13 02:20:34 +02:00
Faryan Rezagholi
e9869f4c88 cleaned up resource structure 2021-08-13 02:06:21 +02:00
Faryan Rezagholi
52597d4dcb removed 7zip binarys from project 2021-08-13 01:44:26 +02:00
Faryan Rezagholi
dc7ce27b81 fixed designer error 2021-08-13 01:17:27 +02:00
Faryan Rezagholi
4242595a66 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-08-13 01:12:45 +02:00
Faryan Rezagholi
50b9a11503 change searchbar placement default property 2021-08-13 01:12:20 +02:00
Faryan Rezagholi
621a723602 Merge pull request #2022 from mRemoteNG/webview2
Replace CefSharp with Webview2
2021-08-12 23:46:04 +02:00
Faryan Rezagholi
6260cc3655 fixed tests 2021-08-12 23:35:19 +02:00
Faryan Rezagholi
300e668327 updated wix file fragments 2021-08-12 23:26:18 +02:00
Faryan Rezagholi
3cf274c37a updated changelog 2021-08-12 23:11:55 +02:00
Faryan Rezagholi
2ca356ee5c removed CefSharp from credits 2021-08-12 22:55:40 +02:00
Faryan Rezagholi
ca8751c40c little code cleanup 2021-08-12 22:54:20 +02:00
Faryan Rezagholi
3c7e97d2d9 replaced CefSharp with WebView2 2021-08-12 22:46:07 +02:00
Faryan Rezagholi
dbe2d690da removed majority of cefsharp related code 2021-08-12 21:00:26 +02:00
Faryan Rezagholi
949410e2cc unified release channel names across program 2021-08-11 03:21:16 +02:00
Faryan Rezagholi
100f856b5f cleaned up view menu and made all properties saveable 2021-08-11 03:08:20 +02:00
Faryan Rezagholi
d7bee01454 removed orphaned templates dir 2021-08-10 01:17:15 +02:00
Faryan Rezagholi
5566081986 update nuget packages 2021-08-10 00:59:27 +02:00
Faryan Rezagholi
29f7dd93f3 optimized form closing event 2021-08-10 00:56:14 +02:00
Faryan Rezagholi
3dd8db5728 updated icons in connection tree 2021-08-08 22:30:55 +02:00
Dimitrij
17e70d11f5 Merge pull request #2016 from xjoker/develop
Cannot connect to the database when the password has special characters
2021-08-06 14:59:15 +01:00
wuwenjing
f8afd439b2 When the password contains special characters, it will be unable to connect to the database. Using "SqlConnectionStringBuilder" to construct "ConnectionString" can solve the problem 2021-08-06 16:35:01 +08:00
Faryan Rezagholi
0dc61b1c26 Merge pull request #2014 from mRemoteNG/revised_icons
Revised icons
2021-08-04 02:39:03 +02:00
Faryan Rezagholi
de6c4fcb17 updated readme 2021-08-04 02:18:53 +02:00
Faryan Rezagholi
57f5c854ff moved logo 2021-08-04 02:13:17 +02:00
Faryan Rezagholi
4f4523ab77 removed old form icons 2021-08-04 02:11:29 +02:00
Faryan Rezagholi
e34e632519 removed ICOs from project 2021-08-04 01:49:06 +02:00
Faryan Rezagholi
f810b902a6 added image converter class to get ico from resources (get rid of redundant image resources) 2021-08-04 01:48:08 +02:00
Faryan Rezagholi
fd5bdc1484 replaced remaining icons 2021-08-04 01:11:34 +02:00
Faryan Rezagholi
e3a12ae6c5 you guessed it... ICONS! 2021-08-04 00:51:54 +02:00
Faryan Rezagholi
c9c5664ec6 icons icons icons 2021-08-04 00:39:33 +02:00
Faryan Rezagholi
75cff549ce more icons changed 2021-08-03 23:53:08 +02:00
Faryan Rezagholi
885cb6915d Merge branch 'develop' into revised_icons 2021-08-03 23:13:27 +02:00
Faryan Rezagholi
f9396a4ecf moved photoshop image templates out of project folder 2021-08-03 22:43:57 +02:00
Faryan Rezagholi
f1a03329e5 removed ultravnc icon 2021-08-03 22:38:15 +02:00
Faryan Rezagholi
f65be671a3 moved icons that will stay the same 2021-08-03 22:36:34 +02:00
Faryan Rezagholi
fa9e8f6cba merged develop 2021-08-03 22:27:51 +02:00
Faryan Rezagholi
67a3e76cfe removed icons that are obsolete since #2011 and #2013 2021-08-03 22:16:53 +02:00
Faryan Rezagholi
e4569c0bb8 Merge pull request #2013 from mRemoteNG/remove_components_check
Remove components check
2021-08-03 22:11:10 +02:00
Faryan Rezagholi
6f1a62e917 Merge branch 'develop' into remove_components_check 2021-08-03 21:57:06 +02:00
Faryan Rezagholi
3f6e21f15a Merge pull request #2011 from mRemoteNG/remove_screenshot_manager
removed screenshot manager
2021-08-03 21:54:52 +02:00
Faryan Rezagholi
46c4287c67 updated changelog 2021-08-03 21:51:09 +02:00
Faryan Rezagholi
1ea1826a27 removed leftovers from components check 2021-08-03 21:46:00 +02:00
Faryan Rezagholi
151457daf0 removed components check options page 2021-08-03 21:39:07 +02:00
Faryan Rezagholi
38cc21fa3a first wave of icons changed 2021-08-03 21:36:03 +02:00
Faryan Rezagholi
77f759f258 more icons cleaned up 2021-08-03 18:50:47 +02:00
Faryan Rezagholi
07c04061c2 more unused icons removed 2021-08-03 01:30:06 +02:00
Faryan Rezagholi
d4bf6ed0c8 added icons that were no part of the resource file 2021-08-03 01:21:11 +02:00
Faryan Rezagholi
ebd46efe81 Merge branch 'develop' into remove_screenshot_manager 2021-08-03 01:11:28 +02:00
Faryan Rezagholi
24d193efb0 revised host status icons 2021-08-03 00:59:59 +02:00
Faryan Rezagholi
3b2a63178f removed unused images/duplicate resources 2021-08-03 00:52:28 +02:00
Faryan Rezagholi
78f60afb85 Removed famfamfam folder and obsolete icons from images folder 2021-08-03 00:49:11 +02:00
Faryan Rezagholi
52a7957789 Update README.MD
Embedded new logo
2021-08-02 12:56:04 +02:00
Faryan Rezagholi
6870583b1c new logo 2021-08-02 12:50:00 +02:00
Faryan Rezagholi
9ffe514350 fixed error from previous merge 2021-08-02 00:29:15 +02:00
Faryan Rezagholi
fc6e04497a updated changelog 2021-08-02 00:16:14 +02:00
Faryan Rezagholi
cfb3f9a3ca merged from develop 2021-08-02 00:13:33 +02:00
Faryan Rezagholi
d47fac791e removed unused language strings 2021-08-02 00:05:10 +02:00
Faryan Rezagholi
490b70c2d3 removed cef scheme handler for obsolete in-app documentation 2021-08-02 00:01:48 +02:00
Faryan Rezagholi
3eecdd9ada Merge pull request #2010 from mRemoteNG/redesign_menus
Redesigned Menus
2021-08-01 23:51:22 +02:00
Faryan Rezagholi
7bdbc5417c update changelog 2021-08-01 23:28:32 +02:00
Faryan Rezagholi
2cd07dcb72 Merge branch 'develop' into redesign_menus 2021-08-01 23:01:53 +02:00
Faryan Rezagholi
adb83ade67 Merge pull request #2005 from mRemoteNG/remove_in_app_documentation
Remove in-app documentation
2021-08-01 23:00:21 +02:00
Faryan Rezagholi
a90f5da8b0 updated changelog 2021-08-01 22:45:39 +02:00
Faryan Rezagholi
38937a4f83 more rearrangements 2021-08-01 22:43:59 +02:00
Faryan Rezagholi
31f35a23ee removed some icons from file menu 2021-08-01 22:39:16 +02:00
Faryan Rezagholi
74de010d3c cleaned up icons in view menu 2021-08-01 22:32:27 +02:00
Faryan Rezagholi
a9e4c880df redesigned help menu 2021-08-01 22:29:04 +02:00
Faryan Rezagholi
b7fe265604 rearranged view menu 2021-08-01 21:45:15 +02:00
Faryan Rezagholi
25c4af5a9f cleaned up file menu 2021-08-01 21:40:14 +02:00
Faryan Rezagholi
b3ecf702e1 removed developer notice 2021-07-28 21:31:59 +02:00
Faryan Rezagholi
c34a3cc7e7 Added back sphinx documentation files 2021-07-26 01:22:31 +02:00
Faryan Rezagholi
158783f2d1 removed screenshot manager 2021-07-26 01:11:01 +02:00
Faryan Rezagholi
624192d301 Added featured project 2021-07-26 00:51:21 +02:00
Faryan Rezagholi
e9be139ed0 removed HelpWindows from code 2021-07-24 19:40:52 +02:00
Faryan Rezagholi
2b9195ed9c fixed typo 2021-07-24 19:38:09 +02:00
Faryan Rezagholi
dfdfecba57 open help in external browsr instead of in-app 2021-07-24 19:37:38 +02:00
Faryan Rezagholi
2d6fec13fb added url to documentation 2021-07-24 19:37:22 +02:00
Faryan Rezagholi
216f340468 removed sphinx documentation files 2021-07-24 19:35:00 +02:00
Faryan Rezagholi
a4211a7e55 removed postbuild sphinx script 2021-07-24 19:34:04 +02:00
Faryan Rezagholi
d6a2488fde removed obsolete citrix reference from minimum requirements section 2021-07-22 22:33:58 +02:00
Faryan Rezagholi
d4d60439b6 Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop 2021-07-22 22:12:02 +02:00
Faryan Rezagholi
75edd0d8ef round corners on splash screen 2021-07-22 22:11:05 +02:00
Dimitrij
b4e6e21094 Merge pull request #2001 from radiosti/patch-1
added optional but helpful winscp arguments
2021-07-20 09:54:42 +01:00
radiosti
8c48bc926e Update external_tools_cheat_sheet.rst 2021-07-19 20:56:26 +02:00
Dimitrij
031b6fb30d set AutoGenerateBindingRedirects 2021-07-05 20:17:39 +01:00
Dimitrij
647542e462 update supported os list 2021-07-04 14:51:00 +01:00
Dimitrij
dbf28d83f3 update PuTTY to v.0.75 2021-07-04 14:42:03 +01:00
Dimitrij
142acdd42f cleanup unused files 2021-06-29 12:18:02 +01:00
Dimitrij
ce103d30d3 update lib 2021-06-29 10:11:16 +01:00
Kvarkas
556d65e8b4 upd README.MD 2021-06-24 23:47:14 +01:00
Kvarkas
e0cf070bd0 fx mistypo 2021-06-24 23:45:52 +01:00
Kvarkas
70c5a336c2 upd 2021-06-24 23:43:52 +01:00
Kvarkas
f82d5fbd2d nb 2021-06-24 23:26:34 +01:00
John Carew
67dfd6b036 Update change log 2020-08-29 17:56:18 -05:00
John Carew
162eb0c958 Add missing db updates for Favorite & ICAEncryptionStrength columns.
Misc vs project automated updates.
2020-08-29 17:44:45 -05:00
John Carew
a2dcc42f68 Update to support reading/writing from config
Update db version to 2.9
Change version tracking from double to Version, to support revision changes between minor versions in db
2020-08-29 17:43:11 -05:00
John Carew
6b7f6dcb19 Add Remote Desktop Services group
Add StartProgram & StartProgramWorkDir properties to Remote Desktop Services group
Corrected Redirect Drives & Smart Cards display names
2020-08-29 17:26:46 -05:00
David Sparer
066e783a37 changed the Edit sub-menu to Inheritance in the connection context menu 2019-06-18 09:16:17 -05:00
David Sparer
3e1bf001c7 Merge branch 'develop' into push_settings_recursively
# Conflicts:
#	mRemoteV1/Resources/Language/Language.Designer.cs
#	mRemoteV1/Resources/Language/Language.resx
2019-06-18 09:10:23 -05:00
David Sparer
722e18c07d updated changelog 2019-05-15 10:41:00 -05:00
David Sparer
a66ec00587 put the ''apply to children" menu options in a sub-menu 2019-05-15 10:09:08 -05:00
David Sparer
2b5100c019 Merge branch 'develop' into push_settings_recursively 2019-05-15 09:29:02 -05:00
David Sparer
74da05e6e8 fixed tests 2019-05-10 15:47:11 -05:00
David Sparer
af24e3b284 the inheritance button will now be shown on items whose parent is the root node 2019-05-10 15:41:43 -05:00
David Sparer
fb68d0bff3 added a button to apply default inheritance to the selected node 2019-05-10 13:57:58 -05:00
David Sparer
d3a2ba26ba only allow pushing inheritance from containers 2019-05-10 08:10:37 -05:00
David Sparer
2f70ec5cb6 Merge branch 'develop' into push_settings_recursively 2019-05-10 08:04:15 -05:00
David Sparer
9173e9e56a added a context menu item to push inheritance to child nodes 2019-04-29 08:39:06 -05:00
David Sparer
11ad8a8398 simplified how inheritance is globally disabled/enabled 2019-04-25 10:21:09 -05:00
David Sparer
0d518e44c7 Merge branch 'develop' into push_settings_recursively 2019-04-24 12:26:21 -05:00
David Sparer
7d8a5a2bdf added methods on the container info to push settings to children recursively 2019-04-01 13:26:25 -05:00
1091 changed files with 179806 additions and 33681 deletions

130
.github/workflows/build-x86_64.yml vendored Normal file
View File

@@ -0,0 +1,130 @@
name: Build x86_64
on:
push:
branches:
- v1.77.3-dev
jobs:
Build-Debug-MSI:
runs-on: windows-2022
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1 # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
with:
vs-version: '17.8.3'
- name: 03. Restore nuget packages for solution
shell: pwsh
run: |
dotnet restore
- name: 04. Compile mRemoteNG
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Debug Installer" -p:Platform=x64 /verbosity:normal
- name: 05. Publish MSI as Artifact
uses: actions/upload-artifact@v4
with:
name: debug-msi-x86_64
path: ${{ github.workspace }}\mRemoteNGInstaller\Installer\bin\x64\Debug\en-US\
if-no-files-found: error
Build-Debug-Portable:
runs-on: windows-2022
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1 # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
with:
vs-version: '17.8.3'
- name: 03. Restore nuget packages for solution
shell: pwsh
run: |
dotnet restore
- name: 04. Compile mRemoteNG
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Debug Portable" -p:Platform=x64 /verbosity:normal
- name: 05. Publish Portable Binary as Artifact
uses: actions/upload-artifact@v4
with:
name: debug-portable-x86_64
path: ${{ github.workspace }}\mRemoteNG\bin\x64\Debug Portable\
if-no-files-found: error
Build-Release:
runs-on: windows-2022
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1 # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
with:
vs-version: '17.8.3'
- name: 03. Restore nuget packages for solution
shell: pwsh
run: |
dotnet restore
- name: 04. Compile mRemoteNG
shell: pwsh
run: |
msbuild "$Env:GITHUB_WORKSPACE\mRemoteNG.sln" -p:Configuration="Release Installer and Portable" -p:Platform=x64 /verbosity:normal
- name: 05. Publish MSI Binary as Artifact
uses: actions/upload-artifact@v4
with:
name: release-msi-x86_64
path: ${{ github.workspace }}\mRemoteNGInstaller\Installer\bin\x64\Release\en-US\
if-no-files-found: error
- name: 06. Publish Portable Binary as Artifact
uses: actions/upload-artifact@v4
with:
name: release-portable-x86_64
path: ${{ github.workspace }}\mRemoteNG\bin\x64\Release
if-no-files-found: error
Create-Release:
needs: [Build-Debug-MSI, Build-Debug-Portable, Build-Release]
runs-on: ubuntu-22.04
steps:
- name: 01. Copy repository
uses: actions/checkout@v4
- name: 02. Download Artifacts
uses: actions/download-artifact@v4
- name: 03. Create compressed archives # Needs to be done because "actions/download-artifact@v4" is extracting the zipped Artifacts
shell: bash
run: |
zip -r debug-msi-x86_64.zip debug-msi-x86_64/
zip -r debug-portable-x86_64.zip debug-portable-x86_64/
zip -r release-msi-x86_64.zip release-msi-x86_64/
zip -r release-portable-x86_64.zip release-portable-x86_64/
- name: 04. Create Release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "v1.77.3-dev-${GITHUB_RUN_NUMBER}" \
--title "v1.77.3-dev-${GITHUB_RUN_NUMBER}" \
--prerelease \
--generate-notes \
$GITHUB_WORKSPACE/debug-msi-x86_64.zip \
$GITHUB_WORKSPACE/debug-portable-x86_64.zip \
$GITHUB_WORKSPACE/release-msi-x86_64.zip \
$GITHUB_WORKSPACE/release-portable-x86_64.zip

6
.gitignore vendored
View File

@@ -283,6 +283,6 @@ Installer Projects/Installer/Fragments/HelpFilesFragment.wxs
InstallerProjects/Installer/Fragments/FilesFragment.wxs
InstallerProjects/Installer/Resources/License.rtf
# gh-pages info
runlocal.bat
/_site
# mRemoteNG
**/mRemoteNG/Properties/AssemblyInfo.tt
**/mRemoteNG/Properties/AssemblyInfo.cs

14
.readthedocs.yaml Normal file
View File

@@ -0,0 +1,14 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: mRemoteNGDocumentation/conf.py
# Optionally build your docs in additional formats such as PDF
formats:
- pdf

11
Add-ons/README.md Normal file
View File

@@ -0,0 +1,11 @@
## Add-ons library by 3rd party
This is a list of add-ons, plugins and extentions what could be used with mRemoteNG, if you wish to add yours to this list - just drop me a line: <a href="mailto:support@mremoteng.org">support@mremoteng.org</a>
<br>
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Date&nbsp;added</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Author</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <b>Type</b> | <b>Name</b> | <b>Description</b> | <b>Repository</b> |
| :---------------------------------------------------------:|:-------------------------------------------------:| :---------: |-------------|--------------------|:-----------------:|
| 02-08-2022 | <a href="https://github.com/JustBeta"><img align="left" src="https://avatars.githubusercontent.com/u/25150896?v=4" alt="JustBeta" width="30px"/>JustBeta</a> | script | Export-MobaXterm2mRemoteNG | Conversion of MobaXterm's ini file to mRemoteNG format. | [GITHUB Repository](https://github.com/JustBeta/Export-MobaXtern2mRemoteNG/tree/main) |
<br>
For a detailed usage examples and documentation please reach out authors.

View File

@@ -2,36 +2,91 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.77.3.1784]
### Fixed
- #2362: Fix use of sql database
- #2356: Improve speed for the display of the options page
- #2352: SSH.NET Update
- #2346: Modify "auto reconnect" to have the ability to really auto-reconnect
- #2340: Set the default theme setting
- #2339: Add 2 missing settings
- #2261: Implement Show/Hide file menu in view menu
- #2244: Save RCG and RestrictedAdmin fields correctly in connections file
- #2195: Fix crafted XML File Code Execution vulnerability
- #304: use pwfile instead of cleartext password for puttyng
## [Unreleased]
### Added
- #1427: Fix RDP local desktop scale not taking effect on remote
- #2285: Support extraction of SSH private keys from external cred prov
- #2268: Postregsql database support
### Updated
- #2295: Updates hyperlink style to make links more visible to end users
- #2337: Set language.resx to auto generate the designer class
## [1.77.3]
### Added
- #1736: Update of SSH.NET to 2020.0.2 to allow File Transfer again
- #2138: Improve compatibility with Remote Desktop Connection Manager v2.83
- #2123: Thycotic Secret Server - Added 2FA OTP support
### Changed
- #1546: Enable resize without reconnect for RDP Version Rdc9 or higher
## [1.77.2]
### Added
- #2086: Replace WebClient with async HttpClient for updater.
- #1850: Minify config xml
- #1770: Added missing RDP performance settings
- #1516: added API to access credential vault (Thycotic Secret Server) by specifying SSAPI:ID as username
- #1476: Configurable backups. Can now edit/set backup frequency, backup path, and max number of backup files.
- #1427: Fix RDP local desktop scale not taking effect on remote
- #1332: Added option to hide menu strip container
- #870: Added option to push inheritance settings to child nodes recursively
- #545: Option to minimize to system tray on closing
- #503: SSH Execute a single command after login
- #420: SSH tunneling implemented
- #327: Added Alternative Shell for RDP settings
- #319: Override quick connect username when using user@domain
- #283: Support for native PowerShell remoting as new protocol
- #1850: Minify config xml
- #xxx: Add external connector to retrieve ip address from Amazon EC2 Instance IDs
### Changed
- #2102: Extended the field RenderingEngine from 10 chars to 16
- #2022: Replaced CefSharp with WebView2
- #2014: Revised icons
- #2013: Removed components check
- #2011: Removed screenshot manager
- #2010: Redesigned menus
- #2005: Removed in-app documentation
- #1777: Cleaned up VisualStudio project structure
- #1767: Turned about window into a simple popup form
- #1766: Converted components check page into options page
- #1690: Replaced GeckoFX (Firefox) with CefSharp (Chromium)
- #1325: Language resource files cleanup
- #xxxx: Secret Server connector via new field "API User ID" instead of SSAPI: prefix
### Fixed
- #2125: Fixed string parsing logic for Quick Connect toolbar.
- #2122: Fix to avoid throwing exception incase if not able decrypt connections and ask to open another one or create a new.
- #2117: Fix of broken Links due migration to .NET 6 and branch renaming
- #2098: Fix failed BinaryFileTest
- #2097: Fix failed tests related to mRemoteNGTests.UI.Window.ConfigWindowTests
- #2096: Corrected encryption code of LegacyRijndaelCryptographyProvider
- #2089: Fixed the exception thrown by menu buttons "Documentation" and "Website"
- #2087: Fixed application crash, when the update file is launched from the application
- #2079: Fixed theme files not being copied to output directory
- #2012: Updated PuTTYNG to v0.76
- #1884: Allow setting Port when using MSSQL
- #1783: Added missing inheritance properties to SQL scripts
- #1773: Connection issue with mysql - Missing fields in
- #1773: Connection issue with MySql - Missing fields in
- #1756: Cannot type any character on MultiSSH toolbar
- #1720: Show configuration file name in title of password prompt form
- #1713: Sound redirection does not work if Clipboard redirection is set to No
- #1632: 1.77.1 breaks RDP drive and sound redirection
- #1610: Menu bar changes to english when cancelling options form
- #1610: Menu bar changes to English when canceling options form
- #1595: Unhandled exception when trying to browse through non existent multi ssh history with keyboard key strokes
- #1589: Update SQL tables instead of rewriting them
- #1465: REGRESSION: Smart Cards redirection to Remote Desktop not working
- #1363: Don't show "Disk Usage" button in installer
- #1337: Unhandled exception after closing mRemoteNG
- #359: Making a VNC connection to an unreachable host causes the application to not respond for 20-30 seconds
- #618: Do not break the Windows Clipboard Chain when exiting.
## [1.77.1] - 2019-09-02
### Added

View File

@@ -278,62 +278,3 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,180 @@
namespace ExternalConnectors.AWS
{
partial class AWSConnectionForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tbAccesKeyID = new System.Windows.Forms.TextBox();
this.tbAccesKey = new System.Windows.Forms.TextBox();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// tbAccesKeyID
//
this.tbAccesKeyID.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbAccesKeyID.Location = new System.Drawing.Point(152, 4);
this.tbAccesKeyID.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.tbAccesKeyID.Name = "tbAccesKeyID";
this.tbAccesKeyID.Size = new System.Drawing.Size(490, 23);
this.tbAccesKeyID.TabIndex = 0;
//
// tbAccesKey
//
this.tbAccesKey.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbAccesKey.Location = new System.Drawing.Point(152, 43);
this.tbAccesKey.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.tbAccesKey.Name = "tbAccesKey";
this.tbAccesKey.Size = new System.Drawing.Size(490, 23);
this.tbAccesKey.TabIndex = 2;
//
// btnOK
//
this.btnOK.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(219, 12);
this.btnOK.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(88, 26);
this.btnOK.TabIndex = 10;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
//
// btnCancel
//
this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(338, 12);
this.btnCancel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(88, 26);
this.btnCancel.TabIndex = 11;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 22.92994F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 77.07006F));
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.tbAccesKeyID, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.tbAccesKey, 1, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(646, 102);
this.tableLayoutPanel1.TabIndex = 12;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(4, 0);
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(140, 39);
this.label1.TabIndex = 2;
this.label1.Text = "Access Key ID";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(4, 39);
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(140, 39);
this.label2.TabIndex = 4;
this.label2.Text = "Access Key";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 5;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 23F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 93F));
this.tableLayoutPanel2.Controls.Add(this.btnOK, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.btnCancel, 3, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 112);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(646, 50);
this.tableLayoutPanel2.TabIndex = 13;
//
// AWSConnectionForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(646, 162);
this.Controls.Add(this.tableLayoutPanel2);
this.Controls.Add(this.tableLayoutPanel1);
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.Name = "AWSConnectionForm";
this.Text = "AWS EC2 API Login Data";
this.Activated += new System.EventHandler(this.AWSConnectionForm_Activated);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
public System.Windows.Forms.TextBox tbAccesKeyID;
public System.Windows.Forms.TextBox tbAccesKey;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
}
}

View File

@@ -0,0 +1,16 @@
namespace ExternalConnectors.AWS
{
public partial class AWSConnectionForm : Form
{
public AWSConnectionForm()
{
InitializeComponent();
}
private void AWSConnectionForm_Activated(object sender, EventArgs e)
{
tbAccesKeyID.Focus();
}
}
}

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,119 @@
using Amazon;
using Amazon.EC2;
using Amazon.EC2.Model;
using Microsoft.Win32;
namespace ExternalConnectors.AWS
{
public class EC2FetchDataService
{
private static DateTime lastFetch;
private static List<InstanceInfo>? lastData;
// input must be in format "AWSAPI:instanceid" where instanceid is the ec2 instance id, e.g. i-066f750a76c97583d
public static async Task<string> GetEC2InstanceDataAsync(string input, string region)
{
// get secret id
if (!input.StartsWith("AWSAPI:"))
throw new Exception("calling this function requires AWSAPI: input");
string InstanceID = input[7..];
// init connection credentials, display popup if necessary
AWSConnectionData.Init();
var alldata = await GetEC2IPDataAsync(region);
var found = alldata.Where(x => x.InstanceId == InstanceID).SingleOrDefault();
return (found == null) ? "" : found.PublicIP;
}
private static async Task<List<InstanceInfo>> GetEC2IPDataAsync(string region)
{
// caching
TimeSpan timeSpan = DateTime.Now - lastFetch;
if (timeSpan.TotalMinutes < 1 && lastData != null)
return lastData;
//AWSConfigs.AWSRegion = AWSConnectionData.region;
AWSConfigs.AWSRegion = region;
string awsAccessKeyId = AWSConnectionData.awsKeyID;
string awsSecretAccessKey = AWSConnectionData.awsKey;
var _client = new AmazonEC2Client(awsAccessKeyId, awsSecretAccessKey, RegionEndpoint.EUCentral1);
bool done = false;
List<InstanceInfo> instanceList = new();
var request = new DescribeInstancesRequest();
while (!done)
{
DescribeInstancesResponse response = await _client.DescribeInstancesAsync(request);
foreach (var reservation in response.Reservations)
{
foreach (var instance in reservation.Instances)
{
string vmname = "";
foreach (var tag in instance.Tags)
{
if (tag.Key == "Name")
{
vmname = tag.Value;
}
}
InstanceInfo inf = new(instance, vmname);
instanceList.Add(inf);
}
}
request.NextToken = response.NextToken;
if (response.NextToken == null)
{
done = true;
}
}
lastData = instanceList.OrderBy(x => x.Name).ToList();
lastFetch = DateTime.Now;
return lastData;
}
public static class AWSConnectionData
{
private static readonly RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\mRemoteAWSInterface");
public static string awsKeyID = "";
public static string awsKey = "";
//public static string _region = "eu-central-1";
public static void Init()
{
if (awsKey != "")
return;
// display gui and ask for data
AWSConnectionForm f = new();
f.tbAccesKeyID.Text = "" + key.GetValue("KeyID");
f.tbAccesKey.Text = "" + key.GetValue("Key");
//f.tbRegion.Text = "" + key.GetValue("Region");
//if (f.tbRegion.Text == null || f.tbRegion.Text.Length < 2)
// f.tbRegion.Text = region;
_ = f.ShowDialog();
if (f.DialogResult != DialogResult.OK)
return;
// store values to memory
awsKeyID = f.tbAccesKeyID.Text;
awsKey = f.tbAccesKey.Text;
//region = f.tbRegion.Text;
// write values to registry
key.SetValue("KeyID", awsKeyID);
key.SetValue("Key", awsKey);
//key.SetValue("Region", region);
key.Close();
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Amazon.EC2.Model;
using System;
namespace ExternalConnectors.AWS
{
public class InstanceInfo
{
public string InstanceId { get; }
public string Name { get; }
public string Status { get; }
public string PublicIP { get; }
public string PrivateIP { get; }
public InstanceInfo(Instance instance, string name)
{
InstanceId = instance.InstanceId;
Name = name;
switch(instance.State.Code)
{
case 0: Status = "Pending"; break;
case 16: Status = "Running"; break;
case 32: Status = "Shutdown"; break;
case 48: Status = "Terminated"; break;
case 64: Status = "Stopping"; break;
case 80: Status = "Stopped"; break;
default: Status = "Unknown"; break;
};
PublicIP = instance.PublicIpAddress ?? "";
PrivateIP = instance.PrivateIpAddress ?? "";
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,241 @@
namespace ExternalConnectors.CPS
{
partial class CPSConnectionForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CPSConnectionForm));
tbServerURL = new TextBox();
label3 = new Label();
tbAPIKey = new TextBox();
btnOK = new Button();
btnCancel = new Button();
tableLayoutPanel1 = new TableLayoutPanel();
label1 = new Label();
label6 = new Label();
tbOTP = new TextBox();
cbUseSSO = new CheckBox();
tableLayoutPanel2 = new TableLayoutPanel();
label4 = new Label();
tableLayoutPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
SuspendLayout();
//
// tbServerURL
//
tbServerURL.Dock = DockStyle.Fill;
tbServerURL.Location = new Point(298, 5);
tbServerURL.Margin = new Padding(5);
tbServerURL.Name = "tbServerURL";
tbServerURL.Size = new Size(611, 27);
tbServerURL.TabIndex = 0;
//
// label3
//
label3.AutoSize = true;
label3.Dock = DockStyle.Fill;
label3.Location = new Point(5, 84);
label3.Margin = new Padding(5, 0, 5, 0);
label3.Name = "label3";
label3.Size = new Size(283, 42);
label3.TabIndex = 5;
label3.Text = "API Key";
label3.TextAlign = ContentAlignment.MiddleLeft;
//
// tbAPIKey
//
tbAPIKey.Dock = DockStyle.Fill;
tbAPIKey.Location = new Point(298, 89);
tbAPIKey.Margin = new Padding(5);
tbAPIKey.Name = "tbAPIKey";
tbAPIKey.Size = new Size(611, 27);
tbAPIKey.TabIndex = 4;
tbAPIKey.UseSystemPasswordChar = true;
//
// btnOK
//
btnOK.Anchor = AnchorStyles.Right;
btnOK.DialogResult = DialogResult.OK;
btnOK.Location = new Point(337, 16);
btnOK.Margin = new Padding(5);
btnOK.Name = "btnOK";
btnOK.Size = new Size(101, 35);
btnOK.TabIndex = 6;
btnOK.Text = "OK";
btnOK.UseVisualStyleBackColor = true;
//
// btnCancel
//
btnCancel.Anchor = AnchorStyles.Left;
btnCancel.DialogResult = DialogResult.Cancel;
btnCancel.Location = new Point(474, 16);
btnCancel.Margin = new Padding(5);
btnCancel.Name = "btnCancel";
btnCancel.Size = new Size(101, 35);
btnCancel.TabIndex = 11;
btnCancel.Text = "Cancel";
btnCancel.UseVisualStyleBackColor = true;
//
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 2;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 32.06997F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 67.93003F));
tableLayoutPanel1.Controls.Add(label1, 0, 0);
tableLayoutPanel1.Controls.Add(label3, 0, 2);
tableLayoutPanel1.Controls.Add(tbServerURL, 1, 0);
tableLayoutPanel1.Controls.Add(tbAPIKey, 1, 2);
tableLayoutPanel1.Controls.Add(label6, 0, 3);
tableLayoutPanel1.Controls.Add(tbOTP, 1, 3);
tableLayoutPanel1.Controls.Add(cbUseSSO, 0, 1);
tableLayoutPanel1.Dock = DockStyle.Top;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Margin = new Padding(5);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 5;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 20F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 20F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 20F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 20F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 20F));
tableLayoutPanel1.Size = new Size(914, 212);
tableLayoutPanel1.TabIndex = 12;
//
// label1
//
label1.AutoSize = true;
label1.Dock = DockStyle.Fill;
label1.Location = new Point(5, 0);
label1.Margin = new Padding(5, 0, 5, 0);
label1.Name = "label1";
label1.Size = new Size(283, 42);
label1.TabIndex = 2;
label1.Text = "Passwordstate URL";
label1.TextAlign = ContentAlignment.MiddleLeft;
//
// label6
//
label6.AutoSize = true;
label6.Dock = DockStyle.Fill;
label6.Location = new Point(3, 126);
label6.Name = "label6";
label6.Size = new Size(287, 42);
label6.TabIndex = 15;
label6.Text = "2FA OTP (Optional)";
//
// tbOTP
//
tbOTP.Dock = DockStyle.Fill;
tbOTP.Location = new Point(298, 131);
tbOTP.Margin = new Padding(5);
tbOTP.Name = "tbOTP";
tbOTP.Size = new Size(611, 27);
tbOTP.TabIndex = 5;
//
// cbUseSSO
//
cbUseSSO.Anchor = AnchorStyles.Left;
cbUseSSO.AutoSize = true;
cbUseSSO.Location = new Point(5, 53);
cbUseSSO.Margin = new Padding(5, 5, 5, 0);
cbUseSSO.Name = "cbUseSSO";
cbUseSSO.Size = new Size(157, 24);
cbUseSSO.TabIndex = 14;
cbUseSSO.Text = "Use SSO / WinAuth";
cbUseSSO.UseVisualStyleBackColor = true;
cbUseSSO.CheckedChanged += cbUseSSO_CheckedChanged;
//
// tableLayoutPanel2
//
tableLayoutPanel2.ColumnCount = 5;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 106F));
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 26F));
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 107F));
tableLayoutPanel2.Controls.Add(btnOK, 1, 0);
tableLayoutPanel2.Controls.Add(btnCancel, 3, 0);
tableLayoutPanel2.Dock = DockStyle.Bottom;
tableLayoutPanel2.Location = new Point(0, 300);
tableLayoutPanel2.Margin = new Padding(5);
tableLayoutPanel2.Name = "tableLayoutPanel2";
tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel2.Size = new Size(914, 67);
tableLayoutPanel2.TabIndex = 13;
//
// label4
//
label4.AutoSize = true;
label4.Dock = DockStyle.Fill;
label4.Location = new Point(0, 212);
label4.Margin = new Padding(5, 0, 5, 0);
label4.Name = "label4";
label4.Size = new Size(345, 20);
label4.TabIndex = 14;
label4.Text = "URL is the base URL, like https://pass.domain.local/";
label4.TextAlign = ContentAlignment.MiddleLeft;
//
// CPSConnectionForm
//
AcceptButton = btnOK;
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(914, 367);
Controls.Add(label4);
Controls.Add(tableLayoutPanel2);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
Margin = new Padding(5);
Name = "CPSConnectionForm";
Text = "Passwordstate API Login Data";
Activated += CPSConnectionForm_Activated;
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
tableLayoutPanel2.ResumeLayout(false);
ResumeLayout(false);
PerformLayout();
}
#endregion
private System.Windows.Forms.Label label3;
public System.Windows.Forms.TextBox tbServerURL;
//public System.Windows.Forms.TextBox tbUsername;
public System.Windows.Forms.TextBox tbAPIKey;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
public System.Windows.Forms.CheckBox cbUseSSO;
private System.Windows.Forms.Label label4;
private Label label6;
public TextBox tbOTP;
}
}

View File

@@ -0,0 +1,41 @@
namespace ExternalConnectors.CPS
{
public partial class CPSConnectionForm : Form
{
public CPSConnectionForm()
{
InitializeComponent();
}
private void CPSConnectionForm_Activated(object sender, EventArgs e)
{
SetVisibility();
if (cbUseSSO.Checked)
btnOK.Focus();
else
{
if (tbAPIKey.Text.Length == 0)
tbAPIKey.Focus();
else
tbOTP.Focus();
}
tbAPIKey.Focus();
if (!string.IsNullOrEmpty(tbAPIKey.Text) || cbUseSSO.Checked == true)
tbOTP.Focus();
}
private void cbUseSSO_CheckedChanged(object sender, EventArgs e)
{
SetVisibility();
}
private void SetVisibility()
{
bool ch = cbUseSSO.Checked;
tbAPIKey.Enabled = !ch;
//tbUsername.Enabled = !ch;
}
}
}

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@@ -117,35 +117,33 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="resultsMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="portScanToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>161, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAGxsbP9sbGz/EVuT/xRclP8XX5f/GmGZ/x1jm/8hZp7/JGig/yhro/8sbqb/MHGp/66u
rv+3t7f/AAAAAAAAAAAAAAAAAAAAABVdlf90qNH/dqrS/3mr0/97rdT/fa/V/4Gy1v+Ds9f/hrbY/zZ1
rf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZYJj/d6vT/1SVx/9Yl8j/W5rJ/1+dy/9ioM3/ZqLO/4u5
2v88ebH/IGqqAiZqoJMbYpl3AAAAAAAAAAAAAAAAHmSc/3ut1P9Zmcn/XJvK/2CezP9koc3/Z6TP/3an
yf+buMv/Tn+u/0OEv5t6qNL/MnKotwAAAAAAAAAAAAAAACNnn/9/sNX/XpzL/2KfzP9mos7/aaXP/4+u
wP/bxK//682z/9y9o/+sr7b/UYzCvSJopBgAAAAAAAAAAAAAAAAoa6P/gbTX/1TC7f9bt+P/a6fQ/2+p
0v/ezrz/9+PQ//Xcw//64cf/4cGm/WGCpCoAAAAAAAAAAAAAAAAAAAAALm+n/3y74P9L1P//X7rk/3Gr
0v91rdT/8d3J//bizv/03MP/9t3E/+3Qtv/TpH4qAAAAAAAAAAAAAAAAAAAAADNzq/+Mutr/bavU/3Os
0/93r9X/erLW/+LYy//46dr/9uPQ//jl0//qzLLr3bGNGQAAAAAAAAAAAAAAAAAAAAA5d6//j73c/3St
1P95sNX/fLPX/4C22P+bwNX/49nN//Phzv/czcH/58KhSgAAAAAAAAAAAAAAAAAAAAAAAAAAP3y0/5TB
3f96stb/frTX/4G32f+Futv/iL3c/4y/3f+oz+X/Y5XN/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWA
uP+ZxOD/gLbY/4O42v+Hu9v/ir7c/43A3v+Qwt//q9Hn/2eY0P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABLhLz/ncfh/6DJ4v+iy+T/pc3k/6jP5f+q0ef/q9Po/67U6P9rm9P/AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAUYjA/1WLw/9Zjsb/XJDI/2CTy/9jlc3/ZpfP/2ma0v9sm9P/bp3V/wAAAAAAAAAAAAAAAAAA
AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAA
AAAtLDAA+PDaAP///wD79ugA/PrzAPf39wBGRUkA7NacAM2WAAA3z6kA+Pz/AIKBgwD+//4A4sNtAHXe
xAD8+vIAjuTOANOjHgDV6/4AJZf3APn5+QDw37IAIB8jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA//+cQYABnEHgB5xB4ACcQeAAnEHgAJxB4AGcQeABnEHgAZxB4AOcQeAHnEHgB5xB4AecQeAH
nEH//5xB//+cQQ==
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAgICAgICCQ4CAgIWAgIUAgICAgICAgkJAgICFhYWAAIIDwICAgICCQwCAhYWFgYCCAgIBwIC
AgkJAgsWFhYWBQICCAgIAwIJCQIWFhYWAgICAgINCAgCAgICFhYCAgICAgICAgIRAgICAgICAgICAgIC
AgICEwICAgICEhMTExMCAgITExMCAgICAgITExMTAhMTExMCAgICAgICAgICAhMTEwICAgIICAIJCQIC
AgIKAgICAgIICAQCAgkJAgICAgICAgICCAgCAgICCQkCAgICAgICFQgBAgICAgwJAgICAgICAggIAgIC
AgICEAkCAgICAgIIAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
</value>
</data>
</root>

View File

@@ -0,0 +1,301 @@
using Microsoft.Win32;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.Security.Cryptography;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace ExternalConnectors.CPS;
public class PasswordstateInterface
{
private static class CPSConnectionData
{
public static string ssUsername = "";
public static string ssPassword = "";
public static string ssUrl = "";
public static string ssOTP = "";
public static DateTime ssOTPTimeStampExpiration;
public static bool ssSSO = false;
public static bool initdone = false;
//token
//public static string ssTokenBearer = "";
//public static DateTime ssTokenExpiresOn = DateTime.UtcNow;
//public static string ssTokenRefresh = "";
public static void Init()
{
// 2024-05-04 passwordstate currently does not support auth tokens, so we need to re-enter otp codes frequently
if (!string.IsNullOrEmpty(ssOTP) && DateTime.Now > ssOTPTimeStampExpiration)
{
ssOTP = "";
initdone = false;
}
if (initdone == true)
return;
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\mRemoteCPSInterface");
try
{
// display gui and ask for data
CPSConnectionForm f = new CPSConnectionForm();
//string? un = key.GetValue("Username") as string;
//f.tbUsername.Text = un ?? "";
f.tbAPIKey.Text = CPSConnectionData.ssPassword; // in OTP refresh cases, this value might already be filled
string? url = key.GetValue("URL") as string;
if (url == null || !url.Contains("://"))
url = "https://cred.domain.local/SecretServer";
f.tbServerURL.Text = url;
var b = key.GetValue("SSO");
if (b == null || (string)b != "True")
ssSSO = false;
else
ssSSO = true;
f.cbUseSSO.Checked = ssSSO;
// show dialog
while (true)
{
_ = f.ShowDialog();
if (f.DialogResult != DialogResult.OK)
return;
// store values to memory
//ssUsername = f.tbUsername.Text;
ssPassword = f.tbAPIKey.Text;
ssUrl = f.tbServerURL.Text;
ssSSO = f.cbUseSSO.Checked;
ssOTP = f.tbOTP.Text;
ssOTPTimeStampExpiration = DateTime.Now.AddSeconds(30);
// check connection first
try
{
if (TestCredentials() == true)
{
initdone = true;
break;
}
}
catch (Exception)
{
MessageBox.Show("Test Credentials failed - please check your credentials");
}
}
// write values to registry
//key.SetValue("Username", ssUsername);
key.SetValue("URL", ssUrl);
key.SetValue("SSO", ssSSO);
}
catch (Exception)
{
throw;
}
finally
{
key.Close();
}
}
}
private static bool TestCredentials()
{
return ConnectionTest();
}
private static bool ConnectionTest()
{
if (CPSConnectionData.ssSSO)
{
string url = $"{CPSConnectionData.ssUrl}/winapi/passwordlists/";
using HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "mRemote");
client.DefaultRequestHeaders.Add("OTP", CPSConnectionData.ssOTP);
var json = client.GetStringAsync(url).Result;
JsonNode? data = JsonSerializer.Deserialize<JsonNode>(json);
if (data == null)
return false;
return true;
}
else
{
string url = $"{CPSConnectionData.ssUrl}/api/passwordlists/";
using HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "mRemote");
client.DefaultRequestHeaders.Add("APIKey", CPSConnectionData.ssPassword);
client.DefaultRequestHeaders.Add("OTP", CPSConnectionData.ssOTP);
var json = client.GetStringAsync(url).Result;
JsonNode? data = JsonSerializer.Deserialize<JsonNode>(json);
if (data == null)
return false;
return true;
}
}
private static JsonNode? FetchDataWinAuth(int secretID)
{
string url = $"{CPSConnectionData.ssUrl}/winapi/passwords/{secretID}";
using HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "mRemote");
client.DefaultRequestHeaders.Add("OTP", CPSConnectionData.ssOTP);
var json = client.GetStringAsync(url).Result;
JsonNode? data = JsonSerializer.Deserialize<JsonNode>(json);
if (data == null)
return null;
JsonNode? element = data[0];
return element;
}
private static JsonNode? FetchDataAPIKeyAuth(int secretID)
{
string url = $"{CPSConnectionData.ssUrl}/api/passwords/{secretID}";
using HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "mRemote");
client.DefaultRequestHeaders.Add("APIKey", CPSConnectionData.ssPassword);
client.DefaultRequestHeaders.Add("OTP", CPSConnectionData.ssOTP);
var json = client.GetStringAsync(url).Result;
JsonNode? data = JsonSerializer.Deserialize<JsonNode>(json);
if (data == null)
return null;
JsonNode? element = data[0];
return element;
}
private static void FetchSecret(int secretID, out string secretUsername, out string secretPassword, out string secretDomain, out string privatekey)
{
// clear return variables
secretDomain = "";
secretUsername = "";
secretPassword = "";
privatekey = "";
string privatekeypassphrase = "";
JsonNode? element = null;
if (CPSConnectionData.ssSSO)
element = FetchDataWinAuth(secretID);
else
element = FetchDataAPIKeyAuth(secretID);
if (element == null)
return;
var dom = element["Domain"];
if (dom != null) secretDomain = dom.ToString();
var user = element["UserName"];
if (user != null) secretUsername = user.ToString();
var pw = element["Password"];
if (pw != null) secretPassword = pw.ToString();
var privkey = element["GenericField1"];
if (privkey != null) privatekey = privkey.ToString();
var phrase = element["GenericField3"];
if (phrase != null) privatekeypassphrase = phrase.ToString();
// need to decode the private key?
if (!string.IsNullOrEmpty(privatekeypassphrase))
{
try
{
var key = DecodePrivateKey(privatekey, privatekeypassphrase);
privatekey = key;
}
catch(Exception)
{
}
}
// conversion to putty format necessary?
if (!string.IsNullOrEmpty(privatekey) && !privatekey.StartsWith("PuTTY-User-Key-File-2"))
{
try
{
RSACryptoServiceProvider key = ImportPrivateKey(privatekey);
privatekey = PuttyKeyFileGenerator.ToPuttyPrivateKey(key);
}
catch (Exception)
{
}
}
}
#region PUTTY KEY HANDLING
// decode rsa private key with encryption password
private static string DecodePrivateKey(string encryptedPrivateKey, string password)
{
TextReader textReader = new StringReader(encryptedPrivateKey);
PemReader pemReader = new PemReader(textReader, new PasswordFinder(password));
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
TextWriter textWriter = new StringWriter();
var pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(keyPair.Private);
pemWriter.Writer.Flush();
return ""+textWriter.ToString();
}
private class PasswordFinder : IPasswordFinder
{
private string password;
public PasswordFinder(string password)
{
this.password = password;
}
public char[] GetPassword()
{
return password.ToCharArray();
}
}
// read private key pem string to rsacryptoserviceprovider
public static RSACryptoServiceProvider ImportPrivateKey(string pem)
{
PemReader pr = new PemReader(new StringReader(pem));
AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParams);
return rsa;
}
#endregion
// input: must be the secret id to fetch
public static void FetchSecretFromServer(string secretID, out string username, out string password, out string domain, out string privatekey)
{
// get secret id
int sid = Int32.Parse(secretID);
// init connection credentials, display popup if necessary
CPSConnectionData.Init();
// get the secret
FetchSecret(sid, out username, out password, out domain, out privatekey);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,281 @@
namespace ExternalConnectors.DSS
{
partial class SSConnectionForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SSConnectionForm));
this.tbSSURL = new System.Windows.Forms.TextBox();
this.tbUsername = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.tbPassword = new System.Windows.Forms.TextBox();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label5 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.cbUseSSO = new System.Windows.Forms.CheckBox();
this.label6 = new System.Windows.Forms.Label();
this.tbOTP = new System.Windows.Forms.TextBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.label4 = new System.Windows.Forms.Label();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// tbSSURL
//
this.tbSSURL.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbSSURL.Location = new System.Drawing.Point(298, 5);
this.tbSSURL.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.tbSSURL.Name = "tbSSURL";
this.tbSSURL.Size = new System.Drawing.Size(611, 27);
this.tbSSURL.TabIndex = 0;
//
// tbUsername
//
this.tbUsername.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbUsername.Location = new System.Drawing.Point(298, 47);
this.tbUsername.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.tbUsername.Name = "tbUsername";
this.tbUsername.Size = new System.Drawing.Size(611, 27);
this.tbUsername.TabIndex = 2;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Dock = System.Windows.Forms.DockStyle.Fill;
this.label3.Location = new System.Drawing.Point(5, 84);
this.label3.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(283, 42);
this.label3.TabIndex = 5;
this.label3.Text = "Password";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// tbPassword
//
this.tbPassword.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbPassword.Location = new System.Drawing.Point(298, 89);
this.tbPassword.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.tbPassword.Name = "tbPassword";
this.tbPassword.Size = new System.Drawing.Size(611, 27);
this.tbPassword.TabIndex = 4;
this.tbPassword.UseSystemPasswordChar = true;
//
// btnOK
//
this.btnOK.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(337, 16);
this.btnOK.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(101, 35);
this.btnOK.TabIndex = 6;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
//
// btnCancel
//
this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(474, 16);
this.btnCancel.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(101, 35);
this.btnCancel.TabIndex = 11;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 32.06997F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67.93003F));
this.tableLayoutPanel1.Controls.Add(this.label5, 1, 4);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.tbSSURL, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.cbUseSSO, 0, 4);
this.tableLayoutPanel1.Controls.Add(this.tbUsername, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.tbPassword, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.label6, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.tbOTP, 1, 3);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 5;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(914, 212);
this.tableLayoutPanel1.TabIndex = 12;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Dock = System.Windows.Forms.DockStyle.Fill;
this.label5.Location = new System.Drawing.Point(298, 168);
this.label5.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(611, 44);
this.label5.TabIndex = 15;
this.label5.Text = "For SSO to work, additional IIS configuration is required!";
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(5, 0);
this.label1.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(283, 42);
this.label1.TabIndex = 2;
this.label1.Text = "Secret Server URL";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(5, 42);
this.label2.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(283, 42);
this.label2.TabIndex = 4;
this.label2.Text = "DOMAIN\\Username";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// cbUseSSO
//
this.cbUseSSO.AutoSize = true;
this.cbUseSSO.Location = new System.Drawing.Point(5, 173);
this.cbUseSSO.Margin = new System.Windows.Forms.Padding(5, 5, 5, 0);
this.cbUseSSO.Name = "cbUseSSO";
this.cbUseSSO.Size = new System.Drawing.Size(86, 24);
this.cbUseSSO.TabIndex = 14;
this.cbUseSSO.Text = "Use SSO";
this.cbUseSSO.UseVisualStyleBackColor = true;
this.cbUseSSO.CheckedChanged += new System.EventHandler(this.cbUseSSO_CheckedChanged);
//
// label6
//
this.label6.AutoSize = true;
this.label6.Dock = System.Windows.Forms.DockStyle.Fill;
this.label6.Location = new System.Drawing.Point(3, 126);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(287, 42);
this.label6.TabIndex = 15;
this.label6.Text = "2FA OTP (Optional)";
//
// tbOTP
//
this.tbOTP.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbOTP.Location = new System.Drawing.Point(296, 130);
this.tbOTP.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.tbOTP.Name = "tbOTP";
this.tbOTP.Size = new System.Drawing.Size(615, 27);
this.tbOTP.TabIndex = 5;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 5;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 106F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 26F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 107F));
this.tableLayoutPanel2.Controls.Add(this.btnOK, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.btnCancel, 3, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 300);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(914, 67);
this.tableLayoutPanel2.TabIndex = 13;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Dock = System.Windows.Forms.DockStyle.Fill;
this.label4.Location = new System.Drawing.Point(0, 212);
this.label4.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(427, 20);
this.label4.TabIndex = 14;
this.label4.Text = "URL is the base URL, like https://cred.domain.local/SecretServer";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// SSConnectionForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(914, 367);
this.Controls.Add(this.label4);
this.Controls.Add(this.tableLayoutPanel2);
this.Controls.Add(this.tableLayoutPanel1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.Name = "SSConnectionForm";
this.Text = "Secret Server API Login Data";
this.Activated += new System.EventHandler(this.SSConnectionForm_Activated);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label3;
public System.Windows.Forms.TextBox tbSSURL;
public System.Windows.Forms.TextBox tbUsername;
public System.Windows.Forms.TextBox tbPassword;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
public System.Windows.Forms.CheckBox cbUseSSO;
private System.Windows.Forms.Label label4;
private Label label5;
private Label label6;
public TextBox tbOTP;
}
}

View File

@@ -0,0 +1,35 @@
namespace ExternalConnectors.DSS
{
public partial class SSConnectionForm : Form
{
public SSConnectionForm()
{
InitializeComponent();
}
private void SSConnectionForm_Activated(object sender, EventArgs e)
{
SetVisibility();
if (cbUseSSO.Checked)
btnOK.Focus();
else
{
if (tbPassword.Text.Length == 0)
tbPassword.Focus();
else
tbOTP.Focus();
}
}
private void cbUseSSO_CheckedChanged(object sender, EventArgs e)
{
SetVisibility();
}
private void SetVisibility()
{
bool ch = cbUseSSO.Checked;
tbPassword.Enabled = !ch;
tbUsername.Enabled = !ch;
}
}
}

View File

@@ -0,0 +1,615 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAQAQEAAAAEAIAAoQAAARgAAACAgAAABACAAKBAAAG5AAAAYGAAAAQAgACgJAACWUAAAEBAAAAEA
IAAoBAAAvlkAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f3e/f397vz9
/e79/f3u7ezr7p6Xju5XTEHuNScV7i8hCe4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isf
CO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isf
CO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isf
CO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHAjuKx8I7jYoFu5XTUHumJGO7u3r6+79/f3u/f397v39
/e79/f3e/f399P//////////u7Wy/0M1KP8jEwD/KRgA/ywdBv8tHwj/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8sHAT/KRcA/yAR
AP9DNSX/ubOt/////////////f399Pv8/e7/////m5aK/xoMAP8lFAD/LSAI/y0gCv8uIAr/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cv8uIAr/LB4J/ysfCf8uIQj/JBYA/xoLAP+elYz///////z9/O79/f3uvLWw/xsNAP8rHAX/LiAK/y0f
Cf8tHwj/LR8I/y0fCf8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCf8tHwn/LR8J/y4gCv8pGgP/GgsA/7y3sP/9/f3u6unp7kM0
I/8nFwH/LiEL/yweCP8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAr/LR8J/yIU
AP9DNSL/6+nq7pqUju4fEQD/LiAI/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8uIAf/HxAA/5qTju5YTT7uJRYA/ywgCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/Kx8I/ygXAP9YTkDuOCkV7iweBv8sHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sHQX/NykW7ioc
CO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8uIAn/Lh8I/yocCO4qHAjuLyEK/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8K/y4gCf8rHAjuKx8I7i4gCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8J/y0fCP8tHwn/LR8J/y0f
CP8tHwn/LR8J/y0fCP8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
CP8tHwj/LR8J/y0fCf8tHwj/LR8J/y0fCf8tHwn/LR8J/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8uIAj/Kx8I7isfCO4uIAn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8I/y8fCP8uHwj/LR8G/yweCP8uHgn/LR4H/yweB/8rHgf/Kx4H/yweCP8sHgj/Kx4I/yse
CP8sHgj/LB4I/yweCP8sHgn/LB4J/yoeCP8qHgj/LB4I/y4fCP8sIQj/LB8H/y0eCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysf
CO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tIAn/LiAK/y0WAf8sFgH/LRsG/ywbBv8uGwX/MR0B/y8cAv8uGwX/LRkG/ysZ
Bf8qGQX/KhkF/ygaBP8oGgX/JxoF/ycaBf8pGgX/KRkG/ykZBv8nGQT/JxkF/ygZCv8jFAb/IBUG/ywe
Cf8tHwf/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/Lh0I/y0XA/84Qyf/P31P/0aSXP9KkVv/UpJT/2OV
Sv93mUf/jJ9A/6CjPP+vpjv/rac4/6ilN/+ppDn/qaQ4/62jOP+uozj/sKI2/7KiNv+yojX/s6Az/7Wi
NP+0oDP/mIUs/1pIFv8lFQb/Kh4I/y4gCf8sHgn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR4I/ygWA/83b0X/SsOE/0zC
f/9QvHf/Ubp0/1e4b/9YtGz/WrJl/2KwZP96tWD/lL9X/7fNUf/b2E//3NhP/9nWTP/X00v/29NL/9vS
Sv/d0Ur/39FJ/9/RSP/j0Ej/5tBD/+3VRP/r0EX/jHYl/yMUBv8sHwb/LB4I/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/ysV
AP8zWTb/ScmH/0e8ef9Ltnb/TrRx/1Cyb/9VsGr/Wa1m/1mrYf9dqV3/XqRc/1yfWf9ooVL/g6tQ/7XD
Tf/R0Ur/ys1H/87LR//Oykb/0MlG/9PKRf/Uy0X/18pF/9jJQf/byEH/4MtD/+7VRv9rWxz/HxMC/y8h
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4g
Cf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/Kx8I/y0cBv8vHQj/QKFs/0fEgP9IuHX/TLZ0/0+0cP9UsW3/Vq9o/1isZP9cqWD/X6hc/2Ok
Wf9loVX/aKBT/2iZUP9um0j/obZJ/87RTP/SzUz/yspI/8zLSP/Qykj/0stH/9XJR//VyUT/2clE/9fH
RP/izkn/vao2/ywdBv8rHAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tGwX/MCoV/0azfP9Fvnv/Sbh2/0y2c/9PtG//VbFs/1av
Z/9YrGT/XKlg/2KnXP9kpVr/ZaJX/2mhU/9unkz/bZtK/2qVR/+asUj/zdJM/8nOSf/JzUv/zcxJ/8/L
R//Rykf/0cpE/9XKRP/WykX/3c5G/9DBQv86Kw//KRoH/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LiAI/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwr/LRoE/ywsGP9Dt3//R7x6/0q3
dv9OtHL/ULNu/1Wwa/9Xrmb/Watj/12pXv9hplv/ZaRY/2eiVP9qoFH/bp5M/3OcSf9ymUb/b5BC/6m5
SP/L0k7/yM5M/8vNS//LzEn/z8xJ/87LR//Rykf/08tH/9nNSP/RxkT/PS8R/ygZBv8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4g
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LB8K/y4a
A/8uLRj/RLZ9/0e8ev9LtnX/ULNy/1Gybf9VsGr/Wa5l/1mrYv9dqVz/YKZa/2WkVv9oolL/aqBQ/2+e
S/9zm0n/dJpE/3SUQ/+Dmj7/wMxM/8fPTP/IzUz/yc5L/8zNS//LzEr/z8tK/8/LSP/UzUj/0MZG/z0u
EP8oGgX/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8uIAj/Kx8I7isfCO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/ywfCv8uGgP/Li0Y/0W2fP9Iu3n/TLZ0/1Czcf9Rsm3/VbBq/1muZf9aq2L/Xqlc/2Gm
Wv9lpFb/aKJS/2ugUP9wnkv/c5tI/3WaQ/95l0H/do07/6m6Rf/F007/xM5N/8XOTP/IzUz/yM5L/8zN
S//MzEn/0c9J/83HR/89LhD/KBoG/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwr/LRsE/zAsGP9HtHr/S7p3/061cv9Qs2//U7Fr/1Wv
af9arGP/XKlh/2GnW/9lpFn/ZaNV/2igUf9unk7/cpxK/3WbRv91mEH/e5Y//3mPOP+YrEH/wtVT/7/O
Uf/CzlD/xc1Q/8TOTP/IzUz/yc5L/87QTP/HyEn/PS8P/ykZBv8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8K/y0bBP8wLBj/R7R6/0u6
d/9OtXL/ULNv/1Oxa/9Vr2n/Wqxj/1ypYf9hp1v/ZaRZ/2WjVf9ooFH/bp5O/3KcSv91m0b/dZhB/3yW
P/97kDj/j6I9/7/VV/+90VH/wNBR/8PPUf/Bz0z/xM5M/8XOS//K0Uz/xclJ/z0vD/8pGQb/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isf
CO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tGwT/MCwa/0qzef9MuXb/TrRx/1Kybv9Tr2n/V61k/12qYP9fqF3/YKZZ/2SkVv9qoVL/bKBP/26d
TP9ym0b/dJpE/3iWQf98lD7/fY43/42gPf+111v/t9RU/7nSU/+/z1L/vtBQ/8HPUP/Cz03/xtFN/8HJ
TP88MA//KhsF/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LRsE/zAsGv9Ks3n/TLl2/060cf9Ssm7/U69p/1etZP9dqmD/X6hd/2Cm
Wf9kpFb/aqFS/2ygT/9unUz/cptG/3SaRP94lkH/fJQ+/36NNv+LpkP/qNxh/6zYWv+v1Ff/ttFV/7zS
Uf/A0VL/wNFP/8TUT//Ayk3/PDAP/yobBP8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4cA/8wLBn/SrN2/024dP9Ps3D/VLFs/1eu
Z/9Zq2T/XKlf/2KnXf9jpVj/ZaNV/2qgUf9unk7/cJ1K/3KbRf92mUP/e5U+/3mUPP9/jDP/ibRM/5zi
aP+g2mD/pdhe/6zVW/+01Ff/utNU/7vSUv/D1VH/vctN/zswEf8pGgb/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8uHQL/MCwY/0qz
df9NuHP/T7Nv/1Wwa/9arWb/Wqtj/1qpX/9jplz/ZKRY/2WiVf9qoFH/b55N/3CdSf9ym0T/d5hC/3yW
Pf98kjn/g441/4nRZP+N4mv/ld5n/5rcZf+g22D/p9hd/63XWf+y1Fb/utZU/7jMTv86MBH/KBoG/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LiAI/ysf
CO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/Lh0D/zAsF/9LsnT/Trdz/1Gybv9WsGr/WK1l/1uqYv9dqV3/YqZb/2WkVv9nolT/aqBQ/2+e
TP9ynEn/c5pD/3aXQf97lT3/gokz/3uvT/986nr/g+Rw/4nibf+O32v/lN5n/5rcY/+h22D/ptdd/6/Y
Wv+xzlX/Oi8R/ygZBv8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4cBf8wLRb/TbFz/1C2cv9TsWz/V7Bo/1etZP9cqmH/Yahb/2Gl
Wv9mo1T/aKFS/2ugTv9wnUr/dJpI/3WZQ/98kz3/gYo3/3WsUP9s7ID/but8/3fneP995XT/geJy/4fh
bf+O32r/lN5m/5rbZP+j3GL/pdJd/zkvEv8pFwX/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHAX/MC0W/02xc/9QtnL/U7Fs/1ev
aP9YrWT/XKpg/1+oW/9hpVr/ZqNV/2mhUv9sn03/cJxJ/3WVRP95kT3/eJZA/2TAYf9Y8Yj/XPOI/2fs
gv9r637/cel7/3bneP995XT/g+Nw/4nibP+P32r/l+Bo/5jXYf85MBL/KhgG/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/KhsE/zAs
FP9NsXH/UbVv/1awav9arWf/Wqxi/12oXv9jo1v/Y6FU/2mcUP9tm0r/bptI/2+cSv9rp1P/YMNo/1Do
hf9G/ZX/SfaO/1PyjP9b8Ir/X+6F/2btgv9s637/cul6/3fmeP995XT/g+Nw/4vlbv+O22n/NjAU/yca
BP8uHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4g
Cf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/yobBP8wLBT/TbJy/1G1b/9WsGr/Wq1n/1uoX/9dp13/YKlf/2CvXv9gt2X/XcBq/1XQ
dv9P4YP/SPCO/0T3lP9J85L/R/SR/0n1kf9L9ZD/TfSP/1Tzi/9b8Yj/Yu+E/2ftgP9r637/cel6/3jn
dv+A6XT/geBs/zgxFf8pGwX/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y8fCf8rHAL/LisU/02ucv9Vs23/VLBp/1ipYP9XuGr/TtOA/0fg
if9H5Ir/RuqO/0Xukf9G7pL/Ru2Q/0Ttjf9J7I7/R+6N/0nwj/9L8ZD/S/KR/0nzkP9I85D/TPSN/1X0
if9d8If/Ye6D/2fsf/9s6nz/cux7/3Xic/81MRb/KxkE/ywfCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sHwn/Lh0D/y4gCP9PnWP/Vbdx/1eq
ZP9TwXP/RuSM/0fmjv9F4ov/Q+SJ/0bliv9F5or/RuaM/0bojP9G6or/R+uM/0jtjP9J7o3/SO+O/0nw
j/9I8o//RvKP/0f0j/9K947/S/WN/1Tyif9b8YT/YO6D/2n2hP9kz27/KyEM/y4dBv8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LB8J/y4e
B/8sFgH/PGU2/1i9dP9Utm3/RN6J/0Leif9J3on/SN+K/0Xgif9H4ov/R+KL/0fjjP9I5Yz/R+eL/0jo
jP9I6o3/SeuO/0jsjf9J7Y7/SO+O/0jwjv9J8Y//S/OQ/0r0kf9M9ZD/T/SO/1Pziv9h/5X/SIJE/yoP
Af8sHwf/LR8K/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8uIAn/Kx8I7isfCO4uIAj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwn/LBwH/ywdCf9IfEf/Tsx8/0Ddif9F14X/RduH/0bdiP9E3on/Rd+K/0fl
jf9I6JD/SOqQ/0jsj/9J7ZD/SO6R/0nvkv9H8JD/SPKR/0n0kf9K84//SPCP/0fxkP9J8pH/SvWS/0r3
lP9M/pn/RKxh/y0YBv8sHAf/LR8J/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LiAI/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sGgX/KhUE/0GsbP9E4Y7/QteG/0TZ
h/9F2oj/RdyI/0Teiv9Ez3//RMp7/0XNe/9Eznr/RM97/0TQff9F0H3/Q9J7/0PTfP9E0n3/SNyC/0zq
iv9M6Yr/TeqL/0zsiv9P8Iz/S7Vp/ywWB/8sGgT/LiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sHwn/Lh8G/ywR
BP87m2b/ReCR/0PUiP9E1oj/RtiJ/0bZh/9D5o//Nlk1/ywZB/8vJg3/LyYM/y8mDP8vJQ3/LyUN/ywm
DP8sJgz/KhgH/z9sO/9c2Hr/Vslx/1fJcf9YyXL/XdF3/0yRUv8pEwT/LyEJ/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isf
CO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LB8J/y0eBv8sEwX/PJ1n/0Tej/9D0of/Q9SG/0TWiP9F2Ib/QuWO/zVPLv8sDgD/MBsI/y8b
B/8vGwb/LhsE/y4bBP8sGgb/KxoG/ywKAP87Zjr/U+CD/1HQe/9R0Hv/UtB7/1Pcg/9En17/KxMD/y4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4fCf8sHwj/LhUD/0CbZP9F2o7/RM+H/0TQhv9F0of/Q9WG/0bk
kf8yVzL/KxEA/y4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tDgD/O3ZF/0zslP9I2ob/SdqG/0na
hv9L5o7/QaNm/ywVAv8uHgf/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sHwj/LiAJ/ywUAf89jlf/Q9qO/0LN
hf9Dz4T/RNCG/0LRg/9H4I//O4dQ/yoOAP8tIAj/LR8J/y0fCf8tHwn/LR8J/y0fCP8tHgj/LBMC/z+n
ZP9H6pH/RN+K/0Tfiv9E34r/RuyT/z2bXv8uEwH/LR8H/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LB8J/y0f
Cf8rDwD/NXNF/0PZjP9DyYX/RcuF/0XNhv9EzYT/RdSJ/0TFfv8uKRH/LBYC/ywfCP8tHwn/LR8J/ywf
Cf8sHwj/KBAA/zZAIf9H34n/R+GL/0Xdif9F3Yn/Rd2I/0nvlv86gU3/Kg4A/y0eCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysf
CO4rHwjuLiAI/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCf8rHwj/LRMB/zZRLv9H0ov/QsmE/0LKhP9Ey4X/Q8uE/0XMhP9H3I7/Pppj/ysa
Bv8sEQD/Lh0I/y0fB/8tGgX/Kg4A/y0lD/9AuXH/R+qQ/0Lci/9D34n/Rd6J/0PdiP9C65H/M1wx/y8U
Av8uIAf/LR8J/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y4gCP8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LB4I/y4bBv8uJQ//QLV4/0LNh/9Bx4P/Q8iE/0PJ
g/9Ey4P/RMuG/0Xajv9EpGn/MEoo/ysfC/8uFgr/LiUN/zNULf8+vHf/SOWQ/0TYh/9F3Ij/Rt6J/0fe
i/9E44z/Rc9//y0qDv8vGQX/LSAH/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCf8tHwn/KxEA/zt2
Sv9F047/QcOC/0PFg/9Cx4L/RMmD/0PKgv9EzIP/RdaL/0fUif8/t3P/Pqpv/0C+dv9H3I//Rt6O/0HW
hv9E1oj/RdiI/0Tah/9G3In/R+6U/zuET/8sDwD/LR8J/y0fCf8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LiAI/ysfCO4rHwjuLiAJ/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0aBP8wKhH/QLV4/0HKhv9BxIP/QsWB/0LHgv9CyIL/QsmD/0XKg/9FzoT/Q9KH/0LY
iP9G14r/Q9CH/0XRhf9F0oX/RNSI/0LXiP9C14X/ReGM/0XOgv8uKxT/KxgF/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4g
Cf8rHwjuKx8I7i4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwf/LRYA/zRTL/9Dy4v/QcWG/0HCgf9CxIL/QsSC/0PE
g/9CxoP/Q8iC/0TKhP9Dy4T/RsyF/0PNhf9Cz4b/RNCH/0XSiP9H0oj/QtiJ/0jikP8yWjX/KxAA/ywg
B/8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isfCO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LSAH/y8gBv8vEgD/OWlC/0PL
if8+xYP/P8KA/0DCgf9Bw4L/QsaC/0LHgf9DyIL/QsqC/0PLg/9CzIT/Q82F/0TOhf9Fz4X/RdaK/0fg
lf85dkf/KhEA/yseB/8uHwj/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysfCO4rHwjuLiAJ/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8vHwn/Kh4I/y8WAP82Yzj/P7+C/0LLiP9CwoL/QMGC/0HFhP9BxIH/Q8WD/0PGhP9Ex4X/RMmE/0bK
hf9DzYT/QtyN/0nTiP86aj3/LRIA/y4eCP8sIAr/Lh8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuKx8I7i4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8rIAj/KhQA/zU/IP9Bl2X/RseI/0LLiv8/x4b/QMaD/0DF
g/9CxoT/Q8mG/0LOh/9G1o3/RtSK/0WjaP8yQiD/LBEA/y8eCP8sIAn/LR8I/y0fCP8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8uIAn/Kx8I7isfCO4uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sHwn/LR4I/y4gCv8sFQD/KxoE/zRJ
Kf9Cg1P/Q6tv/0O6ev9EwoL/QsOC/0a+fv9FsHD/QoZS/zZJJ/8sGgT/KxMB/y4fCf8wIAj/Lh8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LiAJ/ysfCO4rHwjuLiAI/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8J/y0f
Cf8tHwj/LR8J/y0dCP8rEwL/LBQA/zEjCf8yLxP/Njce/zQ3H/8yMBT/MiMJ/y8UAP8rEgD/LB0H/y4g
Cf8tHwn/LB8J/y0fCf8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y4gCP8rHwjuKx8I7i4gCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAI/yseB/8rHQj/LBoF/ysXAv8sGAP/KxsF/ygb
Bv8wHgf/LR8J/y4fCv8uIAr/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/Kx8I7isf
CO4uIAj/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8I/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LB8J/y0fCf8tHwj/LR8I/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LiAJ/ysfCO4rHwjuLyEJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHwjuLh8J7i8hCP8tIAj/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwj/LyEJ7jgqFu4sHgX/LR8H/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/LB4G/zUn
FO5YTT7uJhUA/y4gCv8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LSAL/yoZAP9XTD7um5SO7iMRAP8vIAn/LR8J/y0fCf8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwn/LR8I/ywfBv8iEgD/npeO7urq6e5ENSX/JBQA/y0hCP8tIAf/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/Kx0H/y4gCv8lFQD/QzYm/+vr6e79/f3uvLax/xoM
AP8pGwL/LiEI/y0fCf8tHwj/LR8J/y0fCf8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0f
CP8tHwj/LR8I/y0fCP8tHwj/LR8I/y0fCP8tHwj/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHQX/Gw0A/723
tP/9/f3u+vv87v////+ak4n/GQsA/yQUAP8uHwn/LR8J/y0fCP8uIAn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0eCf8sHgj/LB8J/y4g
B/8mFwD/Gw0A/5qViv//////+/z87v39/fT//////////7q1sP9DNCb/IxEA/ycWAP8rHgX/LiAH/y8h
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/zAh
Cv8uHwj/LB0G/yQWAP8fEQD/QzQm/7q0r/////////////39/fT9/f3e/f397vz9/e79/f3u6+rp7puU
ju5YTj/uOCkW7i4fCu4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isf
CO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isf
CO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isfCO4rHwjuKx8I7isf
CO4rHwjuKx8I7isfCO4rHwjuKyAI7jcpFu5YTj7umpOO7uvr6u79/f3u/Pz97v39/e79/f3eKAAAACAA
AABAAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP39/dzt6+vtdGte7TQmFu0rHQjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7SsdBu00Jhbtc2le7e3r6e39/f3c6ubl81ZKOP8dDgD/LB4G/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LyAK/ywdBf8dDgD/VUk4/+rn5vN0a13tHg4A/y4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8dDQD/dWtd7TQm
Eu0rHQb/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/ywd
Bf80JhLtKx0G7S8gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LiAJ/ysdBu0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwj/LBcC/ysT
AP8pFAH/JhMC/yISA/8hEQP/IBID/yASA/8gEgT/HxIE/x8RBP8jFgb/LB4I/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR4I/ywY
BP81QiP/Olw1/0RbLP9WXSb/bGMj/3RnIP9vZCD/bmIg/3FiIP9yYh7/dWMf/1ZFFv8lFwb/LB4I/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8rFgL/N2c//0vDgf9SwHr/W7pv/2a2Zf9+t13/p8RT/9bYT//g20z/3tZL/+LWSv/p10f/69RF/39r
Iv8iFQT/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LBwG/y4lD/9Esnb/Sr55/1Kybv9XrWf/Xahe/1+iWP9imlH/faJJ/8DHSv/Pz0r/z8tI/9PK
Rf/f0Uf/z75A/zQmC/8pGwj/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8sGgX/Ly0W/0S0ef9NuHb/U7Fs/1itZP9ep1z/ZqNW/2yfTv9slUb/hqFE/8fP
TP/Lzkv/zcxJ/9TOSf/Ow0T/PS4P/ygaB/8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/ywbBf8wLBX/RrF1/0+4dP9UsGv/Wqxj/2CmWv9molT/b55N/3WZ
RP93kTz/r8BI/8fST//Hzkz/zdFM/8bERv87LQ7/KRoH/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/y0f
CO0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LBsF/zAsFf9Jr3T/ULdz/1WvaP9dqmD/YqVZ/2mg
Uv9wnEv/dplD/3mOOf+iuEn/wNZV/8HPT//H0k7/v8ZJ/zstDv8pGgf/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8sGwX/MCwV/0mvc/9RtnH/Vq1m/16p
Xv9jpFf/bKBQ/3CcSP93mEH/fIw2/5bCU/+q3F//tdNW/8HWUv+7yEv/Oi4O/ykaB/8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/ywbBf8wLRT/S65w/1O1
bv9ZrGT/YKdc/2ajVv9sn0//cpxG/3uPOf+AmT7/hd5t/5Hhav+e22L/rdtc/6/KUf85LQ//KRoH/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LBsG/zAs
E/9NrW7/VrRt/1qrYf9ipFj/aZ5R/3GXR/94kj//dKFI/2bddv9t74H/eeZ2/4Xib/+U4mr/mdFe/zgt
EP8qGQb/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8sGwb/LiwU/06ubf9ZsGn/Xahf/2CqXv9jr13/YLtj/1jRdP9K8o7/SvqT/1byi/9j7oP/b+p8/3zq
d/+D22r/NjAS/yoaBv8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/ywcBv8vJw7/Ualp/1e3bP9N0n//R+GJ/0bojf9E75H/RPKR/0jwj/9J8ZD/R/OR/0z1
jv9W8on/ZfWF/2vhd/8yKg//KxoG/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8I/ysXAv9CaTr/TNSC/0PijP9F34n/RueP/0n0lv9J95b/SvqY/0n9
mP9J+5b/R/OR/0j4lP9Q/pb/RI5N/ysTAv8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/LR8I7S0f
CO0uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LRwG/ywbB/9Aunf/RN6M/0bijf9At3D/OXJC/zp7
Rf86fEb/NnhD/z+SUv9S3H//U+KD/068bf8sGgj/LRsH/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4g
Cf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHQf/LRwI/0CydP9E2oz/RuWR/zqO
Vv8qAAD/LA8A/ywOAP8pAgD/Mzkb/0/bhP9Q24T/SLRs/y0dCP8tHQf/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0eCP8tGQT/PqZp/0TW
jP9F1or/Qbh0/ywbBv8sFQL/LBwG/ykGAP86eEX/Ru6U/0Xpkf9At3H/LRkE/y0eB/8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/ysR
AP86fk//RNeP/0TJg/9G14z/PI1Y/y4pEP8tHQn/M1ky/0TWhv9F4Yz/R/CV/zqOU/8sEAD/LR8I/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LBcD/zE5HP9CxoX/QsqF/0PIgv9F1ov/QsR+/0C7d/9F2oz/RNmK/0Xdiv9G34z/MT0d/ywW
A/8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LBQA/zdmPf9C0Iz/QcmG/0LFgv9DzIX/RNGI/0POhv9F14v/R+WU/zdv
Qv8qEQD/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHgj/LBUB/zVeNv9Ct3v/Q8+M/0LRjP9E1I7/RteO/0TE
fv84ZDr/LRQB/y0eCP8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHgj/LBMA/y8qEf84Xjb/O3lM/zt6
Tf86YDf/MCoR/ysSAP8tHgj/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LiAJ/y0f
CO0tHwjtLiAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LBoF/ysT
AP8sEQD/KxEA/ysSAP8sGgX/LSAJ/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8uIAn/LR8I7SweBu0vIAn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y4gCf8rHQbtNCYT7SwdBv8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LB4G/zQmEu11a17tHQ4A/y4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0gCf8dDgD/dmxe7ern5vNVSTf/Hg4A/ywdBv8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8rHQX/Hg4A/1ZKOP/q5+fz/f393Ozr6e10aV7tNSYU7Swe
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLB4I7TQmFO1zaV7t7evp7f39/dwoAAAAGAAAADAA
AAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f393JSPhO00JhbtKx0G7S0fCO0tHwjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0rHQbtMyUW7ZSO
g+39/f3ckouC8yESAP8qHAT/LyAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8vIAn/KhwE/yERAP+Si4LzMyUR7SocBP8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/yocBP8zJRLtKx0F7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0eCP8sGgX/KxoG/yka
B/8oGgf/KBoH/ygaB/8nGgf/KBoH/yweCP8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8rHQXtLR8I7S4g
Cf8tHwn/LR8J/y0fCf8tHwn/LRwH/y0aBf8wLRP/Ni8Q/0ExDv9FMw3/PjAN/z4vDv8/MA3/PS4N/ycZ
B/8qHAj/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHQf/LB8K/z6E
VP9NsnL/Wapi/3GoVv+bskv/x8VG/87FRP/PwkL/2cZB/6GMLf8tHwj/Kx0I/y0fCf8tHwn/LR8J/y4g
Cf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8sFgH/MkYn/0nIhP9Rt3L/WK9m/16nXf9jnlP/iKlK/8nO
S//T0Er/2M9H/+jYSv9XSRf/IxUF/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0f
Cf8sFQH/M0os/0vBfv9Tsm3/Wqxi/2OlWP9sn07/bJJD/5uuRP/M0k3/y81L/9nWTP9cTxv/IhQF/y0f
Cf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8rFQH/NEkq/02+e/9UsGr/Xalg/2Wj
Vv9unkz/dJRB/4ufPv+/01P/xM9O/8/XT/9YThr/IxQE/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4g
Cf8tHwn/LR8J/y0fCf8rFgH/NUkp/068ef9Xrmf/X6dc/2iiVP9wnUn/eI86/4ilRP+k3mL/tNVX/8ba
U/9WTxv/JBQE/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8rFgH/Nkgo/1K7
dv9ZrWT/YqRZ/2ycTf93kj//epU+/3bVa/+D53T/lN5n/63hYv9RTx//JRMD/y0fCf8tHwn/LR8J/y4g
Cf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8qFQL/NUop/1a6c/9cqWH/Yatd/2SwW/9gv2b/UeeE/1L4
kP9k7oL/dOh5/4vvdf9JViX/JxIC/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0f
Cf8rFwP/NT4e/1a5cP9N0H3/R+GI/0fwkv9F+5n/SPuY/0j7lv9J95H/VfaM/2f6iP88SyH/KhQC/y0f
Cf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHgj/LBUC/z6ETv9E6JL/Rd+L/0LG
ef9DwHP/QsR1/0LHdP9L4oX/T/aS/0KaV/8rFgT/LR4I/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4g
Cf8tHwn/LR8J/y0fCf8tHwn/Kw8A/zVgOv9F4pL/Rd+N/zJGJP8tEAD/LRoF/ywaBv9Lum3/VOeL/zle
M/8qDwD/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/KxMA/zVX
Mf9F2I7/RtuO/zl3R/8qBQD/KQQA/zJDIv9F4Iv/RvCW/zVfNf8rEQD/LR8J/y0fCf8tHwn/LR8J/y4g
Cf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/LBoF/zAtE/9Cv3//RNCJ/0TNhf86g1D/N29C/0LF
fP9G6JH/RNeF/y8wFP8sGQT/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/ywTAP82Yzv/QtKN/0PPif9F2I3/Rd2Q/0XekP9H5ZP/N2w//ysRAP8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0eCP8sFQH/NVs1/0Cu
dP9CxoT/RMqG/0O3dv83YTj/LBQB/y0eCP8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtLR8I7S4g
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHgj/LBMA/y4iC/8zPB7/Mj0e/y8hCv8rEgD/LR4I/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4gCf8tHwjtKx0F7S4gCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/ywcB/8sFwP/LBcD/ywcB/8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y4g
Cf8rHQbtNCUS7SocBP8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0f
Cf8tHwn/LR8J/y0fCf8tHwn/LR8J/y0fCf8tHwn/LR8J/yocBP80JhLtkouD8yERAP8qHAT/LyAJ/y4g
Cf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4gCf8uIAn/LiAJ/y4g
Cf8vIAn/KhwE/yERAP+VjITz/f393JSOhO00JhbtKx0G7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0rHQbtMyUW7ZSOg+39/f3cKAAAABAA
AAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL65stw/MR/tKBkF7S0fCO0tHwjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0oGQXtPzEf7b65stw8MR3zJxgA/y8gCf8uIAn/LiAJ/y4g
Cf8uHwn/Lh8J/y4fCf8uHwn/LiAJ/y4gCf8uIAn/LyAJ/ycYAP88MR3zKBoE7S8gCf8tHwn/LSAJ/ywa
Bf8rFAH/LBcD/ysXBP8kFQT/IxUF/yATBP8oGgf/LiAJ/y0fCf8vIQn/KBkE7S0fCO0uIAn/LR8J/ywa
Bf8wMxj/QYNR/1OFSP94iTr/npg0/6aYM/+hji7/RDQP/ycaB/8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0f
Cf8rEQD/OW9F/1LNhP9dtGj/aahY/5u2TP/Z2U3/7+ZP/4V2KP8eEAT/LR8J/y4gCf8tHwjtLR8I7S4g
Cf8tHwn/KxIA/ztvRf9Tv3f/Xqhd/2ufT/91kj7/tMNK/9fgU/+AeSr/IBAD/y0fCf8uIAn/LR8I7S0f
CO0uIAn/LR8J/ysTAP89bUL/Vrxz/2OjWP9ylkX/fZQ7/5XTX/+952D/d3ot/yEQA/8tHwn/LiAJ/y0f
CO0tHwjtLiAJ/y0fCf8qEwD/P29C/1y6bv9iqlv/Z7Fa/1zad/9l8oX/ifZ6/2OGPP8lDgH/LR8J/y4g
Cf8tHwjtLR8I7S4gCf8tHwn/KhQB/zxULf9P0oD/SOSL/0b1lf9F/Jn/SPaS/1j7kP9DbTb/KRAB/y0f
Cf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0cB/8uIwz/QcuC/0HCef8zRSL/MD0e/0SmYP9M0n7/LSMN/ywc
Bv8tHwn/LiAJ/y0fCO0tHwjtLiAJ/y0fCf8tHQj/LRsG/0Cxc/9Ez4b/MDca/yweCf9Cxnr/Qsd6/y0b
Bv8tHQj/LR8J/y4gCf8tHwjtLR8I7S4gCf8tHwn/LR8J/ywUAf81XTf/RNiR/0TTiv9E1In/R+2Y/zZn
Ov8rEgH/LR8J/y0fCf8uIAn/LR8I7S0fCO0uIAn/LR8J/y0fCf8tHgj/LBcC/zRWMv8+nWb/P6Jo/zZb
NP8sFgL/LR4I/y0fCf8tHwn/LiAJ/y0fCO0oGgTtLyEJ/y0fCf8tHwn/LR8J/y0fCP8sFAH/LBYC/ywW
Av8rEwD/LR4I/y0fCf8tHwn/LR8J/y8hCf8oGQTtPTEd8ycYAP8vIAn/LiAJ/y4gCf8uIAn/LiAJ/y4f
CP8uHwn/LiAJ/y4gCf8uIAn/LiAJ/y8gCf8nGAD/PTEd87u5stw/MR/tKBkF7S0fCO0tHwjtLR8I7S0f
CO0tHwjtLR8I7S0fCO0tHwjtLR8I7S0fCO0oGQXtPzEf7b65stwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</value>
</data>
</root>

View File

@@ -0,0 +1,383 @@
//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
#pragma warning disable 8073 // Disable "CS8073 The result of the expression is always 'false' since a value of type 'T' is never equal to 'null' of type 'T?'"
#pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-compliant"
namespace SecretServerAuthentication.DSS
{
using System = global::System;
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class OAuth2ServiceClient
{
private string _baseUrl = "";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public OAuth2ServiceClient(string baseUrl, System.Net.Http.HttpClient httpClient)
{
BaseUrl = baseUrl;
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
{
var settings = new Newtonsoft.Json.JsonSerializerSettings();
UpdateJsonSerializerSettings(settings);
return settings;
}
public string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <summary>Retrieve or Refresh Access Token</summary>
/// <param name="grant_type">Authentication grant type. Use 'password' when authenticating, and 'refresh_token' when refreshing a token.</param>
/// <param name="username">Secret Server authentication username. Required when authenticating.</param>
/// <param name="password">Secret Server authentication password. Required when authenticating.</param>
/// <param name="refresh_token">The refresh token. Required when refreshing a token.</param>
/// <returns>Successful retrieval of an access token</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<TokenResponse> AuthorizeAsync(Grant_type grant_type, string username, string password, string refresh_token, string OTP)
{
return AuthorizeAsync(grant_type, username, password, refresh_token, System.Threading.CancellationToken.None, OTP);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Retrieve or Refresh Access Token</summary>
/// <param name="grant_type">Authentication grant type. Use 'password' when authenticating, and 'refresh_token' when refreshing a token.</param>
/// <param name="username">Secret Server authentication username. Required when authenticating.</param>
/// <param name="password">Secret Server authentication password. Required when authenticating.</param>
/// <param name="refresh_token">The refresh token. Required when refreshing a token.</param>
/// <returns>Successful retrieval of an access token</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<TokenResponse> AuthorizeAsync(Grant_type grant_type, string username, string password, string refresh_token, System.Threading.CancellationToken cancellationToken, string OTP)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/oauth2/token");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
var keyValues_ = new System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>>();
if (grant_type == null)
throw new System.ArgumentNullException("grant_type");
else
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("grant_type", ConvertToString(grant_type, System.Globalization.CultureInfo.InvariantCulture)));
if (username != null)
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("username", ConvertToString(username, System.Globalization.CultureInfo.InvariantCulture)));
if (password != null)
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("password", ConvertToString(password, System.Globalization.CultureInfo.InvariantCulture)));
if (refresh_token != null)
keyValues_.Add(new System.Collections.Generic.KeyValuePair<string, string>("refresh_token", ConvertToString(refresh_token, System.Globalization.CultureInfo.InvariantCulture)));
if (OTP != null)
request_.Headers.Add("OTP", ConvertToString(OTP, System.Globalization.CultureInfo.InvariantCulture));
request_.Content = new System.Net.Http.FormUrlEncodedContent(keyValues_);
request_.Method = new System.Net.Http.HttpMethod("POST");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<TokenResponse>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 400)
{
var objectResponse_ = await ReadObjectResponseAsync<TokenErrorResponse>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<TokenErrorResponse>("An error occurred", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
this.Object = responseObject;
this.Text = responseText;
}
public T Object { get; }
public string Text { get; }
}
public bool ReadResponseAsString { get; set; }
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Threading.CancellationToken cancellationToken)
{
if (response == null || response.Content == null)
{
return new ObjectResponseResult<T>(default(T), string.Empty);
}
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
}
}
else
{
try
{
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var streamReader = new System.IO.StreamReader(responseStream))
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
{
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
var typedBody = serializer.Deserialize<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, string.Empty);
}
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
}
}
}
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return "";
}
if (value is System.Enum)
{
var name = System.Enum.GetName(value.GetType(), value);
if (name != null)
{
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
if (field != null)
{
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
as System.Runtime.Serialization.EnumMemberAttribute;
if (attribute != null)
{
return attribute.Value != null ? attribute.Value : name;
}
}
var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
return converted == null ? string.Empty : converted;
}
}
else if (value is bool)
{
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return System.Convert.ToBase64String((byte[])value);
}
else if (value.GetType().IsArray)
{
var array = System.Linq.Enumerable.OfType<object>((System.Array)value);
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
}
var result = System.Convert.ToString(value, cultureInfo);
return result == null ? "" : result;
}
}
/// <summary>API access token response</summary>
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class TokenResponse
{
/// <summary>Authentication token</summary>
[Newtonsoft.Json.JsonProperty("access_token", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Access_token { get; set; }
/// <summary>Authentication token type</summary>
[Newtonsoft.Json.JsonProperty("token_type", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public TokenResponseToken_type Token_type { get; set; }
private string _Expires_in;
/// <summary>Authentication token expiration time, in seconds</summary>
[Newtonsoft.Json.JsonProperty("expires_in", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
// public string Expires_in { get; set; }
public string Expires_in
{
get { return _Expires_in; }
set
{
_Expires_in = value;
Expires_on = DateTime.UtcNow.AddSeconds(Double.Parse(value) - 60);
}
}
/// <summary>Authentication token expiration time in UTC</summary>
public DateTime Expires_on { get; set; }
/// <summary>Refresh token. This is only provided when the server is set to allow refresh tokens for web services and when the session timeout duration is not set to Unlimited.</summary>
[Newtonsoft.Json.JsonProperty("refresh_token", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Refresh_token { get; set; }
}
/// <summary>API access token error response</summary>
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class TokenErrorResponse
{
/// <summary>Authentication token</summary>
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Message { get; set; }
}
/// <summary>Authentication grant type. Use 'password' when authenticating, and 'refresh_token' when refreshing a token.</summary>
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
public enum Grant_type
{
[System.Runtime.Serialization.EnumMember(Value = @"password")]
Password = 0,
[System.Runtime.Serialization.EnumMember(Value = @"refresh_token")]
Refresh_token = 1,
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v11.0.0.0)")]
public enum TokenResponseToken_type
{
[System.Runtime.Serialization.EnumMember(Value = @"bearer")]
Bearer = 0,
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class ApiException : System.Exception
{
public int StatusCode { get; private set; }
public string Response { get; private set; }
public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Exception innerException)
: base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException)
{
StatusCode = statusCode;
Response = response;
Headers = headers;
}
public override string ToString()
{
return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.14.8.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))")]
public partial class ApiException<TResult> : ApiException
{
public TResult Result { get; private set; }
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, TResult result, System.Exception innerException)
: base(message, statusCode, response, headers, innerException)
{
Result = result;
}
}
}
#pragma warning restore 1591
#pragma warning restore 1573
#pragma warning restore 472
#pragma warning restore 114
#pragma warning restore 108
#pragma warning restore 3016

View File

@@ -0,0 +1,341 @@
using Microsoft.Win32;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using SecretServerAuthentication.DSS;
using SecretServerRestClient.DSS;
using System.Security.Cryptography;
namespace ExternalConnectors.DSS;
public class SecretServerInterface
{
private static class SSConnectionData
{
public static string ssUsername = "";
public static string ssPassword = "";
public static string ssUrl = "";
public static string ssOTP = "";
public static bool ssSSO = false;
public static bool initdone = false;
//token
public static string ssTokenBearer = "";
public static DateTime ssTokenExpiresOn = DateTime.UtcNow;
public static string ssTokenRefresh = "";
public static void Init()
{
if (initdone == true)
return;
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\mRemoteSSInterface");
try
{
// display gui and ask for data
SSConnectionForm f = new();
string? un = key.GetValue("Username") as string;
f.tbUsername.Text = un ?? "";
f.tbPassword.Text = SSConnectionData.ssPassword; // in OTP refresh cases, this value might already be filled
string? url = key.GetValue("URL") as string;
if (url == null || !url.Contains("://"))
url = "https://cred.domain.local/SecretServer";
f.tbSSURL.Text = url;
var b = key.GetValue("SSO");
if (b == null || (string)b != "True")
ssSSO = false;
else
ssSSO = true;
f.cbUseSSO.Checked = ssSSO;
// show dialog
while (true)
{
_ = f.ShowDialog();
if (f.DialogResult != DialogResult.OK)
return;
// store values to memory
ssUsername = f.tbUsername.Text;
ssPassword = f.tbPassword.Text;
ssUrl = f.tbSSURL.Text;
ssSSO = f.cbUseSSO.Checked;
ssOTP = f.tbOTP.Text;
// check connection first
try
{
if (TestCredentials() == true)
{
initdone = true;
break;
}
}
catch (Exception)
{
MessageBox.Show("Test Credentials failed - please check your credentials");
}
}
// write values to registry
key.SetValue("Username", ssUsername);
key.SetValue("URL", ssUrl);
key.SetValue("SSO", ssSSO);
}
catch (Exception)
{
throw;
}
finally
{
key.Close();
}
}
}
private static bool TestCredentials()
{
if (SSConnectionData.ssSSO)
{
// checking creds doesn't really make sense here, as we can't modify them anyway if something is wrong
return true;
}
else
{
if (!String.IsNullOrEmpty(GetToken()))
{
return true;
}
else
{
return false;
}
}
}
private static SecretsServiceClient ConstructSecretsServiceClient()
{
string baseURL = SSConnectionData.ssUrl;
if (SSConnectionData.ssSSO)
{
// REQUIRES IIS CONFIG! https://docs.thycotic.com/ss/11.0.0/api-scripting/webservice-iwa-powershell
var handler = new HttpClientHandler() { UseDefaultCredentials = true };
var httpClient = new HttpClient(handler);
{
// Call REST API:
return new SecretsServiceClient($"{baseURL}/winauthwebservices/api", httpClient);
}
}
else
{
var httpClient = new HttpClient();
{
var token = GetToken();
// Set credentials (token):
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
// Call REST API:
return new SecretsServiceClient($"{baseURL}/api", httpClient);
}
}
}
private static void FetchSecret(int secretID, out string secretUsername, out string secretPassword, out string secretDomain, out string privatekey)
{
var client = ConstructSecretsServiceClient();
SecretModel secret = client.GetSecretAsync(false, true, secretID, null).Result;
// clear return variables
secretDomain = "";
secretUsername = "";
secretPassword = "";
privatekey = "";
string privatekeypassphrase = "";
// parse data and extract what we need
foreach (var item in secret.Items)
{
if (item.FieldName.ToLower().Equals("domain"))
secretDomain = item.ItemValue;
else if (item.FieldName.ToLower().Equals("username"))
secretUsername = item.ItemValue;
else if (item.FieldName.ToLower().Equals("password"))
secretPassword = item.ItemValue;
else if (item.FieldName.ToLower().Equals("private key"))
{
client.ReadResponseNoJSONConvert = true;
privatekey = client.GetFieldAsync(false, false, secretID, "private-key").Result;
client.ReadResponseNoJSONConvert = false;
}
else if (item.FieldName.ToLower().Equals("private key passphrase"))
privatekeypassphrase = item.ItemValue;
}
// need to decode the private key?
if (!string.IsNullOrEmpty(privatekeypassphrase))
{
try
{
var key = DecodePrivateKey(privatekey, privatekeypassphrase);
privatekey = key;
}
catch(Exception)
{
}
}
// conversion to putty format necessary?
if (!string.IsNullOrEmpty(privatekey) && !privatekey.StartsWith("PuTTY-User-Key-File-2"))
{
try
{
RSACryptoServiceProvider key = ImportPrivateKey(privatekey);
privatekey = PuttyKeyFileGenerator.ToPuttyPrivateKey(key);
}
catch (Exception)
{
}
}
}
#region PUTTY KEY HANDLING
// decode rsa private key with encryption password
private static string DecodePrivateKey(string encryptedPrivateKey, string password)
{
TextReader textReader = new StringReader(encryptedPrivateKey);
PemReader pemReader = new(textReader, new PasswordFinder(password));
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
TextWriter textWriter = new StringWriter();
var pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(keyPair.Private);
pemWriter.Writer.Flush();
return ""+textWriter.ToString();
}
private class PasswordFinder : IPasswordFinder
{
private string password;
public PasswordFinder(string password)
{
this.password = password;
}
public char[] GetPassword()
{
return password.ToCharArray();
}
}
// read private key pem string to rsacryptoserviceprovider
public static RSACryptoServiceProvider ImportPrivateKey(string pem)
{
PemReader pr = new(new StringReader(pem));
AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
RSACryptoServiceProvider rsa = new();
rsa.ImportParameters(rsaParams);
return rsa;
}
#endregion
#region TOKEN
private static string GetToken()
{
// if there is no token, fetch a fresh one
if (String.IsNullOrEmpty(SSConnectionData.ssTokenBearer))
{
return GetTokenFresh();
}
// if there is a token, check if it is valid
if (SSConnectionData.ssTokenExpiresOn >= DateTime.UtcNow)
{
return SSConnectionData.ssTokenBearer;
}
else
{
// try using refresh token
using (var httpClient = new HttpClient())
{
var tokenClient = new OAuth2ServiceClient(SSConnectionData.ssUrl, httpClient);
TokenResponse token = new();
try
{
token = tokenClient.AuthorizeAsync(Grant_type.Refresh_token, null, null, SSConnectionData.ssTokenRefresh, null).Result;
var tokenResult = token.Access_token;
SSConnectionData.ssTokenBearer = tokenResult;
SSConnectionData.ssTokenRefresh = token.Refresh_token;
SSConnectionData.ssTokenExpiresOn = token.Expires_on;
return tokenResult;
}
catch (Exception)
{
// refresh token failed. clean memory and start fresh
SSConnectionData.ssTokenBearer = "";
SSConnectionData.ssTokenRefresh = "";
SSConnectionData.ssTokenExpiresOn = DateTime.Now;
// if OTP is required we need to ask user for a new OTP
if (!String.IsNullOrEmpty(SSConnectionData.ssOTP))
{
SSConnectionData.initdone = false;
// the call below executes a connection test, which fetches a valid token
SSConnectionData.Init();
// we now have a fresh token in memory. return it to caller
return SSConnectionData.ssTokenBearer;
}
else
{
// no user interaction required. get a fresh token and return it to caller
return GetTokenFresh();
}
}
}
}
}
static string GetTokenFresh()
{
using (var httpClient = new HttpClient())
{
// Authenticate:
var tokenClient = new OAuth2ServiceClient(SSConnectionData.ssUrl, httpClient);
// call below will throw an exception if the creds are invalid
var token = tokenClient.AuthorizeAsync(Grant_type.Password, SSConnectionData.ssUsername, SSConnectionData.ssPassword, null, SSConnectionData.ssOTP).Result;
// here we can be sure the creds are ok - return success state
var tokenResult = token.Access_token;
SSConnectionData.ssTokenBearer = tokenResult;
SSConnectionData.ssTokenRefresh = token.Refresh_token;
SSConnectionData.ssTokenExpiresOn = token.Expires_on;
return tokenResult;
}
}
#endregion
// input must be the secret id to fetch
public static void FetchSecretFromServer(string input, out string username, out string password, out string domain, out string privatekey)
{
// get secret id
int secretID = Int32.Parse(input);
// init connection credentials, display popup if necessary
SSConnectionData.Init();
// get the secret
FetchSecret(secretID, out username, out password, out domain, out privatekey);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<UseWindowsForms>True</UseWindowsForms>
<Platforms>x64</Platforms>
<Configurations>Debug;Release;Debug Portable;Release Portable;Deploy to github</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Portable|x64'">
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.7.401.4" />
<PackageReference Include="AWSSDK.EC2" Version="3.7.428" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<Compile Update="AWS\AWSConnectionForm.cs" />
<Compile Update="CPS\CPSConnectionForm.cs" />
<Compile Update="DSS\SSConnectionForm.cs" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,111 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace ExternalConnectors;
public class PuttyKeyFileGenerator
{
private const int prefixSize = 4;
private const int paddedPrefixSize = prefixSize + 1;
private const int lineLength = 64;
private const string keyType = "ssh-rsa";
private const string encryptionType = "none";
public static string ToPuttyPrivateKey(RSACryptoServiceProvider cryptoServiceProvider, string Comment = "imported-openssh-key")
{
var publicParameters = cryptoServiceProvider.ExportParameters(false);
byte[] publicBuffer = new byte[3 + keyType.Length + GetPrefixSize(publicParameters.Exponent) + publicParameters.Exponent!.Length + GetPrefixSize(publicParameters.Modulus) + publicParameters.Modulus!.Length + 1];
using (var bw = new BinaryWriter(new MemoryStream(publicBuffer)))
{
bw.Write(new byte[] { 0x00, 0x00, 0x00 });
bw.Write(Encoding.ASCII.GetBytes(keyType));
PutPrefixed(bw, publicParameters.Exponent, CheckIsNeddPadding(publicParameters.Exponent));
PutPrefixed(bw, publicParameters.Modulus, CheckIsNeddPadding(publicParameters.Modulus));
}
var publicBlob = System.Convert.ToBase64String(publicBuffer);
var privateParameters = cryptoServiceProvider.ExportParameters(true);
byte[] privateBuffer = new byte[paddedPrefixSize + privateParameters.D!.Length + paddedPrefixSize + privateParameters.P!.Length + paddedPrefixSize + privateParameters.Q!.Length + paddedPrefixSize + privateParameters.InverseQ!.Length];
using (var bw = new BinaryWriter(new MemoryStream(privateBuffer)))
{
PutPrefixed(bw, privateParameters.D, true);
PutPrefixed(bw, privateParameters.P, true);
PutPrefixed(bw, privateParameters.Q, true);
PutPrefixed(bw, privateParameters.InverseQ, true);
}
var privateBlob = System.Convert.ToBase64String(privateBuffer);
HMACSHA1 hmacSha1 = new(SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes("putty-private-key-file-mac-key")));
byte[] bytesToHash = new byte[prefixSize + keyType.Length + prefixSize + encryptionType.Length + prefixSize + Comment.Length + prefixSize + publicBuffer.Length + prefixSize + privateBuffer.Length];
using (var bw = new BinaryWriter(new MemoryStream(bytesToHash)))
{
PutPrefixed(bw, Encoding.ASCII.GetBytes(keyType));
PutPrefixed(bw, Encoding.ASCII.GetBytes(encryptionType));
PutPrefixed(bw, Encoding.ASCII.GetBytes(Comment));
PutPrefixed(bw, publicBuffer);
PutPrefixed(bw, privateBuffer);
}
var hash = string.Join("", hmacSha1.ComputeHash(bytesToHash).Select(x => $"{x:x2}"));
var sb = new StringBuilder();
sb.AppendLine("PuTTY-User-Key-File-2: " + keyType);
sb.AppendLine("Encryption: " + encryptionType);
sb.AppendLine("Comment: " + Comment);
var publicLines = SpliceText(publicBlob, lineLength);
sb.AppendLine("Public-Lines: " + publicLines.Length);
foreach (var line in publicLines)
{
sb.AppendLine(line);
}
var privateLines = SpliceText(privateBlob, lineLength);
sb.AppendLine("Private-Lines: " + privateLines.Length);
foreach (var line in privateLines)
{
sb.AppendLine(line);
}
sb.AppendLine("Private-MAC: " + hash);
return sb.ToString();
}
private static void PutPrefixed(BinaryWriter bw, byte[] bytes, bool addLeadingNull = false)
{
bw.Write(BitConverter.GetBytes(bytes.Length + (addLeadingNull ? 1 : 0)).Reverse().ToArray());
if (addLeadingNull)
bw.Write(new byte[] { 0x00 });
bw.Write(bytes);
}
private static string[] SpliceText(string text, int lineLength)
{
return Regex.Matches(text, ".{1," + lineLength + "}").Cast<Match>().Select(m => m.Value).ToArray();
}
private static int GetPrefixSize(byte[]? bytes)
{
if (bytes is null)
return 0;
return CheckIsNeddPadding(bytes) ? paddedPrefixSize : prefixSize;
}
private static bool CheckIsNeddPadding(byte[] bytes)
{
if (bytes is null || bytes.Length == 0)
return false;
// 128 == 10000000
// This means that the number of bits can be divided by 8.
// According to the algorithm in putty, you need to add a padding.
return bytes[0] >= 128;
}
}

63
Jenkinsfile vendored
View File

@@ -1,63 +0,0 @@
#!groovy
node('windows') {
def jobDir = pwd()
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\""
def msBuild = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\msbuild.exe"
def nunitConsolePath = "${jobDir}\\packages\\NUnit.ConsoleRunner.3.7.0\\tools\\nunit3-console.exe"
def openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe"
def reportGeneratorPath = "${jobDir}\\packages\\ReportGenerator.3.0.2\\tools\\ReportGenerator.exe"
def testResultFilePrefix = "TestResult"
def testResultFileNormal = "${testResultFilePrefix}_UnitTests_normal.xml"
def testResultFilePortable = "${testResultFilePrefix}_UnitTests_portable.xml"
def testResultFileAcceptance = "${testResultFilePrefix}_AcceptanceTests.xml"
def coverageReport = "code_coverage_report.xml"
def codeCoverageHtml = "CodeCoverageReport.html"
stage ('Checkout Branch') {
checkout scm
bat "del /Q \"${jobDir}\\${testResultFilePrefix}*.xml\""
}
stage ('Restore NuGet Packages') {
def nugetPath = "C:\\nuget.exe"
bat "${nugetPath} restore ${solutionFilePath}"
}
stage ('Build mRemoteNG (Normal)') {
bat "\"${msBuild}\" /nologo /p:Platform=x86 \"${jobDir}\\mRemoteV1.sln\""
}
stage ('Build mRemoteNG (Portable)') {
bat "\"${msBuild}\" /nologo /p:Configuration=\"Debug Portable\";Platform=x86 \"${jobDir}\\mRemoteV1.sln\""
}
stage ('Run Unit Tests (Normal, w/coverage)') {
try {
bat "\"${openCoverPath}\" -register:user -target:\"${nunitConsolePath}\" -targetargs:\"\"${jobDir}\\mRemoteNGTests\\bin\\debug\\mRemoteNGTests.dll\" --result=${testResultFileNormal} --x86\" -output:\"${coverageReport}\""
}
catch (ex) {
nunit testResultsPattern: "${testResultFilePrefix}*.xml"
throw ex
}
}
stage ('Run Unit Tests (Portable)') {
try {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\debug portable\\mRemoteNGTests.dll\" --result=${testResultFilePortable} --x86"
}
catch (ex) {
nunit testResultsPattern: "${testResultFilePrefix}*.xml"
throw ex
}
}
stage ('Run Acceptance Tests') {
try {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNG.Specs\\bin\\debug\\mRemoteNG.Specs.dll\" --result=${testResultFileAcceptance} --x86"
}
catch (ex) {
nunit testResultsPattern: "${testResultFilePrefix}*.xml"
throw ex
}
}
}

View File

@@ -1,71 +0,0 @@
node('windows') {
def jobDir = pwd()
def solutionFilePath = "\"${jobDir}\\mRemoteV1.sln\""
def msBuild = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\msbuild.exe"
def nunitConsolePath = "${jobDir}\\packages\\NUnit.ConsoleRunner.3.10.0\\tools\\nunit3-console.exe"
def openCoverPath = "${jobDir}\\packages\\OpenCover.4.6.519\\tools\\OpenCover.Console.exe"
def testResultFilePrefix = "TestResult"
def testResultFileNormal = "${testResultFilePrefix}_UnitTests_normal.xml"
def testResultFilePortable = "${testResultFilePrefix}_UnitTests_portable.xml"
def coverageReport = "code_coverage_report.xml"
stage ('Clean output dir') {
bat script: "rmdir /S /Q \"${jobDir}\\Release\" 2>nul", returnStatus: true
}
stage ('Checkout Branch') {
checkout([
$class: 'GitSCM',
branches: [[name: '*/${TargetBranch}']],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [[
credentialsId: '9c3fbff4-5b90-402f-a298-00e607fcec87',
url: 'https://github.com/mRemoteNG/mRemoteNG.git'
]]
])
}
stage ('Restore NuGet Packages') {
def nugetPath = "C:\\nuget.exe"
bat "${nugetPath} restore ${solutionFilePath}"
}
withCredentials([file(credentialsId: '9b674d57-6792-48e3-984a-4d1bab2abb64', variable: 'CODE_SIGNING_CERT')]) {
withCredentials([usernamePassword(credentialsId: '05b7449b-05c0-490f-8661-236242526e62', passwordVariable: 'MRNG_CERT_PASSWORD', usernameVariable: 'NO_USERNAME')]) {
stage ('Build mRemoteNG (Normal - MSI)') {
bat "\"${msBuild}\" /nologo /t:Clean,Build /p:Configuration=\"Release Installer\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
archiveArtifacts artifacts: "Release\\*.msi", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
}
stage ('Build mRemoteNG (Portable)') {
bat "\"${msBuild}\" /nologo /t:Clean,Build /p:Configuration=\"Release Portable\" /p:Platform=x86 /p:CertPath=\"${env.CODE_SIGNING_CERT}\" /p:CertPassword=${env.MRNG_CERT_PASSWORD} \"${jobDir}\\mRemoteV1.sln\""
archiveArtifacts artifacts: "Release\\*.zip", caseSensitive: false, onlyIfSuccessful: true, fingerprint: true
}
}
}
stage ('Run Unit Tests (Normal - MSI)') {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release\\mRemoteNGTests.dll\" --result=${testResultFileNormal} --x86"
}
stage ('Run Unit Tests (Portable)') {
bat "\"${nunitConsolePath}\" \"${jobDir}\\mRemoteNGTests\\bin\\release portable\\mRemoteNGTests.dll\" --result=${testResultFilePortable} --x86"
}
stage ('Generate UpdateCheck Files') {
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\create_upg_chk_files.ps1\" -TagName \"${env.TagName}\" -UpdateChannel \"${env.UpdateChannel}\""
archiveArtifacts artifacts: "Release\\*.txt", caseSensitive: false, onlyIfSuccessful: true
}
stage ('Publish to GitHub') {
withCredentials([string(credentialsId: '5443a369-dbe8-42d3-b4e8-04d0b4e9039a', variable: 'GH_AUTH_TOKEN')]) {
def releaseFolder = "${jobDir}\\Release"
// because batch files suck at handling newline characters, we have to convert to base64 in groovy and back to text in powershell
def base64Description = env.ReleaseDescription.bytes.encodeBase64().toString()
bat "powershell -ExecutionPolicy Bypass -File \"${jobDir}\\Tools\\publish_to_github.ps1\" -Owner \"mRemoteNG\" -Repository \"mRemoteNG\" -ReleaseTitle \"${env.ReleaseTitle}\" -TagName \"${env.TagName}\" -TargetCommitish \"${env.TargetBranch}\" -Description \"${base64Description}\" -IsDraft ${env.IsDraft} -IsPrerelease ${env.IsPreRelease} -ReleaseFolderPath \"${releaseFolder}\" -AuthToken \"${env.GH_AUTH_TOKEN}\" -DescriptionIsBase64Encoded"
}
}
}

View File

@@ -1,8 +1,8 @@
**NOTICE: This project is currently stalled and we are transitioning to a new maintainer. Please see [this stickied issue](https://github.com/mRemoteNG/mRemoteNG/issues/1949) for more details. Development help would be greatly appreciated.**
**NOTICE: This project currently transited to a new maintainer. Development help would be greatly appreciated.**
<br/><br/>
<p align="center">
<img width="500" src="https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/develop/Tools/img/logo.png">
<img width="450" src="https://github.com/mRemoteNG/mRemoteNG/blob/mRemoteNGProjectFiles/Header_dark.png">
</p>
<p align="center">
@@ -20,10 +20,12 @@
<a href="https://twitter.com/mremoteng">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/mremoteng?color=%231DA1F2&label=Twitter&logo=Twitter&style=flat-square">
</a>
<a href="https://gitter.im/mRemoteNG/PublicChat">
<img alt="Gitter" src="https://img.shields.io/gitter/room/mRemoteNG/PublicChat?label=Join%20the%20Chat&logo=Gitter&style=flat-square">
<a href="https://app.element.io/#/room/#mremoteng:matrix.org">
<img alt="Element" src="https://img.shields.io/matrix/mremoteng:matrix.org?label=Join%20to%20chat%20about%20mRemoteNG&logo=element&style=social&link=https://app.element.io/#/room/#mremoteng:matrix.org">
</a>
<a href="https://www.paypal.me/DavidSparer">
</p>
<p align="center">
<a href="https://www.paypal.com/paypalme/mremoteng">
<img alt="PayPal" src="https://img.shields.io/badge/%24-PayPal-blue.svg?label=Donate&logo=PayPal&style=flat-square">
</a>
<a href="bitcoin:16fUnHUM3k7W9Fvpc6dug7TAdfeGEcLbSg">
@@ -41,15 +43,18 @@
<a href='https://mremoteng.readthedocs.io/en/latest/?badge=latest'>
<img src='https://readthedocs.org/projects/mremoteng/badge/?version=latest' alt='Documentation Status' />
</a>
<a href="https://gurubase.io/g/mremoteng">
<img alt="Gurubase" src="https://img.shields.io/badge/Gurubase-Ask%20mRemoteNG%20Guru-006BFF?style=flat-square">
</a>
</p>
---
| Update Channel | Build Status | Downloads |
| 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.76.20/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.20) |
| Prerelease | [![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.77.1/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.1) |
| Nightly build | [![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.77.2/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.2) |
| Stable | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf?svg=true) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.76.20/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.76.20) |
| Preview | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf/branch/preview?svg=true) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.77.1/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.77.1) |
| Nightly | ![Build status](https://ci.appveyor.com/api/projects/status/rqwxjxldail7btcf/branch/develop?svg=true) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/2023.03.03-v1.77.3-nb/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/2023.03.03-v1.77.3-nb) |
## Features
@@ -70,26 +75,14 @@ For a detailed feature list and general usage support, refer to the [Documentati
### Supported Operating Systems
- [Windows 11](https://en.wikipedia.org/wiki/Windows_11)
- [Windows 10](https://en.wikipedia.org/wiki/Windows_10)
- [Windows 8.1](https://en.wikipedia.org/wiki/Windows_8.1)
- [Windows Server 2022](https://en.wikipedia.org/wiki/Windows_Server_2022)
- [Windows Server 2019](https://en.wikipedia.org/wiki/Windows_Server_2019)
- [Windows Server 2016](https://en.wikipedia.org/wiki/Windows_Server_2016)
- [Windows Server 2012 R2](https://en.wikipedia.org/wiki/Windows_Server_2012_R2)
### Packaging
Downloads are provided in three different packages.
#### Binary package
The binary package of mRemoteNG is a compiled version of mRemoteNG which comes in an MSI installer.
This is the most common way to install mRemoteNG and get up and running.
#### Portable package
The portable package contains a modified version of the executable which stores and loads all your settings from files in the application's directory.
This package can be used to run mRemoteNG from a USB stick and preserve your configuration wherever you go.
#### Source package
This contains the source code from which mRemoteNG is build.
@@ -97,15 +90,15 @@ You will need to compile it yourself using Visual Studio.
### Minimum Requirements
* [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)
* [Microsoft .NET Framework 4.0](https://www.microsoft.com/en-us/download/details.aspx?id=17851)
* [Microsoft Visual C++ Redistributable for Visual Studio 2015 - 2022](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)
* [Microsoft .NET 6.0 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/6.0)
* Microsoft Terminal Service Client 6.0 or later
* Needed if you use RDP. mstscax.dll and/or msrdp.ocx be registered.
* [Citrix ICA Client](https://www.citrix.com/downloads/citrix-receiver.html)
* Needed if you use ICA. wfica.ocx must be registered
### Download
> :star: Starting Windows 11 you can use winget to install mRemoteNG. Just run `winget install -e --id mRemoteNG.mRemoteNG`
mRemoteNG is available as a redistributable MSI package or as a portable ZIP package and can be downloaded from the following locations:
* [GitHub](https://github.com/mRemoteNG/mRemoteNG/releases)
* [Project Website](https://mremoteng.org/download)
@@ -114,56 +107,36 @@ mRemoteNG is available as a redistributable MSI package or as a portable ZIP pac
The MSI package of mRemoteNG can be installed using the command line:
`msiexec /i C:\Path\To\mRemoteNG-Installer.exe [INSTALLDIR=value] [IGNOREPREREQUISITES=value]`
`msiexec /i [/qn] C:\Path\To\mRemoteNG-Installer.exe [INSTALLDIR=value] [IGNOREPREREQUISITES=value] [/lv* <log path>]`
| Property | Value | Description |
| Argument/Property | Value | Description |
|-|-|-|
| INSTALLDIR | `folder path` | This allows you to set the installation directory from the command line. For paths that contain spaces, enclose the path in double quotes (""). This overrides any value found in the registry. |
| /qn | `Silent Installation` | Will run the installer silently in the background. |
| /lv* | `Silent Installation` | Will write a logfile to the specified location. (For paths that contain spaces, enclose the path in double quotes) |
| INSTALLDIR | `folder path` | Allows you to set the installation directory from the command line. (For paths that contain spaces, enclose the path in double quotes) |
| IGNOREPREREQUISITES | `0` or `1` | When set to `1`, the installer will not be halted if any prerequisite check is not met. You must still run the installer as administrator. |
#### Examples
**Install to a custom folder**
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi INSTALLDIR="D:\Work Apps\mRemoteNG"`
**Ignore prerequisites during a normal install**
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi IGNOREPREREQUISITES=1`
**Ignore prerequisites during a silent install**
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi /qn IGNOREPREREQUISITES=1`
### Troubleshooting installation
Turn on verbose logging by using the `/lv* <log path>` argument at the command line.
`msiexec /i C:\Path\To\mRemoteNG-Installer.msi /l*v C:\mremoteng_install.log`
## Uninstall
### Standard Uninstall
mRemoteNG basic binary package can be uninstalled with Windows Control Panel. If for some reason it does not work please
follow information provided below for Manual Uninstall.
### Manual Uninstall
## Manual Uninstall
_If you are using the Portable version, simply deleting the folder that contains mRemoteNG should be sufficient. These uninstall instructions are only necessary for the normal binary .MSI installed version of mRemoteNG_
* Delete the folder where mRemoteNG was installed. By default, this is:
`%PROGRAMFILES%\mRemoteNG`
`%PROGRAMFILES%\mRemoteNG` (for versions before 1.77 on a x64 Windows its `%programfiles(x86)%\mRemoteNG`)
* Delete the mRemoteNG install entry from one of the following locations. Search for "mRemoteNG" in the DisplayName field:
* x86: ``HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\``
* x64: ``HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\``
* Delete the mRemoteNG install entry from the following location. You may search for "mRemoteNG" in the DisplayName field:
* x86 Windows or mRemoteNG starting with v1.77: `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\`
* x64 Windows and mRemoteNG before 1.77: `HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\`
* Remove the following registry key: `HKLM\SOFTWARE\mRemoteNG` (on x64 Windows with mRemoteNG before 1.77 it's `HKLM\SOFTWARE\WOW6432Node\mRemoteNG`)
* (Optional) If you would also like to delete user data remove `%LOCALAPPDATA%\mRemoteNG`
* (Optional) If you would also like to remove the connection configuration, delete `%APPDATA%\mRemoteNG`
* (Optional) If no other software uses it, the "Microsoft Windows Desktop Runtime" may be uninstalled too.
## Featured Projects
* [PSmRemoteNG](https://github.com/realslacker/PSmRemoteNG) A module to create mRemoteNG connection files from PowerShell.
* [mRemoteNGOpenVPN](https://github.com/T3los/mRemoteNGOpenVPN) A script that can be embedded as an external tool to control OpenVPN.
## Contribute
@@ -177,5 +150,5 @@ Check out the [Wiki page](https://github.com/mRemoteNG/mRemoteNG/wiki) on how to
</br>
<p align="center">
<img alt="Developed with ReSharper" src="https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/develop/Tools/img/icon_ReSharper.png">
<img alt="Developed with ReSharper" src="https://github.com/mRemoteNG/mRemoteNG/blob/mRemoteNGProjectFiles/icon_ReSharper.png">
</p>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,31 +0,0 @@
7-Zip Extra
~~~~~~~~~~~
License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Copyright (C) 1999-2019 Igor Pavlov.
7-Zip Extra files are under the GNU LGPL license.
Notes:
You can use 7-Zip Extra on any computer, including a computer in a commercial
organization. You don't need to register or pay for 7-Zip.
GNU LGPL information
--------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You can receive a copy of the GNU Lesser General Public License from
http://www.gnu.org/

View File

@@ -1,111 +0,0 @@
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.
19.00 2019-02-21
-------------------------
- Encryption strength for 7z archives was increased:
the size of random initialization vector was increased from 64-bit to 128-bit,
and the pseudo-random number generator was improved.
- Some bugs were fixed.
18.06 2018-12-30
-------------------------
- The speed for LZMA/LZMA2 compressing was increased by 3-10%,
and there are minor changes in compression ratio.
- Some bugs were fixed.
18.05 2018-04-30
-------------------------
- The speed for LZMA/LZMA2 compressing was increased
by 8% for fastest/fast compression levels and
by 3% for normal/maximum compression levels.
18.03 beta 2018-03-04
-------------------------
- The speed for single-thread LZMA/LZMA2 decoding
was increased by 30% in x64 version and by 3% in x86 version.
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
if there are multiple independent data chunks in LZMA2 stream.
9.35 beta 2014-12-07
------------------------------
- SFX modules were moved to LZMA SDK package.
9.34 alpha 2014-06-22
------------------------------
- Minimum supported system now is Windows 2000 for EXE and DLL files.
- all EXE and DLL files use msvcrt.dll.
- 7zr.exe now support AES encryption.
9.18 2010-11-02
------------------------------
- New small SFX module for installers.
9.17 2010-10-04
------------------------------
- New 7-Zip plugin for FAR Manager x64.
9.10 2009-12-30
------------------------------
- 7-Zip for installers now supports LZMA2.
9.09 2009-12-12
------------------------------
- LZMA2 compression method support.
- Some bugs were fixed.
4.65 2009-02-03
------------------------------
- Some bugs were fixed.
4.38 beta 2006-04-13
------------------------------
- SFX for installers now supports new properties in config file:
Progress, Directory, ExecuteFile, ExecuteParameters.
4.34 beta 2006-02-27
------------------------------
- ISetProperties::SetProperties:
it's possible to specify desirable number of CPU threads:
PROPVARIANT: name=L"mt", vt = VT_UI4, ulVal = NumberOfThreads
If "mt" is not defined, 7za.dll will check number of processors in system to set
number of desirable threads.
Now 7za.dll can use:
2 threads for LZMA compressing
N threads for BZip2 compressing
4 threads for BZip2 decompressing
Other codecs use only one thread.
Note: 7za.dll can use additional "small" threads with low CPU load.
- It's possible to call ISetProperties::SetProperties to specify "mt" property for decoder.
4.33 beta 2006-02-05
------------------------------
- Compressing speed and Memory requirements were increased.
Default dictionary size was increased: Fastest: 64 KB, Fast: 1 MB,
Normal: 4 MB, Max: 16 MB, Ultra: 64 MB.
- 7z/LZMA now can use only these match finders: HC4, BT2, BT3, BT4
4.27 2005-09-21
------------------------------
- Some GUIDs/interfaces were changed.
IStream.h:
ISequentialInStream::Read now works as old ReadPart
ISequentialOutStream::Write now works as old WritePart

View File

@@ -1,124 +0,0 @@
7-Zip Extra 19.00
-----------------
7-Zip Extra is package of extra modules of 7-Zip.
7-Zip Copyright (C) 1999-2019 Igor Pavlov.
7-Zip is free software. Read License.txt for more information about license.
Source code of binaries can be found at:
http://www.7-zip.org/
This package contains the following files:
7za.exe - standalone console version of 7-Zip with reduced formats support.
7za.dll - library for working with 7z archives
7zxa.dll - library for extracting from 7z archives
License.txt - license information
readme.txt - this file
Far\ - plugin for Far Manager
x64\ - binaries for x64
All 32-bit binaries can work in:
Windows 2000 / 2003 / 2008 / XP / Vista / 7 / 8 / 10
and in any Windows x64 version with WoW64 support.
All x64 binaries can work in any Windows x64 version.
All binaries use msvcrt.dll.
7za.exe
-------
7za.exe - is a standalone console version of 7-Zip with reduced formats support.
Extra: 7za.exe : support for only some formats of 7-Zip.
7-Zip: 7z.exe with 7z.dll : support for all formats of 7-Zip.
7za.exe and 7z.exe from 7-Zip have same command line interface.
7za.exe doesn't use external DLL files.
You can read Help File (7-zip.chm) from 7-Zip package for description
of all commands and switches for 7za.exe and 7z.exe.
7za.exe features:
- High compression ratio in 7z format
- Supported formats:
- Packing / unpacking: 7z, xz, ZIP, GZIP, BZIP2 and TAR
- Unpacking only: Z, lzma, CAB.
- Highest compression ratio for ZIP and GZIP formats.
- Fast compression and decompression
- Strong AES-256 encryption in 7z and ZIP formats.
Note: LZMA SDK contains 7zr.exe - more reduced version of 7za.exe.
But you can use 7zr.exe as "public domain" code.
DLL files
---------
7za.dll and 7zxa.dll are reduced versions of 7z.dll from 7-Zip.
7za.dll and 7zxa.dll support only 7z format.
Note: 7z.dll is main DLL file that works with all archive types in 7-Zip.
7za.dll and 7zxa.dll support the following decoding methods:
- LZMA, LZMA2, PPMD, BCJ, BCJ2, COPY, 7zAES, BZip2, Deflate.
7za.dll also supports 7z encoding with the following encoding methods:
- LZMA, LZMA2, PPMD, BCJ, BCJ2, COPY, 7zAES.
7za.dll and 7zxa.dll work via COM interfaces.
But these DLLs don't use standard COM interfaces for objects creating.
Look also example code that calls DLL functions (in source code of 7-Zip):
7zip\UI\Client7z
Another example of binary that uses these interface is 7-Zip itself.
The following binaries from 7-Zip use 7z.dll:
- 7z.exe (console version)
- 7zG.exe (GUI version)
- 7zFM.exe (7-Zip File Manager)
Note: The source code of LZMA SDK also contains the code for similar DLLs
(DLLs without BZip2, Deflate support). And these files from LZMA SDK can be
used as "public domain" code. If you use LZMA SDK files, you don't need to
follow GNU LGPL rules, if you want to change the code.
License FAQ
-----------
Can I use the EXE or DLL files from 7-Zip in a commercial application?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, but you are required to specify in documentation for your application:
(1) that you used parts of the 7-Zip program,
(2) that 7-Zip is licensed under the GNU LGPL license and
(3) you must give a link to www.7-zip.org, where the source code can be found.
Can I use the source code of 7-Zip in a commercial application?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since 7-Zip is licensed under the GNU LGPL you must follow the rules of that license.
In brief, it means that any LGPL'ed code must remain licensed under the LGPL.
For instance, you can change the code from 7-Zip or write a wrapper for some
code from 7-Zip and compile it into a DLL; but, the source code of that DLL
(including your modifications / additions / wrapper) must be licensed under
the LGPL or GPL.
Any other code in your application can be licensed as you wish. This scheme allows
users and developers to change LGPL'ed code and recompile that DLL. That is the
idea of free software. Read more here: http://www.gnu.org/.
Note: You can look also LZMA SDK, which is available under a more liberal license.
---
End of document

View File

@@ -0,0 +1,38 @@
U2FsdGVkX1/uEeToOEIrunpoPNl7NUYNQfI+ixMzGgKX0DlHZxa/PonAVd9NoAE+
dqWegkN8fa/M2HcW8moN5sN0yS88amG8cfwRZNRSgRB4IxDdYPjM/iX7y8FjUh9R
OZnGhq1rAkqcf7ASAdZfQDSFOAEDPQgByN4IB2j/G3ueqV3jf5sWWiM0ielcorWX
jXuEL7uIk9diI3Qh3BVqmrotzErzqTTLB4DWoL1aWqRRYH+exKahfcMT3C9r+tul
ETH6o1im3kdYzFgHl58FmihbHa+h1+c+DWVGGXRxJPw1DZfg8/+ldIy8J75aWimz
2MX+PiBVQj+wYlSSkQLj2EdbpSERlinE1O55ldwpbnMPAlYCgFRdO3/hiB6LiLLt
n9s8f32HLNG20Mk1oxXdN9VPOw+RwQpUf6Zfcyps6e/9EFKBLnwq4cYwM/dHRuez
w48EJX5wKzpukHn2UFg5aCRGYU/4NyUn+AlIjjCMBWY1R0uBhC340cl6YqoPFN12
clzbS6JdQS+ktusCeaKcsj2iknVqQrGY81LKrTaQZdfehGwAn9pMWE3iWRX80yzO
s08lpmHfPK4uhtlyIbdReLn4n7hvB8KRVa7Foms+4wpEwKrL8KF/8CYc89Tm3PSD
LCrLr7rzCHh51ncJXHAwZqY2ZRLnQBVwhIRsFYyZ595b89tuDY00sYpWnTKzWubK
UD993CmYKg1cA+mj6NR6iSmecawsUz68nI/nmHM2APE5cCCHSK3lz40e9Z9Hmy5Y
kVS6c86a+gwNyn4F9t3iISdj2vIOwGMVWQLeY+nwpiKnnOuI0XPtIMjNbhoaDToT
kph2ZVjqbpmYHgTSX71v8Y16Stl+p/dZn0dE2d4JhxOJxDN//H6y7mOwg8DYX9GP
rFBMIEWyEQyEFYTmWgztQ5KU89w0lV1qiWpaiWR/IDkGbUzHR8ELp4NHYPbZnuYa
FFXooJGPsQ02ioXPm18Lkhloo63lANgyBE0jc1x9hPrI0oVn1wTkKdeW13IbHzrn
VsGXeZz06bB46QChXUPmQ49sNkAXcMDnfNFM9ayUa8eVmNx9fWabtBy8qs7rpdv0
1y/2ud4Da9t7SAUvxwI65+b2Ytk05pLFLmQYb01g4BpBDxbJW3yw3CqKgMnLoZ3t
s2kiUpn7FEQU8jbpbFV+UB4DdJgm8S7o1gbTEWYTscZ7l+oLCmQgMYoi/EJDDIa2
cCSdGy4p7kLlLUoO438Mz36+FDf6qX2B86ezVdNnXQb3UPljjDxiOFM6NkI3HTpl
RqxjBg8JdrwoQ1UMha6ucDKhPXq1xkg0dpO9QyjxywssG3krgQ5Py64s5Xu7IgQm
AzmwGTZ6gFZlDTr9SpJkiucF9vexCo6JHHkF8OjhS49FanqB8otJvg5JclVugP51
LcqqvuMkAsFago261SNcOhgtR6nV5B9QgHyr66c6YnTlwt07T1Qq3S1lw2x0Eccs
PKbJDVU5rAHiM71QYmwsuoC8qkYPTtVPIoUTs+5u5aLywVoLejr1dE5twNXy5PYY
fDwubg0YG3kchvv85N3epZ1h50ADq3W3msU9bWDKWwdwIbpGq+dwjkLssBQmjVtI
R8rGbt1DgL7xtRNF9ESnWVkfHJvJu/5oD6wGAU/oIfBxVON0VYb1evc8wRdQTbDH
Dnt+aKwcSPYdyGVRKfRtBGvEZ8rB5hzCXQnS795L0imdfXjBSJn7Pnl9VwpcB3Pr
aZ6s0GcB8kYDEXzjv+o7JF6k5i2I+sVGwvFVGIoVd/Igq2ysrk/GfWVov0SUu78A
JeHYdtRuKwXOdZw2cjZQ72bvFaHOuoXrQnyKyZDWRyu0NB5HLW75v/YEbr4msIm9
E+3HFwRvKSTfUx/M4NgVKrgsHDeBRD4tLNx/SerQvqaplunM7OfAtULucveUhwSo
vT6uNK3URe1qDgX554cz8c6+KrkglTLFMuKfNWj3q/uSM0BxTTD9QgorNdlMmErH
TfV/ZpZACpuMFRbC5xQRkCG1x4U12pdPbtIkGtVBJROEXhP1aw3BDWwrIN7zSgfj
8I4OF4fbj/rSuvI4klzi1zlUMQQnenlRURE+7DKRxtWipJhW9vtDI0LXN7gGfmbR
73uR3YUny6zUJ0svqaWj4Eo6t3g99nmk4D2hm/622dRksv2HqEQiq29jJxlcbdZB
PU96wOp54s/BzgodyI5dh+xL06Obr9AltLV9vw3iK0VBZqquj9FuhvWC1tYlZQJF
AOgVDOGUZzmAJXftI7gaohFBwsT5tAHQtBuY7tB3b1hrnfrFb9FTNxGZJKcIH3p4
dOAvedsfuq+2/lU9iM4tX9fjSzfnGRZRuKCGDSdhE6EDik9/f2kSCoY9z0zJwdZH
324TpGbZNbgcwgHDL9i5Nsnaua5yxtr0/Fr1We1tvn0=

View File

@@ -1,15 +0,0 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output "Copying PUTTYNG to correct directory"
Copy-Item -Path (Join-Path -Path $SolutionDir -ChildPath "mRemoteNG\Resources\PuTTYNG.exe") -Destination $TargetDir -Force
Write-Output ""

View File

@@ -1,21 +0,0 @@
param (
[string]
$SourcePath,
[string]
$DestinationDir
)
Write-Host $SourcePath
Write-Host $DestinationDir
if (!(Test-Path -Path $DestinationDir))
{
New-Item -Path $DestinationDir -ItemType "directory"
}
$sourceFiles = Get-ChildItem -Path $SourcePath -Recurse | ?{$_.Extension -match "exe|msi"}
foreach ($item in $sourceFiles)
{
Copy-Item -Path $item.FullName -Destination $DestinationDir -Force
}

View File

@@ -1,19 +0,0 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output "Copying THEMES folder to output"
$sourceFiles = [io.path]::combine($SolutionDir , 'mRemoteNG\Resources\Themes' )
$DestinationDir = [io.path]::combine($TargetDir , 'Themes')
robocopy $sourceFiles $DestinationDir *.vstheme /s
Write-Output ""

View File

@@ -1,17 +0,0 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output "Copying TILES folder to output"
$sourceFiles = [io.path]::combine($SolutionDir , 'mRemoteNG\Resources\Tiles' )
robocopy $sourceFiles $TargetDir *.*
Write-Output ""

View File

@@ -1,17 +1,27 @@
#Requires -Version 4.0
param (
[string]
[Parameter(Mandatory=$true)]
$WebsiteTargetOwner,
[string]
[Parameter(Mandatory=$true)]
$WebsiteTargetRepository,
[string]
[Parameter(Mandatory=$false)]
$PreTagName = "",
[string]
[Parameter(Mandatory=$true)]
$TagName,
[string]
[Parameter(Mandatory=$true)]
[ValidateSet("Stable","Beta","Development")]
$UpdateChannel
$ProjectName
)
function New-MsiUpdateFileContent {
param (
[System.IO.FileInfo]
@@ -25,7 +35,7 @@ function New-MsiUpdateFileContent {
$version = $MsiFile.BaseName -replace "[a-zA-Z-]*"
$certThumbprint = (Get-AuthenticodeSignature -FilePath $MsiFile).SignerCertificate.Thumbprint
$hash = Get-FileHash -Algorithm SHA512 $MsiFile | % { $_.Hash }
$hash = Get-FileHash -Algorithm SHA512 $MsiFile | ForEach-Object { $_.Hash }
$fileContents = `
"Version: $version
@@ -49,7 +59,7 @@ function New-ZipUpdateFileContent {
)
$version = $ZipFile.BaseName -replace "[a-zA-Z-]*"
$hash = Get-FileHash -Algorithm SHA512 $ZipFile | % { $_.Hash }
$hash = Get-FileHash -Algorithm SHA512 $ZipFile | ForEach-Object { $_.Hash }
$fileContents = `
"Version: $version
@@ -64,7 +74,7 @@ function Resolve-UpdateCheckFileName {
param (
[string]
[Parameter(Mandatory=$true)]
[ValidateSet("Stable","Beta","Development")]
[ValidateSet("Stable","Preview","Nightly")]
$UpdateChannel,
[string]
@@ -75,8 +85,8 @@ function Resolve-UpdateCheckFileName {
$fileName = ""
if ($UpdateChannel -eq "Beta") { $fileName += "beta-" }
elseif ($UpdateChannel -eq "Development") { $fileName += "dev-" }
if ($UpdateChannel -eq "Preview") { $fileName += "preview-" }
elseif ($UpdateChannel -eq "Nightly") { $fileName += "nightly-" }
$fileName += "update"
@@ -87,23 +97,72 @@ function Resolve-UpdateCheckFileName {
Write-Output $fileName
}
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
# determine update channel
if ($env:APPVEYOR_PROJECT_NAME -match "(Nightly)") {
Write-Output "UpdateChannel = Nightly"
$UpdateChannel = "Nightly"
$ModifiedTagName = "$PreTagName-$TagName-NB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Preview)") {
Write-Output "UpdateChannel = Preview"
$UpdateChannel = "Preview"
$ModifiedTagName = "v$TagName-PB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Stable)") {
Write-Output "UpdateChannel = Stable"
$UpdateChannel = "Stable"
$ModifiedTagName = "v" + $TagName.Split("-")[0]
} else {
$UpdateChannel = ""
}
#$buildFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\mRemoteNG\bin\x64\Release" -Resolve -ErrorAction Ignore
$ReleaseFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\Release" -Resolve
if ($UpdateChannel -ne "" -and $ReleaseFolder -ne "" -and $WebsiteTargetOwner -and $WebsiteTargetRepository) {
$releaseFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\Release" -Resolve
$msiFile = Get-ChildItem -Path "$ReleaseFolder\*.msi" -Exclude "*-symbols-*.zip" | Sort-Object LastWriteTime | Select-Object -last 1
if (![string]::IsNullOrEmpty($msiFile)) {
$msiUpdateContents = New-MsiUpdateFileContent -MsiFile $msiFile -TagName $ModifiedTagName
$msiUpdateFileName = Resolve-UpdateCheckFileName -UpdateChannel $UpdateChannel -Type Normal
Write-Output "`n`nMSI Update Check File Contents ($msiUpdateFileName)`n------------------------------"
Tee-Object -InputObject $msiUpdateContents -FilePath "$ReleaseFolder\$msiUpdateFileName"
# commit msi update txt file
if ($env:WEBSITE_UPDATE_ENABLED.ToLower() -eq "true") {
if ((Test-Path -Path "$ReleaseFolder\$msiUpdateFileName") -and (-not [string]::IsNullOrEmpty($WebsiteTargetRepository))) {
Write-Output "Publish Update File $msiUpdateFileName to $WebsiteTargetRepository"
$update_file_content_string = Get-Content "$ReleaseFolder\$msiUpdateFileName" | Out-String
Set-GitHubContent -OwnerName $WebsiteTargetOwner -RepositoryName $WebsiteTargetRepository -Path $msiUpdateFileName -CommitMessage "Build $ModifiedTagName" -Content $update_file_content_string -BranchName main
} else {
Write-Warning "WARNING: Update file does not exist: $ReleaseFolder\$msiUpdateFileName"
}
}
}
# build msi update file
$msiFile = Get-ChildItem -Path "$releaseFolder\*.msi" | sort LastWriteTime | select -last 1
$msiUpdateContents = New-MsiUpdateFileContent -MsiFile $msiFile -TagName $TagName
$msiUpdateFileName = Resolve-UpdateCheckFileName -UpdateChannel $UpdateChannel -Type Normal
Write-Output "`n`nMSI Update Check File Contents ($msiUpdateFileName)`n------------------------------"
Tee-Object -InputObject $msiUpdateContents -FilePath "$releaseFolder\$msiUpdateFileName"
# build zip update file
$zipFile = Get-ChildItem -Path "$ReleaseFolder\*.zip" -Exclude "*-symbols-*.zip" | Sort-Object LastWriteTime | Select-Object -last 1
if (![string]::IsNullOrEmpty($zipFile)) {
$zipUpdateContents = New-ZipUpdateFileContent -ZipFile $zipFile -TagName $ModifiedTagName
$zipUpdateFileName = Resolve-UpdateCheckFileName -UpdateChannel $UpdateChannel -Type Portable
Write-Output "`n`nZip Update Check File Contents ($zipUpdateFileName)`n------------------------------"
Tee-Object -InputObject $zipUpdateContents -FilePath "$ReleaseFolder\$zipUpdateFileName"
# commit zip update txt file
if ($env:WEBSITE_UPDATE_ENABLED.ToLower() -eq "true") {
if ((Test-Path -Path "$ReleaseFolder\$zipUpdateFileName") -and (-not [string]::IsNullOrEmpty($WebsiteTargetRepository))) {
Write-Output "Publish Update File $zipUpdateFileName to $WebsiteTargetRepository"
$update_file_content_string = Get-Content "$ReleaseFolder\$zipUpdateFileName" | Out-String
Set-GitHubContent -OwnerName $WebsiteTargetOwner -RepositoryName $WebsiteTargetRepository -Path $zipUpdateFileName -CommitMessage "Build $ModifiedTagName" -Content $update_file_content_string -BranchName main
} else {
Write-Warning "WARNING: Update file does not exist: $ReleaseFolder\$zipUpdateFileName"
}
}
}
} else {
Write-Output "ReleaseFolder not found"
}
# build zip update file
$zipFile = Get-ChildItem -Path "$releaseFolder\*.zip" | sort LastWriteTime | select -last 1
$zipUpdateContents = New-ZipUpdateFileContent -ZipFile $zipFile -TagName $TagName
$zipUpdateFileName = Resolve-UpdateCheckFileName -UpdateChannel $UpdateChannel -Type Portable
Write-Output "`n`nZip Update Check File Contents ($zipUpdateFileName)`n------------------------------"
Tee-Object -InputObject $zipUpdateContents -FilePath "$releaseFolder\$zipUpdateFileName"
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

2
Tools/decrypt.bat Normal file
View File

@@ -0,0 +1,2 @@
openssl enc -base64 -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -d -in cert/CodeSigning_Cert_mRemoteNG_Certum.enc -out cert/CodeSigning_Cert_mRemoteNG_Certum.cer
pause

2
Tools/encrypt.bat Normal file
View File

@@ -0,0 +1,2 @@
openssl enc -base64 -aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -e -in cert/CodeSigning_Cert_mRemoteNG_Certum.cer -out cert/CodeSigning_Cert_mRemoteNG_Certum.enc
pause

View File

@@ -19,27 +19,28 @@ function EditBinCertificateIsValid() {
"3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC",
"98ED99A67886D020C564923B7DF25E9AC019DF26",
"108E2BA23632620C427C570B6D9DB51AC31387FE",
"5EAD300DC7E4D637948ECB0ED829A072BD152E17"
"5EAD300DC7E4D637948ECB0ED829A072BD152E17",
"97221B97098F37A135DCC212E2B41E452BCE51F2"
)
$file_signature = Get-AuthenticodeSignature -FilePath $Path
if (($file_signature.Status -ne "Valid") -or ($valid_microsoft_cert_thumbprints -notcontains $file_signature.SignerCertificate.Thumbprint)) {
Write-Warning "Could not validate the signature of $Path"
Write-Warning "Could not validate the signature of $Path $($file_signature.SignerCertificate.Thumbprint)"
Write-Output "file_signature.SignerCertificate.Thumbprint: $($file_signature.SignerCertificate.Thumbprint)"
return $false
} else {
return $true
}
}
function ToolCanBeExecuted {
param (
[string]
$Path
)
$null = & $Path
Write-Output ($LASTEXITCODE -gt 0)
$env:PATHEXT.Contains((Get-Item $Path).Extension.ToUpper())
}
$rootSearchPaths = @(
[System.IO.Directory]::EnumerateFileSystemEntries("C:\Program Files", "*Visual Studio*", [System.IO.SearchOption]::TopDirectoryOnly),
[System.IO.Directory]::EnumerateFileSystemEntries("C:\Program Files (x86)", "*Visual Studio*", [System.IO.SearchOption]::TopDirectoryOnly)
@@ -51,7 +52,8 @@ foreach ($searchPath in $rootSearchPaths) {
Write-Verbose "Searching in folder '$visualStudioFolder'"
$matchingExes = [System.IO.Directory]::EnumerateFileSystemEntries($visualStudioFolder, $FileName, [System.IO.SearchOption]::AllDirectories)
foreach ($matchingExe in $matchingExes) {
if ((EditBinCertificateIsValid -Path $matchingExe) -and (ToolCanBeExecuted -Path $matchingExe)) {
#if ((EditBinCertificateIsValid -Path $matchingExe) -and (ToolCanBeExecuted -Path $matchingExe)) {
if (ToolCanBeExecuted -Path $matchingExe) {
return $matchingExe
}
}

View File

@@ -2,6 +2,32 @@ $githubUrl = 'https://api.github.com'
# GitHub doesn't support the default powershell protocol (TLS 1.0)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
if ($IsAppVeyor) {
#$CURRENT_GITHUB_USER = $env:APPVEYOR_REPO_NAME.Split("/")[0]
Install-Module -Name PowerShellForGitHub -Scope CurrentUser
Set-GitHubConfiguration -DisableTelemetry
$PSDefaultParameterValues["*-GitHub*:AccessToken"] = "$env:ACCESS_TOKEN"
#New-Item -Path "$Env:APPVEYOR_BUILD_FOLDER\Release" -ItemType Directory -Force
}
function New-TemporaryDirectory {
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
$fullTempPath = (Join-Path $parent $name)
New-Item -ItemType Directory -Path $fullTempPath
return $fullTempPath
}
Function ConvertFrom-Base64($base64) {
return [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64))
}
Function ConvertTo-Base64($plain) {
return [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($plain))
}
function Publish-GitHubRelease {
param (
[string]
@@ -232,4 +258,4 @@ function New-GitHubReleaseRequestBody {
$json_body = ConvertTo-Json -InputObject $body_params -Compress
Write-Output $json_body
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

76
Tools/postbuild.ps1 Normal file
View File

@@ -0,0 +1,76 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir,
[string]
[Parameter(Mandatory=$true)]
$TargetFileName,
[string]
[Parameter(Mandatory=$true)]
$ConfigurationName,
[string]
$CertificatePath,
[string]
$CertificatePassword,
[string[]]
$ExcludeFromSigning
)
. "$PSScriptRoot\github_functions.ps1"
Write-Output ""
Write-Output "+============================================================+"
Write-Output "| Beginning mRemoteNG Post Build |"
Write-Output "+============================================================+"
Format-Table -AutoSize -Wrap -InputObject @{
"SolutionDir" = $SolutionDir
"TargetDir" = $TargetDir
"TargetFileName" = $TargetFileName
"ConfigurationName" = $ConfigurationName
"CertificatePath" = $CertificatePath
"ExcludeFromSigning" = $ExcludeFromSigning
}
if ( $ConfigurationName -match "Debug" -and ([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) ) { return; } #skip when Debug local developer build
if ( $env:APPVEYOR_PROJECT_NAME -match "(CI)" -and -not ([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) ) { return; } #skip when AppVeyor (CI) build
$dstPath = "$($SolutionDir)Release"
New-Item -Path $dstPath -ItemType Directory -Force
# $RunInstaller = $TargetDir -match "\\mRemoteNGInstaller\\Installer\\bin\\"
# $RunPortable = ( ($Targetdir -match "\\mRemoteNG\\bin\\") -and -not ($TargetDir -match "\\mRemoteNGInstaller\\Installer\\bin\\") )
if ( ($ConfigurationName -match "Release") -and ($env:APPVEYOR_PROJECT_NAME -notmatch "(CI)") -and -not ([string]::IsNullOrEmpty($env:WEBSITE_TARGET_OWNER)) -and -not ([string]::IsNullOrEmpty($env:WEBSITE_TARGET_REPOSITORY)) ) {
Write-Output "-Begin Release Portable"
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
& "$PSScriptRoot\zip_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\create_upg_chk_files.ps1" -WebsiteTargetOwner $env:WEBSITE_TARGET_OWNER -WebsiteTargetRepository $env:WEBSITE_TARGET_REPOSITORY -PreTagName $env:NightlyBuildTagName -TagName $env:APPVEYOR_BUILD_VERSION -ProjectName $env:APPVEYOR_PROJECT_NAME
& "$PSScriptRoot\update_and_upload_website_release_json_file.ps1" -WebsiteTargetOwner $env:WEBSITE_TARGET_OWNER -WebsiteTargetRepository $env:WEBSITE_TARGET_REPOSITORY -PreTagName $env:NightlyBuildTagName -TagName $env:APPVEYOR_BUILD_VERSION -ProjectName $env:APPVEYOR_PROJECT_NAME
Write-Output "-End Release Portable"
}
Write-Output "End mRemoteNG Post Build"
Write-Output ""

View File

@@ -25,9 +25,12 @@ param (
$ExcludeFromSigning
)
Write-Output "+=================================================================+"
Write-Output "| Beginning mRemoteNG Installer Post Build |"
Write-Output "+=================================================================+"
. "$PSScriptRoot\github_functions.ps1"
Write-Output ""
Write-Output "+===========================================================================================+"
Write-Output "| Beginning mRemoteNG Installer Post Build |"
Write-Output "+===========================================================================================+"
Format-Table -AutoSize -Wrap -InputObject @{
"SolutionDir" = $SolutionDir
"TargetDir" = $TargetDir
@@ -37,8 +40,24 @@ Format-Table -AutoSize -Wrap -InputObject @{
"ExcludeFromSigning" = $ExcludeFromSigning
}
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
& "$PSScriptRoot\rename_installer_with_version.ps1" -SolutionDir $SolutionDir
& "$PSScriptRoot\copy_release_installer.ps1" -SourcePath $TargetDir -DestinationDir (Join-Path -Path $SolutionDir -ChildPath "Release")
if ( $IsAppVeyor -and ($ConfigurationName.ToUpper() -match "RELEASE") -and (($env:APPVEYOR_PROJECT_NAME).ToUpper() -notmatch "(CI)") ) {
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
& "$PSScriptRoot\rename_and_copy_installer.ps1" -SolutionDir $SolutionDir -BuildConfiguration $ConfigurationName.Trim()
& "$PSScriptRoot\create_upg_chk_files.ps1" -WebsiteTargetOwner $env:WEBSITE_TARGET_OWNER -WebsiteTargetRepository $env:WEBSITE_TARGET_REPOSITORY -PreTagName $env:NightlyBuildTagName -TagName $env:APPVEYOR_BUILD_VERSION -ProjectName $env:APPVEYOR_PROJECT_NAME
& "$PSScriptRoot\update_and_upload_website_release_json_file.ps1" -WebsiteTargetOwner $env:WEBSITE_TARGET_OWNER -WebsiteTargetRepository $env:WEBSITE_TARGET_REPOSITORY -PreTagName $env:NightlyBuildTagName -TagName $env:APPVEYOR_BUILD_VERSION -ProjectName $env:APPVEYOR_PROJECT_NAME
& "$PSScriptRoot\update_and_upload_assemblyinfocs.ps1"
}
Write-Output "End mRemoteNG Installer Post Build"
Write-Output ""

View File

@@ -1,52 +0,0 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir,
[string]
[Parameter(Mandatory=$true)]
$TargetFileName,
[string]
[Parameter(Mandatory=$true)]
$ConfigurationName,
[string]
$CertificatePath,
[string]
$CertificatePassword,
[string[]]
$ExcludeFromSigning
)
Write-Output "+=================================================================+"
Write-Output "| Beginning mRemoteNG Post Build |"
Write-Output "+=================================================================+"
Format-Table -AutoSize -Wrap -InputObject @{
"SolutionDir" = $SolutionDir
"TargetDir" = $TargetDir
"TargetFileName" = $TargetFileName
"ConfigurationName" = $ConfigurationName
"CertificatePath" = $CertificatePath
"ExcludeFromSigning" = $ExcludeFromSigning
}
& "$PSScriptRoot\copy_puttyng.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
& "$PSScriptRoot\copy_themes.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
& "$PSScriptRoot\copy_tiles.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
& "$PSScriptRoot\sphinx_docs.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir
& "$PSScriptRoot\set_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\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
& "$PSScriptRoot\zip_symbols.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
& "$PSScriptRoot\zip_portable_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName

View File

@@ -0,0 +1,91 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir,
[string]
[Parameter(Mandatory=$true)]
$TargetFileName,
[string]
[Parameter(Mandatory=$true)]
$ConfigurationName,
[string]
$CertificatePath,
[string]
$CertificatePassword,
[string[]]
$ExcludeFromSigning
)
. "$PSScriptRoot\github_functions.ps1"
Write-Output ""
Write-Output "+===========================================================================================+"
Write-Output "| Beginning mRemoteNG Portable Post Build |"
Write-Output "+===========================================================================================+"
Format-Table -AutoSize -Wrap -InputObject @{
"SolutionDir" = $SolutionDir
"TargetDir" = $TargetDir
"TargetFileName" = $TargetFileName
"ConfigurationName" = $ConfigurationName
"CertificatePath" = $CertificatePath
"ExcludeFromSigning" = $ExcludeFromSigning
}
# Move dlls resurses into folder
#Remove-Item -Path "$TargetDir\libs" -Recurse -ErrorAction Ignore
#New-Item -ItemType "directory" -Force -Path $TargetDir -Name "libs"
#Move-Item -Path "$TargetDir\*.dll" -Destination "$TargetDir\libs" -force
###
# Move lang resurses into folder
#Remove-Item -Path "$TargetDir\languages" -Recurse -ErrorAction Ignore
#New-Item -ItemType "directory" -Force -Path $TargetDir -Name "languages"
#"cs-CZ,de,el,en-US,es-AR,es,fr,hu,it,lt,ja-JP,ko-KR,nb-NO,nl,pt,pt-BR,pl,ru,uk,tr-TR,zh-CN,zh-TW,fi-FI".Split(",") | ForEach {
# Move-Item -Path "$TargetDir\$_" -Destination "$TargetDir\languages" -force
# }
###
# Currently targeting x64, shouldn't need to manually set LargeAddressAware...
#& "$PSScriptRoot\set_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
#& "$PSScriptRoot\verify_LargeAddressAware.ps1" -TargetDir $TargetDir -TargetFileName $TargetFileName
if (!([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))) {
$postbuild_installer_executed = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\AppVeyor_mRemoteNG' -Name postbuild_installer_executed
} else {
$postbuild_installer_executed = ""
}
write-host "-SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName "
& "$PSScriptRoot\tidy_files_for_release.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName
if ($postbuild_installer_executed -ne "true" -or $env:postbuild_installer_executed -ne "true") {
& "$PSScriptRoot\sign_binaries.ps1" -TargetDir $TargetDir -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -ConfigurationName $ConfigurationName -Exclude $ExcludeFromSigning -SolutionDir $SolutionDir
& "$PSScriptRoot\verify_binary_signatures.ps1" -TargetDir $TargetDir -ConfigurationName $ConfigurationName -CertificatePath $CertificatePath -SolutionDir $SolutionDir
}
& "$PSScriptRoot\zip_files.ps1" -SolutionDir $SolutionDir -TargetDir $TargetDir -ConfigurationName $ConfigurationName
if ( ![string]::IsNullOrEmpty($env:WEBSITE_TARGET_OWNER) -and ![string]::IsNullOrEmpty($env:WEBSITE_TARGET_REPOSITORY) ) {
& "$PSScriptRoot\create_upg_chk_files.ps1" -WebsiteTargetOwner $env:WEBSITE_TARGET_OWNER -WebsiteTargetRepository $env:WEBSITE_TARGET_REPOSITORY -PreTagName $env:NightlyBuildTagName -TagName $env:APPVEYOR_BUILD_VERSION -ProjectName $env:APPVEYOR_PROJECT_NAME
& "$PSScriptRoot\update_and_upload_website_release_json_file.ps1" -WebsiteTargetOwner $env:WEBSITE_TARGET_OWNER -WebsiteTargetRepository $env:WEBSITE_TARGET_REPOSITORY -PreTagName $env:NightlyBuildTagName -TagName $env:APPVEYOR_BUILD_VERSION -ProjectName $env:APPVEYOR_PROJECT_NAME
}
Write-Output "End mRemoteNG Portable Post Build"
Write-Output ""

View File

@@ -0,0 +1,61 @@
param (
[string]
$SolutionDir,
[string]
$BuildConfiguration
)
$ErrorActionPreference = "Stop"
Write-Output ""
Write-Output " /===== Begin rename_and_copy_installer =====/"
$targetVersionedFile = "$SolutionDir\mRemoteNG\bin\x64\$BuildConfiguration\mRemoteNG.exe"
#$fileversion = &"$SolutionDir\Tools\exes\sigcheck.exe" /accepteula -q -n $targetVersionedFile
#$prodversion = ((Get-Item -Path $targetVersionedFile).VersionInfo | Select-Object -Property ProductVersion)."ProductVersion"
$fileversion = ((Get-Item -Path $targetVersionedFile).VersionInfo | Select-Object -Property FileVersion)."FileVersion"
Write-Output "fileversion: $fileversion"
$msiversion = $fileversion
# determine update channel
if ($env:APPVEYOR_PROJECT_NAME -match "(Nightly)") {
Write-Output " UpdateChannel = Nightly"
$msiversion = "$msiversion-NB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Preview)") {
Write-Output " UpdateChannel = Preview"
$msiversion = "$msiversion-PB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Stable)") {
Write-Output " UpdateChannel = Stable"
} else {
}
$dstPath = "$($SolutionDir)Release"
New-Item -Path $dstPath -ItemType Directory -Force
$srcMsi = $SolutionDir + "mRemoteNGInstaller\Installer\bin\x64\$BuildConfiguration\en-US\mRemoteNG-Installer.msi"
$dstMsi = $dstPath + "\mRemoteNG-Installer-" + $msiversion + ".msi"
#$srcSymbols = $SolutionDir + "mRemoteNGInstaller\Installer\bin\x64\$BuildConfiguration\en-US\mRemoteNG-Installer-Symbols*.zip"
#$dstSymbols = $SolutionDir + "Release\mRemoteNG-Installer-Symbols-" + $msiversion + ".zip"
Write-Output " Copy Installer file:"
Write-Output " From: $srcMsi"
Write-Output " To: $dstMsi"
Write-Output ""
# Copy file
try
{
Copy-Item $srcMsi -Destination $dstMsi -Force -ErrorAction Stop
#Copy-Item $srcSymbols -Destination $dstSymbols -Force -ErrorAction Stop
Write-Host " [Success!]" -ForegroundColor green
}
catch
{
Write-Host " [Failure!]" -ForegroundColor red
Write-Output $Error[0]
$PSCmdlet.ThrowTerminatingError()
}
Write-Output ""
Write-Output " /===== End rename_and_copy_installer.ps1 =====/"
Write-Output ""

View File

@@ -1,29 +0,0 @@
param (
[string]
$SolutionDir
)
$renameTarget = $SolutionDir + "InstallerProjects\Installer\bin\Release\en-US\mRemoteNG-Installer.msi"
Write-Host $SolutionDir
Write-Host $renameTarget
$targetVersionedFile = "$SolutionDir\mRemoteNG\bin\Release\mRemoteNG.exe"
$version = &"$SolutionDir\Tools\exes\sigcheck.exe" /accepteula -q -n $targetVersionedFile
$renameTargetFileObject = Get-Item -Path $renameTarget -ErrorAction SilentlyContinue
if ($renameTargetFileObject)
{
# Build the new file name
$oldFileName = $renameTargetFileObject.Name
$newFileName = $oldFileName -replace "$("\"+$renameTargetFileObject.Extension)",$("-"+$version+$renameTargetFileObject.Extension)
Write-Host $oldFileName
Write-Host $newFileName
# Delete any items that already exist with the new name (effectively an overwrite)
Remove-Item -Path "$($renameTargetFileObject.Directory.FullName)\$newFileName" -ErrorAction SilentlyContinue
# Rename file
Rename-Item -Path $renameTarget -NewName $newFileName -ErrorAction SilentlyContinue
}

View File

@@ -24,65 +24,80 @@ param (
$SolutionDir
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
$timeserver = "http://timestamp.verisign.com/scripts/timstamp.dll"
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
# validate release versions and if the certificate value was passed
if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
try {
# validate release versions and if the certificate value was passed
if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
if(-Not ([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) ) {
$CertificatePath = Join-Path -Path $SolutionDir -ChildPath $CertificatePath
if($IsAppVeyor) {
$CertificatePath = Join-Path -Path $SolutionDir -ChildPath $CertificatePath
Write-Output "Decrypt Cert"
& appveyor-tools\secure-file -decrypt "$($Env:cert_path).enc" -secret "$Env:cert_decrypt_pwd"
if(-Not (Test-Path $Env:cert_path)) {
Write-Output "decrypt cert does not exist..."
Throw "Could not decrypt cert"
}
Write-Output "Restoring NuGets"
}
# make sure the cert is actually available
if ($CertificatePath -eq "" -or !(Test-Path -Path $CertificatePath -PathType Leaf))
{
Write-Output "Certificate is not present - we won't sign files."
return
}
if ($CertificatePassword -eq "") {
Write-Output "No certificate password was provided - we won't sign files."
return
}
try {
$certKeyStore = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath, $CertificatePassword, $certKeyStore) -ErrorAction Stop
} catch {
Write-Output "Error loading certificate file - we won't sign files."
Write-Output $Error[0]
return
}
# Sign MSI if we are building a release version and the certificate is available
Write-Output "Signing Binaries"
Write-Output "Getting files from path: $TargetDir"
$signableFiles = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"} | ?{$Exclude -notcontains $_.Name}
$excluded_files = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"} | ?{$Exclude -contains $_.Name}
$excluded_files | ForEach-Object `
-Begin { Write-Output "The following files were excluded from signing due to being on the exclusion list:" } `
-Process { Write-Output "-- $($_.FullName)" }
Write-Output "Signable files count: $($signableFiles.Count)"
foreach ($file in $signableFiles) {
Set-AuthenticodeSignature -Certificate $cert -TimestampServer $timeserver -IncludeChain all -FilePath $file.FullName
}
# Release certificate
if ($null -ne $cert) {
$cert.Dispose()
}
} else {
Write-Output "This is not a release build or CertificatePath wasn't provided - we won't sign files."
Write-Output "Config: $($ConfigurationName)`tCertPath: $($CertificatePath)"
}
# make sure the cert is actually available
if ($CertificatePath -eq "" -or !(Test-Path -Path $CertificatePath -PathType Leaf))
{
Write-Output "Certificate is not present - we won't sign files."
return
}
if ($CertificatePassword -eq "") {
Write-Output "No certificate password was provided - we won't sign files."
return
}
try {
$certKeyStore = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath, $CertificatePassword, $certKeyStore) -ErrorAction Stop
} catch {
Write-Output "Error loading certificate file - we won't sign files."
Write-Output $Error[0]
return
}
# Sign MSI if we are building a release version and the certificate is available
Write-Output "Signing Binaries"
Write-Output "Getting files from path: $TargetDir"
$signableFiles = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"} | ?{$Exclude -notcontains $_.Name}
$excluded_files = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"} | ?{$Exclude -contains $_.Name}
$excluded_files | ForEach-Object `
-Begin { Write-Output "The following files were excluded from signing due to being on the exclusion list:" } `
-Process { Write-Output "-- $($_.FullName)" }
Write-Output "Signable files count: $($signableFiles.Count)"
foreach ($file in $signableFiles) {
Set-AuthenticodeSignature -Certificate $cert -TimestampServer $timeserver -IncludeChain all -FilePath $file.FullName
}
# Release certificate
if ($cert -ne $null) {
$cert.Dispose()
}
} else {
Write-Output "This is not a release build or CertificatePath wasn't provided - we won't sign files."
Write-Output "Config: $($ConfigurationName)`tCertPath: $($CertificatePath)"
}
catch {
Write-Output $Error[0]
}
Write-Output ""
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

View File

@@ -28,4 +28,6 @@ Write-Output "Signable files count: $($signableFiles.Count)"
foreach ($file in $signableFiles) {
Set-AuthenticodeSignature -Certificate $cert -TimestampServer $timeserver -IncludeChain all -FilePath $file.FullName
}
}
Write-Output ""

View File

@@ -1,33 +0,0 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output "Building HTML-Documentation with Sphinx"
$path_HelpFilesDir = Join-Path -Path $TargetDir -ChildPath "Help"
$path_SphinxSourceDir = Join-Path -Path $SolutionDir -ChildPath "mRemoteNG\Documentation"
# Remove stale Help files, if they exist
if (Test-Path -Path $path_HelpFilesDir) {
Remove-Item -Path $path_HelpFilesDir -Recurse -Force
}
# Build docs
sphinx-build $path_SphinxSourceDir $path_HelpFilesDir
# Place dummy html file if build failed
if (-Not (Test-Path $path_HelpFilesDir\index.html -PathType Leaf)) {
New-Item -Path $path_HelpFilesDir -ItemType "directory"
New-Item $path_HelpFilesDir\index.html
Set-Content $path_HelpFilesDir\index.html 'Welcome to mRemoteNG!'
}
Write-Output ""

View File

@@ -8,14 +8,14 @@ param (
$ConfigurationName
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
# Remove unnecessary files from Release versions
if ($ConfigurationName -match "Release") {
Write-Output "Removing unnecessary files from Release versions"
$test = Join-Path -Path $TargetDir -ChildPath "app.publish"
if (Test-Path $test -PathType Container) {
if (Test-Path $test -PathType Container)
{
Remove-Item -Path (Join-Path -Path $TargetDir -ChildPath "app.publish") -Recurse -Force
}
@@ -29,11 +29,18 @@ if ($ConfigurationName -match "Release") {
) -Exclude @(
"mRemoteNG.VisualElementsManifest.xml"
)
Remove-Item -Path $filesToDelete.FullName
Write-Output $filesToDelete.FullName
}
else {
if ($filesToDelete)
{
Write-Output "Unnecessary files are detected and will be removed"
Remove-Item -Path $filesToDelete.FullName
Write-Output $filesToDelete.FullName
} else {
Write-Output " No unnecessary files are detected"
}
} else {
Write-Output "We will not remove anything - this is not a release build."
}
Write-Output ""
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

View File

@@ -0,0 +1,53 @@
#Requires -Version 4.0
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
$MainRepository = $Env:APPVEYOR_REPO_NAME.Split("/\")[1]
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
Write-Output "MainRepository: $MainRepository"
if ($IsAppVeyor) {
# determine update channel
if ($env:APPVEYOR_PROJECT_NAME -match "(Nightly)") {
Write-Output "UpdateChannel = Nightly"
$UpdateChannel = "Nightly"
$ModifiedTagName = "$PreTagName-$TagName-NB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Preview)") {
Write-Output "UpdateChannel = Preview"
$UpdateChannel = "Preview"
$ModifiedTagName = "v$TagName-PB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Stable)") {
Write-Output "UpdateChannel = Stable"
$UpdateChannel = "Stable"
$ModifiedTagName = "v" + $TagName.Split("-")[0]
} else {
$UpdateChannel = ""
}
if ($UpdateChannel -ne "" -and $MainRepository -ne "" ) {
# commit AssemblyInfo.cs change
Write-Output "publish AssemblyInfo.cs"
$buildFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\" -Resolve -ErrorAction Ignore
if (Test-Path -Path "$buildFolder\mRemoteNG\Properties\AssemblyInfo.cs") {
$assemblyinfocs_content = [System.String]::Join("`r`n", (Get-Content "$buildFolder\mRemoteNG\Properties\AssemblyInfo.cs"))
Set-GitHubContent -OwnerName $MainRepository -RepositoryName $MainRepository -Path "mRemoteNG\Properties\AssemblyInfo.cs" -CommitMessage "AssemblyInfo.cs updated for $UpdateChannel $ModifiedTagName" -Content $assemblyinfocs_content -BranchName main
Write-Output "publish completed"
}
} else {
Write-Output "Source folder not found"
}
}
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

View File

@@ -0,0 +1,178 @@
#Requires -Version 4.0
param (
[string]
[Parameter(Mandatory=$true)]
$WebsiteTargetOwner,
[string]
[Parameter(Mandatory=$true)]
$WebsiteTargetRepository,
[string]
[Parameter(Mandatory=$false)]
$PreTagName = "",
[string]
[Parameter(Mandatory=$true)]
$TagName,
[string]
[Parameter(Mandatory=$true)]
$ProjectName
)
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
$MainRepository = $Env:APPVEYOR_REPO_NAME.Split("/\")[1]
# determine update channel
if ($env:APPVEYOR_PROJECT_NAME -match "(Nightly)") {
Write-Output "UpdateChannel = Nightly"
$UpdateChannel = "Nightly"
$ModifiedTagName = "$PreTagName-$TagName-NB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Preview)") {
Write-Output "UpdateChannel = Preview"
$UpdateChannel = "Preview"
$ModifiedTagName = "v$TagName-PB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Stable)") {
Write-Output "UpdateChannel = Stable"
$UpdateChannel = "Stable"
$ModifiedTagName = "v" + $TagName.Split("-")[0]
} else {
$UpdateChannel = ""
}
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
if ($IsAppVeyor) {
#$buildFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\mRemoteNG\bin\x64\Release" -Resolve -ErrorAction Ignore
$ReleaseFolder = Join-Path -Path $PSScriptRoot -ChildPath "..\Release" -Resolve
if ($UpdateChannel -ne "" -and $ReleaseFolder -ne "" -and $MainRepository -ne "" -and $WebsiteTargetOwner -ne "" -and $WebsiteTargetRepository -ne "" ) {
$published_at = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
# get releases.json from github
$releases_json = Get-GitHubContent -OwnerName $WebsiteTargetOwner -RepositoryName $WebsiteTargetRepository -Path _data\releases.json
ConvertFrom-Base64($releases_json.content) | Out-File -FilePath "$ReleaseFolder\releases.json"
$websiteJsonReleaseFile = Get-ChildItem -Path "$ReleaseFolder\releases.json"
# installer
$msiFile = Get-ChildItem -Path "$ReleaseFolder\*.msi" | Sort-Object LastWriteTime | Select-Object -last 1
if (![string]::IsNullOrEmpty($msiFile)) {
Write-Output "UpdateChannel: $UpdateChannel"
Write-Output "msiFile: $msiFile"
$checksum = (Get-FileHash $msiFile -Algorithm SHA512).Hash
$file_size = (Get-ChildItem $msiFile).Length
$a = Get-Content $websiteJsonReleaseFile | ConvertFrom-Json
switch ($UpdateChannel) {
"Nightly" {
$GithubTag = "$((Get-Date).ToUniversalTime().ToString("yyyyMMdd"))-$TagName-NB"
$html_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/tag/$GithubTag"
$browser_download_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/download/$GithubTag/$($msiFile.Name)"
$a.nightlybuild.name = "v$TagName-NB"
$a.nightlybuild.published_at = $published_at
$a.nightlybuild.html_url = $html_url
$a.nightlybuild.assets.installer.browser_download_url = $browser_download_url
$a.nightlybuild.assets.installer.checksum = $checksum
$a.nightlybuild.assets.installer.size = $file_size
break
}
"Preview" {
$GithubTag = "$TagName-PB"
$html_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/tag/$GithubTag"
$browser_download_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/download/$GithubTag/$($msiFile.Name)"
$a.prerelease.name = "v$TagName-PB"
$a.prerelease.published_at = $published_at
$a.prerelease.html_url = $html_url
$a.prerelease.assets.installer.browser_download_url = $browser_download_url
$a.prerelease.assets.installer.checksum = $checksum
$a.prerelease.assets.installer.size = $file_size
break
}
"Stable" {
$GithubTag = "$TagName"
$html_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/tag/$GithubTag"
$browser_download_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/download/$GithubTag/$($msiFile.Name)"
$a.stable.name = "v$TagName"
$a.stable.published_at = $published_at
$a.stable.html_url = $html_url
$a.stable.assets.installer.browser_download_url = $browser_download_url
$a.stable.assets.installer.checksum = $checksum
$a.stable.assets.installer.size = $file_size
break
}
}
}
# portable
$zipFile = Get-ChildItem -Path "$ReleaseFolder\*.zip" -Exclude "*-symbols-*.zip" | Sort-Object LastWriteTime | Select-Object -last 1
if (![string]::IsNullOrEmpty($zipFile)) {
Write-Output "UpdateChannel: $UpdateChannel"
Write-Output "zipFile: $zipFile"
$checksum = (Get-FileHash $zipFile -Algorithm SHA512).Hash
$file_size = (Get-ChildItem $zipFile).Length
$a = Get-Content $websiteJsonReleaseFile | ConvertFrom-Json
switch ($UpdateChannel) {
"Nightly" {
$GithubTag = "$((Get-Date).ToUniversalTime().ToString("yyyyMMdd"))-$TagName-NB"
$html_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/tag/$GithubTag"
$browser_download_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/download/$GithubTag/$($zipFile.Name)"
$a.nightlybuild.name = "v$TagName-NB"
$a.nightlybuild.published_at = $published_at
$a.nightlybuild.html_url = $html_url
$a.nightlybuild.assets.portable.browser_download_url = $browser_download_url
$a.nightlybuild.assets.portable.checksum = $checksum
$a.nightlybuild.assets.portable.size = $file_size
break
}
"Preview" {
$GithubTag = "$TagName-PB"
$html_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/tag/$GithubTag"
$browser_download_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/download/$GithubTag/$($zipFile.Name)"
$a.prerelease.name = "v$TagName-PB"
$a.prerelease.published_at = $published_at
$a.prerelease.html_url = $html_url
$a.prerelease.assets.portable.browser_download_url = $browser_download_url
$a.prerelease.assets.portable.checksum = $checksum
$a.prerelease.assets.portable.size = $file_size
break
}
"Stable" {
$GithubTag = "$TagName"
$html_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/tag/$GithubTag"
$browser_download_url = "https://github.com/$WebsiteTargetOwner/$MainRepository/releases/download/$GithubTag/$($zipFile.Name)"
$a.stable.name = "v$TagName"
$a.stable.published_at = $published_at
$a.stable.html_url = $html_url
$a.stable.assets.portable.browser_download_url = $browser_download_url
$a.stable.assets.portable.checksum = $checksum
$a.stable.assets.portable.size = $file_size
break
}
}
}
$a | ConvertTo-Json -Depth 10 | Set-Content $websiteJsonReleaseFile
# commit releases.json change
if ($env:WEBSITE_UPDATE_ENABLED.ToLower() -eq "true") {
Write-Output "publish releases.json"
if (Test-Path -Path "$ReleaseFolder\releases.json") {
$releases_json_string = Get-Content "$ReleaseFolder\releases.json" | Out-String
Set-GitHubContent -OwnerName $WebsiteTargetOwner -RepositoryName $WebsiteTargetRepository -Path _data\releases.json -CommitMessage "Updated for $UpdateChannel $ModifiedTagName" -Content $releases_json_string -BranchName main
Write-Output "publish completed"
}
}
} else {
Write-Output "ReleaseFolder not found"
}
}
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

View File

@@ -5,7 +5,13 @@ param (
$FullPath
)
$validMSCertThumbprints = @("3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC", "108E2BA23632620C427C570B6D9DB51AC31387FE", "98ED99A67886D020C564923B7DF25E9AC019DF26", "5EAD300DC7E4D637948ECB0ED829A072BD152E17")
$validMSCertThumbprints = @(
"3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC",
"108E2BA23632620C427C570B6D9DB51AC31387FE",
"98ED99A67886D020C564923B7DF25E9AC019DF26",
"5EAD300DC7E4D637948ECB0ED829A072BD152E17",
"97221B97098F37A135DCC212E2B41E452BCE51F2"
)
$exeSignature = Get-AuthenticodeSignature -FilePath $FullPath
$baseErrorMsg = "Could not validate the certificate of $FullPath. "
@@ -14,4 +20,4 @@ if ($exeSignature.Status -ne "Valid") {
}
elseif ($validMSCertThumbprints -notcontains $exeSignature.SignerCertificate.Thumbprint) {
Write-Error -Message ($baseErrorMsg+"The certificate thumbprint ($($exeSignature.SignerCertificate.Thumbprint)) is not trusted.") -ErrorAction Stop
}
}

View File

@@ -10,7 +10,8 @@ param (
$TargetFileName
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
$path_dumpBin = Join-Path -Path $PSScriptRoot -ChildPath "exes\dumpbin.exe"
$path_outputExe = Join-Path -Path $TargetDir -ChildPath $TargetFileName
@@ -18,7 +19,7 @@ $path_outputExe = Join-Path -Path $TargetDir -ChildPath $TargetFileName
# Dump exe header
$output = & "$path_dumpBin" /NOLOGO /HEADERS "$path_outputExe" | Select-String large
if ($output -eq $null)
if ($null -eq $output)
{
Write-Warning "Could not validate LargeAddressAware"
}
@@ -27,4 +28,5 @@ else
Write-Output $output.ToString().TrimStart(" ")
}
Write-Output ""
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

View File

@@ -18,12 +18,15 @@ param (
$SolutionDir
)
Write-Output "===== Beginning $($PSCmdlet.MyInvocation.MyCommand) ====="
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
# validate release versions and if the certificate value was passed
if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
if(-Not ([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER)) ) {
if($IsAppVeyor) {
$CertificatePath = Join-Path -Path $SolutionDir -ChildPath $CertificatePath
}
@@ -36,9 +39,10 @@ if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
Write-Output "Verifying signature of binaries"
Write-Output "Getting files from path: $TargetDir"
$signableFiles = Get-ChildItem -Path $TargetDir -Recurse | ?{$_.Extension -match "dll|exe|msi"}
$signableFiles = Get-ChildItem -Path $TargetDir -Recurse | Where-Object {$_.Extension -match "dll|exe|msi"}
Write-Output "Signable files count: $($signableFiles.Count)"
$badSignatureFound = $false
foreach ($file in $signableFiles) {
$signature = Get-AuthenticodeSignature -FilePath $file.FullName
if ($signature.Status -ne "Valid") {
@@ -46,6 +50,7 @@ if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
$badSignatureFound = $true
}
}
if ($badSignatureFound) {
Write-Output "One or more files were improperly signed."
} else {
@@ -56,4 +61,5 @@ if ($ConfigurationName -match "Release" -And ($CertificatePath)) {
Write-Output "Config: $($ConfigurationName)`tCertPath: $($CertificatePath)"
}
Write-Output ""
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

93
Tools/zip_files.ps1 Normal file
View File

@@ -0,0 +1,93 @@
param (
[string]
[Parameter(Mandatory=$true)]
$SolutionDir,
[string]
[Parameter(Mandatory=$true)]
$TargetDir,
[string]
[Parameter(Mandatory=$true)]
$ConfigurationName
)
Write-Output ""
Write-Output "===== Begin $($PSCmdlet.MyInvocation.MyCommand) ====="
$IsAppVeyor = !([string]::IsNullOrEmpty($Env:APPVEYOR_BUILD_FOLDER))
$ConfigurationName = $ConfigurationName.Trim()
$exe = Join-Path -Path $TargetDir -ChildPath $TargetFileName
#$version = ((Get-Item -Path $exe).VersionInfo | Select-Object -Property ProductVersion)."ProductVersion"
$version = $(Get-Item -Path $exe).VersionInfo.FileVersion
Write-Output "FileVersion: $version"
# determine update channel
if ($env:APPVEYOR_PROJECT_NAME -match "(Nightly)") {
Write-Output "UpdateChannel = Nightly"
$ModifiedVersion = "$version-NB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Preview)") {
Write-Output "UpdateChannel = Preview"
$ModifiedVersion = "$version-PB"
} elseif ($env:APPVEYOR_PROJECT_NAME -match "(Stable)") {
Write-Output "UpdateChannel = Stable"
$ModifiedVersion = $version
} else {
}
# Fix for AppVeyor
if($IsAppVeyor) {
if(!(Test-Path "Release")) {
New-Item -ItemType Directory -Force -Path "Release" | Out-Null
}
}
# Package debug symbols zip file
Write-Output "Packaging debug symbols"
$zipFilePrefix = "mRemoteNG-symbols"
$pdbFiles = Get-ChildItem -Path $SolutionDir -Filter *.pdb -Recurse
$tempPdbPath = (New-TemporaryDirectory)[0]
foreach ($pdbFile in $pdbFiles) {
if (($pdbFile.FullName).Contains("\$ConfigurationName\")) {
Copy-Item $pdbFile.FullName -Destination $tempPdbPath -Force
}
}
if ($IsAppVeyor) {
# AppVeyor build
$outputZipPath = Join-Path -Path $SolutionDir -ChildPath "Release\$zipFilePrefix-$($ModifiedVersion).zip"
Write-Output "outputZipPath: $outputZipPath"
7z a $outputZipPath "$tempPdbPath\*.pdb"
}
# else {
# # Local build
# $outputZipPath = "$($SolutionDir)Release\$zipFilePrefix-$($ModifiedVersion).zip"
# Write-Output "outputZipPath: $outputZipPath"
# Compress-Archive -Path $tempPdbPath -DestinationPath $outputZipPath -Force
# }
# Package portable release zip file
Write-Output "Packaging portable ZIP file"
# AppVeyor build
if ($IsAppVeyor) {
$outputZipPath = Join-Path -Path $SolutionDir -ChildPath "Release\mRemoteNG-Portable-$($ModifiedVersion).zip"
7z a -bt -bd -bb1 -mx=9 -tzip -y -r $outputZipPath $TargetDir\*
Write-Output "Portable ZIP: $outputZipPath"
}
# Local build
else {
if ($Source)
{
$outputZipPath="$($SolutionDir)\Release\mRemoteNG-Portable-$($ModifiedVersion).zip"
Compress-Archive $Source $outputZipPath -Force
} else {
Write-Output "Files do not exist:" $Source", nothing to compress"
}
}
Write-Output "End $($PSCmdlet.MyInvocation.MyCommand)"
Write-Output ""

View File

@@ -1,64 +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 (tirmmed): '$($ConfigurationName)'"
# Windows Sysinternals Sigcheck from http://technet.microsoft.com/en-us/sysinternals/bb897441
$SIGCHECK="$($SolutionDir)Tools\exes\sigcheck.exe"
$SEVENZIP="$($SolutionDir)Tools\7zip\7za.exe"
# Package Zip
if ($ConfigurationName -eq "Release Portable") {
Write-Output "Packaging Release Portable ZIP"
$version = & $SIGCHECK /accepteula -q -n "$($SolutionDir)mRemoteNG\bin\$($ConfigurationName)\mRemoteNG.exe"
Write-Output "Version is $($version)"
$PortableZip="$($SolutionDir)Release\mRemoteNG-Portable-$($version).zip"
$tempFolderPath = Join-Path -Path $SolutionDir -ChildPath "mRemoteNG\bin\package"
Remove-Item -Recurse $tempFolderPath -ErrorAction SilentlyContinue | Out-Null
New-Item $tempFolderPath -ItemType "directory" | Out-Null
Copy-Item "$($SolutionDir)mRemoteNG\Resources\PuTTYNG.exe" -Destination $tempFolderPath
#Write-Output "$($SolutionDir)mRemoteNG\bin\$ConfigurationName"
#Write-Output "$($SolutionDir)mRemoteNG\bin\package"
Copy-Item "$($SolutionDir)mRemoteNG\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 {
Write-Output "We will not zip anything - this isnt a portable release build."
}
Write-Output ""

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)mRemoteNG\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 ""

6
mRemoteNG.lutconfig Normal file
View File

@@ -0,0 +1,6 @@
<LUTConfig Version="1.0">
<Repository />
<ParallelBuilds>true</ParallelBuilds>
<ParallelTestRuns>true</ParallelTestRuns>
<TestCaseTimeout>180000</TestCaseTimeout>
</LUTConfig>

View File

@@ -1,11 +1,11 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.352
# Visual Studio Version 17
VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 14.0.25420.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mRemoteNG", "mRemoteNG\mRemoteNG.csproj", "{4934A491-40BC-4E5B-9166-EA1169A220F6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNG", "mRemoteNG\mRemoteNG.csproj", "{4934A491-40BC-4E5B-9166-EA1169A220F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mRemoteNGTests", "mRemoteNGTests\mRemoteNGTests.csproj", "{1453B37F-8621-499E-B0B2-6091F76DC0BB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNGTests", "mRemoteNGTests\mRemoteNGTests.csproj", "{1453B37F-8621-499E-B0B2-6091F76DC0BB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mRemoteNGInstaller", "mRemoteNGInstaller", "{4FE795BE-646E-4F1B-BAD0-A68EA26394DD}"
EndProject
@@ -13,111 +13,52 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomActions", "mRemoteNGI
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Installer", "mRemoteNGInstaller\Installer\Installer.wixproj", "{F0168B9F-6815-40DF-BA53-46CEE7683B68}"
ProjectSection(ProjectDependencies) = postProject
{4934A491-40BC-4E5B-9166-EA1169A220F6} = {4934A491-40BC-4E5B-9166-EA1169A220F6}
{5423D985-CB48-4344-B47F-E8C6D60C8B04} = {5423D985-CB48-4344-B47F-E8C6D60C8B04}
{A56A2029-79B8-492A-ABE5-D2BFE05801BD} = {A56A2029-79B8-492A-ABE5-D2BFE05801BD}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mRemoteNGSpecs", "mRemoteNGSpecs\mRemoteNGSpecs.csproj", "{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "mRemoteNGSpecs", "mRemoteNGSpecs\mRemoteNGSpecs.csproj", "{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExternalConnectors", "ExternalConnectors\ExternalConnectors.csproj", "{A56A2029-79B8-492A-ABE5-D2BFE05801BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug Portable|Any CPU = Debug Portable|Any CPU
Debug Portable|x86 = Debug Portable|x86
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release Installer|Any CPU = Release Installer|Any CPU
Release Installer|x86 = Release Installer|x86
Release Portable|Any CPU = Release Portable|Any CPU
Release Portable|x86 = Release Portable|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
Debug|x64 = Debug|x64
Release Installer and Portable|x64 = Release Installer and Portable|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug Portable|x86.Build.0 = Debug Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|Any CPU.ActiveCfg = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|Any CPU.Build.0 = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.ActiveCfg = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x86.Build.0 = Debug|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|Any CPU.Build.0 = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer|x86.Build.0 = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|Any CPU.Build.0 = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.ActiveCfg = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Portable|x86.Build.0 = Release Portable|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|Any CPU.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|Any CPU.Build.0 = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.ActiveCfg = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x86.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|Any CPU.Build.0 = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.ActiveCfg = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug Portable|x86.Build.0 = Debug Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|Any CPU.ActiveCfg = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|Any CPU.Build.0 = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.ActiveCfg = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x86.Build.0 = Debug|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|Any CPU.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer|x86.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|Any CPU.Build.0 = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.ActiveCfg = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Portable|x86.Build.0 = Release Portable|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|Any CPU.Build.0 = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.ActiveCfg = Release|x86
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x86.Build.0 = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug Portable|Any CPU.Build.0 = 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|x86.ActiveCfg = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x86.Build.0 = Debug|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|Any CPU.ActiveCfg = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer|Any CPU.Build.0 = 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 Portable|Any CPU.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.Build.0 = Release|x86
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x86.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|Any CPU.ActiveCfg = Debug Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug Portable|Any CPU.Build.0 = 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|x86.ActiveCfg = Debug|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|Any CPU.Build.0 = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer|x86.Build.0 = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|Any CPU.ActiveCfg = Release Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Portable|x86.ActiveCfg = Release Portable|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|Any CPU.ActiveCfg = Release|x86
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|x86.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|Any CPU.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|Any CPU.Build.0 = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|x86.ActiveCfg = Debug|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug Portable|x86.Build.0 = Debug|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|Any CPU.ActiveCfg = Debug|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x86.ActiveCfg = Debug|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x86.Build.0 = Debug|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|Any CPU.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|Any CPU.Build.0 = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|x86.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer|x86.Build.0 = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|Any CPU.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|Any CPU.Build.0 = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|x86.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Portable|x86.Build.0 = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|Any CPU.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x86.ActiveCfg = Release|x86
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x86.Build.0 = Release|x86
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x64.ActiveCfg = Debug|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Debug|x64.Build.0 = Debug|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release Installer and Portable|x64.Build.0 = Release|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x64.ActiveCfg = Release|x64
{4934A491-40BC-4E5B-9166-EA1169A220F6}.Release|x64.Build.0 = Release|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x64.ActiveCfg = Debug|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Debug|x64.Build.0 = Debug|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{1453B37F-8621-499E-B0B2-6091F76DC0BB}.Release|x64.ActiveCfg = Release|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x64.ActiveCfg = Debug|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Debug|x64.Build.0 = Debug|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release Installer and Portable|x64.Build.0 = Release|x64
{5423D985-CB48-4344-B47F-E8C6D60C8B04}.Release|x64.ActiveCfg = Release|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x64.ActiveCfg = Debug|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Debug|x64.Build.0 = Debug|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release Installer and Portable|x64.Build.0 = Release|x64
{F0168B9F-6815-40DF-BA53-46CEE7683B68}.Release|x64.ActiveCfg = Release|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x64.ActiveCfg = Debug|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Debug|x64.Build.0 = Debug|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{16AA21E2-D6B7-427D-AB7D-AA8C611B724E}.Release|x64.ActiveCfg = Release Installer|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|x64.ActiveCfg = Debug|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Debug|x64.Build.0 = Debug|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer and Portable|x64.ActiveCfg = Release|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release Installer and Portable|x64.Build.0 = Release|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|x64.ActiveCfg = Release|x64
{A56A2029-79B8-492A-ABE5-D2BFE05801BD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

11
mRemoteNG/App.config Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LanguageFolder" value="Language"/>
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Languages"/>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -5,12 +5,14 @@ using Microsoft.Win32;
using mRemoteNG.App.Info;
using mRemoteNG.Messages;
using mRemoteNG.Properties;
using mRemoteNG.Resources.Language;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.TaskDialog;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class CompatibilityChecker
{
public static void CheckCompatibility(MessageCollector messageCollector)
@@ -33,18 +35,13 @@ namespace mRemoteNG.App
if (!FipsPolicyEnabledForServer2003() && !FipsPolicyEnabledForServer2008AndNewer()) return;
var errorText = string.Format(Language.ErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName);
string errorText = string.Format(Language.ErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName);
messageCollector.AddMessage(MessageClass.ErrorMsg, errorText, true);
//About to pop up a message, let's not block it...
FrmSplashScreen.getInstance().Close();
FrmSplashScreenNew.GetInstance().Close();
var ShouldIStayOrShouldIGo = CTaskDialog.MessageBox(Application.ProductName,
Language.CompatibilityProblemDetected, errorText, "",
"",
Language.CheckboxDoNotShowThisMessageAgain,
ETaskDialogButtons.OkCancel, ESysIcons.Warning,
ESysIcons.Warning);
DialogResult ShouldIStayOrShouldIGo = CTaskDialog.MessageBox(Application.ProductName, Language.CompatibilityProblemDetected, errorText, "", "", Language.CheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.OkCancel, ESysIcons.Warning, ESysIcons.Warning);
if (CTaskDialog.VerificationChecked && ShouldIStayOrShouldIGo == DialogResult.OK)
{
messageCollector.AddMessage(MessageClass.ErrorMsg, "User requests that FIPS check be overridden", true);
@@ -59,7 +56,7 @@ namespace mRemoteNG.App
private static bool FipsPolicyEnabledForServer2003()
{
var regKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Lsa");
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Lsa");
if (!(regKey?.GetValue("FIPSAlgorithmPolicy") is int fipsPolicy))
return false;
return fipsPolicy != 0;
@@ -67,7 +64,7 @@ namespace mRemoteNG.App
private static bool FipsPolicyEnabledForServer2008AndNewer()
{
var regKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy");
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy");
if (!(regKey?.GetValue("Enabled") is int fipsPolicy))
return false;
return fipsPolicy != 0;
@@ -80,7 +77,7 @@ namespace mRemoteNG.App
if (!Settings.Default.CompatibilityWarnLenovoAutoScrollUtility)
return;
var proccesses = new Process[] { };
Process[] proccesses = new Process[] { };
try
{
proccesses = Process.GetProcessesByName("virtscrl");

View File

@@ -1,5 +1,6 @@
using System;
using System;
using System.Linq;
using System.Runtime.Versioning;
using System.Windows.Forms;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.DataProviders;
@@ -17,15 +18,16 @@ using mRemoteNG.UI.Forms;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class Export
{
public static void ExportToFile(ConnectionInfo selectedNode, ConnectionTreeModel connectionTreeModel)
{
try
{
var saveFilter = new SaveFilter();
SaveFilter saveFilter = new();
using (var exportForm = new FrmExport())
using (FrmExport exportForm = new())
{
if (selectedNode?.GetTreeNodeType() == TreeNodeType.Container)
exportForm.SelectedFolder = selectedNode as ContainerInfo;
@@ -79,9 +81,9 @@ namespace mRemoteNG.App
switch (saveFormat)
{
case SaveFormat.mRXML:
var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
var rootNode = exportTarget.GetRootParent() as RootNodeInfo;
var connectionNodeSerializer = new XmlConnectionNodeSerializer27(
ICryptographyProvider cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
RootNodeInfo rootNode = exportTarget.GetRootParent() as RootNodeInfo;
XmlConnectionNodeSerializer28 connectionNodeSerializer = new(
cryptographyProvider,
rootNode?.PasswordString
.ConvertToSecureString() ??
@@ -100,8 +102,8 @@ namespace mRemoteNG.App
throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null);
}
var serializedData = serializer.Serialize(exportTarget);
var fileDataProvider = new FileDataProvider(fileName);
string serializedData = serializer.Serialize(exportTarget);
FileDataProvider fileDataProvider = new(fileName);
fileDataProvider.Save(serializedData);
}
catch (Exception ex)

View File

@@ -6,24 +6,26 @@ using mRemoteNG.Config.Import;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Container;
using mRemoteNG.Resources.Language;
using mRemoteNG.Tools;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
namespace mRemoteNG.App
{
public static class Import
[SupportedOSPlatform("windows")]
public static class Import
{
public static void ImportFromFile(ContainerInfo importDestinationContainer)
{
try
{
using (var openFileDialog = new OpenFileDialog())
using (OpenFileDialog openFileDialog = new())
{
openFileDialog.CheckFileExists = true;
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
openFileDialog.Multiselect = true;
var fileTypes = new List<string>();
List<string> fileTypes = new();
fileTypes.AddRange(new[] {Language.FilterAllImportable, "*.xml;*.rdp;*.rdg;*.dat;*.csv"});
fileTypes.AddRange(new[] {Language.FiltermRemoteXML, "*.xml"});
fileTypes.AddRange(new[] {Language.FiltermRemoteCSV, "*.csv"});
@@ -31,6 +33,7 @@ namespace mRemoteNG.App
fileTypes.AddRange(new[] {Language.FilterRdgFiles, "*.rdg"});
fileTypes.AddRange(new[] {Language.FilterPuttyConnectionManager, "*.dat"});
fileTypes.AddRange(new[] {Language.FilterAll, "*.*"});
fileTypes.AddRange(new[] { Language.FilterSecureCRT, "*.crt" });
openFileDialog.Filter = string.Join("|", fileTypes.ToArray());
@@ -38,8 +41,8 @@ namespace mRemoteNG.App
return;
HeadlessFileImport(
openFileDialog.FileNames,
importDestinationContainer,
openFileDialog.FileNames,
importDestinationContainer,
Runtime.ConnectionsService,
fileName => MessageBox.Show(string.Format(Language.ImportFileFailedContent, fileName), Language.AskUpdatesMainInstruction,
MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1));
@@ -51,19 +54,50 @@ namespace mRemoteNG.App
}
}
public static void ImportFromRemoteDesktopManagerCsv(ContainerInfo importDestinationContainer)
{
try
{
using (Runtime.ConnectionsService.BatchedSavingContext())
{
using (OpenFileDialog openFileDialog = new())
{
openFileDialog.CheckFileExists = true;
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
openFileDialog.Multiselect = false;
List<string> fileTypes = new();
fileTypes.AddRange(new[] {Language.FiltermRemoteRemoteDesktopManagerCSV, "*.csv"});
openFileDialog.Filter = string.Join("|", fileTypes.ToArray());
if (openFileDialog.ShowDialog() != DialogResult.OK)
return;
RemoteDesktopManagerImporter importer = new();
importer.Import(openFileDialog.FileName, importDestinationContainer);
}
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("App.Import.ImportFromRemoteDesktopManagerCsv() failed.", ex);
}
}
public static void HeadlessFileImport(
IEnumerable<string> filePaths,
ContainerInfo importDestinationContainer,
IEnumerable<string> filePaths,
ContainerInfo importDestinationContainer,
ConnectionsService connectionsService,
Action<string> exceptionAction = null)
{
using (connectionsService.BatchedSavingContext())
{
foreach (var fileName in filePaths)
foreach (string fileName in filePaths)
{
try
{
var importer = BuildConnectionImporterFromFileExtension(fileName);
IConnectionImporter<string> importer = BuildConnectionImporterFromFileExtension(fileName);
importer.Import(fileName, importDestinationContainer);
}
catch (Exception ex)
@@ -100,7 +134,7 @@ namespace mRemoteNG.App
{
using (Runtime.ConnectionsService.BatchedSavingContext())
{
var importer = new PortScanImporter(protocol);
PortScanImporter importer = new(protocol);
importer.Import(hosts, importDestinationContainer);
}
}
@@ -110,10 +144,25 @@ namespace mRemoteNG.App
}
}
internal static void ImportFromPutty(ContainerInfo selectedNodeAsContainer)
{
try
{
using (Runtime.ConnectionsService.BatchedSavingContext())
{
RegistryImporter.Import("Software\\SimonTatham\\PuTTY\\Sessions", selectedNodeAsContainer);
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("App.Import.ImportFromPutty() failed.", ex);
}
}
private static IConnectionImporter<string> BuildConnectionImporterFromFileExtension(string fileName)
{
// TODO: Use the file contents to determine the file type instead of trusting the extension
var extension = Path.GetExtension(fileName) ?? "";
string extension = Path.GetExtension(fileName) ?? "";
switch (extension.ToLowerInvariant())
{
case ".xml":
@@ -126,6 +175,8 @@ namespace mRemoteNG.App
return new RemoteDesktopConnectionManagerImporter();
case ".dat":
return new PuttyConnectionManagerImporter();
case ".crt":
return new SecureCRTImporter();
default:
throw new FileFormatException("Unrecognized file format.");
}

View File

@@ -1,10 +1,14 @@
namespace mRemoteNG.App.Info
{
public static class ConnectionsFileInfo
{
public static readonly string DefaultConnectionsPath = SettingsFileInfo.SettingsPath;
public static readonly string DefaultConnectionsFile = "confCons.xml";
public static readonly string DefaultConnectionsFileNew = "confConsNew.xml";
public static readonly double ConnectionFileVersion = 2.8;
}
using System;
using System.Runtime.Versioning;
namespace mRemoteNG.App.Info
{
[SupportedOSPlatform("windows")]
public static class ConnectionsFileInfo
{
public static readonly string DefaultConnectionsPath = SettingsFileInfo.SettingsPath;
public static readonly string DefaultConnectionsFile = "confCons.xml";
public static readonly string DefaultConnectionsFileNew = "confConsNew.xml";
public static readonly Version ConnectionFileVersion = new(3, 0);
}
}

View File

@@ -1,5 +1,8 @@
namespace mRemoteNG.App.Info
using System.Runtime.Versioning;
namespace mRemoteNG.App.Info
{
[SupportedOSPlatform("windows")]
public class CredentialsFileInfo
{
public static readonly string CredentialsPath = SettingsFileInfo.SettingsPath;

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using System.Threading;
using System.Windows.Forms;
using static System.Environment;
@@ -9,36 +10,33 @@ using static System.Environment;
namespace mRemoteNG.App.Info
{
[SupportedOSPlatform("windows")]
public static class GeneralAppInfo
{
public const string UrlHome = "https://www.mremoteng.org";
public const string UrlHome = "https://mremoteng.org";
public const string UrlDonate = "https://mremoteng.org/contribute";
public const string UrlForum = "https://www.reddit.com/r/mRemoteNG";
public const string UrlBugs = "https://bugs.mremoteng.org";
public static string ApplicationVersion = Application.ProductVersion;
public const string UrlDocumentation = "https://mremoteng.readthedocs.io/en/latest/";
public static readonly string ApplicationVersion = Application.ProductVersion;
public static readonly string ProductName = Application.ProductName;
public static readonly string Copyright =
((AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
typeof(AssemblyCopyrightAttribute), false))
.Copyright;
public static readonly string Copyright = ((AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCopyrightAttribute), false))?.Copyright;
public static readonly string HomePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
//public static string ReportingFilePath = "";
public static readonly string PuttyPath = HomePath + "\\PuTTYNG.exe";
private static readonly string puttyPath = HomePath + "\\PuTTYNG.exe";
public static string UserAgent
{
get
{
var details = new List<string>
{
List<string> details =
[
"compatible",
OSVersion.Platform == PlatformID.Win32NT
? $"Windows NT {OSVersion.Version.Major}.{OSVersion.Version.Minor}"
: OSVersion.VersionString
};
];
if (Is64BitProcess)
{
details.Add("WOW64");
@@ -46,15 +44,17 @@ namespace mRemoteNG.App.Info
details.Add(Thread.CurrentThread.CurrentUICulture.Name);
details.Add($".NET CLR {Environment.Version}");
var detailsString = string.Join("; ", details.ToArray());
string detailsString = string.Join("; ", [.. details]);
return $"Mozilla/5.0 ({detailsString}) {ProductName}/{ApplicationVersion}";
}
}
public static string PuttyPath => puttyPath;
public static Version GetApplicationVersion()
{
System.Version.TryParse(ApplicationVersion, out var v);
_ = System.Version.TryParse(ApplicationVersion, out Version v);
return v;
}
}

View File

@@ -1,24 +1,23 @@
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using System.Windows.Forms;
using mRemoteNG.Connection;
namespace mRemoteNG.App.Info
{
[SupportedOSPlatform("windows")]
public static class SettingsFileInfo
{
private static readonly string ExePath =
Path.GetDirectoryName(Assembly.GetAssembly(typeof(ConnectionInfo))?.Location);
private static readonly string ExePath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(ConnectionInfo))?.Location);
public static string SettingsPath =>
Runtime.IsPortableEdition
? ExePath
: Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Application.ProductName;
public static string SettingsPath => Runtime.IsPortableEdition ? ExePath : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Application.ProductName;
public static string LayoutFileName { get; } = "pnlLayout.xml";
public static string ExtAppsFilesName { get; } = "extApps.xml";
public static string ThemesFileName { get; } = "Themes.xml";
public static string LocalConnectionProperties { get; } = "LocalConnectionProperties.xml";
public static string ThemeFolder { get; } =
SettingsPath != null ? Path.Combine(SettingsPath, "Themes") : String.Empty;

View File

@@ -1,29 +1,30 @@
using System;
using System.Runtime.Versioning;
using mRemoteNG.Properties;
// ReSharper disable InconsistentNaming
namespace mRemoteNG.App.Info
{
[SupportedOSPlatform("windows")]
public static class UpdateChannelInfo
{
public const string STABLE = "Stable";
public const string BETA = "Beta";
public const string DEV = "Development";
public const string PREVIEW = "Preview";
public const string NIGHTLY = "Nightly";
/* no #if here since they are used for unit tests as well */
public const string STABLE_PORTABLE = "update-portable.txt";
public const string BETA_PORTABLE = "beta-update-portable.txt";
public const string DEV_PORTABLE = "dev-update-portable.txt";
public const string PREVIEW_PORTABLE = "preview-update-portable.txt";
public const string NIGHTLY_PORTABLE = "nightly-update-portable.txt";
public const string STABLE_MSI = "update.txt";
public const string BETA_MSI = "beta-update.txt";
public const string DEV_MSI = "dev-update.txt";
public const string PREVIEW_MSI = "preview-update.txt";
public const string NIGHTLY_MSI = "nightly-update.txt";
public static Uri GetUpdateChannelInfo()
{
var channel = IsValidChannel(Settings.Default.UpdateChannel) ? Settings.Default.UpdateChannel : STABLE;
string channel = IsValidChannel(Properties.OptionsUpdatesPage.Default.UpdateChannel) ? Properties.OptionsUpdatesPage.Default.UpdateChannel : STABLE;
return GetUpdateTxtUri(channel);
}
@@ -40,10 +41,10 @@ namespace mRemoteNG.App.Info
{
case STABLE:
return STABLE_MSI;
case BETA:
return BETA_MSI;
case DEV:
return DEV_MSI;
case PREVIEW:
return PREVIEW_MSI;
case NIGHTLY:
return NIGHTLY_MSI;
default:
return STABLE_MSI;
}
@@ -55,10 +56,10 @@ namespace mRemoteNG.App.Info
{
case STABLE:
return STABLE_PORTABLE;
case BETA:
return BETA_PORTABLE;
case DEV:
return DEV_PORTABLE;
case PREVIEW:
return PREVIEW_PORTABLE;
case NIGHTLY:
return NIGHTLY_PORTABLE;
default:
return STABLE_PORTABLE;
}
@@ -66,13 +67,13 @@ namespace mRemoteNG.App.Info
private static Uri GetUpdateTxtUri(string channel)
{
return new Uri(new Uri(Settings.Default.UpdateAddress),
return new Uri(new Uri(Properties.OptionsUpdatesPage.Default.UpdateAddress),
new Uri(GetChannelFileName(channel), UriKind.Relative));
}
private static bool IsValidChannel(string s)
{
return s.Equals(STABLE) || s.Equals(BETA) || s.Equals(DEV);
return s.Equals(STABLE) || s.Equals(PREVIEW) || s.Equals(NIGHTLY);
}
}
}

View File

@@ -0,0 +1,87 @@
using Microsoft.Win32;
using System.Runtime.Versioning;
namespace mRemoteNG.App.Info
{
[SupportedOSPlatform("windows")]
public static class WindowsRegistryInfo
{
#region General Parameters
public const RegistryHive Hive = RegistryHive.LocalMachine;
public const string RootKey = "SOFTWARE\\mRemoteNG";
private const string OptionsSubKey = "Options";
#endregion
#region Key Locations
// StartupExit
// Registry subkey for general application startup and exit settings
// Registry subkey for startup and exit options page settings
public const string StartupExit = RootKey + "\\StartupExit";
public const string StartupExitOptions = StartupExit + "\\" + OptionsSubKey;
// Appearance
// Registry subkey for general application appearance settings
// Registry subkey for appearance options page settings
public const string Appearance = RootKey + "\\Appearance";
public const string AppearanceOptions = Appearance + "\\" + OptionsSubKey;
// Connections
// Registry subkey for general application connection settings
// Registry subkey for connections options page settings
public const string Connection = RootKey + "\\Connections";
public const string ConnectionOptions = Connection + "\\" + OptionsSubKey;
// Tabs & Panels
// Registry subkey for general application tabs and panels settings
// Registry subkey for tabs and panels options page settings
public const string TabsAndPanels = RootKey + "\\TabsAndPanels";
public const string TabsAndPanelsOptions = TabsAndPanels + "\\" + OptionsSubKey;
// Notifications
// Registry subkey for general application notifications settings
// Registry subkey for notifications options page settings
public const string Notification = RootKey + "\\Notifications";
public const string NotificationOptions = Notification + "\\" + OptionsSubKey;
// Credential
// Registry subkey for general application credentials settings
// Registry subkey for credentials options page settings
public const string Credential = RootKey + "\\Credentials";
public const string CredentialOptions = Credential + "\\" + OptionsSubKey;
// SQL Server
// Registry subkey for general application SQL server settings
// Registry subkey for SQL server options page settings
public const string SQLServer = RootKey + "\\SQLServer";
public const string SQLServerOptions = SQLServer + "\\" + OptionsSubKey;
// Updates
// Registry subkey for general application update settings
// Registry subkey for updates options page settings
public const string Update = RootKey + "\\Updates";
public const string UpdateOptions = Update + "\\" + OptionsSubKey;
// Security
// Registry subkey for general application security settings
// Registry subkey for security options page settings
public const string Security = RootKey + "\\Security";
public const string SecurityOptions = Security + "\\" + OptionsSubKey;
// Advanced
// Registry subkey for general application advanced settings
// Registry subkey for advanced options page settings
public const string Advanced = RootKey + "\\Advanced";
public const string AdvancedOptions = Advanced + "\\" + OptionsSubKey;
// Backup
// Registry subkey for general application backup settings
// Registry subkey for backup options page settings
public const string Backup = RootKey + "\\Backup";
public const string BackupOptions = Backup + "\\" + OptionsSubKey;
#endregion
}
}

View File

@@ -1,10 +1,12 @@
using System;
using System.IO;
using System.Runtime.Versioning;
using mRemoteNG.Connection;
namespace mRemoteNG.App.Initialization
{
[SupportedOSPlatform("windows")]
public class ConnectionIconLoader
{
private readonly string _path;
@@ -22,9 +24,9 @@ namespace mRemoteNG.App.Initialization
if (Directory.Exists(_path) == false)
return;
foreach (var f in Directory.GetFiles(_path, "*.ico", SearchOption.AllDirectories))
foreach (string f in Directory.GetFiles(_path, "*.ico", SearchOption.AllDirectories))
{
var fInfo = new FileInfo(f);
FileInfo fInfo = new(f);
Array.Resize(ref ConnectionIcon.Icons, ConnectionIcon.Icons.Length + 1);
ConnectionIcon.Icons.SetValue(fInfo.Name.Replace(".ico", ""), ConnectionIcon.Icons.Length - 1);
}

View File

@@ -1,19 +1,19 @@
using System.IO;
using System.Runtime.Versioning;
using mRemoteNG.Config.Connections;
using mRemoteNG.Properties;
namespace mRemoteNG.App.Initialization
{
[SupportedOSPlatform("windows")]
public class CredsAndConsSetup
{
public void LoadCredsAndCons()
{
new SaveConnectionsOnEdit(Runtime.ConnectionsService);
if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation &&
!File.Exists(Runtime.ConnectionsService.GetStartupConnectionFileName()))
Runtime.ConnectionsService.NewConnectionsFile(Runtime.ConnectionsService
.GetStartupConnectionFileName());
if (Properties.App.Default.FirstStart && !Properties.OptionsBackupPage.Default.LoadConsFromCustomLocation && !File.Exists(Runtime.ConnectionsService.GetStartupConnectionFileName()))
Runtime.ConnectionsService.NewConnectionsFile(Runtime.ConnectionsService.GetStartupConnectionFileName());
Runtime.LoadConnections();
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Versioning;
using mRemoteNG.Messages;
using mRemoteNG.Messages.MessageFilteringOptions;
using mRemoteNG.Messages.MessageWriters;
@@ -7,17 +8,24 @@ using mRemoteNG.Messages.WriterDecorators;
namespace mRemoteNG.App.Initialization
{
[SupportedOSPlatform("windows")]
public class MessageCollectorSetup
{
public static void SetupMessageCollector(MessageCollector messageCollector,
IList<IMessageWriter> messageWriterList)
public static void SetupMessageCollector(MessageCollector messageCollector, IList<IMessageWriter> messageWriterList)
{
messageCollector.CollectionChanged += (o, args) =>
{
var messages = args.NewItems.Cast<IMessage>().ToArray();
foreach (var printer in messageWriterList)
foreach (var message in messages)
if (args.NewItems == null) return;
IMessage[] messages = args.NewItems.Cast<IMessage>().ToArray();
foreach (IMessageWriter printer in messageWriterList)
{
foreach (IMessage message in messages)
{
printer.Write(message);
}
}
};
}
@@ -39,37 +47,30 @@ namespace mRemoteNG.App.Initialization
private static IMessageWriter BuildTextLogMessageWriter()
{
return new MessageTypeFilterDecorator(
new LogMessageTypeFilteringOptions(),
new TextLogMessageWriter(Logger.Instance)
);
new LogMessageTypeFilteringOptions(),
new TextLogMessageWriter(Logger.Instance)
);
}
private static IMessageWriter BuildNotificationPanelMessageWriter()
{
return new OnlyLogMessageFilter(
new MessageTypeFilterDecorator(
new
NotificationPanelMessageFilteringOptions(),
new MessageFocusDecorator(
Windows.ErrorsForm,
new
NotificationPanelSwitchOnMessageFilteringOptions(),
new
NotificationPanelMessageWriter(Windows
.ErrorsForm)
)
)
);
new MessageTypeFilterDecorator(
new NotificationPanelMessageFilteringOptions(),
new MessageFocusDecorator(Windows.ErrorsForm,
new NotificationPanelSwitchOnMessageFilteringOptions(),
new NotificationPanelMessageWriter(Windows.ErrorsForm))
)
);
}
private static IMessageWriter BuildPopupMessageWriter()
{
return new OnlyLogMessageFilter(
new MessageTypeFilterDecorator(
new PopupMessageFilteringOptions(),
new PopupMessageWriter()
)
);
new MessageTypeFilterDecorator(
new PopupMessageFilteringOptions(),
new PopupMessageWriter())
);
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Management;
using System.Runtime.Versioning;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.Messages;
@@ -7,16 +8,14 @@ using mRemoteNG.Resources.Language;
namespace mRemoteNG.App.Initialization
{
[SupportedOSPlatform("windows")]
public class StartupDataLogger
{
private readonly MessageCollector _messageCollector;
public StartupDataLogger(MessageCollector messageCollector)
{
if (messageCollector == null)
throw new ArgumentNullException(nameof(messageCollector));
_messageCollector = messageCollector;
_messageCollector = messageCollector ?? throw new ArgumentNullException(nameof(messageCollector));
}
public void LogStartupData()
@@ -30,25 +29,25 @@ namespace mRemoteNG.App.Initialization
private void LogSystemData()
{
var osData = GetOperatingSystemData();
var architecture = GetArchitectureData();
var nonEmptyData = Array.FindAll(new[] {osData, architecture}, s => !string.IsNullOrEmpty(s));
var data = string.Join(" ", nonEmptyData);
string osData = GetOperatingSystemData();
string architecture = GetArchitectureData();
string[] nonEmptyData = Array.FindAll(new[] {osData, architecture}, s => !string.IsNullOrEmpty(s));
string data = string.Join(" ", nonEmptyData);
_messageCollector.AddMessage(MessageClass.InformationMsg, data, true);
}
private string GetOperatingSystemData()
{
var osVersion = string.Empty;
var servicePack = string.Empty;
string osVersion = string.Empty;
string servicePack = string.Empty;
try
{
foreach (var o in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem WHERE Primary=True")
foreach (ManagementBaseObject o in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem WHERE Primary=True")
.Get())
{
var managementObject = (ManagementObject)o;
osVersion = Convert.ToString(managementObject.GetPropertyValue("Caption")).Trim();
ManagementObject managementObject = (ManagementObject)o;
osVersion = Convert.ToString(managementObject.GetPropertyValue("Caption"))?.Trim();
servicePack = GetOSServicePack(servicePack, managementObject);
}
}
@@ -57,13 +56,13 @@ namespace mRemoteNG.App.Initialization
_messageCollector.AddExceptionMessage("Error retrieving operating system information from WMI.", ex);
}
var osData = string.Join(" ", osVersion, servicePack);
string osData = string.Join(" ", osVersion, servicePack);
return osData;
}
private string GetOSServicePack(string servicePack, ManagementObject managementObject)
{
var servicePackNumber = Convert.ToInt32(managementObject.GetPropertyValue("ServicePackMajorVersion"));
int servicePackNumber = Convert.ToInt32(managementObject.GetPropertyValue("ServicePackMajorVersion"));
if (servicePackNumber != 0)
{
servicePack = $"Service Pack {servicePackNumber}";
@@ -74,14 +73,13 @@ namespace mRemoteNG.App.Initialization
private string GetArchitectureData()
{
var architecture = string.Empty;
string architecture = string.Empty;
try
{
foreach (var o in new ManagementObjectSearcher("SELECT AddressWidth FROM Win32_Processor WHERE DeviceID=\'CPU0\'")
.Get())
foreach (ManagementBaseObject o in new ManagementObjectSearcher("SELECT AddressWidth FROM Win32_Processor WHERE DeviceID=\'CPU0\'").Get())
{
var managementObject = (ManagementObject)o;
var addressWidth = Convert.ToInt32(managementObject.GetPropertyValue("AddressWidth"));
ManagementObject managementObject = (ManagementObject)o;
int addressWidth = Convert.ToInt32(managementObject.GetPropertyValue("AddressWidth"));
architecture = $"{addressWidth}-bit";
}
}
@@ -95,7 +93,7 @@ namespace mRemoteNG.App.Initialization
private void LogApplicationData()
{
var data = $"{Application.ProductName} {Application.ProductVersion}";
string data = $"{Application.ProductName} {Application.ProductVersion}";
if (Runtime.IsPortableEdition)
data += $" {Language.PortableEdition}";
data += " starting.";
@@ -104,20 +102,19 @@ namespace mRemoteNG.App.Initialization
private void LogCmdLineArgs()
{
var data = $"Command Line: {string.Join(" ", Environment.GetCommandLineArgs())}";
string data = $"Command Line: {string.Join(" ", Environment.GetCommandLineArgs())}";
_messageCollector.AddMessage(MessageClass.InformationMsg, data, true);
}
private void LogClrData()
{
var data = $"Microsoft .NET CLR {Environment.Version}";
string data = $"Microsoft .NET CLR {Environment.Version}";
_messageCollector.AddMessage(MessageClass.InformationMsg, data, true);
}
private void LogCultureData()
{
var data =
$"System Culture: {Thread.CurrentThread.CurrentUICulture.Name}/{Thread.CurrentThread.CurrentUICulture.NativeName}";
string data = $"System Culture: {Thread.CurrentThread.CurrentUICulture.Name}/{Thread.CurrentThread.CurrentUICulture.NativeName}";
_messageCollector.AddMessage(MessageClass.InformationMsg, data, true);
}
}

View File

@@ -1,18 +1,18 @@
using System;
using System;
using System.IO;
using System.Runtime.Versioning;
using System.Windows.Forms;
using log4net;
using log4net.Appender;
using log4net.Config;
using mRemoteNG.Properties;
// ReSharper disable ArrangeAccessorOwnerBody
using log4net.Repository;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public class Logger
{
public static readonly Logger Instance = new Logger();
public static readonly Logger Instance = new();
public ILog Log { get; private set; }
@@ -26,21 +26,27 @@ namespace mRemoteNG.App
private void Initialize()
{
XmlConfigurator.Configure(LogManager.CreateRepository("mRemoteNG"));
if (string.IsNullOrEmpty(Settings.Default.LogFilePath))
Settings.Default.LogFilePath = BuildLogFilePath();
SetLogPath(Settings.Default.LogToApplicationDirectory ? DefaultLogPath : Settings.Default.LogFilePath);
if (string.IsNullOrEmpty(Properties.OptionsNotificationsPage.Default.LogFilePath))
{
Properties.OptionsNotificationsPage.Default.LogFilePath = BuildLogFilePath();
}
SetLogPath(Properties.OptionsNotificationsPage.Default.LogToApplicationDirectory ? DefaultLogPath : Properties.OptionsNotificationsPage.Default.LogFilePath);
}
public void SetLogPath(string path)
{
var repository = LogManager.GetRepository("mRemoteNG");
var appenders = repository.GetAppenders();
ILoggerRepository repository = LogManager.GetRepository("mRemoteNG");
foreach (var appender in appenders)
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
IAppender[] appenders = repository.GetAppenders();
foreach (IAppender appender in appenders)
{
var fileAppender = (RollingFileAppender)appender;
if (fileAppender == null || fileAppender.Name != "LogFileAppender") continue;
RollingFileAppender fileAppender = (RollingFileAppender)appender;
if (fileAppender is not { Name: "LogFileAppender" }) continue;
fileAppender.File = path;
fileAppender.ActivateOptions();
}
@@ -50,22 +56,26 @@ namespace mRemoteNG.App
private static string BuildLogFilePath()
{
var logFilePath = Runtime.IsPortableEdition ? GetLogPathPortableEdition() : GetLogPathNormalEdition();
var logFileName = Path.ChangeExtension(Application.ProductName, ".log");
string logFilePath = Runtime.IsPortableEdition ? GetLogPathPortableEdition() : GetLogPathNormalEdition();
string logFileName = Path.ChangeExtension(Application.ProductName, ".log");
if (logFileName == null) return "mRemoteNG.log";
var logFile = Path.Combine(logFilePath, logFileName);
string logFile = Path.Combine(logFilePath, logFileName);
return logFile;
}
private static string GetLogPathNormalEdition()
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
Application.ProductName);
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Application.ProductName);
}
private static string GetLogPathPortableEdition()
{
return Application.StartupPath;
}
}
}

View File

@@ -1,7 +1,8 @@
using System;
using System;
using System.Drawing;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
#pragma warning disable 649
@@ -9,6 +10,7 @@ using System.Text;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class NativeMethods
{
#region Functions
@@ -71,6 +73,12 @@ namespace mRemoteNG.App
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool ChangeClipboardChain(
IntPtr hWndRemove, // handle to window to remove
IntPtr hWndNewNext // handle to next window
);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool SetForegroundWindow(IntPtr hWnd);
@@ -106,7 +114,6 @@ namespace mRemoteNG.App
internal static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("kernel32", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static extern bool CloseHandle(IntPtr handle);
#endregion

View File

@@ -1,15 +1,22 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.Properties;
using mRemoteNG.Config.Settings;
using mRemoteNG.UI.Forms;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class ProgramRoot
{
private static Mutex _mutex;
private static FrmSplashScreenNew _frmSplashScreen = null;
private static string customResourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Languages");
/// <summary>
/// The main entry point for the application.
@@ -17,19 +24,79 @@ namespace mRemoteNG.App
[STAThread]
public static void Main(string[] args)
{
if (Settings.Default.SingleInstance)
Trace.WriteLine("!!!!!!=============== TEST ==================!!!!!!!!!!!!!");
// Forcing to load System.Configuration.ConfigurationManager before any other assembly to be able to check settings
try
{
string assemblyFile = "System.Configuration.ConfigurationManager" + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
if (File.Exists(assemblyPath))
{
Assembly.LoadFrom(assemblyPath);
}
}
catch (FileNotFoundException ex)
{
Trace.WriteLine("Error occured: " + ex.Message);
}
//Subscribe to AssemblyResolve event
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
//Check if local settings DB exist or accessible
CheckLockalDB();
Lazy<bool> singleInstanceOption = new Lazy<bool>(() => Properties.OptionsStartupExitPage.Default.SingleInstance);
if (singleInstanceOption.Value)
{
StartApplicationAsSingleInstance();
}
else
{
StartApplication();
}
}
private static void CheckLockalDB()
{
LocalSettingsDBManager settingsManager = new LocalSettingsDBManager(dbPath: "mRemoteNG.appSettings", useEncryption: false, schemaFilePath: "");
}
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs resolveArgs)
{
string assemblyName = new AssemblyName(resolveArgs.Name).Name.Replace(".resources", string.Empty);
string assemblyFile = assemblyName + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
return null;
}
private static void StartApplication()
{
CatchAllUnhandledExceptions();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var frmSplashScreen = FrmSplashScreen.getInstance();
frmSplashScreen.Show();
_frmSplashScreen = FrmSplashScreenNew.GetInstance();
Screen targetScreen = Screen.PrimaryScreen;
Rectangle viewport = targetScreen.WorkingArea;
_frmSplashScreen.Top = viewport.Top;
_frmSplashScreen.Left = viewport.Left;
// normally it should be screens[1] however due DPI apply 1 size "same" as default with 100%
_frmSplashScreen.Left = viewport.Left + (targetScreen.Bounds.Size.Width - _frmSplashScreen.Width) / 2;
_frmSplashScreen.Top = viewport.Top + (targetScreen.Bounds.Size.Height - _frmSplashScreen.Height) / 2;
_frmSplashScreen.ShowInTaskbar = false;
_frmSplashScreen.Show();
Application.Run(FrmMain.Default);
}
@@ -41,7 +108,7 @@ namespace mRemoteNG.App
private static void StartApplicationAsSingleInstance()
{
const string mutexID = "mRemoteNG_SingleInstanceMutex";
_mutex = new Mutex(false, mutexID, out var newInstanceCreated);
_mutex = new Mutex(false, mutexID, out bool newInstanceCreated);
if (!newInstanceCreated)
{
SwitchToCurrentInstance();
@@ -54,18 +121,18 @@ namespace mRemoteNG.App
private static void SwitchToCurrentInstance()
{
var singletonInstanceWindowHandle = GetRunningSingletonInstanceWindowHandle();
IntPtr singletonInstanceWindowHandle = GetRunningSingletonInstanceWindowHandle();
if (singletonInstanceWindowHandle == IntPtr.Zero) return;
if (NativeMethods.IsIconic(singletonInstanceWindowHandle) != 0)
NativeMethods.ShowWindow(singletonInstanceWindowHandle, (int)NativeMethods.SW_RESTORE);
_ = NativeMethods.ShowWindow(singletonInstanceWindowHandle, (int)NativeMethods.SW_RESTORE);
NativeMethods.SetForegroundWindow(singletonInstanceWindowHandle);
}
private static IntPtr GetRunningSingletonInstanceWindowHandle()
{
var windowHandle = IntPtr.Zero;
var currentProcess = Process.GetCurrentProcess();
foreach (var enumeratedProcess in Process.GetProcessesByName(currentProcess.ProcessName))
IntPtr windowHandle = IntPtr.Zero;
Process currentProcess = Process.GetCurrentProcess();
foreach (Process enumeratedProcess in Process.GetProcessesByName(currentProcess.ProcessName))
{
if (enumeratedProcess.Id != currentProcess.Id &&
enumeratedProcess.MainModule.FileName == currentProcess.MainModule.FileName &&
@@ -78,30 +145,31 @@ namespace mRemoteNG.App
private static void CatchAllUnhandledExceptions()
{
Application.ThreadException += ApplicationOnThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
System.Windows.Forms.Application.ThreadException += ApplicationOnThreadException;
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
}
private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e)
{
if (!FrmSplashScreen.getInstance().IsDisposed)
FrmSplashScreen.getInstance().Close();
// if (PresentationSource.FromVisual(FrmSplashScreenNew))
FrmSplashScreenNew.GetInstance().Close();
if (FrmMain.Default.IsDisposed) return;
var window = new FrmUnhandledException(e.Exception, false);
FrmUnhandledException window = new(e.Exception, false);
window.ShowDialog(FrmMain.Default);
}
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (!FrmSplashScreen.getInstance().IsDisposed)
FrmSplashScreen.getInstance().Close();
//TODO: Check if splash closed properly
//if (!FrmSplashScreenNew.GetInstance().IsDisposed)
// FrmSplashScreenNew.GetInstance().Close();
var window = new FrmUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
FrmUnhandledException window = new(e.ExceptionObject as Exception, e.IsTerminating);
window.ShowDialog(FrmMain.Default);
}
}
}

View File

@@ -17,9 +17,11 @@ using System.Threading;
using System.Windows.Forms;
using mRemoteNG.Properties;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class Runtime
{
public static bool IsPortableEdition
@@ -44,19 +46,19 @@ namespace mRemoteNG.App
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 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);
public static ConnectionInitiator ConnectionInitiator { get; set; } = new ConnectionInitiator();
public static ConnectionsService ConnectionsService { get; } = new ConnectionsService(PuttySessionsManager.Instance);
#region Connections Loading/Saving
public static void LoadConnectionsAsync()
{
var t = new Thread(LoadConnectionsBGd);
Thread t = new(LoadConnectionsBGd);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
@@ -75,7 +77,7 @@ namespace mRemoteNG.App
/// </param>
public static void LoadConnections(bool withDialog = false)
{
var connectionFileName = "";
string connectionFileName = "";
try
{
@@ -84,24 +86,28 @@ namespace mRemoteNG.App
if (withDialog)
{
var loadDialog = DialogFactory.BuildLoadConnectionsDialog();
OpenFileDialog loadDialog = DialogFactory.BuildLoadConnectionsDialog();
if (loadDialog.ShowDialog() != DialogResult.OK)
return;
connectionFileName = loadDialog.FileName;
Settings.Default.UseSQLServer = false;
Settings.Default.Save();
Properties.OptionsDBsPage.Default.UseSQLServer = false;
Properties.OptionsDBsPage.Default.Save();
}
else if (!Settings.Default.UseSQLServer)
else if (!Properties.OptionsDBsPage.Default.UseSQLServer)
{
connectionFileName = ConnectionsService.GetStartupConnectionFileName();
}
ConnectionsService.LoadConnections(Settings.Default.UseSQLServer, false, connectionFileName);
ConnectionsService.LoadConnections(Properties.OptionsDBsPage.Default.UseSQLServer, false, connectionFileName);
if (Settings.Default.UseSQLServer)
if (Properties.OptionsDBsPage.Default.UseSQLServer)
{
ConnectionsService.LastSqlUpdate = DateTime.Now;
ConnectionsService.LastSqlUpdate = DateTime.Now.ToUniversalTime();
}
else
{
ConnectionsService.LastFileUpdate = System.IO.File.GetLastWriteTime(connectionFileName);
}
// re-enable sql update checking after updates are loaded
@@ -109,26 +115,20 @@ namespace mRemoteNG.App
}
catch (Exception ex)
{
FrmSplashScreen.getInstance().Close();
FrmSplashScreenNew.GetInstance().Close();
if (Settings.Default.UseSQLServer)
if (Properties.OptionsDBsPage.Default.UseSQLServer)
{
MessageCollector.AddExceptionMessage(Language.LoadFromSqlFailed, ex);
var commandButtons = string.Join("|", Language._TryAgain,
Language.CommandOpenConnectionFile,
string.Format(Language.CommandExitProgram,
Application.ProductName));
CTaskDialog.ShowCommandBox(Application.ProductName, Language.LoadFromSqlFailed,
Language.LoadFromSqlFailedContent,
MiscTools.GetExceptionMessageRecursive(ex), "", "",
commandButtons, false, ESysIcons.Error, ESysIcons.Error);
string commandButtons = string.Join("|", Language._TryAgain, Language.CommandOpenConnectionFile, string.Format(Language.CommandExitProgram, Application.ProductName));
CTaskDialog.ShowCommandBox(Application.ProductName, Language.LoadFromSqlFailed, Language.LoadFromSqlFailedContent, MiscTools.GetExceptionMessageRecursive(ex), "", "", commandButtons, false, ESysIcons.Error, ESysIcons.Error);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
LoadConnections(withDialog);
return;
case 1:
Settings.Default.UseSQLServer = false;
Properties.OptionsDBsPage.Default.UseSQLServer = false;
LoadConnections(true);
return;
default:
@@ -152,19 +152,12 @@ namespace mRemoteNG.App
Language.Exit
};
var answered = false;
bool answered = false;
while (!answered)
{
try
{
CTaskDialog.ShowTaskDialogBox(
GeneralAppInfo.ProductName,
Language.ConnectionFileNotFound,
"", "", "", "", "",
string.Join(" | ", commandButtons),
ETaskDialogButtons.None,
ESysIcons.Question,
ESysIcons.Question);
CTaskDialog.ShowTaskDialogBox(GeneralAppInfo.ProductName, Language.ConnectionFileNotFound, "", "", "", "", "", string.Join(" | ", commandButtons), ETaskDialogButtons.None, ESysIcons.Question, ESysIcons.Question);
switch (CTaskDialog.CommandButtonResult)
{
@@ -189,11 +182,7 @@ namespace mRemoteNG.App
}
catch (Exception exc)
{
MessageCollector.AddExceptionMessage(
string
.Format(Language.ConnectionsFileCouldNotBeLoadedNew,
connectionFileName), exc,
MessageClass.InformationMsg);
MessageCollector.AddExceptionMessage(string.Format(Language.ConnectionsFileCouldNotBeLoadedNew, connectionFileName), exc, MessageClass.InformationMsg);
}
}
@@ -209,12 +198,7 @@ namespace mRemoteNG.App
}
else
{
MessageBox.Show(FrmMain.Default,
string.Format(Language.ErrorStartupConnectionFileLoad, Environment.NewLine,
Application.ProductName,
ConnectionsService.GetStartupConnectionFileName(),
MiscTools.GetExceptionMessageRecursive(ex)),
@"Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(FrmMain.Default, string.Format(Language.ErrorStartupConnectionFileLoad, Environment.NewLine, Application.ProductName, ConnectionsService.GetStartupConnectionFileName(), MiscTools.GetExceptionMessageRecursive(ex)), @"Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}

View File

@@ -1,4 +1,5 @@
using System.Windows.Forms;
using System.Runtime.Versioning;
using System.Windows.Forms;
using mRemoteNG.UI.Forms;
using WeifenLuo.WinFormsUI.Docking;
@@ -6,10 +7,11 @@ namespace mRemoteNG.App
{
public static class Screens
{
[SupportedOSPlatform("windows")]
public static void SendFormToScreen(Screen screen)
{
var frmMain = FrmMain.Default;
var wasMax = false;
FrmMain frmMain = FrmMain.Default;
bool wasMax = false;
if (frmMain.WindowState == FormWindowState.Maximized)
{

View File

@@ -2,16 +2,19 @@
using System;
using System.Diagnostics;
using System.Windows.Forms;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.Putty;
using mRemoteNG.Properties;
using mRemoteNG.Resources.Language;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Forms;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class Shutdown
{
private static string _updateFilePath;
@@ -60,8 +63,33 @@ namespace mRemoteNG.App
private static void SaveConnections()
{
if (Settings.Default.SaveConsOnExit)
DateTime lastUpdate;
DateTime updateDate;
DateTime currentDate = DateTime.Now;
if ((Properties.OptionsBackupPage.Default.SaveConnectionsFrequency == (int)ConnectionsBackupFrequencyEnum.OnExit))
{
Runtime.ConnectionsService.SaveConnections();
return;
}
lastUpdate = Runtime.ConnectionsService.UsingDatabase ? Runtime.ConnectionsService.LastSqlUpdate : Runtime.ConnectionsService.LastFileUpdate;
switch (Properties.OptionsBackupPage.Default.SaveConnectionsFrequency)
{
case (int)ConnectionsBackupFrequencyEnum.Daily:
updateDate = lastUpdate.AddDays(1);
break;
case (int)ConnectionsBackupFrequencyEnum.Weekly:
updateDate = lastUpdate.AddDays(7);
break;
default:
return;
}
if (currentDate >= updateDate)
{
Runtime.ConnectionsService.SaveConnections();
}
}
private static void SaveSettings(Control quickConnectToolStrip,
@@ -93,7 +121,7 @@ namespace mRemoteNG.App
private static void RunUpdateFile()
{
if (UpdatePending)
Process.Start(_updateFilePath);
Process.Start(new ProcessStartInfo(_updateFilePath) { UseShellExecute = true });
}
}
}

View File

@@ -1,11 +1,13 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using mRemoteNG.App.Info;
using mRemoteNG.App.Initialization;
using mRemoteNG.App.Update;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.Settings.Registry;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Properties;
@@ -17,8 +19,10 @@ using mRemoteNG.UI.Forms;
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public class Startup
{
private RegistryLoader _RegistryLoader;
private AppUpdater _appUpdate;
private readonly ConnectionIconLoader _connectionIconLoader;
private readonly FrmMain _frmMain = FrmMain.Default;
@@ -27,19 +31,15 @@ namespace mRemoteNG.App
private Startup()
{
_appUpdate = new AppUpdater();
_RegistryLoader = RegistryLoader.Instance; //created instance
_appUpdate = new AppUpdater();
_connectionIconLoader = new ConnectionIconLoader(GeneralAppInfo.HomePath + "\\Icons\\");
}
static Startup()
{
}
public void InitializeProgram(MessageCollector messageCollector)
{
Debug.Print("---------------------------" + Environment.NewLine + "[START] - " +
Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture));
var startupLogger = new StartupDataLogger(messageCollector);
Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture));
StartupDataLogger startupLogger = new(messageCollector);
startupLogger.LogStartupData();
CompatibilityChecker.CheckCompatibility(messageCollector);
ParseCommandLineArgs(messageCollector);
@@ -51,21 +51,20 @@ namespace mRemoteNG.App
private static void ParseCommandLineArgs(MessageCollector messageCollector)
{
var interpreter = new StartupArgumentsInterpreter(messageCollector);
StartupArgumentsInterpreter interpreter = new(messageCollector);
interpreter.ParseArguments(Environment.GetCommandLineArgs());
}
public void CreateConnectionsProvider(MessageCollector messageCollector)
{
messageCollector.AddMessage(MessageClass.DebugMsg, "Determining if we need a database syncronizer");
if (!Settings.Default.UseSQLServer) return;
if (!Properties.OptionsDBsPage.Default.UseSQLServer) return;
messageCollector.AddMessage(MessageClass.DebugMsg, "Creating database syncronizer");
Runtime.ConnectionsService.RemoteConnectionsSyncronizer =
new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker());
Runtime.ConnectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker());
Runtime.ConnectionsService.RemoteConnectionsSyncronizer.Enable();
}
public void CheckForUpdate()
public async Task CheckForUpdate()
{
if (_appUpdate == null)
{
@@ -76,43 +75,15 @@ namespace mRemoteNG.App
return;
}
var nextUpdateCheck =
Convert.ToDateTime(Settings.Default.CheckForUpdatesLastCheck.Add(
TimeSpan
.FromDays(Convert.ToDouble(Settings
.Default
.CheckForUpdatesFrequencyDays))));
if (!Settings.Default.UpdatePending && DateTime.UtcNow < nextUpdateCheck)
DateTime nextUpdateCheck = Convert.ToDateTime(Properties.OptionsUpdatesPage.Default.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(Convert.ToDouble(Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays))));
if (!Properties.OptionsUpdatesPage.Default.UpdatePending && DateTime.UtcNow < nextUpdateCheck)
{
return;
}
_appUpdate.GetUpdateInfoCompletedEvent += GetUpdateInfoCompleted;
_appUpdate.GetUpdateInfoAsync();
}
private void GetUpdateInfoCompleted(object sender, AsyncCompletedEventArgs e)
{
if (_frmMain.InvokeRequired)
{
_frmMain.Invoke(new AsyncCompletedEventHandler(GetUpdateInfoCompleted), sender, e);
return;
}
try
{
_appUpdate.GetUpdateInfoCompletedEvent -= GetUpdateInfoCompleted;
if (e.Cancelled)
{
return;
}
if (e.Error != null)
{
throw e.Error;
}
await _appUpdate.GetUpdateInfoAsync();
if (_appUpdate.IsUpdateAvailable())
{
Windows.Show(WindowType.Update);
@@ -120,7 +91,7 @@ namespace mRemoteNG.App
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("GetUpdateInfoCompleted() failed.", ex);
Runtime.MessageCollector.AddExceptionMessage("CheckForUpdate() failed.", ex);
}
}
}

View File

@@ -1,14 +1,16 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using mRemoteNG.Properties;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
[Serializable]
public sealed class SupportedCultures : Dictionary<string, string>
{
@@ -22,11 +24,11 @@ namespace mRemoteNG.App
private SupportedCultures()
{
foreach (var CultureName in Settings.Default.SupportedUICultures.Split(','))
foreach (string CultureName in Properties.AppUI.Default.SupportedUICultures.Split(','))
{
try
{
var CultureInfo = new CultureInfo(CultureName.Trim());
CultureInfo CultureInfo = new(CultureName.Trim());
Add(CultureInfo.Name, CultureInfo.TextInfo.ToTitleCase(CultureInfo.NativeName));
}
catch (Exception ex)
@@ -55,13 +57,13 @@ namespace mRemoteNG.App
public static string get_CultureName(string CultureNativeName)
{
var Names = new string[SingletonInstance.Count + 1];
var NativeNames = new string[SingletonInstance.Count + 1];
string[] Names = new string[SingletonInstance.Count + 1];
string[] NativeNames = new string[SingletonInstance.Count + 1];
SingletonInstance.Keys.CopyTo(Names, 0);
SingletonInstance.Values.CopyTo(NativeNames, 0);
for (var Index = 0; Index <= SingletonInstance.Count; Index++)
for (int Index = 0; Index <= SingletonInstance.Count; Index++)
{
if (NativeNames[Index] == CultureNativeName)
{
@@ -81,8 +83,8 @@ namespace mRemoteNG.App
{
get
{
var ValueList = new List<string>();
foreach (var Value in SingletonInstance.Values)
List<string> ValueList = new();
foreach (string Value in SingletonInstance.Values)
{
ValueList.Add(Value);
}

View File

@@ -1,13 +1,14 @@
using System;
using System.IO;
using System.Net;
using System.ComponentModel;
using System.Net.Http;
using System.Threading;
using System.Reflection;
using mRemoteNG.App.Info;
using mRemoteNG.Security.SymmetricEncryption;
using System.Security.Cryptography;
using System.Threading.Tasks;
using mRemoteNG.Properties;
using System.Runtime.Versioning;
#if !PORTABLE
using mRemoteNG.Tools;
@@ -19,31 +20,33 @@ using System.Windows.Forms;
namespace mRemoteNG.App.Update
{
[SupportedOSPlatform("windows")]
public class AppUpdater
{
private const int _bufferLength = 8192;
private WebProxy _webProxy;
private Thread _getUpdateInfoThread;
private Thread _getChangeLogThread;
private HttpClient _httpClient;
private CancellationTokenSource _changeLogCancelToken;
private CancellationTokenSource _getUpdateInfoCancelToken;
#region Public Properties
public UpdateInfo CurrentUpdateInfo { get; private set; }
public string ChangeLog { get; private set; }
public bool IsGetUpdateInfoRunning
{
get { return _getUpdateInfoThread != null && _getUpdateInfoThread.IsAlive; }
get
{
return _getUpdateInfoCancelToken != null;
}
}
private bool IsGetChangeLogRunning
{
get { return _getChangeLogThread != null && _getChangeLogThread.IsAlive; }
}
public bool IsDownloadUpdateRunning
{
get { return _downloadUpdateWebClient != null; }
get
{
return _changeLogCancelToken != null;
}
}
#endregion
@@ -52,39 +55,35 @@ namespace mRemoteNG.App.Update
public AppUpdater()
{
SetProxySettings();
SetDefaultProxySettings();
}
private void SetProxySettings()
private void SetDefaultProxySettings()
{
var shouldWeUseProxy = Settings.Default.UpdateUseProxy;
var proxyAddress = Settings.Default.UpdateProxyAddress;
var port = Settings.Default.UpdateProxyPort;
var useAuthentication = Settings.Default.UpdateProxyUseAuthentication;
var username = Settings.Default.UpdateProxyAuthUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
bool shouldWeUseProxy = Properties.OptionsUpdatesPage.Default.UpdateUseProxy;
string proxyAddress = Properties.OptionsUpdatesPage.Default.UpdateProxyAddress;
int port = Properties.OptionsUpdatesPage.Default.UpdateProxyPort;
bool useAuthentication = Properties.OptionsUpdatesPage.Default.UpdateProxyUseAuthentication;
string username = Properties.OptionsUpdatesPage.Default.UpdateProxyAuthUser;
LegacyRijndaelCryptographyProvider cryptographyProvider = new();
string password = cryptographyProvider.Decrypt(Properties.OptionsUpdatesPage.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
SetProxySettings(shouldWeUseProxy, proxyAddress, port, useAuthentication, username, password);
}
public void SetProxySettings(bool useProxy,
string address,
int port,
bool useAuthentication,
string username,
string password)
public void SetProxySettings(bool useProxy, string address, int port, bool useAuthentication, string username, string password)
{
if (useProxy && !string.IsNullOrEmpty(address))
{
_webProxy = port != 0 ? new WebProxy(address, port) : new WebProxy(address);
_webProxy.Credentials = useAuthentication ? new NetworkCredential(username, password) : null;
}
else
{
_webProxy = null;
}
UpdateHttpClient();
}
public bool IsUpdateAvailable()
@@ -96,54 +95,24 @@ namespace mRemoteNG.App.Update
return CurrentUpdateInfo.Version > GeneralAppInfo.GetApplicationVersion();
}
public void GetUpdateInfoAsync()
public async Task DownloadUpdateAsync(IProgress<int> progress)
{
if (IsGetUpdateInfoRunning)
{
_getUpdateInfoThread.Abort();
}
_getUpdateInfoCancelToken.Cancel();
_getUpdateInfoCancelToken.Dispose();
_getUpdateInfoCancelToken = null;
_getUpdateInfoThread = new Thread(GetUpdateInfo);
_getUpdateInfoThread.SetApartmentState(ApartmentState.STA);
_getUpdateInfoThread.IsBackground = true;
_getUpdateInfoThread.Start();
}
public void GetChangeLogAsync()
{
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
{
throw new InvalidOperationException(
"CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling GetChangeLogAsync().");
}
if (IsGetChangeLogRunning)
{
_getChangeLogThread.Abort();
}
_getChangeLogThread = new Thread(GetChangeLog);
_getChangeLogThread.SetApartmentState(ApartmentState.STA);
_getChangeLogThread.IsBackground = true;
_getChangeLogThread.Start();
}
public void DownloadUpdateAsync()
{
if (_downloadUpdateWebClient != null)
{
throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress.");
}
if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid)
{
throw new InvalidOperationException(
"CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync().");
}
#if !PORTABLE
CurrentUpdateInfo.UpdateFilePath =
Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
CurrentUpdateInfo.UpdateFilePath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi"));
#else
var sfd = new SaveFileDialog
{
@@ -160,137 +129,40 @@ namespace mRemoteNG.App.Update
return;
}
#endif
DownloadUpdateWebClient.DownloadFileAsync(CurrentUpdateInfo.DownloadAddress,
CurrentUpdateInfo.UpdateFilePath);
}
#endregion
#region Private Properties
private WebClient _downloadUpdateWebClient;
private WebClient DownloadUpdateWebClient
{
get
{
if (_downloadUpdateWebClient != null)
{
return _downloadUpdateWebClient;
}
_downloadUpdateWebClient = CreateWebClient();
_downloadUpdateWebClient.DownloadProgressChanged += DownloadUpdateProgressChanged;
_downloadUpdateWebClient.DownloadFileCompleted += DownloadUpdateCompleted;
return _downloadUpdateWebClient;
}
}
#endregion
#region Private Methods
private WebClient CreateWebClient()
{
var webClient = new WebClient();
webClient.Headers.Add("user-agent", GeneralAppInfo.UserAgent);
webClient.Proxy = _webProxy;
return webClient;
}
private static DownloadStringCompletedEventArgs NewDownloadStringCompletedEventArgs(string result,
Exception exception,
bool cancelled,
object userToken)
{
var type = typeof(DownloadStringCompletedEventArgs);
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
Type[] argumentTypes = {typeof(string), typeof(Exception), typeof(bool), typeof(object)};
var constructor = type.GetConstructor(bindingFlags, null, argumentTypes, null);
object[] arguments = {result, exception, cancelled, userToken};
if (constructor == null)
return null;
return (DownloadStringCompletedEventArgs)constructor.Invoke(arguments);
}
private DownloadStringCompletedEventArgs DownloadString(Uri address)
{
var webClient = CreateWebClient();
var result = string.Empty;
Exception exception = null;
var cancelled = false;
try
{
result = webClient.DownloadString(address);
}
catch (ThreadAbortException)
{
cancelled = true;
}
catch (Exception ex)
{
exception = ex;
}
_getUpdateInfoCancelToken = new CancellationTokenSource();
using HttpResponseMessage response = await _httpClient.GetAsync(CurrentUpdateInfo.DownloadAddress, HttpCompletionOption.ResponseHeadersRead, _getUpdateInfoCancelToken.Token);
byte[] buffer = new byte[_bufferLength];
long totalBytes = response.Content.Headers.ContentLength ?? 0;
long readBytes = 0L;
return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null);
}
private void GetUpdateInfo()
{
var e = DownloadString(UpdateChannelInfo.GetUpdateChannelInfo());
if (!e.Cancelled && e.Error == null)
{
try
await using (Stream httpStream = await response.Content.ReadAsStreamAsync(_getUpdateInfoCancelToken.Token))
{
CurrentUpdateInfo = UpdateInfo.FromString(e.Result);
await using FileStream fileStream = new(CurrentUpdateInfo.UpdateFilePath, FileMode.Create,
FileAccess.Write, FileShare.None, _bufferLength, true);
Settings.Default.CheckForUpdatesLastCheck = DateTime.UtcNow;
if (!Settings.Default.UpdatePending)
while (readBytes <= totalBytes || !_getUpdateInfoCancelToken.IsCancellationRequested)
{
Settings.Default.UpdatePending = IsUpdateAvailable();
int bytesRead =
await httpStream.ReadAsync(buffer.AsMemory(0, _bufferLength), _getUpdateInfoCancelToken.Token);
if (bytesRead == 0)
{
progress.Report(100);
break;
}
await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead), _getUpdateInfoCancelToken.Token);
readBytes += bytesRead;
int percentComplete = (int)(readBytes * 100 / totalBytes);
progress.Report(percentComplete);
}
}
catch (Exception ex)
{
e = NewDownloadStringCompletedEventArgs(e.Result, ex, e.Cancelled, null);
}
}
GetUpdateInfoCompletedEventEvent?.Invoke(this, e);
}
private void GetChangeLog()
{
var e = DownloadString(CurrentUpdateInfo.ChangeLogAddress);
if (!e.Cancelled && e.Error == null)
{
ChangeLog = e.Result;
}
GetChangeLogCompletedEventEvent?.Invoke(this, e);
}
private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
DownloadUpdateProgressChangedEventEvent?.Invoke(sender, e);
}
private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e)
{
var raiseEventArgs = e;
if (!e.Cancelled && e.Error == null)
{
try
{
#if !PORTABLE
var updateAuthenticode = new Authenticode(CurrentUpdateInfo.UpdateFilePath)
Authenticode updateAuthenticode = new(CurrentUpdateInfo.UpdateFilePath)
{
RequireThumbprintMatch = true,
ThumbprintToMatch = CurrentUpdateInfo.CertificateThumbprint
@@ -307,101 +179,85 @@ namespace mRemoteNG.App.Update
}
#endif
using (var cksum = SHA512.Create())
{
using (var stream = File.OpenRead(CurrentUpdateInfo.UpdateFilePath))
{
var hash = cksum.ComputeHash(stream);
var hashString = BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant();
if (!hashString.Equals(CurrentUpdateInfo.Checksum))
throw new Exception("SHA512 Hashes didn't match!");
}
}
}
catch (Exception ex)
{
raiseEventArgs = new AsyncCompletedEventArgs(ex, false, null);
}
using SHA512 checksum = SHA512.Create();
await using FileStream stream = File.OpenRead(CurrentUpdateInfo.UpdateFilePath);
byte[] hash = await checksum.ComputeHashAsync(stream);
string hashString = BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant();
if (!hashString.Equals(CurrentUpdateInfo.Checksum))
throw new Exception("SHA512 Hashes didn't match!");
} finally{
_getUpdateInfoCancelToken?.Dispose();
_getUpdateInfoCancelToken = null;
}
if (raiseEventArgs.Cancelled || raiseEventArgs.Error != null)
{
File.Delete(CurrentUpdateInfo.UpdateFilePath);
}
DownloadUpdateCompletedEventEvent?.Invoke(this, raiseEventArgs);
_downloadUpdateWebClient.Dispose();
_downloadUpdateWebClient = null;
}
#endregion
#region Events
#region Private Methods
private AsyncCompletedEventHandler GetUpdateInfoCompletedEventEvent;
public event AsyncCompletedEventHandler GetUpdateInfoCompletedEvent
private void UpdateHttpClient()
{
add
if (_httpClient != null)
{
GetUpdateInfoCompletedEventEvent =
(AsyncCompletedEventHandler)Delegate.Combine(GetUpdateInfoCompletedEventEvent, value);
_httpClient.Dispose();
}
remove
HttpClientHandler httpClientHandler = new();
if (_webProxy != null)
{
GetUpdateInfoCompletedEventEvent =
(AsyncCompletedEventHandler)Delegate.Remove(GetUpdateInfoCompletedEventEvent, value);
httpClientHandler.UseProxy = true;
httpClientHandler.Proxy = _webProxy;
}
_httpClient = new HttpClient(httpClientHandler);
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(GeneralAppInfo.UserAgent);
}
public async Task GetUpdateInfoAsync()
{
if (IsGetUpdateInfoRunning)
{
_getUpdateInfoCancelToken.Cancel();
_getUpdateInfoCancelToken.Dispose();
_getUpdateInfoCancelToken = null;
}
try
{
_getUpdateInfoCancelToken = new CancellationTokenSource();
string updateInfo = await _httpClient.GetStringAsync(UpdateChannelInfo.GetUpdateChannelInfo(), _getUpdateInfoCancelToken.Token);
CurrentUpdateInfo = UpdateInfo.FromString(updateInfo);
Properties.OptionsUpdatesPage.Default.CheckForUpdatesLastCheck = DateTime.UtcNow;
if (!Properties.OptionsUpdatesPage.Default.UpdatePending)
{
Properties.OptionsUpdatesPage.Default.UpdatePending = IsUpdateAvailable();
}
}
finally
{
_getUpdateInfoCancelToken?.Dispose();
_getUpdateInfoCancelToken = null;
}
}
private AsyncCompletedEventHandler GetChangeLogCompletedEventEvent;
public event AsyncCompletedEventHandler GetChangeLogCompletedEvent
public async Task<string> GetChangeLogAsync()
{
add
if (IsGetChangeLogRunning)
{
GetChangeLogCompletedEventEvent =
(AsyncCompletedEventHandler)Delegate.Combine(GetChangeLogCompletedEventEvent, value);
_changeLogCancelToken.Cancel();
_changeLogCancelToken.Dispose();
_changeLogCancelToken = null;
}
remove
{
GetChangeLogCompletedEventEvent =
(AsyncCompletedEventHandler)Delegate.Remove(GetChangeLogCompletedEventEvent, value);
}
}
private DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEventEvent;
public event DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEvent
{
add
try
{
DownloadUpdateProgressChangedEventEvent =
(DownloadProgressChangedEventHandler)Delegate.Combine(DownloadUpdateProgressChangedEventEvent,
value);
_changeLogCancelToken = new CancellationTokenSource();
return await _httpClient.GetStringAsync(CurrentUpdateInfo.ChangeLogAddress, _changeLogCancelToken.Token);
}
remove
finally
{
DownloadUpdateProgressChangedEventEvent =
(DownloadProgressChangedEventHandler)Delegate.Remove(DownloadUpdateProgressChangedEventEvent,
value);
}
}
private AsyncCompletedEventHandler DownloadUpdateCompletedEventEvent;
public event AsyncCompletedEventHandler DownloadUpdateCompletedEvent
{
add
{
DownloadUpdateCompletedEventEvent =
(AsyncCompletedEventHandler)Delegate.Combine(DownloadUpdateCompletedEventEvent, value);
}
remove
{
DownloadUpdateCompletedEventEvent =
(AsyncCompletedEventHandler)Delegate.Remove(DownloadUpdateCompletedEventEvent, value);
_changeLogCancelToken?.Dispose();
_changeLogCancelToken = null;
}
}

View File

@@ -34,19 +34,19 @@ namespace mRemoteNG.App.Update
// no separators means no valid update data...
if (content.Trim().IndexOfAny(keyValueSeparators) == -1) return;
using (var sr = new StringReader(content))
using (StringReader sr = new(content))
{
string line;
while ((line = sr.ReadLine()) != null)
{
var trimmedLine = line.Trim();
string trimmedLine = line.Trim();
if (trimmedLine.Length == 0)
continue;
if (trimmedLine.Substring(0, 1).IndexOfAny(commentCharacters) != -1)
continue;
var parts = trimmedLine.Split(keyValueSeparators, 2);
string[] parts = trimmedLine.Split(keyValueSeparators, 2);
if (parts.Length != 2)
continue;
@@ -68,13 +68,13 @@ namespace mRemoteNG.App.Update
public Version GetVersion(string key = "Version")
{
var value = GetString(key);
string value = GetString(key);
return string.IsNullOrEmpty(value) ? null : new Version(value);
}
public Uri GetUri(string key)
{
var value = GetString(key);
string value = GetString(key);
return string.IsNullOrEmpty(value) ? null : new Uri(value);
}
@@ -85,8 +85,8 @@ namespace mRemoteNG.App.Update
public string GetFileName()
{
var value = GetString("dURL");
var sv = value.Split('/');
string value = GetString("dURL");
string[] sv = value.Split('/');
return sv[sv.Length - 1];
}

View File

@@ -22,14 +22,14 @@ namespace mRemoteNG.App.Update
public static UpdateInfo FromString(string input)
{
var newInfo = new UpdateInfo();
UpdateInfo newInfo = new();
if (string.IsNullOrEmpty(input))
{
newInfo.IsValid = false;
}
else
{
var updateFile = new UpdateFile(input);
UpdateFile updateFile = new(input);
newInfo.Version = updateFile.GetVersion();
newInfo.DownloadAddress = updateFile.GetUri("dURL");
newInfo.ChangeLogAddress = updateFile.GetUri("clURL");

View File

@@ -1,17 +1,20 @@
using System;
#region Usings
using System;
using System.Runtime.Versioning;
using mRemoteNG.Resources.Language;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
#endregion
namespace mRemoteNG.App
{
[SupportedOSPlatform("windows")]
public static class Windows
{
private static ActiveDirectoryImportWindow _adimportForm;
private static HelpWindow _helpForm;
private static ExternalToolsWindow _externalappsForm;
private static PortScanWindow _portscanForm;
private static ScreenshotManagerWindow _screenshotmanagerForm;
private static UltraVNCWindow _ultravncscForm;
private static ConnectionTreeWindow _treeForm;
@@ -23,7 +26,6 @@ namespace mRemoteNG.App
internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
internal static ScreenshotManagerWindow ScreenshotForm { get; set; } = new ScreenshotManagerWindow();
private static UpdateWindow UpdateForm { get; set; } = new UpdateWindow();
internal static SSHTransferWindow SshtransferForm { get; private set; } = new SSHTransferWindow();
@@ -32,7 +34,7 @@ namespace mRemoteNG.App
{
try
{
var dockPanel = FrmMain.Default.pnlDock;
WeifenLuo.WinFormsUI.Docking.DockPanel dockPanel = FrmMain.Default.pnlDock;
// ReSharper disable once SwitchStatementMissingSomeCases
switch (windowType)
{
@@ -42,11 +44,8 @@ namespace mRemoteNG.App
_adimportForm.Show(dockPanel);
break;
case WindowType.Options:
using (var optionsForm = new FrmOptions())
{
optionsForm.ShowDialog(dockPanel);
}
FrmMain.OptionsForm.SetActivatedPage(Language.StartupExit);
FrmMain.OptionsForm.Visible = true;
break;
case WindowType.SSHTransfer:
if (SshtransferForm == null || SshtransferForm.IsDisposed)
@@ -58,11 +57,6 @@ namespace mRemoteNG.App
UpdateForm = new UpdateWindow();
UpdateForm.Show(dockPanel);
break;
case WindowType.Help:
if (_helpForm == null || _helpForm.IsDisposed)
_helpForm = new HelpWindow();
_helpForm.Show(dockPanel);
break;
case WindowType.ExternalApps:
if (_externalappsForm == null || _externalappsForm.IsDisposed)
_externalappsForm = new ExternalToolsWindow();
@@ -72,10 +66,6 @@ namespace mRemoteNG.App
_portscanForm = new PortScanWindow();
_portscanForm.Show(dockPanel);
break;
case WindowType.ScreenshotManager:
_screenshotmanagerForm = new ScreenshotManagerWindow();
_screenshotmanagerForm.Show(dockPanel);
break;
case WindowType.UltraVNCSC:
if (_ultravncscForm == null || _ultravncscForm.IsDisposed)
_ultravncscForm = new UltraVNCWindow();

View File

@@ -0,0 +1,9 @@
namespace mRemoteNG.Config.ACL
{
public enum ACLPermissions
{
Hidden = 0,
ReadOnly = 1,
WriteAllow = 2
}
}

View File

@@ -0,0 +1,13 @@
namespace mRemoteNG.Config.Connections
{
public enum ConnectionsBackupFrequencyEnum
{
Unassigned = 0,
Never = 1,
OnEdit = 2,
OnExit = 3,
Daily = 4,
Weekly = 5,
Custom = 6
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Runtime.Versioning;
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.ConnectionSerializers.Csv;
@@ -7,6 +8,7 @@ using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections
{
[SupportedOSPlatform("windows")]
public class CsvConnectionsSaver : ISaver<ConnectionTreeModel>
{
private readonly string _connectionFileName;
@@ -25,10 +27,10 @@ namespace mRemoteNG.Config.Connections
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
{
var csvConnectionsSerializer =
new CsvConnectionsSerializerMremotengFormat(_saveFilter, Runtime.CredentialProviderCatalog);
var dataProvider = new FileDataProvider(_connectionFileName);
var csvContent = csvConnectionsSerializer.Serialize(connectionTreeModel);
CsvConnectionsSerializerMremotengFormat csvConnectionsSerializer =
new(_saveFilter, Runtime.CredentialProviderCatalog);
FileDataProvider dataProvider = new(_connectionFileName);
string csvContent = csvConnectionsSerializer.Serialize(connectionTreeModel);
dataProvider.Save(csvContent);
}
}

View File

@@ -1,14 +1,16 @@
using mRemoteNG.App;
using System;
using System.Runtime.Versioning;
using System.Timers;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Config.Connections.Multiuser
{
[SupportedOSPlatform("windows")]
public class RemoteConnectionsSyncronizer : IConnectionsUpdateChecker
{
private readonly Timer _updateTimer;
private readonly System.Timers.Timer _updateTimer;
private readonly IConnectionsUpdateChecker _updateChecker;
public double TimerIntervalInMilliseconds
@@ -19,7 +21,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker)
{
_updateChecker = updateChecker;
_updateTimer = new Timer(3000);
_updateTimer = new System.Timers.Timer(3000);
SetEventListeners();
}
@@ -27,8 +29,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
{
_updateChecker.UpdateCheckStarted += OnUpdateCheckStarted;
_updateChecker.UpdateCheckFinished += OnUpdateCheckFinished;
_updateChecker.ConnectionsUpdateAvailable +=
(sender, args) => ConnectionsUpdateAvailable?.Invoke(sender, args);
_updateChecker.ConnectionsUpdateAvailable += (sender, args) => ConnectionsUpdateAvailable?.Invoke(sender, args);
_updateTimer.Elapsed += (sender, args) => _updateChecker.IsUpdateAvailableAsync();
ConnectionsUpdateAvailable += Load;
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
using System.Runtime.Versioning;
using System.Threading;
using mRemoteNG.App;
using mRemoteNG.Config.DatabaseConnectors;
@@ -8,6 +9,7 @@ using mRemoteNG.Messages;
namespace mRemoteNG.Config.Connections.Multiuser
{
[SupportedOSPlatform("windows")]
public class SqlConnectionsUpdateChecker : IConnectionsUpdateChecker
{
private readonly IDatabaseConnector _dbConnector;
@@ -27,7 +29,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
{
RaiseUpdateCheckStartedEvent();
ConnectToSqlDb();
var updateIsAvailable = DatabaseIsMoreUpToDateThanUs();
bool updateIsAvailable = DatabaseIsMoreUpToDateThanUs();
if (updateIsAvailable)
RaiseConnectionsUpdateAvailableEvent();
RaiseUpdateCheckFinishedEvent(updateIsAvailable);
@@ -36,7 +38,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
public void IsUpdateAvailableAsync()
{
var thread = new Thread(() => IsUpdateAvailable());
Thread thread = new(() => IsUpdateAvailable());
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
@@ -49,46 +51,44 @@ namespace mRemoteNG.Config.Connections.Multiuser
}
catch (Exception e)
{
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg,
"Unable to connect to Sql DB to check for updates." +
Environment.NewLine + e.Message, true);
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, $"Unable to connect to SQL DB to check for updates.{Environment.NewLine}{e.Message}", true);
}
}
private bool DatabaseIsMoreUpToDateThanUs()
{
var lastUpdateInDb = GetLastUpdateTimeFromDbResponse();
var amTheLastoneUpdated = CheckIfIAmTheLastOneUpdated(lastUpdateInDb);
DateTime lastUpdateInDb = GetLastUpdateTimeFromDbResponse();
bool amTheLastoneUpdated = CheckIfIAmTheLastOneUpdated(lastUpdateInDb);
return (lastUpdateInDb > LastUpdateTime && !amTheLastoneUpdated);
}
private bool CheckIfIAmTheLastOneUpdated(DateTime lastUpdateInDb)
{
DateTime lastSqlUpdateWithoutMilliseconds =
new DateTime(LastUpdateTime.Ticks - (LastUpdateTime.Ticks % TimeSpan.TicksPerSecond),
LastUpdateTime.Kind);
DateTime lastSqlUpdateWithoutMilliseconds = new(LastUpdateTime.Ticks - (LastUpdateTime.Ticks % TimeSpan.TicksPerSecond), LastUpdateTime.Kind);
return lastUpdateInDb == lastSqlUpdateWithoutMilliseconds;
}
private DateTime GetLastUpdateTimeFromDbResponse()
{
var lastUpdateInDb = default(DateTime);
DateTime lastUpdateInDb = default(DateTime);
try
{
var sqlReader = _dbQuery.ExecuteReader(CommandBehavior.CloseConnection);
DbDataReader sqlReader = _dbQuery.ExecuteReader(CommandBehavior.CloseConnection);
sqlReader.Read();
if (sqlReader.HasRows)
{
lastUpdateInDb = Convert.ToDateTime(sqlReader["LastUpdate"]);
}
sqlReader.Close();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg,
"Error executing Sql query to get updates from the DB." +
Environment.NewLine + ex.Message, true);
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Error executing SQL query to get updates from the DB." + Environment.NewLine + ex.Message, true);
}
_lastDatabaseUpdateTime = lastUpdateInDb;
return lastUpdateInDb;
}
@@ -104,7 +104,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
private void RaiseUpdateCheckFinishedEvent(bool updateAvailable)
{
var args = new ConnectionsUpdateCheckFinishedEventArgs {UpdateAvailable = updateAvailable};
ConnectionsUpdateCheckFinishedEventArgs args = new() { UpdateAvailable = updateAvailable};
UpdateCheckFinished?.Invoke(this, args);
}
@@ -113,7 +113,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
private void RaiseConnectionsUpdateAvailableEvent()
{
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Remote connection update is available");
var args = new ConnectionsUpdateAvailableEventArgs(_dbConnector, _lastDatabaseUpdateTime);
ConnectionsUpdateAvailableEventArgs args = new(_dbConnector, _lastDatabaseUpdateTime);
ConnectionsUpdateAvailable?.Invoke(this, args);
}

View File

@@ -3,9 +3,12 @@ using System.Collections.Specialized;
using System.ComponentModel;
using mRemoteNG.Connection;
using mRemoteNG.UI.Forms;
using mRemoteNG.Properties;
using System.Runtime.Versioning;
namespace mRemoteNG.Config.Connections
{
[SupportedOSPlatform("windows")]
public class SaveConnectionsOnEdit
{
private readonly ConnectionsService _connectionsService;
@@ -19,41 +22,38 @@ namespace mRemoteNG.Config.Connections
connectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded;
}
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;
foreach (var oldTree in connectionsLoadedEventArgs.PreviousConnectionTreeModel)
foreach (Tree.ConnectionTreeModel oldTree in connectionsLoadedEventArgs.PreviousConnectionTreeModel)
{
oldTree.CollectionChanged -= ConnectionTreeModelOnCollectionChanged;
oldTree.PropertyChanged -= ConnectionTreeModelOnPropertyChanged;
}
}
private void ConnectionTreeModelOnPropertyChanged(object sender,
PropertyChangedEventArgs propertyChangedEventArgs)
private void ConnectionTreeModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
SaveConnectionOnEdit(propertyChangedEventArgs.PropertyName);
}
private void ConnectionTreeModelOnCollectionChanged(object sender,
NotifyCollectionChangedEventArgs
notifyCollectionChangedEventArgs)
private void ConnectionTreeModelOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
SaveConnectionOnEdit();
}
private void SaveConnectionOnEdit(string propertyName = "")
{
if (!Properties.Settings.Default.SaveConnectionsAfterEveryEdit)
return;
if (FrmMain.Default.IsClosing)
return;
//OBSOLETE: mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit is obsolete and should be removed in a future release
if (Properties.OptionsBackupPage.Default.SaveConnectionsAfterEveryEdit || (Properties.OptionsBackupPage.Default.SaveConnectionsFrequency == (int)ConnectionsBackupFrequencyEnum.OnEdit))
{
if (FrmMain.Default.IsClosing)
return;
_connectionsService.SaveConnectionsAsync(propertyName);
_connectionsService.SaveConnectionsAsync(propertyName);
}
}
}
}

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Versioning;
using System.Security;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.ConnectionSerializers.MsSql;
using mRemoteNG.Config.Serializers.ConnectionSerializers.Sql;
using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Container;
using mRemoteNG.Security;
@@ -17,66 +18,58 @@ using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Connections
{
[SupportedOSPlatform("windows")]
public class SqlConnectionsLoader : IConnectionsLoader
{
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>>
_localConnectionPropertiesDeserializer;
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> _localConnectionPropertiesDeserializer;
private readonly IDataProvider<string> _dataProvider;
public Func<Optional<SecureString>> AuthenticationRequestor { get; set; } =
() => MiscTools.PasswordDialog("", false);
private Func<Optional<SecureString>> AuthenticationRequestor { get; set; } = () => MiscTools.PasswordDialog("", false);
public SqlConnectionsLoader(
IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> localConnectionPropertiesDeserializer,
IDataProvider<string> dataProvider)
{
_localConnectionPropertiesDeserializer =
localConnectionPropertiesDeserializer.ThrowIfNull(nameof(localConnectionPropertiesDeserializer));
_localConnectionPropertiesDeserializer = localConnectionPropertiesDeserializer.ThrowIfNull(nameof(localConnectionPropertiesDeserializer));
_dataProvider = dataProvider.ThrowIfNull(nameof(dataProvider));
}
public ConnectionTreeModel Load()
{
var connector = DatabaseConnectorFactory.DatabaseConnectorFromSettings();
var dataProvider = new SqlDataProvider(connector);
var metaDataRetriever = new SqlDatabaseMetaDataRetriever();
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
var cryptoProvider = new LegacyRijndaelCryptographyProvider();
var metaData = metaDataRetriever.GetDatabaseMetaData(connector) ??
HandleFirstRun(metaDataRetriever, connector);
var decryptionKey = GetDecryptionKey(metaData);
IDatabaseConnector connector = DatabaseConnectorFactory.DatabaseConnectorFromSettings();
SqlDataProvider dataProvider = new(connector);
SqlDatabaseMetaDataRetriever metaDataRetriever = new();
SqlDatabaseVersionVerifier databaseVersionVerifier = new(connector);
LegacyRijndaelCryptographyProvider cryptoProvider = new();
SqlConnectionListMetaData metaData = metaDataRetriever.GetDatabaseMetaData(connector) ?? HandleFirstRun(metaDataRetriever, connector);
Optional<SecureString> decryptionKey = GetDecryptionKey(metaData);
if (!decryptionKey.Any())
throw new Exception("Could not load SQL connections");
databaseVersionVerifier.VerifyDatabaseVersion(metaData.ConfVersion);
var dataTable = dataProvider.Load();
var deserializer = new DataTableDeserializer(cryptoProvider, decryptionKey.First());
var connectionTree = deserializer.Deserialize(dataTable);
System.Data.DataTable dataTable = dataProvider.Load();
DataTableDeserializer deserializer = new(cryptoProvider, decryptionKey.First());
ConnectionTreeModel connectionTree = deserializer.Deserialize(dataTable);
ApplyLocalConnectionProperties(connectionTree.RootNodes.First(i => i is RootNodeInfo));
return connectionTree;
}
private Optional<SecureString> GetDecryptionKey(SqlConnectionListMetaData metaData)
{
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var cipherText = metaData.Protected;
var authenticator = new PasswordAuthenticator(cryptographyProvider, cipherText, AuthenticationRequestor);
var authenticated =
authenticator.Authenticate(new RootNodeInfo(RootNodeType.Connection).DefaultPassword
.ConvertToSecureString());
LegacyRijndaelCryptographyProvider cryptographyProvider = new();
string cipherText = metaData.Protected;
PasswordAuthenticator authenticator = new(cryptographyProvider, cipherText, AuthenticationRequestor);
bool authenticated = authenticator.Authenticate(new RootNodeInfo(RootNodeType.Connection).DefaultPassword.ConvertToSecureString());
if (authenticated)
return authenticator.LastAuthenticatedPassword;
return Optional<SecureString>.Empty;
return authenticated ? authenticator.LastAuthenticatedPassword : Optional<SecureString>.Empty;
}
private void ApplyLocalConnectionProperties(ContainerInfo rootNode)
{
var localPropertiesXml = _dataProvider.Load();
var localConnectionProperties = _localConnectionPropertiesDeserializer.Deserialize(localPropertiesXml);
string localPropertiesXml = _dataProvider.Load();
IEnumerable<LocalConnectionPropertiesModel> localConnectionProperties = _localConnectionPropertiesDeserializer.Deserialize(localPropertiesXml);
rootNode
.GetRecursiveChildList()

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