Compare commits

...

2104 Commits

Author SHA1 Message Date
vladimir.kuznetsov
12206cdb52 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/graphview 2024-05-15 12:31:21 +02:00
albexk
abb3c918e3 Android notification and routing (#797)
Android notification and routing
2024-05-12 16:04:14 +01:00
Vladyslav Miachkov
ff348a348c Add checking background service before connect (#716)
checking if the service is running for all platforms
2024-05-10 11:06:04 +01:00
pokamest
d67c378bff Merge pull request #800 from amnezia-vpn/bugfix/ssh-check-connection
pass errorCode by reference in configurators
2024-05-10 03:03:59 -07:00
vladimir.kuznetsov
d85a0439c5 pass errorCode by reference in configurators 2024-05-09 20:56:52 +03:00
Mykola Baibuz
5bd8c33a6d Update Mozilla upstream (#790)
* Update Mozilla upstream
2024-05-08 22:02:02 +01:00
pokamest
24759c92ad Merge pull request #791 from amnezia-vpn/feature/prevent-log-spam
Prevent service log spam on Windows
2024-05-07 14:45:26 -07:00
Vladyslav Miachkov
9e92ee020e Add connect button background (#785)
Add connect button background
2024-05-03 01:12:22 +01:00
pokamest
7a4f6b628b Merge pull request #789 from amnezia-vpn/bugfix/page-application-settings-warnings
fixed qml warnings
2024-05-02 17:11:23 -07:00
Mykola Baibuz
7e2f223d7f Prevent service log spam on Windows 2024-04-30 22:17:50 +03:00
pokamest
eb48e4b668 Merge pull request #772 from amnezia-vpn/feature/check-openvpn-config
added checking for dangerous strings in openvpn configuration files
2024-04-30 10:26:12 -07:00
pokamest
9ace09a604 Merge pull request #788 from amnezia-vpn/bugfix/wgshow-invert-transfer-data 2024-04-30 02:34:10 -07:00
vladimir.kuznetsov
702735c2ca fixed qml warnings 2024-04-30 14:32:30 +05:00
Andrey Zaharow
174f2ac3db Censorship levels translation update (#770)
Censorship levels translation update
2024-04-29 22:36:18 +01:00
pokamest
e3b5b4a9d9 Merge pull request #768 from amnezia-vpn/feature/remove-middle-lvl-of-censorship
Remove middle level of censorship
2024-04-29 14:35:45 -07:00
Andrey Zaharow
72ba012765 Minor text corrections (#771)
Minor text corrections
2024-04-29 22:33:35 +01:00
pokamest
0f9bbcd060 Merge pull request #787 from amnezia-vpn/translation/Hindi-Language
Add Hindi language
2024-04-29 14:28:43 -07:00
Vladyslav Miachkov
a9d038d8bf Invert received/sent data for client info 2024-04-29 22:40:37 +03:00
Shehab Ahmed
54a6845315 Add Hindi language 2024-04-29 19:52:57 +03:00
pokamest
0c7059a476 Merge pull request #786 from amnezia-vpn/bugfix/killswitch-switcher-mobile
hide killswitch switcher for mobile platforms
2024-04-29 04:50:11 -07:00
pokamest
5bed92ab0b WindowsTunnelService typo fix 2024-04-29 11:12:27 +01:00
vladimir.kuznetsov
49a14785c6 hide killswitch switcher for mobile platforms 2024-04-29 13:36:23 +05:00
pokamest
2c78c06dda Merge pull request #780 from amnezia-vpn/bugfix/api-server-app-split-tunneling
fixed appSplitTunneling for api servers
2024-04-28 06:04:17 -07:00
Vladyslav Miachkov
cf8a0efd0d Get data from wg show command (#764)
Get data from wg show command
2024-04-28 14:03:41 +01:00
Andrey Zaharow
5211cdd4c0 Add hide password on SFTP page feature (#719)
Hide password on SFTP page feature
2024-04-28 12:48:38 +01:00
vladimir.kuznetsov
d10aa43d8b fixed appSplitTunneling for api servers 2024-04-26 18:45:25 +05:00
pokamest
6b0f1ed429 Merge pull request #779 from amnezia-vpn/bugfix/macos-runner
bump xcode-version for macos build
2024-04-26 04:33:43 -07:00
vladimir.kuznetsov
4bde1ccb44 bump xcode-version for macos build 2024-04-26 14:21:04 +05:00
pokamest
03c18c44e2 Merge pull request #774 from amnezia-vpn/fix/remove_appname_log
Remove logging of application and package names
2024-04-25 07:53:53 -07:00
Shehab Ahmed
72ffc7ce6a Translation/urdu language (#773)
* add Urdu translation
2024-04-25 15:30:31 +01:00
Nethius
87b738ef16 added killSwitch switcher (#746)
* added killSwitch switcher
* KillSwitch toggle for OpenVPN and XRay
* killSwitch toggle for AWG/WG protocol
* Some fixes for killSwitch
2024-04-25 14:01:00 +01:00
albexk
b868831bcb Remove logging of application and package names, as this is personal user data 2024-04-22 16:56:27 +03:00
pokamest
477d7214c5 Version bump 4.5.3.0 2024-04-21 16:02:16 +01:00
vladimir.kuznetsov
f3cd3d4f06 added checking for dangerous strings in openvpn configuration files 2024-04-21 17:58:57 +05:00
Andrey Zaharow
aea4cc2389 Remove middle level of censorship 2024-04-21 02:14:22 +02:00
pokamest
245aa8eb8c Merge pull request #767 from amnezia-vpn/fix/logging 2024-04-20 11:04:28 -07:00
albexk
f14a2add0f Fix clearing logs on Android and checking if logs need to be deleted 2024-04-20 17:51:33 +03:00
pokamest
89703ba58f Merge pull request #766 from amnezia-vpn/feature/native-wg-psk
Add support for native WG configs without PSK parameter
2024-04-20 03:03:06 -07:00
Mykola Baibuz
23715fca8b Add support for native WG configs without PSK parameter 2024-04-19 22:14:06 +03:00
pokamest
d90685600e Merge pull request #763 from amnezia-vpn/bugfix/full-access-share-drawer
fixed drawer closing on full access share screen
2024-04-19 06:37:05 -07:00
vladimir.kuznetsov
f007e5eb5c fixed drawer closing on full access share screen 2024-04-19 18:04:19 +05:00
Nethius
a8ccea00c7 added masking parameters for native wireguard configs (#743)
Added masking parameters for native wireguard configs
2024-04-18 18:23:15 +01:00
pokamest
cd2ee00769 Bump version 4.5.2.0 2024-04-18 15:29:12 +01:00
pokamest
c98a418807 Merge pull request #756 from amnezia-vpn/feature/update-cloak-290
Update Cloak to version 2.9.0
2024-04-18 06:55:38 -07:00
Garegin Harutyunyan
0e4ae26bae Added tab navigation functional. (#721)
- Added tab navigation functional.
- In basic types added parentFlickable property, which will help to ensure, that the item is visible within flickable parent during tab navigation.
- Added focus state for some basic types.
- In PageType qml file added lastItemTabClicked function, which will help to focus tab bar buttons when the last tab on the current page clicked.
- Added Focus for back button for all pages and drawers.
- Added scroll on tab for Servers ListView on PageHome.
2024-04-18 14:54:55 +01:00
Nethius
d50e7dd3f4 added installation_uuid to apiPayload (#747)
Added installation_uuid to apiPayload
2024-04-18 14:02:34 +01:00
pokamest
f0085f52eb Merge pull request #752 from amnezia-vpn/feature/ssh-one-session
ssh client now reuses an existing session instead of opening a new one
2024-04-18 05:05:00 -07:00
Nethius
5c19b08e5e fixed checkbox selection on installedAppsDrawer (#759)
* fixed checkbox selection on installedAppsDrawer
* added sorting by name for split tunneling by application
2024-04-18 13:01:26 +01:00
Vladyslav Miachkov
79edbe52a3 Prevent editing active container (#749)
* Prevent editing active container
* Prevent clear active container's cache
2024-04-18 12:49:57 +01:00
pokamest
0dd181bb5b Merge pull request #757 from amnezia-vpn/bugfix/page-home-height-linux
fixed page home height for linux
2024-04-18 04:48:18 -07:00
vladimir.kuznetsov
d8682003fa fixed page home height for linux 2024-04-18 15:51:22 +05:00
pokamest
f4a2cf9984 Merge pull request #755 from amnezia-vpn/bugfix/api-server-settings-page
for api servers, without the VPN config, the management tab will be selected by default
2024-04-17 03:29:31 -07:00
Nethius
98e6358fd3 added a check that S1 + messageInitiationSize should not be equal to S2 + messageResponseSize (#754) 2024-04-17 03:28:47 -07:00
pokamest
af90065d2e Merge pull request #758 from amnezia-vpn/bugfix/reset-api-non-default-server 2024-04-17 03:27:38 -07:00
vladimir.kuznetsov
f372f4074b fixed reset api button for non-default server 2024-04-17 12:26:35 +05:00
Mykola Baibuz
6a2e5f83a1 Update Cloak to 2.9.0 for iOS 2024-04-16 12:27:51 +03:00
vladimir.kuznetsov
a2badd46c4 for api servers, without the VPN config, the management tab will be selected by default 2024-04-16 13:01:20 +05:00
Mykola Baibuz
8623a983b8 Update Cloak to version 2.9.0 2024-04-15 19:49:03 +03:00
isamnezia
151e662027 VPNC control and logging (#748)
VPNC control and logging
2024-04-14 23:04:01 +01:00
Mykola Baibuz
f588fe29db Stop AWG/WG service after uninstall (#738)
* Stop AWG service after uninstall
* Close Amnezia-service executable after install
* Close Amnezia application with service
2024-04-14 14:08:14 +01:00
pokamest
030b0351a2 Merge pull request #753 from amnezia-vpn/fix/android-openssl
Add openssl .so libs for Android
2024-04-14 06:04:02 -07:00
albexk
d4453a5f38 Add openssl .so libs for Android 2024-04-14 14:07:26 +03:00
pokamest
2252905596 Merge pull request #750 from amnezia-vpn/bugfix/empty-server-import 2024-04-14 02:47:54 -07:00
vladimir.kuznetsov
ec650a65f7 ssh client now reuses an existing session instead of opening a new one 2024-04-12 20:00:21 +05:00
vladimir.kuznetsov
6953f8d814 fixed import of empty server 2024-04-11 13:48:36 +05:00
pokamest
624a84cbfb Merge pull request #741 from amnezia-vpn/bugfix/show-reboot-error
Show error if reboot server failed
2024-04-09 11:10:15 -07:00
Nethius
506d9793e1 remove debug output and unused checks (#745)
* removed debug output
* removed unused check for routeMode
2024-04-08 19:29:39 +01:00
pokamest
ef52f6ab08 Merge pull request #744 from amnezia-vpn/bugfix/disabled-split-tunneling-add-remove-routes
fixed adding/removing routes when split tunneling is disabled
2024-04-08 10:34:41 -07:00
vladimir.kuznetsov
93aebf5256 enabled drag for graphview area 2024-04-08 21:31:24 +05:00
vladimir.kuznetsov
502e815a9f Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/graphview 2024-04-08 21:30:44 +05:00
Mykola Baibuz
5312a6e885 Update OpenSSL (3.0.13) and libssh (0.10.6) (#733)
Update OpenSSL (3.0.13) and libssh (0.10.6)
2024-04-08 15:49:18 +01:00
vladimir.kuznetsov
8bc69bdc62 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/graphview 2024-04-08 18:52:05 +05:00
vladimir.kuznetsov
fdd600794e fixed adding/removing routes when split tunneling is disabled 2024-04-08 16:13:26 +05:00
Vladyslav Miachkov
7bfbdca72a Show error if reboot server failed 2024-04-06 23:35:55 +03:00
Nethius
a22c08a41d added prohibition of using "dangerous" options on the server management page, when the connection is active (#726) 2024-04-06 11:42:41 -07:00
Nethius
10ea9b418a supported container on connection (#736) 2024-04-06 11:42:17 -07:00
Nethius
e39efb1d68 app split tunneling search field (#727) 2024-04-06 08:29:51 -07:00
pokamest
7db84122f9 Merge pull request #737 from amnezia-vpn/bugfix/api-server-rename
fixed api server rename
2024-04-06 04:38:07 -07:00
vladimir.kuznetsov
84ad167ab4 fixed api server rename 2024-04-05 22:00:23 +05:00
isamnezia
ed7e217a6b Add required privacy manifest files (#731)
Add required privacy manifest files
2024-04-05 17:03:30 +01:00
pokamest
c1b0d4a4a7 Merge pull request #735 from amnezia-vpn/fix/andoird-open-config
Fix opening configs
2024-04-05 07:53:23 -07:00
albexk
2f84e24353 Fix opening configs 2024-04-05 14:06:40 +03:00
Mykola Baibuz
f73586185b Add Ukrainian translation (#722)
Add Ukrainian translation
2024-04-04 19:25:39 +01:00
pokamest
653ffb9a68 Merge pull request #728 from amnezia-vpn/bugfix/fix-macos-tray-icon-color
[macOS] Fix tray icon color states
2024-04-04 05:53:05 -07:00
pokamest
fe8c2d157a Merge pull request #732 from amnezia-vpn/bugfix/fix-inverted-switches
Fix inverted switches
2024-04-04 05:47:20 -07:00
pokamest
86367a1276 Merge pull request #725 from amnezia-vpn/bugfix/server-header-on-page-home
fixed the display of server name on the home page
2024-04-04 03:31:10 -07:00
Vladyslav Miachkov
b0fcf92ada Fix inverted switches 2024-04-04 10:40:03 +03:00
pokamest
283b6ebf81 Merge pull request #730 from amnezia-vpn/fix/ovpn-cloak-ios
Fix OpenVPN over Cloak (iOS)
2024-04-03 16:30:06 -07:00
Igor Sorokin
d0a7fc5116 Fix OpenVPN over Cloak (iOS) 2024-04-04 01:56:27 +03:00
Vladyslav Miachkov
9851aacba7 [macOS] Fix tray icon color states 2024-04-03 22:41:26 +03:00
vladimir.kuznetsov
51f9fb9e0a fixed the display of server name on the home page 2024-04-03 13:02:31 +05:00
KsZnak
0325761f3e Update amneziavpn_ru_RU.ts (#723)
Update amneziavpn_ru_RU.ts
2024-04-02 20:39:39 +01:00
vladimir.kuznetsov
b3ae687feb repositioned the graphview 2024-04-01 18:54:42 +05:00
Nethius
a6ca1b12da moved protocol config generation to VpnConfigirationsController (#665)
Moved protocol config generation to VpnConfigurationsController
2024-04-01 14:20:02 +01:00
vladimir.kuznetsov
d6d11d6e60 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/graphview 2024-04-01 17:52:08 +05:00
pokamest
82a9e7e27d Merge pull request #720 from amnezia-vpn/feature/app-split-tunneling-page-home
Added app split tunneling on home page
2024-04-01 13:33:10 +01:00
vladimir.kuznetsov
f5301e1315 added app split tunneling on home page 2024-04-01 17:07:33 +05:00
Nethius
adab30fc81 feature/app-split-tunneling (#702)
App Split Tunneling for Windows and Android
2024-04-01 12:45:00 +01:00
pokamest
e7bd24f065 Merge pull request #718 from amnezia-vpn/bugfix/cancel-button-on-install-page
fixed display of cancel button on install/uninstall pages
2024-03-31 16:03:32 +01:00
pokamest
2ec448ba13 Merge pull request #717 from amnezia-vpn/feature/page-home-drawer
changed the way the drawer is displayed on the pageHome
2024-03-31 12:15:21 +01:00
albexk
c6e6f2ae84 Add a function that minimizes the Android app (#692)
Add a function that minimizes the Android app
2024-03-31 12:14:12 +01:00
vladimir.kuznetsov
b90bf16945 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/graphview 2024-03-31 15:05:14 +05:00
vladimir.kuznetsov
e9468a4c2f fixed display of cancel button on install/uninstall pages 2024-03-31 12:40:42 +05:00
vladimir.kuznetsov
45de951897 changed the way the drawer is displayed on the pageHome 2024-03-30 16:10:37 +05:00
pokamest
db8d966fac Merge pull request #714 from amnezia-vpn/bugfix/wg-and-xray-remove-button 2024-03-29 09:40:13 +00:00
pokamest
6b69bc9618 Tiny fixes 2024-03-28 17:13:48 +00:00
pokamest
0089b0b799 Error code 206 description 2024-03-28 15:01:17 +00:00
vladimir.kuznetsov
e4841e809b fixed remove button for wireguard and xray settings page 2024-03-28 15:33:23 +05:00
Mykola Baibuz
ba4237f1dd Xray with Reality protocol (#494)
* Xray with Reality for desktops
2024-03-27 11:02:34 +00:00
pokamest
f6acec53c0 Merge pull request #712 from amnezia-vpn/bugfix/page-home-recursive-rearrange
fixed recursive rearrange on PageHome
2024-03-27 10:59:01 +00:00
Shehab Ahmed
5f631eaa76 Refactoring/change application text (#687)
Changing some texts
2024-03-26 18:05:04 +00:00
albexk
7730dd510c Add error handling of enabled "always-on" during VPN connection (#698)
* Always add awg-go version to the log
* Display an error message always when no vpn permission is granted
2024-03-25 23:09:50 +00:00
pokamest
30bd264f17 Merge pull request #711 from amnezia-vpn/bugfix/anchors-page-home-warning
fixed anchors warning on PageHome
2024-03-25 18:38:20 +00:00
vladimir.kuznetsov
5206665fa0 fixed recursive rearrange on PageHome 2024-03-25 22:30:44 +05:00
vladimir.kuznetsov
073491ccb4 fixed anchors warning on PageHome 2024-03-25 21:52:38 +05:00
pokamest
561b62cd40 Merge pull request #705 from amnezia-vpn/bugfix/import-error-handling
fixed error handling for config import
2024-03-23 13:23:31 +00:00
pokamest
1284ed4d84 Merge pull request #706 from amnezia-vpn/translations/connection-label-fix
Fix connection button labels
2024-03-23 00:30:10 +00:00
Andrey Zaharow
6f34443191 Fix connection button labels 2024-03-21 21:34:51 +01:00
vladimir.kuznetsov
02f186c54e fixed error handling for config import 2024-03-21 23:32:11 +05:00
alexeyq2
784c6cf585 Fix AWG/WG on Linux - IPv6 gateway address is ULA now (#701) 2024-03-21 15:03:00 +00:00
pokamest
14f132e127 Merge pull request #703 from amnezia-vpn/feature/linux-ipc-fix
Increase timeout for IPC command
2024-03-21 13:29:14 +00:00
Mykola Baibuz
9cb624e681 Increase timeout for IPC command 2024-03-20 23:10:29 +02:00
isamnezia
516e3da7e2 Fix open log crash and side log improvements (#694)
Fix open log crash
2024-03-20 15:35:36 +00:00
Andrey Zaharow
0e83586cae Fix UI for Burmese language (#682)
* Fix UI for Burmese language
2024-03-20 15:20:09 +00:00
Nethius
95bdae68f4 Auto disable logs after 14 days (#610)
Auto disable logs after 14 days
2024-03-20 14:22:29 +00:00
pokamest
294778884b Merge pull request #691 from amnezia-vpn/bugfix/credentials-space-check
fixed checking credentials for spaces
2024-03-18 14:37:35 +00:00
albexk
10caecbffd Fix wg reconnection problem after awg connection (#696)
* Update Android AWG to 0.2.5
2024-03-18 11:20:01 +00:00
pokamest
553a6a73dd Merge pull request #697 from amnezia-vpn/bugfix/Service-crash-after-disconnecting
ISSUE: Service is crashed after disconnecting
2024-03-18 10:52:25 +00:00
Mykola Baibuz
e646b85e56 Setup MTU for WG/AWG protocol (#576)
Setup MTU for AWG/WG protocol
2024-03-18 10:41:53 +00:00
Dan Nguyen
b7c513c05f ISSUE: Service is crashed after disconnecting
ROOT CAUSE: When disconnecting service, m_logworker is deleted in thread which does not have affinity with m_logworker.
			The time m_logworker is deleted, it may be used by m_logthread and make the service crashed

ACTION: Connect signal finished() of m_logthread to deleteLater() slot of m_logworker to safety delete it.
2024-03-17 07:09:57 +07:00
pokamest
9f82b4c21f Merge pull request #689 from amnezia-vpn/translations/burmese-fix
Shortening of translated text in Burmese
2024-03-16 20:32:37 +00:00
pokamest
02b2da38cf Merge pull request #690 from amnezia-vpn/bugfix/native-config-import-error-handling
added error handling for importing a native config
2024-03-14 17:03:06 +00:00
vladimir.kuznetsov
f51077b2be fixed checking credentials for spaces 2024-03-14 15:59:16 +05:00
vladimir.kuznetsov
33f49bfddb added error handling for importing a native config 2024-03-14 12:55:33 +05:00
Andrey Zaharow
9a81f13f81 Short translated text 2024-03-13 22:44:09 +01:00
albexk
915fb6759a Add Android openssl3 libs, fix https connection error (#685)
Add Android openssl3 libs, fix https connection error
2024-03-13 21:22:56 +00:00
Nethius
c5a5bfde69 extended the validation of the contents of the imported file (#670)
Extended the validation of the contents of the imported file
2024-03-13 21:22:10 +00:00
Andrey Zaharow
0a90fd110d Add RU translation for Error 1101 text (#683)
* Add RU translation for Error 1101 text
2024-03-12 23:17:18 +00:00
pokamest
541d6eb0b8 Merge pull request #686 from amnezia-vpn/fix/allowips-config-change
Add AllowedIPs config change
2024-03-12 18:49:09 +00:00
pokamest
d443a0063d Merge pull request #681 from amnezia-vpn/bugfix/mobile-auto-focus-disable
First element auto-focus disabled for the mobile platforms
2024-03-12 18:48:33 +00:00
pokamest
f0c6edb670 Merge pull request #688 from amnezia-vpn/bugfix/sftp-hostname
bugfix/sftp-hostname
2024-03-12 18:47:42 +00:00
vladimir.kuznetsov
9189b53a0d fixed display of hostName on the sftp settings page 2024-03-12 23:43:24 +05:00
Igor Sorokin
fceccaefcc Add AllowedIPs config change 2024-03-12 19:57:45 +03:00
pokamest
fbeabf43ca Merge pull request #684 from amnezia-vpn/fix/android-remove-ss 2024-03-12 15:17:55 +00:00
albexk
78c7893f90 Remove shadowsocks libs from Android build 2024-03-12 17:17:38 +03:00
Garegin866
cb9a25006c - Removed additional focus frames for buttons inside text fields.
- For mobile platforms, disabled auto-focus on the first element when navigating on the page.
2024-03-12 00:02:47 +04:00
pokamest
0e87550d85 Merge pull request #672 from amnezia-vpn/translations/fix-translations
Fix translations
2024-03-10 16:18:27 -07:00
pokamest
dceb0ab832 Merge pull request #674 from amnezia-vpn/version-bump
Bump Android version code to 47
2024-03-10 04:43:44 -07:00
pokamest
a33590476a Merge pull request #677 from artromone/fix/logger
added commit hash in logger
2024-03-08 14:25:19 -08:00
Artem Romanovich
deaf618520 added commit hash in logger 2024-03-09 00:21:57 +03:00
pokamest
3d8a56d922 Merge pull request #673 from amnezia-vpn/feature/api-request-debug-output
extended debug output for api request
2024-03-07 04:43:07 -08:00
albexk
36af7cf471 Bump Android version code to 47 2024-03-07 14:27:21 +03:00
vladimir.kuznetsov
ebd3449b4a extended debug output for api request 2024-03-07 09:18:25 +03:00
Andrey Zaharow
99182f4a67 Fix translations 2024-03-06 23:04:53 +01:00
pokamest
da84ba1a4d Text fixes and some ts updates 2024-03-06 18:34:07 +00:00
pokamest
bca68fc185 iOS crash fix 2024-03-06 10:07:49 -08:00
pokamest
59a7265bac Merge pull request #671 from amnezia-vpn/bugfix/fade-on-page-start-repalce
fixed screen fade when switching from PageSetupWizardStart to PageStart
2024-03-06 06:36:07 -08:00
vladimir.kuznetsov
9201ca1e03 fixed screen fade when switching from PageSetupWizardStart to PageStart 2024-03-06 14:22:44 +05:00
dimov96
6b6a76d2cc Replace sftp with scp (#602)
Replace sftp with scp
2024-03-06 01:24:28 +00:00
isamnezia
840c388ab9 Add in-app screenshot preventing (#606)
In-app screenshot preventing fixes
2024-03-06 01:18:19 +00:00
Shehab Ahmed
5b4ec608c8 pushing the Burmese translation file (#669)
Burmese translation
2024-03-05 20:49:30 +00:00
pokamest
79ff1b81e0 Merge pull request #666 from amnezia-vpn/bugfix/Revert_PR_596
ISSUE: In start page, icon is highlighted not correctly when press ESC key
2024-03-05 05:07:05 -08:00
pokamest
ea67c01da8 Merge pull request #667 from amnezia-vpn/bugfix/http-replacement
removed the replacement of https by http in apiController
2024-03-04 13:07:06 -08:00
vladimir.kuznetsov
1137e169ea removed the replacement of https by http in apiController 2024-03-04 21:45:04 +03:00
Dan Nguyen
17748cca47 ISSUE: In start page, icon is highlighted not correctly when press ESC key
ROOT CAUSE: The button state is decided by the attribute isServerInfoShow and it was added by commit 68fe20ddf6. The logic to decide whether server info showed is not correct

ACTION: Revert commit 68fe20ddf6
2024-03-04 22:35:34 +07:00
albexk
080e1d98c6 Add Quick Settings tile (#660)
* Add Quick Settings tile

- Add multi-client support to AmneziaVpnService
- Make AmneziaActivity permanently connected to AmneziaVpnService while it is running
- Refactor processing of connection state changes on qt side
- Add VpnState DataStore
- Add check if AmneziaVpnService is running

* Add tile reset when the server is removed from the application
2024-03-04 15:08:55 +00:00
isamnezia
ca633ae882 Remove VPN configurations after app reset on iOS (#661) 2024-03-04 12:25:49 +00:00
albexk
b162147a89 Fix app launch on Android, uncomment statistics processing 2024-03-04 15:17:28 +03:00
isamnezia
bb7b64fb96 Fix QML glitches and crash on iOS (#658)
Fix QML glitches and crash on iOS and Android
2024-03-03 23:28:10 +00:00
AlexanderGalkov
bf901631bf Update Dockerfile (#648)
* Update Dockerfile
* update server scripts for cloak and shadowsocks
* specify the latest cloak and shadowsocks releases in server scripts
2024-03-02 19:45:42 +00:00
Shehab Ahmed
0c0ce54b1f fixed the first-generated QR code is visible while generating another QR code bug (#656) 2024-03-02 19:06:33 +00:00
pokamest
ee762c4cef Merge pull request #653 from amnezia-vpn/fix/config-from-tg
Fix adding config from bot (iOS)
2024-02-29 07:05:24 -08:00
pokamest
ed9efb5a79 Merge pull request #654 from amnezia-vpn/fix/config-sync-ios
Sync configs and fix bug in NE (iOS)
2024-02-29 03:09:20 -08:00
Igor Sorokin
73eb85f2f4 Sync configs 2024-02-29 13:58:11 +03:00
Nethius
cd055cff62 removed the display of servers without containers on PageShare (#609)
* removed the display of servers without containers on PageShare

* removed unused isAnyContainerInstalled() from containers model

* added tab navigation to the share connection drawer

* fixed display of default server without containers on PageShare
2024-02-29 10:22:17 +00:00
Igor Sorokin
f8b2cce618 Fix adding config from bot 2024-02-29 08:36:56 +03:00
sa6ta6ni6c
e648054c7a Misc update README (#652)
Update README.md
2024-02-29 00:14:09 +00:00
pokamest
fe558163cc Merge pull request #651 from amnezia-vpn/bugfix/on-escape-pressed
fixed initial value of m_drawerDepth
2024-02-28 06:35:38 -08:00
vladimir.kuznetsov
3883b8ff34 fixed initial value of m_drawerDepth 2024-02-28 17:31:46 +03:00
pokamest
d286664763 Merge pull request #649 from sa6ta6ni6c/patch-1
Ru translation update
2024-02-28 05:31:14 -08:00
Nethius
b05ad2392b added escape key handler (#461)
Added escape key handler for drawer2type
2024-02-28 12:39:28 +00:00
Nethius
6dbdb85aaf fixed "file does not exist" error when opening a file for saving (#636) 2024-02-28 12:32:25 +00:00
sa6ta6ni6c
26b48cfe4f Обновил перевод 2024-02-27 20:47:41 +00:00
Nethius
faaf5973b4 Merge pull request #603 from amnezia-vpn/feature/graphview-ios
Feature/graphview (iOS)
2024-02-27 17:23:09 +07:00
vladimir.kuznetsov
aa4bfc70b9 Merge branch 'feature/graphview' of github.com:amnezia-vpn/amnezia-client into feature/graphview-ios 2024-02-27 15:22:06 +05:00
vladimir.kuznetsov
ef674d1e4f add charts to the list of packages for all platforms 2024-02-27 14:53:09 +05:00
Andrey Zaharow
2f39136143 Fix translations (#646)
Fix awg texts
2024-02-26 21:17:57 +00:00
pokamest
8d0d3c5ce9 Merge pull request #641 from amnezia-vpn/feature/linux-ipv6
Remove ipv6 address for Linux WG/AWG interface
2024-02-26 12:07:50 -08:00
lunardunno
256081e4ed Improved server cleaning (#639)
Deleting the amnezia directory in opt when cleaning the server.
2024-02-26 12:35:31 +00:00
pokamest
1dd7b0a221 Merge pull request #647 from amnezia-vpn/bugfix/ru-translations
fixed ru translations file
2024-02-26 04:17:42 -08:00
vladimir.kuznetsov
82c0b28906 fixed ru translations file 2024-02-26 17:12:46 +05:00
KsZnak
985fe083f0 split-tunneling translate (#640)
Update amneziavpn_ru.ts
2024-02-26 11:53:22 +00:00
pokamest
6a0000dc4b Merge pull request #642 from amnezia-vpn/translations/update_zh_CN
Update amneziavpn_zh_CN.ts
2024-02-26 03:47:31 -08:00
pokamest
1dd2f38066 Merge pull request #643 from amnezia-vpn/translations/update_fa_IR.ts
Update amneziavpn_fa_IR.ts
2024-02-26 03:45:04 -08:00
pokamest
004e1e3ca5 MacOS GH actions QIF fix (#645)
Install Qt Installer Framework 4.6 from R2 to keep compatibility for old MacOS. In addition, update Qt version in build scripts.
2024-02-26 10:44:28 +00:00
KsZnak
7c560d709b Update amneziavpn_fa_IR.ts 2024-02-24 22:16:18 +02:00
KsZnak
d3743ad62f Update amneziavpn_zh_CN.ts 2024-02-24 22:06:05 +02:00
pokamest
ac234b77e2 Merge pull request #638 from amnezia-vpn/update/update_ts
Update all translations
2024-02-24 06:59:50 -08:00
Mykola Baibuz
9886987e68 Remove ipv6 address for Linux WG/AWG interface 2024-02-24 16:07:59 +02:00
pokamest
d34cb8898f Update all translations 2024-02-24 11:51:22 +00:00
Mykola Baibuz
23633e8fa7 Statistic for WG/AWG protocol 2024-02-23 20:31:59 +02:00
pokamest
13aadbda64 Merge pull request #637 from amnezia-vpn/bugfix/connection-drawer-close-button
fixed connection drawer close button
2024-02-23 09:56:52 -08:00
agalehaga
c7c7c8eb01 added export awg native format (#635)
add export awg native format
2024-02-23 17:55:59 +00:00
vladimir.kuznetsov
b1e5bba33f fixed connection drawer close button 2024-02-23 22:51:46 +05:00
agalehaga
3cc846678e merge 2024-02-23 19:15:40 +02:00
pokamest
474e7c6d62 Merge pull request #634 from amnezia-vpn/update/gh_actions_qt_update
Update Qt in deploy.yml
2024-02-22 06:02:04 -08:00
pokamest
794ec921b8 Update Qt in deploy.yml 2024-02-22 13:28:37 +00:00
pokamest
b674240362 Merge pull request #632 from amnezia-vpn/refactoring/changing-settings-item-location
moving settings item to other settings page
2024-02-22 05:02:13 -08:00
pokamest
a768c7c451 Merge pull request #633 from rodionos/patch-1
MacOS build: increase image size to 256Mb
2024-02-22 04:58:21 -08:00
Sergei Rodionov
28d2a4ec2c MacOS build: increase image size to 256Mb
In my case, using Qt 6.6.2, the size of the AmneziaVPN.dmg file is 226Mb so a higher image size is needed for the hdiutil command.
2024-02-22 13:57:58 +03:00
Shehab Ahmed
9f1210d18f changed the location of Auto connect item from settings connections page to settings application page 2024-02-22 02:31:51 +02:00
pokamest
3012559627 Merge pull request #630 from amnezia-vpn/feature/api-containers-listview
for api servers, removed the ability to select a container
2024-02-21 11:03:18 -08:00
vladimir.kuznetsov
b3ed57aee7 for api servers, removed the ability to select a container 2024-02-21 23:41:47 +05:00
pokamest
89d0a8107d Merge pull request #620 from amnezia-vpn/translations/fix-for-pr618
Fix translation for #618
2024-02-21 06:03:12 -08:00
Andrey Zaharow
6c0b71bd1b Fix translation on About Page (#618)
Fix About Page
2024-02-21 14:01:53 +00:00
Nethius
61abf74b2d feature/page-home-split-tunneling (#540)
Added split tunneling button on home page
2024-02-21 11:27:27 +00:00
pokamest
21fdf02921 Merge pull request #625 from amnezia-vpn/bugfix/default-server-default-container-update
fixed the use of defaultServerDefaultContainerChanged
2024-02-21 03:22:09 -08:00
vladimir.kuznetsov
7a245d80ee fixed the use of defaultServerDefaultContainerChanged 2024-02-21 13:06:39 +05:00
KsZnak
da85922f23 Update amneziavpn_zh_CN.ts (#617)
Update amneziavpn_zh_CN.ts
2024-02-20 20:49:26 +00:00
pokamest
a5356b6319 Merge pull request #623 from amnezia-vpn/update/Arabic-translation
updated the Arabic translation for fixing some sentences
2024-02-20 12:47:41 -08:00
KsZnak
3828891b9b Update amneziavpn_fa_IR.ts (#622)
Update amneziavpn_fa_IR.ts
2024-02-20 20:46:23 +00:00
pokamest
15d866ce04 WG/AWG ipv6 fix (#621)
WG/AWG ipv6 fix
2024-02-20 19:05:36 +00:00
Shehab Ahmed
560eb3d620 updated the Arabic translation for fixing some sentences 2024-02-20 20:37:19 +02:00
Andrey Zaharow
ac894254cc Fix translation for #618 2024-02-20 00:23:20 +01:00
pokamest
17e3fbde25 Merge pull request #616 from amnezia-vpn/bugfix/cursor-changing-fix
Fix cursor change when hover over elements
2024-02-19 12:20:46 -08:00
agalehaga
84e8667e57 merge 2024-02-19 21:42:27 +02:00
agalehaga
b500a1f09d update translations 2024-02-19 21:38:43 +02:00
Andrey Zaharow
ee11a8410c Fix cursor change when hover over elements 2024-02-19 18:28:29 +01:00
pokamest
ff5c51cfd9 Merge pull request #615 from amnezia-vpn/KsZnak-patch-1
Update amneziavpn_ru.ts
2024-02-19 07:10:49 -08:00
Nethius
b3943ae5e3 serversModel cleanup (#599) 2024-02-19 14:54:15 +00:00
pokamest
a32952fde6 Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText for
all TextFields
2024-02-19 14:06:18 +00:00
isamnezia
9c4ee4014d Fix for Codacy: variable name should be between 3 and 40 characters long (#608)
Tiny fixes for iOS
2024-02-19 13:13:10 +00:00
KsZnak
dc9069f1f4 Update_2_amneziavpn_ru.ts
Add new change
2024-02-19 13:37:40 +02:00
pokamest
e402cacc05 Merge pull request #614 from amnezia-vpn/bugfix/translations
returned translation files to commit fab167bb34a9f7199359e3d8589a1cd1…
2024-02-19 02:23:39 -08:00
vladimir.kuznetsov
a98cd248d6 returned translation files to commit fab167bb34 2024-02-19 09:31:31 +05:00
pokamest
00fbfb6a01 Merge pull request #611 from amnezia-vpn/refactoring/show-installed-containers-first
show installed protocols first
2024-02-18 11:10:37 -08:00
agalehaga
2399d45bab fixed can't find Qt6::Charts 2024-02-18 15:10:20 +02:00
agalehaga
77e82fbf40 Merge branch 'feature/graphview' of github.com:amnezia-vpn/amnezia-client into feature/graphview 2024-02-18 12:28:35 +02:00
agalehaga
a6467dd0f0 merge dev 2024-02-18 12:28:02 +02:00
vladimir.kuznetsov
86c31c3766 show installed protocols first in services tab and page home containers listview 2024-02-18 13:24:21 +05:00
agalehaga
698cfe910c add navigation using enter + buttons will be clicked if enter (if but… (#556)
Enter navigation
2024-02-17 21:09:05 +00:00
pokamest
16db23c159 Rewrite sftp file copy to Qt way (#562)
Rewrite sftp file copy to Qt way
2024-02-17 21:07:17 +00:00
Andrey Zaharow
b05a5ee1c6 fix connection button behavior (#595)
Fix connection button behavior
2024-02-17 19:57:31 +00:00
pokamest
8cb298937f Merge pull request #604 from amnezia-vpn/KsZnak-ru_translate
Update amneziavpn_ru.ts
2024-02-17 11:52:18 -08:00
Andrey Zaharow
68fe20ddf6 UI fixes (#596)
UI fixes
2024-02-17 19:48:41 +00:00
KsZnak
fab167bb34 Update amneziavpn_ru.ts 2024-02-17 20:29:25 +02:00
Igor Sorokin
2e11cc56ab Fix chart rendering (wrong SplineSeries.style) 2024-02-17 19:55:14 +03:00
isamnezia
f640d4b5f5 Remove config string dependency (#577)
Remove WG/AWG config string dependency
2024-02-16 10:30:00 +00:00
Nethius
074562b141 feature/custom-drawer (#563)
Replaced all the DrawerType with DrawerType2
2024-02-16 10:24:06 +00:00
Shehab Ahmed
fd030a5fd4 Arabic translation (#594)
added Arabic translation
2024-02-16 10:19:47 +00:00
albexk
82fa6b13c6 Fix foreground service type (#592)
Fix foreground service type
2024-02-14 16:35:40 +00:00
Igor Sorokin
c2d204b362 Merge remote-tracking branch 'refs/remotes/origin/feature/graphview' into feature/graphview 2024-02-14 19:18:52 +03:00
Igor Sorokin
77a83e4fc3 Additional setup for Qt Charts 2024-02-14 17:52:30 +03:00
agalehaga
8617896c7a Merge branch 'dev' into feature/graphview 2024-02-14 13:36:22 +02:00
agalehaga
97c6b217f2 refactoring: changed SystemController.hasFocus to SystemController.appHasFocus 2024-02-14 13:34:35 +02:00
pokamest
bf16298c40 Version bump - 4.4.0.0 2024-02-13 21:10:47 +00:00
pokamest
bcebb0a2b5 Merge pull request #580 from amnezia-vpn/feature/update-cloak-binary
Update AWG and Cloak libraries
2024-02-13 12:03:02 -08:00
agalehaga
efde0c99a3 Merge branch 'dev' into feature/graphview 2024-02-13 18:46:56 +02:00
pokamest
b27442cf74 Merge pull request #583 from amnezia-vpn/bugfix/double_clear_server_from_amnezia
fixed bug with double button clear server from amnezia software
2024-02-13 07:50:35 -08:00
Nethius
92fbbd4812 bugfix/default-container-index (#578)
fixed get/set DefaultContainer
2024-02-13 15:20:13 +00:00
agalehaga
321ed810e3 fixed bug with double button clear server from amnezia software 2024-02-13 15:16:04 +02:00
albexk
17ff530683 Merge branch 'fix/android' into feature/update-cloak-binary 2024-02-13 12:32:36 +03:00
albexk
2b413736a4 Build with new version of awg lib. Move GoBackend to org.amnezia.vpn.protocol.wireguard package. 2024-02-13 12:30:55 +03:00
pokamest
a416d03614 Merge pull request #581 from amnezia-vpn/fix/amn-go-version
Update amneziawg-apple to amneziawg-go v0.2.1
2024-02-12 13:08:19 -08:00
Igor Sorokin
4de9a274dd Update amneziawg-apple to amneziawg-go v0.2.1 2024-02-12 23:25:11 +03:00
Mykola Baibuz
0b8f3c9d9d Update Cloak binary to v2.8.0 2024-02-12 21:01:44 +02:00
agalehaga
2dccfce468 merge 2024-02-12 10:33:33 +02:00
isamnezia
f3a168fd43 Codacy compatibility (#575)
Refactor and split iostunnel with cmake changes, code cleanup
2024-02-10 22:55:54 +00:00
isamnezia
158c11a0ec Ios log 4 (#569)
iOS logging refactoring
2024-02-10 16:44:55 +00:00
pokamest
f2d13148a3 Windows build fix 2024-02-09 23:33:24 +00:00
pokamest
6c8b4e1fb2 Merge pull request #572 from amnezia-vpn/cleanup/remove_libleaf
libleaf cleanup
2024-02-09 14:49:19 -08:00
pokamest
c95dffff0c libleaf cleanup 2024-02-09 21:22:27 +00:00
pokamest
6346fc04ae Cleanup/3rd cleanup (#570) 2024-02-09 21:02:24 +00:00
pokamest
3a87354f8d Code cleanup [noci] 2024-02-09 19:28:20 +00:00
Nethius
e0863a58aa feature/api-controller-improvements (#567)
* added error handler for api controller
* while downloading the config from the api, the Connecting status is now displayed
* added a button to delete container config for api servers
* added crc check to avoid re-import of api configs
* fixed currentIndex of serversMenuContent after DefaultServerIndexChanged
* added closing the import window after re-importing the config from api
2024-02-09 18:23:26 +00:00
lunardunno
dba05aab07 Improved docker cleanup. (#568)
Improved docker cleanup.
Removing anonymous volumes associated with containers. 
Specifying the full name of the amn0 network interface to remove when cleaning the server.
2024-02-09 13:00:44 +00:00
pokamest
fec904fd28 Merge pull request #566 from amnezia-vpn/bugfix/build_windows
Revert ninja generator for Windows builds
2024-02-07 05:03:16 -08:00
pokamest
db321bed5d Revert ninja generator for Windows builds 2024-02-07 12:37:39 +00:00
pokamest
28cc0218c5 Merge pull request #564 from amnezia-vpn/pipeline
Improve pipeline
2024-02-06 09:39:04 -08:00
tiaga
a2d5f25b58 Improve pipeline
Update GitHub Actions versions to avoid deprecation warnings.
2024-02-06 23:40:46 +07:00
pokamest
3100160927 Update translations 2024-02-05 22:14:01 +00:00
pokamest
1c3fdd3c72 Merge pull request #561 from amnezia-vpn/bugfix/build_windows_fix
Bugfix/build_windows.bat fix
2024-02-05 06:40:04 -08:00
pokamest
0c13eda1f5 build_windows.bat fix 2024-02-05 13:09:53 +00:00
pokamest
f37b7cec87 Merge pull request #557 from amnezia-vpn/KsZnak-br1
Update PageSetupWizardCredentials.qml
2024-02-05 04:25:24 -08:00
pokamest
962c75b2ca Merge pull request #558 from amnezia-vpn/KsZnak-text-change
Update PageSettingsServerData.qml
2024-02-05 04:25:04 -08:00
pokamest
9a62e2ae41 Merge pull request #560 from amnezia-vpn/revert-559-KsZnak-translation-ru-ex
Revert "Update amneziavpn_ru.ts"
2024-02-05 02:49:46 -08:00
pokamest
0f00dc4e7c Revert "Update amneziavpn_ru.ts" 2024-02-05 10:48:31 +00:00
pokamest
0f04cf6eae Merge pull request #559 from amnezia-vpn/KsZnak-translation-ru-ex
Update amneziavpn_ru.ts
2024-02-05 02:34:54 -08:00
KsZnak
dc76ad820f Update amneziavpn_ru.ts 2024-02-05 01:39:39 +02:00
KsZnak
e0cde9f138 Update PageSetupWizardCredentials.qml 2024-02-04 22:02:47 +02:00
KsZnak
db1dc78e38 Update PageSettingsServerData.qml 2024-02-04 21:59:55 +02:00
agalehaga
fd98ef1250 Reboot server button (#553)
* add button Reboot Server
2024-02-04 16:52:03 +00:00
pokamest
eaa603684c Merge branch 'dev' into feature/graphview 2024-02-02 13:24:11 +00:00
pokamest
cdf46c968a Merge pull request #480 from amnezia-vpn/feature/error-code-output
added error code output
2024-02-01 05:05:36 -08:00
pokamest
72b20ef563 Version bump - 4.3.0.0 2024-01-31 20:37:10 +00:00
pokamest
30a0ac0def Merge pull request #527 from amnezia-vpn/feature/api-awg
added support for awg configs for api
2024-01-31 12:04:54 -08:00
albexk
090208bd2c Bug fix for processing exclude routes for older android versions 2024-01-31 19:59:00 +03:00
vladimir.kuznetsov
1e5c9c9c4d if allowedIps from the backend is empty, split tunneling of the application works 2024-01-31 21:41:46 +07:00
vladimir.kuznetsov
5918f37ffa Merge branch 'feature/api-awg' of github.com:amnezia-vpn/amnezia-client into feature/api-awg 2024-01-31 21:30:47 +07:00
vladimir.kuznetsov
554e1b1b91 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/api-awg 2024-01-31 21:30:18 +07:00
vladimir.kuznetsov
8f510c1431 added allowedIPs processing for configs from the backend 2024-01-31 21:29:39 +07:00
vladimir.kuznetsov
4723019624 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2024-01-31 12:42:19 +07:00
vladimir.kuznetsov
1be9078b6c added break after each line in errorstrings 2024-01-31 12:42:05 +07:00
pokamest
520658a295 Merge pull request #550 from amnezia-vpn/KsZnak-patch-1
Ks znak patch 1
2024-01-30 15:58:50 -08:00
pokamest
b9ec722abb Merge pull request #543 from amnezia-vpn/KsZnak-patch-7
Update PageSettingsSplitTunneling.qml
2024-01-30 15:57:40 -08:00
pokamest
d917c798d7 Merge pull request #544 from amnezia-vpn/KsZnak-patch-8
Update PageSettingsAbout.qml
2024-01-30 15:57:10 -08:00
pokamest
0d168c039f Merge pull request #545 from amnezia-vpn/KsZnak-patch-6
Update PageSettingsSplitTunneling.qml
2024-01-30 15:56:50 -08:00
pokamest
af8f265555 Merge pull request #546 from amnezia-vpn/KsZnak-patch-5
Update PageSettingsConnection.qml
2024-01-30 15:56:29 -08:00
pokamest
c0e0d64284 Merge pull request #547 from amnezia-vpn/KsZnak-patch-4
Update PageServiceTorWebsiteSettings.qml
2024-01-30 15:56:02 -08:00
pokamest
9466a71141 Merge pull request #548 from amnezia-vpn/KsZnak-patch-3
Update PageProtocolOpenVpnSettings.qml
2024-01-30 15:55:29 -08:00
pokamest
d28a586a97 Merge pull request #549 from amnezia-vpn/KsZnak-patch-2
Update containers_defs.cpp
2024-01-30 15:55:04 -08:00
pokamest
6fde0b6663 Merge pull request #551 from amnezia-vpn/KsZnak-change-eng-text
Update PageSetupWizardCredentials.qml
2024-01-30 15:54:10 -08:00
KsZnak
d143b9213b Update PageSettingsAbout.qml 2024-01-30 20:50:30 +02:00
KsZnak
16433e9e46 Update PageSettingsSplitTunneling.qml 2024-01-30 20:40:11 +02:00
KsZnak
39479d1999 Update PageSettingsSplitTunneling.qml 2024-01-30 20:35:05 +02:00
KsZnak
a03b766e33 Update PageSettingsConnection.qml 2024-01-30 20:27:01 +02:00
KsZnak
7df2655ba0 Update PageServiceTorWebsiteSettings.qml 2024-01-30 20:22:26 +02:00
KsZnak
5c2ca9803d Update PageProtocolOpenVpnSettings.qml 2024-01-30 20:08:14 +02:00
KsZnak
4e6af947fa Update containers_defs.cpp 2024-01-30 20:05:18 +02:00
pokamest
bc9d5c8fd6 Merge branch 'dev' into feature/api-awg 2024-01-30 10:15:13 +00:00
pokamest
7ef41bfe75 GraphViewType fixes 2024-01-30 10:02:48 +00:00
pokamest
e5c25e8a0c Merge branch 'dev' into feature/graphview 2024-01-29 23:16:54 +00:00
pokamest
f412ac6260 Merge pull request #537 from amnezia-vpn/ios-log-3
Disable ioslogger (due memory leak)
2024-01-29 11:37:17 -08:00
pokamest
26d8dfbb7f Merge branch 'dev' into feature/api-awg 2024-01-29 19:35:35 +00:00
pokamest
b45517bafd Merge pull request #444 from amnezia-vpn/feature/killswitch
Kill Switch for desktop client
2024-01-29 11:23:23 -08:00
vladimir.kuznetsov
3edb6755b4 fixed filling in the wg private key 2024-01-30 00:47:22 +07:00
pokamest
bda64fa391 Merge pull request #536 from amnezia-vpn/bugfix/revoke-openvpn-client
fixed cache clearing when deleting admin configure
2024-01-29 07:31:09 -08:00
vladimir.kuznetsov
e7040f7cc8 specified error codes 2024-01-29 21:33:35 +07:00
pokamest
229970e799 Merge pull request #542 from amnezia-vpn/KsZnak-patch-2
Update amneziavpn_ru.ts
2024-01-28 13:10:49 -08:00
KsZnak
7b0a9a055f Update amneziavpn_ru.ts 2024-01-28 21:46:20 +02:00
pokamest
06d370f716 Merge pull request #541 from amnezia-vpn/version-bump
Version bump 4.2.1.1
2024-01-28 07:23:58 -08:00
albexk
ce0a4f1f96 Version bump 4.2.1.1 2024-01-28 17:29:54 +03:00
vladimir.kuznetsov
3240aa3cb3 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2024-01-28 21:24:23 +07:00
Victor Corchez
c9af9f34fc fixed CPU consumption and added graph values persistence 2024-01-28 15:50:37 +02:00
pokamest
5c5935c738 Merge pull request #539 from amnezia-vpn/bugfix/android
Fix Android bugs
2024-01-28 05:25:38 -08:00
pokamest
00b2b1abcd Merge pull request #529 from amnezia-vpn/bugfix/container-selection-after-cleanup-server
fixed first container selection on HomeContainersListView after server cleanup
2024-01-28 02:56:16 -08:00
Mykola Baibuz
e0891e1a15 Change license text 2024-01-28 05:39:12 -05:00
vladimir.kuznetsov
f7df621c56 fixed cache clearing when deleting admin configure
- added permissions for the crl.pem file
2024-01-27 18:09:14 +03:00
albexk
0b6dc5bcfc Add unbinding and destroying vpn service after disconnection 2024-01-27 17:34:57 +03:00
albexk
cbd6755aa5 Fix OpenVpn over Cloak 2024-01-27 17:30:56 +03:00
albexk
3afbc248b1 Refactor split-tunneling: separate site addresses from routes 2024-01-27 17:28:31 +03:00
Mykola Baibuz
30af81fe0a Move linuxfirewall header to "headers" part 2024-01-27 07:59:36 -05:00
Mykola Baibuz
427b43c99b Add code license 2024-01-27 07:50:50 -05:00
KsZnak
ed08ac6b46 Update containers_defs.cpp 2024-01-27 00:58:40 +02:00
KsZnak
1a2c1fa1b5 Update PageSetupWizardCredentials.qml 2024-01-27 00:18:17 +02:00
Igor Sorokin
709fbac231 Disable ioslogger (due memory leak) 2024-01-25 19:07:22 +03:00
Victor Corchez
acfe19b914 cleanup 2024-01-25 14:08:43 +02:00
pokamest
6b80a56f92 Merge pull request #530 from amnezia-vpn/bugfix/admin-user-clinet-management
fixed adding admin user to client management
2024-01-25 01:58:39 -08:00
Victor Corchez
81242b405f Update deploy.yml 2024-01-25 09:00:32 +02:00
Mykola Baibuz
5c9d45a8a8 Use MacOS logic for LinuxFirewall 2024-01-24 17:20:50 -05:00
pokamest
2edac24945 Merge pull request #532 from amnezia-vpn/bugfix/issue485
Fix autostart for Linux Desktop
2024-01-24 11:32:37 -08:00
albexk
b68c9cc145 Fix the double extension of the config file name: 'amnezia_config.vpn.vpn' 2024-01-24 17:00:48 +03:00
albexk
6f02d4eb62 Remove useless 'Open folder with logs' button for Adnroid too 2024-01-24 16:34:37 +03:00
pokamest
6e60688e70 Merge pull request #533 from amnezia-vpn/bugfix/easy-setup-random-port
random ports are now used for easy setup
2024-01-24 05:20:17 -08:00
Victor Corchez
61092259ba Implemented graphview for down/up traffic 2024-01-24 07:34:40 +02:00
vladimir.kuznetsov
140b5c4292 random ports are now used for easy setup 2024-01-24 12:27:11 +07:00
pokamest
8ee2ebbd20 Merge pull request #531 from amnezia-vpn/ios-log-2
Fix/iOS log (Part 2)
2024-01-23 14:18:17 -08:00
Igor Sorokin
b3eda4106d Fix: Share view is not showing on iPadOS 2024-01-23 23:41:08 +03:00
Mykola Baibuz
885e22be7c Fix autostart for Linux Desktop 2024-01-23 15:17:07 -05:00
vladimir.kuznetsov
83ec073734 fixed adding admin user to client management 2024-01-24 00:33:19 +07:00
vladimir.kuznetsov
0160b0f9dc editServer now does not update the whole model, but only the modified element 2024-01-23 23:57:14 +07:00
vladimir.kuznetsov
f55bd5e1a1 fixed first container selection on HomeContainersListView after server cleanup 2024-01-23 23:56:16 +07:00
Igor Sorokin
4d88eb8e79 Try to expand 'internal error' 2024-01-23 18:41:33 +03:00
Mykola Baibuz
874de74ac8 Add exclusion for VPN Server host (MacOS/OpenVPN) 2024-01-22 20:32:40 +02:00
pokamest
b3a4b34d48 Merge pull request #524 from amnezia-vpn/KsZnak-patch-1
Update amneziavpn_ru.ts
2024-01-22 07:27:45 -08:00
vladimir.kuznetsov
f7b9d2bae7 added support for awg configs for api 2024-01-22 16:51:11 +03:00
KsZnak
ec4574bfcf Update amneziavpn_ru.ts 2024-01-22 01:52:14 +02:00
pokamest
73cfab166f Merge pull request #523 from amnezia-vpn/fix/ios-log
Fix/iOS log (Part 1)
2024-01-21 13:02:28 -08:00
Igor Sorokin
0e8f85057d Remove distracting 'stale focus object' records from log 2024-01-21 21:15:34 +03:00
Igor Sorokin
2e4908c557 Records detailed disconnect error info to log 2024-01-21 20:41:06 +03:00
Igor Sorokin
401784414a Fix: 'OpenVPN' is recorded to the log instead of 'WireGuard' 2024-01-21 19:05:24 +03:00
Igor Sorokin
8495124bc8 Remove useless 'Open folder with logs' button (iOS) 2024-01-21 17:49:24 +03:00
pokamest
ba6ed540f5 Merge pull request #521 from amnezia-vpn/KsZnak-patch-2
Update README.md
2024-01-20 12:16:16 -08:00
KsZnak
19a60ea856 Update README.md
del signal link
2024-01-20 22:13:00 +02:00
pokamest
aecf1b463c Merge pull request #519 from amnezia-vpn/fix/android-deploy
Enable AAB build for all branches
2024-01-20 11:08:24 -08:00
pokamest
ff24ba1011 Merge pull request #518 from amnezia-vpn/fix/android-wgipv6
Fix wg address parameter parsing
2024-01-20 10:57:36 -08:00
albexk
802b708232 Enable AAB build for all branches 2024-01-20 21:49:37 +03:00
pokamest
adeff3efb9 Version bump 4.2.1.0 2024-01-20 18:46:33 +00:00
albexk
0103c1722e Fix wg address parameter parsing 2024-01-20 21:38:58 +03:00
pokamest
f9123e7b71 Merge pull request #516 from amnezia-vpn/bugfix/easy-setup-default-container
fixed easy setup default container selection
2024-01-20 09:18:57 -08:00
pokamest
0f9ed4e69c Merge pull request #515 from amnezia-vpn/fix/android-wg
set wg PresharedKey parameter as optional
2024-01-20 09:16:16 -08:00
vladimir.kuznetsov
9dfc95bac0 fixed easy setup default container selection 2024-01-20 23:28:20 +07:00
albexk
9b7914538f set wg PresharedKey parameter as optional 2024-01-20 18:43:26 +03:00
pokamest
85c9cd260d Merge pull request #514 from amnezia-vpn/fix/android-camera
Hide "QR-code" button from config import menu for Android devices wit…
2024-01-20 07:42:55 -08:00
pokamest
73751cc049 Merge pull request #513 from amnezia-vpn/bugfix/issue499
Fix import of some native WG configs
2024-01-20 07:27:54 -08:00
albexk
2b61c48303 Hide "QR-code" button from config import menu for Android devices without camera 2024-01-20 18:20:06 +03:00
Mykola Baibuz
47b03f2bf4 PSK paramater is not mandatory 2024-01-20 08:44:48 -05:00
albexk
3e02dfef63 Refactoring Android logging (#511)
Refactoring Android logging
2024-01-20 13:40:12 +00:00
Mykola Baibuz
4176d0130a Fix import of some native WG configs 2024-01-20 08:35:24 -05:00
pokamest
f6175c2c69 Merge pull request #512 from amnezia-vpn/fix/line-ending
Fix amnezia_application line-ending
2024-01-20 05:04:22 -08:00
albexk
b8b423ca19 Fix amnezia_application line-ending 2024-01-20 16:02:35 +03:00
pokamest
3702d69b9d Merge branch 'dev' into feature/killswitch 2024-01-19 14:58:28 +00:00
pokamest
3253de9384 Merge pull request #509 from amnezia-vpn/featute/amneziawg-apple
Change to amneziawg-apple
2024-01-19 02:17:02 -08:00
Igor Sorokin
51070635a5 Change to amneziawg-apple 2024-01-19 03:27:44 +03:00
pokamest
9b533f1ba6 Merge pull request #507 from amnezia-vpn/linux-installer
Improve Linux installer
2024-01-18 09:39:00 -08:00
tiaga
9371dd405e Improve Linux installer
Pack installer to a .tar archive in order to save executable bit for `AmneziaVPN_Linux_Installer.bin`.
2024-01-19 00:16:19 +07:00
pokamest
27d8108e55 Merge pull request #501 from amnezia-vpn/feature/api-spit-tunneling
for servers received via api, ignore the split tunneling settings
2024-01-18 08:51:12 -08:00
pokamest
820a3f0b77 Merge pull request #506 from amnezia-vpn/bugfix/client-management-ss-cloak
fixed append/rename/revoke client for cloak and ss on client management panel
2024-01-18 07:09:14 -08:00
pokamest
3d61b20271 Merge pull request #505 from amnezia-vpn/fix/readme
Update README.md
2024-01-18 07:03:08 -08:00
vladimir.kuznetsov
eec81f8124 fixed append/rename/revoke client for cloak and ss on client management panel 2024-01-18 21:29:56 +07:00
Igor Sorokin
d7fbddb97f Update README.md 2024-01-18 17:13:04 +03:00
pokamest
9170cb0318 Merge pull request #498 from amnezia-vpn/sort-installer-containers-first
show installed protocols first in protocols tab
2024-01-18 05:57:16 -08:00
pokamest
76dec6fa9c Merge pull request #504 from amnezia-vpn/feature/android-deploy
Add Android App Bundle build and upload
2024-01-18 05:56:50 -08:00
pokamest
4e3edcfc0a Merge pull request #503 from amnezia-vpn/fix/ipv6
Fix IPv6 problem
2024-01-18 05:56:07 -08:00
albexk
ad21d7ab64 Add Android App Bundle build and upload
Up upload-artifact action to version 4
2024-01-18 16:06:37 +03:00
Igor Sorokin
f576eb509d Fix IPv6 problem 2024-01-18 15:25:36 +03:00
vladimir.kuznetsov
33e229d0b2 added blocking of the page with dns settings for servers received by API 2024-01-17 23:38:20 +07:00
pokamest
78420d617b Merge pull request #502 from amnezia-vpn/fix/android-clipboard
Fix/android clipboard
2024-01-17 07:24:24 -08:00
albexk
2552e33d64 Add Android TextArea clipboard workaround 2024-01-17 17:46:54 +03:00
albexk
301141c755 Remove Android TextField workaround
It has been fixed in Qt 6.5.3, 6.6.0
2024-01-17 17:43:54 +03:00
vladimir.kuznetsov
fac57ac89a for servers received via api, ignore the split tunneling settings 2024-01-17 11:28:57 +07:00
pokamest
da5ad0a845 Merge pull request #500 from amnezia-vpn/fix/android-keyboard
Restore previous Android keyboard behavior
2024-01-16 05:50:28 -08:00
albexk
60aeefe1c2 Restore previous Android keyboard behaviour
There is a Qt bug related to this behaviour: https://bugreports.qt.io/browse/QTBUG-41170
2024-01-16 15:06:34 +03:00
Morteza Sherafati
d527f6a5ce show installed protocols first in protocols tab 2024-01-15 20:18:10 +00:00
pokamest
2802b42747 Merge pull request #491 from amnezia-vpn/bugfix/current-processed-server-selection
fixed current processed server selection after import/install new server
2024-01-15 05:43:34 -08:00
pokamest
66c5d2f0a8 Updated submodule qtkeychain 2024-01-15 10:06:20 +00:00
pokamest
6dbf4ac62c Release 4.2.0.1 2024-01-15 09:28:48 +00:00
pokamest
ae2872830b Updated submodule qtkeychain 2024-01-15 09:20:13 +00:00
pokamest
6f4a3587e4 Merge pull request #495 from amnezia-vpn/feature/update-awg-core
Update AWG core (v0.1.8)
2024-01-14 17:33:10 -05:00
Mykola Baibuz
145f51906e Update AWG core (v0.1.8) 2024-01-14 21:58:53 +02:00
pokamest
12e72bc74b Merge pull request #481 from amnezia-vpn/refactoring/android
Refactor Android open file method
2024-01-13 06:46:25 -05:00
pokamest
65a04799ef Merge branch 'dev' into feature/killswitch 2024-01-11 13:45:56 +00:00
vladimir.kuznetsov
88cd5825d3 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2024-01-11 20:26:06 +07:00
pokamest
ecdad2a315 Merge branch 'dev' into refactoring/android 2024-01-11 13:01:03 +00:00
pokamest
0398ddd6a2 Merge pull request #488 from amnezia-vpn/bugfix/split-tunnel-reset-on-app-reset
bugfix/split-tunnel-reset-on-app-reset
2024-01-11 07:58:04 -05:00
pokamest
50ea4d3b0f Merge pull request #453 from amnezia-vpn/bugfix/windows-crush-on-utf8-symbolos
added conversion using the system locale
2024-01-11 07:51:22 -05:00
pokamest
77be8169f2 Merge pull request #493 from amnezia-vpn/bugfix/secureqsettings-deadlock-2
now value and setValue of secureQSettings are always called in the main thread
2024-01-11 07:48:42 -05:00
lunardunno
7a435f76b6 ArchLinux_support (#463)
Arch linux support (#464)
2024-01-10 20:15:14 +00:00
pokamest
42949e0dea Merge pull request #492 from amnezia-vpn/bugfix/append-client
fixed insert rows count in appendClient function
2024-01-10 12:42:07 -05:00
pokamest
26db423232 Merge pull request #489 from amnezia-vpn/bugfix/remote-links-on-site
added the ability to change the site link via a translation file
2024-01-10 12:40:19 -05:00
vladimir.kuznetsov
645cf52803 now value and setValue of secureQSettings are always called in the main thread 2024-01-10 23:05:22 +07:00
vladimir.kuznetsov
673b8ad5b2 fixed insert rows count in appendClient function 2024-01-10 11:55:32 +07:00
vladimir.kuznetsov
2a03834bb2 fixed current processed server selection after import/install new server 2024-01-09 00:25:18 +07:00
lunardunno
c1b6149e49 Improve servercontroller.cpp for Ubuntu (#482)
Improve servercontroller.cpp for Ubuntu, CentOS, snd Fedora
2024-01-06 16:41:06 +00:00
vladimir.kuznetsov
0690d86e52 added the ability to change the site link via a translation file 2024-01-06 20:42:43 +07:00
vladimir.kuznetsov
bb8a11d110 added reset routeMode when resetting application settings 2024-01-06 20:38:41 +07:00
pokamest
4f7ba4c9a8 Merge pull request #483 from amnezia-vpn/persian_translation
full persian translation
2023-12-30 09:11:08 -05:00
Morteza Sherafati
aa41e4d915 full persian translation 2023-12-30 11:12:54 +00:00
pokamest
bb43b5451f Merge pull request #478 from amnezia-vpn/bugfix/macos-dns-resolve
Fix resolv-update script for MacOS (OpenVPN DNS)
2023-12-28 14:52:28 -05:00
vladimir.kuznetsov
69dd415ab5 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into bugfix/windows-crush-on-utf8-symbolos 2023-12-28 14:47:19 +07:00
albexk
e605f549bd Merge branch 'dev' into refactoring/android 2023-12-26 18:23:53 +03:00
albexk
a961932b2e Refactor AndroidUtils 2023-12-26 17:41:49 +03:00
albexk
e8cc80f046 Refactor Android open file method
Fix some bugs with mimetype filters when the Qt mimetype database does not match the Android database
2023-12-26 16:30:33 +03:00
vladimir.kuznetsov
67f29ac483 added conversion using the system locale 2023-12-26 13:36:21 +07:00
pokamest
c9bde5cdc0 Merge pull request #479 from amnezia-vpn/feature/client-management-migrations
added migration from version 3 of client management to version 4
2023-12-25 22:00:13 -05:00
pokamest
e878911819 Merge pull request #472 from amnezia-vpn/ksznak
Update amneziavpn_ru.ts
2023-12-25 13:36:03 -05:00
pokamest
f1a0b7f0ef Merge pull request #473 from amnezia-vpn/bugfix/new-client-on-connection
fixed hang after creating configuration on connection
2023-12-25 12:21:44 -05:00
KsZnak
3e0a5104e7 Update amneziavpn_ru.ts 2023-12-25 19:18:23 +02:00
vladimir.kuznetsov
8f53d563a4 moved the client table for cloak and ss to the openvpn folder 2023-12-25 22:49:24 +07:00
pokamest
414740ffb7 Merge pull request #467 from amnezia-vpn/feature/full-access-last-config
full access config no longer contains the last_config field
2023-12-25 10:29:16 -05:00
albexk
7437d47d92 Remove unnecessary permission RECEIVE_BOOT_COMPLETED 2023-12-25 15:16:22 +03:00
vladimir.kuznetsov
a68f19d72f added migration from version 3 of client management to version 4 2023-12-24 21:13:09 +07:00
vladimir.kuznetsov
11641c5e22 added error code output 2023-12-24 21:11:47 +07:00
Mykola Baibuz
8d3e21d46a Fix resolv-update script for MacOS (OpenVPN DNS)
script from https://github.com/andrewgdotcom/openvpn-mac-dns
2023-12-23 23:14:02 +02:00
pokamest
5ad54bfdc1 Merge pull request #452 from amnezia-vpn/refactoring/android
Android refactoring
2023-12-23 13:48:26 -05:00
Mykola Baibuz
a8f5e95fb1 MacOS OpenVPN/OpenVPN over Cloak killswitch 2023-12-23 16:04:17 +02:00
Mykola Baibuz
a4f3d08c02 Fix PF config path 2023-12-23 14:21:13 +02:00
Mykola Baibuz
3d2174d84e MacOS WG/AWG killswitch 2023-12-23 12:51:55 +02:00
pokamest
12fbc7d258 Merge pull request #474 from amnezia-vpn/bugfix/ss-in-cloak-container
returned shadowsocks to cloak container
2023-12-22 15:04:21 +00:00
albexk
164b7e2551 Merge branch 'dev' into refactoring/android 2023-12-22 15:38:29 +03:00
albexk
eafac491d8 Add a stub for errors coming from Android
These errors are related to VPN connection errors
2023-12-22 15:35:24 +03:00
pokamest
3cfb6e968d Merge pull request #475 from amnezia-vpn/bugfix/default-server-full-access-sharing
added selection of a default server for full access sharing
2023-12-22 12:21:59 +00:00
albexk
375825125f Fix cloak config 2023-12-22 15:11:48 +03:00
vladimir.kuznetsov
a8520e7545 added selection of a default server for full access sharing 2023-12-22 13:43:46 +07:00
vladimir.kuznetsov
ac154cdd83 returned shadowsocks to cloak container 2023-12-22 13:08:53 +07:00
vladimir.kuznetsov
9290775ab5 added removal of last_config when revoke admin config on client management panel 2023-12-21 23:34:27 +07:00
pokamest
d14e8cdee4 Merge pull request #460 from amnezia-vpn/bugfix/minor-ui-fixes
added an empty string check for the server name and user name change fields
2023-12-21 15:55:33 +00:00
vladimir.kuznetsov
7aac9f9d0e fixed hang after creating configuration on connection
- config created on connection is displayed as admin (platform name) on the client management page
- added config creation time on the client management page
2023-12-21 17:47:34 +07:00
KsZnak
41aaac7d32 Update amneziavpn_ru.ts 2023-12-20 20:16:35 +02:00
albexk
c8d2399db9 Merge branch 'dev' into refactoring/android 2023-12-20 20:47:19 +03:00
KsZnak
f37c8e5fd4 Update amneziavpn_ru.ts 2023-12-20 19:14:15 +02:00
pokamest
9f5025c10b Merge pull request #471 from amnezia-vpn/bugfix/macos_deploy_fix
build_macos.sh fix
2023-12-20 17:13:37 +00:00
pokamest
c27d999c41 build_macos.sh fix 2023-12-20 08:39:43 -08:00
pokamest
9681bea237 Update ts files 2023-12-20 12:14:06 +00:00
pokamest
8905d6352c Merge pull request #465 from amnezia-vpn/persian_translation
added persian translation file and menu item
2023-12-20 12:07:51 +00:00
vladimir.kuznetsov
8599b20678 full access config no longer contains the last_config field 2023-12-18 13:17:39 +07:00
Morteza Sherafati
491f09a51b added persian translation file and menu item 2023-12-17 18:37:07 +00:00
pokamest
0f1519a21f Merge pull request #462 from amnezia-vpn/bugfix/service-containers-search
fixed server search for sftp, dns and tor containers
2023-12-17 16:53:52 +00:00
Mykola Baibuz
1a17f2956a Fix build action 2023-12-16 10:05:54 -05:00
Mykola Baibuz
d94e27bfa9 Linux killswitch 2023-12-16 09:19:04 -05:00
vladimir.kuznetsov
b892156092 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-12-16 09:23:44 +07:00
vladimir.kuznetsov
7b1b8dc749 fixed server search for sftp, dns and tor containers 2023-12-15 13:58:30 +07:00
albexk
6d0167dcf3 Get back the ability to open configuration files
Doesn't work in all applications because some applications pass an abstract URI instead of the file path in the 'content' scheme
2023-12-14 22:10:22 +03:00
albexk
0c2d661e1c Disable ShadowSocks support on Android 2023-12-14 21:08:45 +03:00
albexk
95d1440d6f Some minor refactoring 2023-12-14 18:01:55 +03:00
albexk
0cabf60dc4 Fixes and refactoring in file saving and import functions 2023-12-14 18:00:58 +03:00
albexk
836ca1cc6b Switch to Qt fileprovider introduced in 6.6 2023-12-14 17:59:03 +03:00
pokamest
be799daafe Merge pull request #431 from amnezia-vpn/re_second_adaptation_to_diff_os
Improve install_docker.sh
2023-12-14 05:27:29 -08:00
pokamest
ad9d674a03 Merge pull request #368 from amnezia-vpn/feature/import-config-from-cloud
API support
2023-12-14 04:15:38 -08:00
vladimir.kuznetsov
f52c3c430f added notification after config revokation 2023-12-14 11:03:27 +07:00
vladimir.kuznetsov
a91ab0e910 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-12-13 14:21:51 +07:00
vladimir.kuznetsov
39d1f1677f fixed description update, after changing the default protocol 2023-12-13 14:14:37 +07:00
albexk
b0dcae3586 Disable global split tunneling if a non-default route exists in the Wireguard configuration 2023-12-12 22:48:18 +03:00
vladimir.kuznetsov
ed6351f8f1 added an empty string check for the server name and user name change fields 2023-12-12 17:15:10 +03:00
pokamest
e486a2fb26 Merge pull request #443 from amnezia-vpn/feature/cancel-installation-button
added a button to cancel installation if the package manager on the server is busy
2023-12-12 05:17:40 -08:00
albexk
195bdb947e Refactor import config
Remove the path filter, as the content path may not contain a filename.
Disable import when viewing files.
Config can be imported from:
- shared file
- shared text
- vpn:// link
2023-12-11 22:56:01 +03:00
albexk
1576aed1ea Add network state listening and reconnection
Vpn reconnects when the default network is changed
2023-12-11 15:16:50 +03:00
vladimir.kuznetsov
e66fbc3289 added default container installation, after downloading the config from the api 2023-12-11 13:42:42 +07:00
vladimir.kuznetsov
b4c89ad58f Reworked the interaction between models. Now only serversModel directly interacts with server config 2023-12-08 13:50:03 +07:00
albexk
8cc5846808 Fix application hangs in disconnection state 2023-12-07 22:43:33 +03:00
albexk
2eaaf01ca1 Up AGP to version 8.2.0 2023-12-07 19:28:41 +03:00
albexk
67694c0f96 Fix abort error: 'Pure virtual function called!' 2023-12-06 18:25:11 +03:00
albexk
163e5b2c52 Fix for Qt Creator 2023-12-06 18:25:11 +03:00
albexk
508f1d3a42 Add service bind timeout 2023-12-06 18:24:52 +03:00
albexk
d2207a5255 Up Gradle to version 8.5 2023-12-06 13:38:36 +03:00
albexk
bf03f5c9ae Fix for Qt Creator 2023-12-05 23:53:49 +03:00
albexk
656223f57d Fix rebinding to the service 2023-12-05 16:57:53 +03:00
albexk
dc6e3ec53b Add passing the VPN connection status when rebinding to the service 2023-12-05 16:10:29 +03:00
albexk
5835a756ce Add onError callback to handle errors in protocol threads 2023-12-05 13:56:01 +03:00
vladimir.kuznetsov
f3f98a50ed fixed include path of servercontroller 2023-12-05 17:49:11 +07:00
vladimir.kuznetsov
0f4bb78712 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-12-05 17:38:53 +07:00
vladimir.kuznetsov
c4014518cb renamed CloudController to ApiController 2023-12-05 17:38:38 +07:00
vladimir.kuznetsov
3605f62feb added support for the updated api 2023-12-05 17:28:14 +07:00
albexk
5c3e253067 Fix service description in AndroidManifest.xml 2023-12-05 13:09:28 +03:00
albexk
8d43cee52e Remove shadowsocks code 2023-12-04 18:45:53 +03:00
albexk
1e64413904 Fix disconnect bug 2023-12-04 18:23:08 +03:00
pokamest
6fd1ea26ee Merge pull request #438 from amnezia-vpn/bugfix/app-is-running-win11
fixed appProcessIsRunning() for win11
2023-12-01 03:24:49 -08:00
vladimir.kuznetsov
e619fd4af9 replaced loader with PageSetupWizardInstalling when updating container settings 2023-12-01 14:16:27 +07:00
albexk
e7658f9859 Add split tunneling 2023-12-01 00:12:50 +03:00
vladimir.kuznetsov
3defb09da9 added a button to cancel installation if the package manager on the server is busy 2023-11-30 19:21:57 +07:00
vladimir.kuznetsov
a672434909 changed tasklist | findstr на tasklist 2023-11-30 07:13:43 +03:00
Mykola Baibuz
c3fdd977b1 Windows OpenVPN/OpenVPN+Cloak killswitch feature 2023-11-29 22:50:36 +02:00
pokamest
dd233f77fc Merge pull request #432 from amnezia-vpn/feature/client-management
added client management
2023-11-29 07:04:56 -08:00
vladimir.kuznetsov
02efd9c217 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/client-management 2023-11-29 17:26:26 +03:00
albexk
20f3c0388a Add sending statistics 2023-11-29 17:08:53 +03:00
albexk
ef530780bd Fixes in AmneziaVpnService 2023-11-29 17:01:21 +03:00
albexk
d7ec611ff4 Fix bugs in awg and wireguard protocols 2023-11-29 16:55:17 +03:00
pokamest
b897e7102e Merge pull request #437 from amnezia-vpn/bugfix/minor-ui-fixes
Bugfix/minor UI fixes
2023-11-29 05:34:30 -08:00
pokamest
1cc5c5384e Merge pull request #407 from amnezia-vpn/feature/ss-and-cloak-native-configs
added native config generation for ss and cloak
2023-11-29 05:28:33 -08:00
vladimir.kuznetsov
db602ac65b fixed ss string generation 2023-11-29 10:57:47 +07:00
albexk
eaa209bc3a Add OpenVpn over Cloak module 2023-11-28 22:27:00 +03:00
albexk
51d4aea9e2 Add OpenVpn module 2023-11-28 20:07:39 +03:00
albexk
9738ada946 ProtocolApi refactoring, move network classes to NetworkUtils.kt 2023-11-28 19:47:22 +03:00
albexk
8ec105bee0 Move Log class to org.amnezia.vpn.util package 2023-11-28 19:07:32 +03:00
tiaga
4fd0852bb3 Improve install_docker.sh
- add delays before and after Docker activation
- cancel installation if `sudo` wasn't found
2023-11-27 21:47:54 +07:00
vladimir.kuznetsov
a53e904f7b fixed appProcessIsRunning() for win11 2023-11-27 13:56:52 +07:00
vladimir.kuznetsov
2d22b52b5d limited client name length 2023-11-27 13:42:08 +07:00
vladimir.kuznetsov
426ac49f6f fixed "auto-connect" option 2023-11-27 12:46:59 +07:00
vladimir.kuznetsov
c164814abd fixed default server setting after importing 2023-11-27 10:59:48 +07:00
vladimir.kuznetsov
3084892ed8 added selection of default server and container on the sharing page 2023-11-26 21:15:58 +07:00
albexk
9297f877c4 Add AWG module 2023-11-26 13:07:31 +03:00
vladimir.kuznetsov
1bf808c9ee fixed qr code generation for native configs 2023-11-25 13:02:02 +07:00
albexk
91f44fb394 Up Qt to version 6.6.1 2023-11-24 22:22:15 +03:00
albexk
385a52f676 Vpn service refactoring 2023-11-24 21:51:09 +03:00
albexk
8ef16781eb Remove old wireguard code 2023-11-24 21:49:54 +03:00
albexk
ad5ea1ca44 Add IpcMessenger class 2023-11-24 17:10:08 +03:00
albexk
0ba5d754d5 Android Activity refactoring 2023-11-23 21:20:31 +03:00
albexk
ccdcfdce8a Remove VPNPermissionHelper class 2023-11-23 16:49:32 +03:00
albexk
712fb4d0d3 Add Wireguard module 2023-11-23 16:45:15 +03:00
albexk
de65a03998 Add ProtocolApi module 2023-11-23 16:03:52 +03:00
albexk
6d6710db4a Prefs refactoring 2023-11-23 14:19:51 +03:00
albexk
c34c3e51ea Remove 'https://jitpack.io' repository 2023-11-23 14:13:38 +03:00
vladimir.kuznetsov
5dc3b64e0b added search bar for client management page 2023-11-23 14:54:49 +07:00
vladimir.kuznetsov
e8ceeb6e20 added full access sharing 2023-11-23 00:04:06 +07:00
pokamest
d38c7ce6a5 Error codes cleanup 2023-11-22 13:57:05 +00:00
albexk
e625543b94 CameraActivity refactoring 2023-11-21 23:35:26 +03:00
albexk
679bd4e4c9 Get rid of AppCompat theme 2023-11-21 21:31:49 +03:00
vladimir.kuznetsov
c6a312845a added client management 2023-11-21 20:31:53 +07:00
pokamest
ef0530ec6b Merge pull request #420 from amnezia-vpn/adaptation_to_different_os
Improve logic of install_docker.sh
2023-11-17 11:51:58 -08:00
albexk
2c98a90d60 Move icons to mipmap folders 2023-11-17 15:30:13 +03:00
albexk
b90fad6664 Android activity and AndroidController class refactoring 2023-11-17 15:10:11 +03:00
albexk
5a5ea4a018 Android project restructuring 2023-11-16 20:16:28 +03:00
albexk
bc68c487ee Update to qt 6.6.0 2023-11-16 19:49:36 +03:00
albexk
617cdf14ad Log class refactoring 2023-11-16 15:30:44 +03:00
albexk
f1c970461f Create utils module, move Log class there
BuildConfig class is now only created in the utils module
2023-11-16 15:15:02 +03:00
albexk
2fde47a86f Move qt binding java code to a separate module 2023-11-15 22:10:44 +03:00
albexk
4e5f2f44b6 Detach shadowsocks module 2023-11-15 22:08:00 +03:00
pokamest
e8a2e54d05 Typo fix 2023-11-15 12:51:39 +00:00
albexk
d77f3ecee8 Fix build error 2023-11-15 15:48:40 +03:00
albexk
06776ebe8f Fix errors 2023-11-14 23:19:46 +03:00
albexk
e1eec55f62 Refactoring build
Move to gradle kotlin DSL
Use gradle version catalog
All android build parameters are set via cmake files
Use gradle abi split to build APKs
Improve local development in the android project folder
2023-11-14 23:18:59 +03:00
albexk
fcabf08e74 Update gradle, fix gradlew.bat crlf 2023-11-14 23:13:14 +03:00
pokamest
b4694313a0 Merge pull request #426 from amnezia-vpn/ios-build
Change Qt mirror for builds
2023-11-14 09:54:54 -08:00
tiaga
abb2cae1f8 Change Qt mirror for builds
Use UC Berkeley mirror for installing Qt during a build. In addition, don't trigger builds on a tag push.
2023-11-14 23:39:15 +07:00
pokamest
b0004fd9dc Version bump 2023-11-14 12:50:52 +00:00
tiaga
362a82f944 Improve logic of install_docker.sh
- check packages update only when it's required
- avoid `dnf/yum update` for RHEL-based systems
2023-11-14 16:57:16 +07:00
pokamest
19fe61ed29 Merge pull request #423 from amnezia-vpn/r2
Upload new versions to R2
2023-11-13 09:34:30 -08:00
tiaga
72de38b4fb Upload new versions to R2
A new GitHub Actions workflow for a tagged commit which uploads installers for a desktop version to Cloudflare R2.
2023-11-10 23:19:00 +07:00
pokamest
02c0f96e5e Merge pull request #418 from amnezia-vpn/feature/split-tunnel-dns-forwad
Use DNS over VPN for ForwardSites mode split tunnel
2023-11-07 06:35:43 -08:00
vladimir.kuznetsov
aee82282ac Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/import-config-from-cloud 2023-11-06 14:10:43 +03:00
vladimir.kuznetsov
8497aeeb91 removed the debugging code 2023-11-06 14:10:31 +03:00
Mykola Baibuz
5e9f688000 Use DNS over VPN for ForwardSites mode split tunnel
This feature was in previous version of Split Tunnel
2023-11-04 15:28:59 -04:00
pokamest
6a7e346695 Merge pull request #416 from amnezia-vpn/bugfix/openvpn-exclude-route
Fix Split tunnel exclude sites mode for OpenVPN and Cloak. Windows.
2023-11-04 06:09:01 -07:00
Mykola Baibuz
071738116e Update Windows OpenVPN binary
This binary builded with ENABLE_DEBUG flag. This flag needed for ROUTE_GATEWAY varible output in log.
2023-11-03 17:29:40 -04:00
pokamest
147726ecb0 Merge branch 'dev' into feature/import-config-from-cloud 2023-11-01 21:42:07 +00:00
pokamest
ae4ee6431d Merge pull request #409 from useribs/patch-2
Update servercontroller.cpp, replace 2 calls (shred ; rm)  with one
2023-11-01 12:23:14 -07:00
vladimir.kuznetsov
9cfcb714ae added native config generation for ss and cloak 2023-11-01 21:29:58 +05:00
pokamest
d1ccde2a4b Merge pull request #396 from amnezia-vpn/bugfix/server-config-sync
bugfix/server config sync
2023-11-01 07:15:10 -07:00
useribs
4848091203 Update servercontroller.cpp, replace 2 calls (shred ; rm) with one (shred -u) 2023-10-30 20:09:13 +03:00
pokamest
282f159311 Merge pull request #402 from amnezia-vpn/bugfix/description_dns
Update DNS description
2023-10-29 09:07:42 -07:00
lunardunno
4ef8c77a2d Update DNS description 2023-10-29 17:56:10 +04:00
pokamest
08c1cf2439 Merge pull request #382 from amnezia-vpn/feature/split-tunnel-mobile
Split tunnel for missed Protocol/OS
2023-10-29 06:26:07 -07:00
Mykola Baibuz
2fc33875bb Bump version 2023-10-27 15:38:24 -04:00
Mykola Baibuz
9e92e4b5ff Merge branch 'dev' into feature/split-tunnel-mobile 2023-10-27 15:37:28 -04:00
pokamest
7f2cf70bf5 Merge pull request #393 from amnezia-vpn/bugfix/return-after-installation
fixed page return after installation
2023-10-26 12:40:39 -07:00
pokamest
40725d4155 Merge pull request #397 from amnezia-vpn/dev
Release 4.0.8
2023-10-26 11:45:11 -07:00
vladimir.kuznetsov
8164026891 fixed server config update, after container config change 2023-10-26 23:37:51 +05:00
Mykola Baibuz
0e23b3a1ac Allow traffic to Amezia DNS for all OS 2023-10-25 22:19:07 +03:00
Mykola Baibuz
1739d4861e Allow acces to Amnezia DNS when used only for selected sites 2023-10-25 21:50:35 +03:00
Mykola Baibuz
a6b6e7850d Allow traffic for excluded route on Windows kill switch 2023-10-24 23:07:07 +03:00
Mykola Baibuz
3e9dea6f07 Remove some not implemented notification 2023-10-24 13:37:40 +03:00
Mykola Baibuz
1b37ca805f Cleanup debug stuff 2023-10-24 11:10:16 +03:00
Mykola Baibuz
c772f56da7 Fixes after merge 2023-10-24 11:00:40 +03:00
Mykola Baibuz
bc183e39bb Merge branch 'feature/split-tunnel-mobile' of github.com:amnezia-vpn/amnezia-client into feature/split-tunnel-mobile 2023-10-24 00:35:58 +03:00
Mykola Baibuz
306d4f70a8 Update NE Sources 2023-10-24 00:33:35 +03:00
Mykola Baibuz
a386d39495 iOS Cloak/OVPN SplitTunnel 2023-10-24 00:28:41 +03:00
Mykola Baibuz
22b14dff5f iOS AWG/WG split tunnel 2023-10-23 22:42:02 +03:00
pokamest
e749cc7578 Update amneziavpn_ru.ts
Typo fix
2023-10-23 20:32:28 +01:00
vladimir.kuznetsov
3e03002ead added getting cloud config for cloak 2023-10-23 23:55:01 +05:00
vladimir.kuznetsov
4ae9cddcce fixed a typo in the serverController include 2023-10-23 23:53:46 +05:00
vladimir.kuznetsov
16724645ce Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/import-config-from-cloud 2023-10-23 21:40:18 +05:00
vladimir.kuznetsov
6a12cad1c9 fixed page return after installation 2023-10-23 21:33:07 +05:00
Mykola Baibuz
c15665803d Merge branch 'dev' into feature/split-tunnel-mobile 2023-10-22 15:26:20 -04:00
pokamest
97090888d5 Bump version 2023-10-22 08:11:37 -07:00
pokamest
4642308fbb Merge pull request #374 from amnezia-vpn/bugfix/split-tunneling
Bugfix/split tunneling
2023-10-22 08:02:43 -07:00
vladimir.kuznetsov
59bccb1188 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into bugfix/split-tunneling 2023-10-22 20:00:39 +05:00
pokamest
cd8fc007ac Merge pull request #392 from amnezia-vpn/bugfix/existing-awg-container
added getting awg parameters when adding an already installed awg container
2023-10-22 07:49:34 -07:00
vladimir.kuznetsov
7cfb38307e removed re-processing of server config for awg 2023-10-22 18:04:34 +05:00
vladimir.kuznetsov
994aa32745 added getting awg parameters when adding an already installed awg container 2023-10-22 17:31:13 +05:00
Mykola Baibuz
f0b872e86b Merge remote-tracking branch 'origin/bugfix/pull-awg-config' into feature/split-tunnel-mobile 2023-10-21 23:24:54 +03:00
Mykola Baibuz
0c33432436 Fix pulling exiting AWG config from server 2023-10-21 14:55:15 -04:00
pokamest
0bb4dd9442 Text and translations fixes 2023-10-21 18:32:30 +01:00
pokamest
7a54dc15da Update amneziavpn_ru.ts 2023-10-21 16:33:21 +01:00
pokamest
e16a1100d8 Update amneziavpn_ru.ts 2023-10-21 16:20:57 +01:00
pokamest
99214e22e3 Fix docs url 2023-10-21 16:05:09 +01:00
pokamest
c77d35a2ed Merge pull request #390 from amnezia-vpn/revert-370-feature/custom_drawer_component
Revert "added new drawer2type for replacing drawertype"
2023-10-21 06:21:07 -07:00
pokamest
d98fdbdc5c Revert "added new drawer2type for replacing drawertype" 2023-10-21 14:17:45 +01:00
ronoaer
4551cf0a21 Merge pull request #370 from amnezia-vpn/feature/custom_drawer_component
added new drawer2type for replacing drawertype
2023-10-21 09:34:21 +08:00
ronoaer
023c3474d2 Merge branch 'dev' into feature/custom_drawer_component 2023-10-21 09:28:41 +08:00
pokamest
2a4cefb4bf Merge pull request #387 from amnezia-vpn/bugfix/awg-mtu-len-fix
Fix MTU len for Win WG/AWG
2023-10-20 15:02:29 -07:00
Mykola Baibuz
09305724fa Fix MTU len for Win WG/AWG 2023-10-20 16:44:30 -04:00
pokamest
360fda1ba7 Merge pull request #386 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
Bugfix/minor UI fixes 4 version
2023-10-20 12:23:03 -07:00
vladimir.kuznetsov
dadf0cf96e Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into dev 2023-10-20 21:51:40 +05:00
vladimir.kuznetsov
3d60ac751e removed the default protocol/server change if connected to VPN 2023-10-20 20:52:14 +05:00
pokamest
32793eef8c Merge pull request #385 from amnezia-vpn/bugfix/translated_new_source_strings_to_chinese
translated new source strings to chinese
2023-10-20 06:36:17 -07:00
ronoaer
da1cdfd6fa translated new source strings to chinese 2023-10-20 18:01:57 +08:00
vladimir.kuznetsov
58ad7dc161 removed the "remove protocol" buttons from where they shouldn't be 2023-10-20 14:10:04 +05:00
ronoaer
0a15f44193 removed states 'opened', 'closed' 2023-10-20 10:38:12 +08:00
pokamest
e1dec3c1ba Merge pull request #384 from amnezia-vpn/bugfix/startCentos7docker
Restoring autostart and enable docker for CentOS 7
2023-10-19 18:30:45 -07:00
pokamest
7834860245 Merge pull request #383 from amnezia-vpn/feature/awg-random-values
Feature/awg random values
2023-10-19 18:28:13 -07:00
pokamest
2da1025f26 Random port on install 2023-10-20 02:25:40 +01:00
Mykola Baibuz
78c83b2e21 Some logic fix 2023-10-19 17:03:24 -04:00
Mykola Baibuz
414a47e2f2 WG/AWG Desktop AllowedIP from plain WG config 2023-10-19 14:50:51 -04:00
ronoaer
6c78b4ec8f enabled drag-pagehome-drawer in tabBar 2023-10-19 23:01:03 +08:00
ronoaer
a6949bd3ae resized questiondrawer of page serverdata 2023-10-19 19:45:22 +08:00
ronoaer
f7bed04ab2 removed invalid function code 2023-10-19 19:32:15 +08:00
ronoaer
6ec773079c added hovering effect of button 2023-10-19 11:22:52 +08:00
ronoaer
366e27a321 re-adatped pagehome 2023-10-19 09:27:39 +08:00
Mykola Baibuz
32c304dc1b WG/AWG SplitTunnel for desktop 2023-10-18 17:44:28 -04:00
vladimir.kuznetsov
338499247d changed the display order of containers 2023-10-19 01:16:36 +05:00
vladimir.kuznetsov
79e1761c1f added generation of random values for awg parameters 2023-10-19 01:14:09 +05:00
Mykola Baibuz
4ea1a19572 Cleanup WG implementation 2023-10-18 13:41:58 -04:00
pokamest
e2ae341ba9 AndroidManifest fix 2023-10-18 14:01:06 +01:00
pokamest
de03435bac Merge pull request #381 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
Bugfix/minor UI fixes 4 version
2023-10-18 04:05:18 -07:00
pokamest
e16c425f87 PageHome.qml fix 2023-10-18 12:04:39 +01:00
ronoaer
c461e00c5c keeping parent's cusorshape and Drawer2Type's close-animation 2023-10-18 16:17:57 +08:00
vladimir.kuznetsov
fcf6bb43b7 Merge branch 'bugfix/split-tunneling' of github.com:amnezia-vpn/amnezia-client into bugfix/split-tunneling 2023-10-18 12:18:46 +05:00
vladimir.kuznetsov
f5f72f87a6 fixed switcher status display for page split site tunneling 2023-10-18 12:17:24 +05:00
vladimir.kuznetsov
3340451245 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into bugfix/split-tunneling 2023-10-18 11:55:24 +05:00
Mykola Baibuz
c14f1b5000 Android OpenVPN/Cloak Split tunnel 2023-10-17 16:39:56 -04:00
vladimir.kuznetsov
a46e55d5c2 added a dash for drawerType 2023-10-18 01:11:41 +05:00
vladimir.kuznetsov
4b64bfaec0 fixed questionDrawer height 2023-10-18 00:37:15 +05:00
vladimir.kuznetsov
2f0c1eeecc fixed selection of default container after installing a new server 2023-10-18 00:36:40 +05:00
Mykola Baibuz
546d4c1d3d WG/AWG Android splitTunnel 2023-10-17 14:54:46 -04:00
lunardunno
160d88f002 Restoring autostart and enable docker for CentOS 7 2023-10-17 21:26:50 +04:00
ronoaer
a83cd29f72 fixed the cursorShape, and some minor issues 2023-10-17 22:00:19 +08:00
pokamest
94304b5777 Version bump 2023-10-17 14:47:31 +01:00
pokamest
61ddfe01a1 macos build script updated [no ci] 2023-10-17 06:39:49 -07:00
pokamest
00d334f704 Merge pull request #377 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
disabled the ability to change the protocol/server when a vpn connection is active
2023-10-17 05:39:51 -07:00
pokamest
f4a4979997 Merge pull request #378 from amnezia-vpn/bugfix/updated_chinese_translations
updated Chinese translations for updating source strings
2023-10-17 05:11:19 -07:00
ronoaer
03171e4743 update background color and drag-effect, moved dulicated code 2023-10-17 19:34:34 +08:00
ronoaer
5369e68267 updated Chinese translations for updating source strings 2023-10-17 14:30:59 +08:00
vladimir.kuznetsov
9eb23e38bd disabled the ability to change the protocol/server when a vpn connection is active 2023-10-16 22:57:12 +05:00
Mykola Baibuz
2a0166bb26 Merge branch 'bugfix/split-tunneling' of https://github.com/amnezia-vpn/amnezia-client into bugfix/split-tunneling 2023-10-16 12:05:50 -04:00
Mykola Baibuz
2df612ec1f Android SplitTunnel 2023-10-16 12:05:35 -04:00
pokamest
36ba3758db Translation updates 2023-10-16 15:27:26 +01:00
ronoaer
7cc0f39d3c adapted pagehome by new custom drawer type 2023-10-16 22:21:01 +08:00
vladimir.kuznetsov
9cf5590371 disabled split site tunneling for awg 2023-10-16 15:17:09 +05:00
pokamest
81f835458f Merge pull request #375 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
Bugfix/minor UI fixes 4 version
2023-10-16 03:10:53 -07:00
vladimir.kuznetsov
e01b1db706 text corrections 2023-10-16 14:34:03 +05:00
vladimir.kuznetsov
cdb18de305 brought back the ability to share wireguard native format configs 2023-10-16 13:43:27 +05:00
vladimir.kuznetsov
8e0eef3316 fixed selection of default container after installing a new container 2023-10-16 13:40:43 +05:00
vladimir.kuznetsov
221d45f564 fixed pageSettingsDns width 2023-10-16 13:32:56 +05:00
vladimir.kuznetsov
2a4a01a4be removed split site tunneling page blocking when switcher is turned off 2023-10-16 13:28:37 +05:00
Mykola Baibuz
501670bdd2 Merge branch 'feature/split-tunneling-config' into bugfix/split-tunneling 2023-10-15 15:10:05 -04:00
vladimir.kuznetsov
24637a1693 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-10-15 21:08:45 +05:00
vladimir.kuznetsov
7bd1340190 fixed display of sites on page split tunneling 2023-10-15 20:41:49 +05:00
ronoaer
cb5c09d967 adapted questionDrawer 2023-10-15 21:29:01 +08:00
pokamest
a01ba5909c Version bump 2023-10-15 12:53:44 +01:00
pokamest
1c4678af95 Merge pull request #373 from amnezia-vpn/fix/update_ru_ts
Updated ru ts #2
2023-10-15 04:43:04 -07:00
pokamest
5f5435c645 Updated ru ts 2023-10-15 12:41:01 +01:00
pokamest
2f7dc2c46c Merge pull request #372 from amnezia-vpn/fix/update_ru_ts
Update ru translation
2023-10-15 04:38:29 -07:00
pokamest
9bc1c9dd03 Merge branch 'dev' into fix/update_ru_ts 2023-10-15 12:30:13 +01:00
pokamest
4c81cdb4a2 Update translation 2023-10-15 12:29:41 +01:00
pokamest
3406ffa7a2 Merge pull request #371 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
Minor UI fixes 4 version
2023-10-15 02:54:27 -07:00
pokamest
6d05b6845e VPN protocol descriptions updated 2023-10-15 10:53:09 +01:00
ronoaer
29b4966119 shown ConnectionTypeSelectionDrawer on top level alway 2023-10-15 17:34:35 +08:00
ronoaer
d0f8358431 removed invalid code, and fixed top button hidden-shown 2023-10-15 17:29:22 +08:00
ronoaer
a75bd07cd8 fixed the clicked event 2023-10-15 15:54:05 +08:00
ronoaer
8c1835950b added transparent-background, for blocking clicked event 2023-10-15 15:17:04 +08:00
pokamest
c7cd8e4c80 Minor ui fixes and refactoring 2023-10-15 02:30:42 +01:00
pokamest
f65e4066e3 ui fixes 2023-10-14 23:59:46 +01:00
vladimir.kuznetsov
37c18c5d3c Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into dev 2023-10-14 21:25:09 +05:00
vladimir.kuznetsov
8885f580b2 added notification after saving backup and logs files 2023-10-14 21:18:38 +05:00
vladimir.kuznetsov
512ac74ee6 temporarily disabled the drawer close button 2023-10-14 20:59:03 +05:00
ronoaer
384ce9853b added new drawer2type for replacing drawertype 2023-10-14 23:00:31 +08:00
pokamest
b6d2030041 Ru translation 2023-10-14 15:55:52 +01:00
pokamest
3ac09181c6 Text lables fixes 2023-10-14 15:55:07 +01:00
vladimir.kuznetsov
ffc9e5823a text corrections 2023-10-14 18:21:49 +05:00
vladimir.kuznetsov
f5448fed59 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into dev 2023-10-14 16:58:14 +05:00
vladimir.kuznetsov
8163e51434 fixes on page split tunneling according to the design layout 2023-10-14 16:52:22 +05:00
pokamest
3836836c72 Change easySetupOrder 2023-10-14 02:15:49 +01:00
vladimir.kuznetsov
b78bf39767 added split tunneling to the config 2023-10-13 15:45:06 +05:00
vladimir.kuznetsov
25f8283edd added getting the config from the cloud service 2023-10-12 20:48:03 +05:00
pokamest
7c8399ce88 Fix awg description 2023-10-12 13:57:58 +01:00
pokamest
9fe2a1dd41 Merge pull request #354 from amnezia-vpn/feature/amnezia-wireguard-client-impl
AWG protocol implementation
2023-10-12 03:39:59 -07:00
Nethius
846f554157 Merge pull request #366 from amnezia-vpn/bigfix/updated_translation_for_wg
updated translations for branch feature/amnezia-wireguard-client-impl
2023-10-12 15:44:12 +07:00
ronoaer
d1f66cbf4d updated translations for branch feature/amnezia-wireguard-client-impl 2023-10-12 16:26:37 +08:00
vladimir.kuznetsov
a4624c7377 removed the close button for the app for mobile platforms 2023-10-12 10:57:13 +05:00
pokamest
10435cea69 Tiny refactoring and text fixes 2023-10-12 01:15:05 +01:00
pokamest
ce9a23e021 Merge branch 'dev' into feature/amnezia-wireguard-client-impl 2023-10-11 19:40:40 +01:00
pokamest
4b7c8f21c2 Merge pull request #364 from amnezia-vpn/bigfix/reset_topbutton_xposition
updated x position of topbutton  when resize window
2023-10-11 11:37:17 -07:00
pokamest
6ddebdbbd1 Merge pull request #365 from amnezia-vpn/bugfix/container-config-on-connect
fixed container config synchronization
2023-10-11 11:36:39 -07:00
pokamest
d92729d346 Fix install_docker.sh 2023-10-11 15:30:55 +01:00
Mykola Baibuz
fa06dbbd29 Bump Android verion 2023-10-10 08:52:36 -04:00
vladimir.kuznetsov
5d59a1a10e fixed an error when after the first connection with admin config the container model was not updated 2023-10-10 12:18:56 +03:00
vladimir.kuznetsov
222a251180 Merge branch 'feature/amnezia-wireguard-client-impl' of github.com:amnezia-vpn/amnezia-client into feature/amnezia-wireguard-client-impl 2023-10-10 14:16:02 +05:00
vladimir.kuznetsov
9d6559f0d7 fixed an error when after the first connection with admin config the container model was not updated 2023-10-10 12:50:41 +05:00
ronoaer
da02f49850 update x value of topbutton when resize window 2023-10-10 08:43:56 +08:00
Mykola Baibuz
992961c488 Update Windows WG to AWG protocol support 2023-10-09 16:32:43 -04:00
vladimir.kuznetsov
0ce30a4e81 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/amnezia-wireguard-client-impl 2023-10-09 23:19:48 +05:00
vladimir.kuznetsov
bb2d794b6f corrections to the text 2023-10-09 23:18:24 +05:00
Nethius
45dc302de4 Merge pull request #362 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
Bugfix/minor UI fixes 4 version
2023-10-10 01:12:57 +07:00
vladimir.kuznetsov
4a2706a9d9 increased the application version to 4.0.8.1 2023-10-09 23:00:53 +05:00
vladimir.kuznetsov
00be3c3ccc corrections to the text 2023-10-09 22:54:33 +05:00
vladimir.kuznetsov
cb7fe50d46 added margins for picture with qr code 2023-10-09 22:40:06 +05:00
vladimir.kuznetsov
d364dbac2c now when a new container is installed, it is selected as the default container 2023-10-09 22:39:32 +05:00
vladimir.kuznetsov
042788bec3 moved add new server button to main tabbar 2023-10-09 20:19:22 +05:00
Mykola Baibuz
def261f578 Merge branch 'dev' into feature/amnezia-wireguard-client-impl 2023-10-09 11:00:37 -04:00
Mykola Baibuz
c08e23085e Fix protocol change from AWG to WG for Android 2023-10-09 10:29:42 -04:00
vladimir.kuznetsov
e01dd2bf57 added close application button in settings page 2023-10-09 19:16:06 +05:00
pokamest
61396ec82e Merge pull request #361 from amnezia-vpn/fix/android-accessibility
Disable android accessibility
2023-10-08 12:43:05 -07:00
albexk
357c283437 Disable android accessibility 2023-10-08 20:08:32 +03:00
Nethius
1b38cd6ca7 Merge pull request #360 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
Bugfix/minor UI fixes 4 version
2023-10-08 23:15:34 +07:00
Mykola Baibuz
bdfa8bfe5b AWG Android support 2023-10-07 09:01:29 -04:00
Mykola Baibuz
7f2ef65fe6 Update WG to AWG for Android 2023-10-06 17:20:41 -04:00
vladimir.kuznetsov
102d0472c7 Merge branch 'feature/amnezia-wireguard-client-impl' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-10-06 22:06:50 +05:00
vladimir.kuznetsov
445fc6efb1 renamed amneziawireguard to awg in ios controller 2023-10-06 22:05:48 +05:00
pokamest
135726f177 Merge branch 'dev' into feature/amnezia-wireguard-client-impl 2023-10-06 14:22:45 +01:00
vladimir.kuznetsov
671ca0a66f renamed amneziawireguard to awg 2023-10-06 17:26:45 +05:00
vladimir.kuznetsov
aa4a79934a renamed amenziawireguard to awg 2023-10-06 17:19:44 +05:00
vladimir.kuznetsov
16fc0617e4 renamed amneziawireguard files to awg 2023-10-06 17:02:28 +05:00
vladimir.kuznetsov
64a2f3f8bb Merge branch 'feature/amnezia-wireguard-client-impl' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-10-06 16:44:58 +05:00
vladimir.kuznetsov
b7a65343af added the ability to change awg parameters on the protocol settings page 2023-10-06 16:43:52 +05:00
Nethius
5c121ea48d Merge pull request #353 from amnezia-vpn/feature/added_i18n_for_v4
added i18n for v4
2023-10-06 11:49:17 +03:00
ronoaer
673f28ed64 retanslate donation way 2023-10-06 16:32:04 +08:00
ronoaer
3fb97d16bb updated about page 2023-10-06 15:49:48 +08:00
ronoaer
079c9176ef fixed minor issues of translation 2023-10-06 15:29:15 +08:00
ronoaer
9377a0b545 updated translated-text to connectStatusText in ConnectionController 2023-10-06 14:37:10 +08:00
ronoaer
1357c4a309 applied translation-funcation to SystemTray 2023-10-06 13:43:32 +08:00
Mykola Baibuz
d77be5a244 Update iOS network extension 2023-10-06 00:38:54 +03:00
Mykola Baibuz
08863edb52 Update AWG iOS binary again 2023-10-05 17:11:40 -04:00
Mykola Baibuz
3a77705142 Update AWG binary 2023-10-05 15:55:32 -04:00
ronoaer
1eafa9a38a updated about and tor 2023-10-05 23:47:50 +08:00
vladimir.kuznetsov
396b7aac18 fixed display of amnezia dns description on main menu 2023-10-05 13:56:00 +05:00
ronoaer
08defbbbd8 updated original string format, for adapting multi-language 2023-10-05 13:26:11 +08:00
ronoaer
79d371fb76 translated pages from english to chinese 2023-10-05 00:54:49 +08:00
vladimir.kuznetsov
9df262d502 fixed sending parameters to the awg daemon for windows 2023-10-04 19:14:27 +03:00
pokamest
6f392ce126 Crash on exit fix for Windows 2023-10-04 16:09:03 +01:00
vladimir.kuznetsov
a83ec10b61 updated description for full access sharing 2023-10-04 14:47:49 +05:00
vladimir.kuznetsov
a93f75fb5a added full version to page about 2023-10-04 14:40:17 +05:00
ronoaer
2353cc4f2c translated sub-page of Settings to Chinese 2023-10-04 15:48:35 +08:00
ronoaer
30709c66ef translated settings page 2023-10-04 09:05:29 +08:00
Nethius
70e6a3d303 Merge pull request #359 from amnezia-vpn/bugfix/minor-ui-fixes-4-version
minor ui fixes
2023-10-03 21:48:30 +03:00
Nethius
cc89939d05 Merge pull request #356 from amnezia-vpn/bugfix/buton_set_up_later_visible_logic
updated visible logic of button 'set up later'
2023-10-03 21:29:23 +03:00
vladimir.kuznetsov
7d4a01c757 minor ui fixes 2023-10-03 23:28:44 +05:00
vladimir.kuznetsov
e2d61cb518 renamed functions and variables 2023-10-03 22:38:17 +05:00
Nethius
fb1a9c9867 Merge pull request #357 from amnezia-vpn/feature/allow-android-screenshots
Added switcher "Allow app screenshots" for android
2023-10-03 20:24:10 +03:00
vladimir.kuznetsov
776ae04cbe Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-10-03 22:23:24 +05:00
Nethius
2447ab4305 Merge pull request #352 from amnezia-vpn/fix/drawerTypePositioning
Limit Drawer positioning by dragHeight and total page height
2023-10-03 19:37:58 +03:00
vladimir.kuznetsov
52124b15e8 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into fix/drawerTypePositioning 2023-10-03 19:00:58 +05:00
vladimir.kuznetsov
b1e9e8677b Merge branch 'fix/drawerTypePositioning' of github.com:amnezia-vpn/amnezia-client into fix/drawerTypePositioning 2023-10-03 18:53:16 +05:00
vladimir.kuznetsov
617e772cc1 added transitions and open/close by clicking on an item for the center menu button 2023-10-03 18:49:54 +05:00
ronoaer
27f770604b tried to translate some pages, from English to Chinese 2023-10-03 15:59:53 +08:00
Matthew Schwiebert
5bfc581ad2 add documentation, remove uneeded changes of drawertype 2023-10-02 15:40:25 -04:00
vladimir.kuznetsov
2664a52007 removed the dropdown with protocols on the share full access page 2023-10-02 22:04:18 +05:00
vladimir.kuznetsov
6dbbf1fc89 added parsing parameters for windows 2023-10-02 18:48:11 +03:00
vladimir.kuznetsov
c254f2fdc4 Merge branch 'feature/amnezia-wireguard-client-impl' of github.com:amnezia-vpn/desktop-client into feature/amnezia-wireguard-client-impl 2023-10-02 18:21:00 +03:00
vladimir.kuznetsov
cf450fa4e4 Merge remote-tracking branch 'origin/feature/amnezia-wireguard-client-impl' into HEAD 2023-10-02 20:04:40 +05:00
vladimir.kuznetsov
304f29bfac returned 'address' to awg server config and set it to 10.8.1.1/24 2023-10-02 20:03:01 +05:00
vladimir.kuznetsov
50b8b3d649 added parsing of wireguard config parameters when importing native configs 2023-10-02 18:30:32 +05:00
vladimir.kuznetsov
4e6c1094f3 minor ui fixes 2023-10-02 16:31:50 +05:00
Matthew Schwiebert
a6134ca10f fix visibility bug of collapsed state 2023-10-01 20:43:39 -04:00
Matthew Schwiebert
3d999a503c Add custom drawer behavior to pageHome, for mobile and desktop 2023-10-01 20:35:05 -04:00
vladimir.kuznetsov
39c2124a26 returned the awg setting via wg-quick 2023-10-01 21:43:30 +05:00
vladimir.kuznetsov
4e3955b39d Added switcher "Allow app screenshots" for android 2023-10-01 12:15:41 +03:00
ronoaer
784ae0da53 updated visible logic of button 'set up later' 2023-10-01 12:11:13 +08:00
ronoaer
eaede032b4 1. updated memory text when language changed,
2. updated initialize index
2023-10-01 11:12:27 +08:00
Mykola Baibuz
4ed153373f Fix Linux build, some naming changes 2023-09-30 16:05:23 -04:00
ronoaer
07d7fac490 removed invalid code 2023-09-30 17:40:26 +08:00
ronoaer
5535b6a6e3 embedded qm files into qrc file 2023-09-30 17:36:06 +08:00
Mykola Baibuz
b7fbb84a58 iOS AWG protocol Setup 2023-09-30 00:58:08 +03:00
vladimir.kuznetsov
19bd94ed02 Merge branch 'feature/amnezia-wireguard-client-impl' of github.com:amnezia-vpn/amnezia-client into feature/amnezia-wireguard-client-impl 2023-09-29 18:42:45 +05:00
vladimir.kuznetsov
54b45a36e1 test configuration using wg instead of wg-quick to configure the server 2023-09-29 18:41:00 +05:00
Nethius
ed1afa7549 Merge pull request #348 from amnezia-vpn/bugfix/changed_textfield_border_hover_color
added border hover effect for textarea
2023-09-29 16:24:28 +03:00
Mykola Baibuz
2986a18c8f iOS AWG support 2023-09-28 23:54:32 +03:00
Nethius
b2072c06b7 Merge pull request #355 from amnezia-vpn/fixbug/not_hide_topright_corner_button
Fixbug/not hide topright corner button
2023-09-28 23:39:22 +03:00
Nethius
762018883f Merge pull request #347 from amnezia-vpn/bigfix/no_container_redirecteto_wizardeasy
redirected to pagesetupwizardeasy when none containers installed
2023-09-28 21:01:55 +03:00
Nethius
0322c01c0e Merge pull request #340 from amnezia-vpn/bugfix/add_hover_in_home_page
added  hover effect for default-server in pagehome
2023-09-28 20:55:57 +03:00
Nethius
16ccfb8714 Merge pull request #349 from amnezia-vpn/bugfix/changed_cursorshape_for_cardtype
updated cursorshape of cardtype to Qt.PointingHandCursor
2023-09-28 20:55:03 +03:00
ronoaer
68095700a2 added i18n for v4 2023-09-28 23:21:13 +08:00
Matthew Schwiebert
058f8b544e Limit Drawer positioning by dragHeight and total page height 2023-09-28 10:14:01 -04:00
vladimir.kuznetsov
4cb871849b Merge remote-tracking branch 'remotes/origin/dev' into feature/amnezia-wireguard-client-impl 2023-09-28 00:26:26 +03:00
vladimir.kuznetsov
423305c35a moved the configuration of new parameters for awg to addInterface() 2023-09-28 02:14:07 +05:00
vladimir.kuznetsov
b55313527e added passing new amneziawireguard config parameters over uapi for all platforms 2023-09-27 00:45:42 +05:00
vladimir.kuznetsov
af53c456ea added passing new wireguard config parameters over uapi and configuring the amneziawireguard container 2023-09-27 00:40:01 +05:00
ronoaer
37024eb91d updated cursorshape of cardtype to Qt.PointingHandCursor 2023-09-26 17:23:35 +08:00
ronoaer
ee99565b63 1. added border-hover-interaction
2. updated textarea-focus-interaction
2023-09-26 16:38:08 +08:00
pokamest
1a8c08799f Merge pull request #346 from amnezia-vpn/bugfix/win-build
Windows. Remove unused binary from build files
2023-09-25 09:48:15 -07:00
ronoaer
8b08a5bee0 added border hover effect for textarea 2023-09-25 22:16:59 +08:00
ronoaer
51497d87e0 redirected to pagesetupwizardeasy when none containers installed 2023-09-25 07:22:11 +08:00
Mykola Baibuz
7ede1a8d83 Remove unused binary from build files 2023-09-24 22:09:30 +03:00
Mykola Baibuz
b4df5c076e Fix Linux App startup icon (#344)
* Fix Linux App startup icon
* Use project version from cmake
* Set Release date automatically
2023-09-24 16:57:59 +01:00
Mykola Baibuz
52400252dd Fix disconnect button for desktop WG (#345)
* Fix disconnect button for desktop WG
2023-09-24 12:06:52 +01:00
ronoaer
49923c4214 renamed deaultservertype, and moved to components 2023-09-24 08:21:27 +08:00
ronoaer
81b77c9688 Merge branch 'feature/new-gui' into fixbug/not_hide_topright_corner_button 2023-09-22 06:28:02 +08:00
vladimir.kuznetsov
7284bb54bc Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/amnezia-wireguard-client-impl 2023-09-22 00:39:32 +05:00
vladimir.kuznetsov
6afdd8375d added models, classes and ui files for amnezia wireguard 2023-09-22 00:37:55 +05:00
pokamest
af23d9fd14 Merge pull request #209 from amnezia-vpn/feature/new-gui
feature/new-gui
2023-09-21 12:07:22 -07:00
pokamest
e7aead292c Merge pull request #341 from amnezia-vpn/feature/icons-android-round
Android round icons
2023-09-21 11:53:09 -07:00
Mykola Baibuz
fd2678ce2f Android round icons
Icons for some older Android phones that use round icons.
2023-09-21 14:45:46 -04:00
Nethius
a6d660e708 Merge pull request #336 from amnezia-vpn/bugfix/close_drawer_easily
Bugfix/close drawer easily, short distance with dragging
2023-09-21 20:18:43 +05:00
ronoaer
de35a26285 added hover effect for default-server in pagehome 2023-09-21 23:03:12 +08:00
vladimir.kuznetsov
18bb045e9a Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-09-21 19:41:41 +05:00
pokamest
9090ec54e7 Merge pull request #339 from amnezia-vpn/dev
Release 3.1.0.1
2023-09-21 07:28:08 -07:00
pokamest
6fa9994366 Merge pull request #335 from amnezia-vpn/feature/linux-wg-rework
WireGuard rework for Linux
2023-09-21 05:43:10 -07:00
pokamest
665f2412f1 Version bump, macos/ios build fix [no ci] 2023-09-21 05:14:15 -07:00
pokamest
395099aa40 Merge pull request #338 from amnezia-vpn/bugfix/windows_signing_fix
build_windows.bat fix
2023-09-21 04:13:04 -07:00
pokamest
97a72a9ee2 build_windows.bat fix 2023-09-21 11:28:18 +01:00
pokamest
3414202b7b Merge pull request #332 from amnezia-vpn/bugfix/wireguard-config-import
added parsing of wireguard config parameters when importing native configs
2023-09-21 03:23:41 -07:00
Mykola Baibuz
52e5453d56 Upload AWG binary 2023-09-20 14:27:28 -04:00
ronoaer
dd039a612f used position-changed to closes drawer 2023-09-20 14:18:21 +08:00
Mykola Baibuz
f5ab034aeb WG routing rework for Linux 2023-09-19 17:59:04 -04:00
ronoaer
893ec2d61c researching: tried to close drawer easily 2023-09-20 00:18:10 +08:00
vladimir.kuznetsov
ff41b26e94 added parsing of wireguard config parameters when importing native configs 2023-09-19 18:45:06 +05:00
vladimir.kuznetsov
d4d6fbab88 changed the protocols for easySetup setup 2023-09-18 21:06:10 +05:00
vladimir.kuznetsov
e38fe871b2 Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-09-18 20:24:15 +05:00
vladimir.kuznetsov
152d7bc3b3 added restore default settings for dns settings page 2023-09-18 17:52:41 +05:00
vladimir.kuznetsov
9e7cf3ccd9 added PageServiceDnsSettings 2023-09-18 16:39:26 +05:00
ronoaer
f7370a0280 fixed: topright-corner button not visible when drawer closed 2023-09-18 14:35:22 +08:00
Nethius
814c574f26 Merge pull request #328 from amnezia-vpn/bugfix/add_top_close_button
added close button when drawer shown in the topright corner
2023-09-18 10:48:13 +05:00
Nethius
fd9f9ee178 Merge pull request #320 from amnezia-vpn/bugfix/scroll_stuck_on_fl_textarea
fixed scroll stuck on textarea in page OpenVpnSettings
2023-09-18 10:47:58 +05:00
ronoaer
29e8f8f5fb Merge branch 'feature/new-gui' into bugfix/scroll_stuck_on_fl_textarea 2023-09-18 07:36:01 +08:00
Mykola Baibuz
279692afea WireGuard rework for Linux 2023-09-17 17:06:24 -04:00
vladimir.kuznetsov
fd09321f8e removed the 'mount sftp folder' button for mobile platforms 2023-09-18 00:16:58 +05:00
vladimir.kuznetsov
ad236baa86 fixed a typo in the variable name 2023-09-17 23:24:21 +05:00
vladimir.kuznetsov
8965b1fbba fixed the size of the drawer close button 2023-09-17 23:21:00 +05:00
vladimir.kuznetsov
9b32411659 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-09-17 17:07:28 +05:00
Nethius
32dda9b904 Merge pull request #325 from amnezia-vpn/bugfix/reconnectvpn_when_dc_changed
auto reconection when current-server's defaul container hase been cha…
2023-09-17 17:06:02 +05:00
vladimir.kuznetsov
c0cb5b96bf added reconnection to vpn after changing any protocol settings 2023-09-17 17:03:39 +05:00
Nethius
ff60030ffb Merge pull request #329 from amnezia-vpn/bugfix/text_not_saved_after_edited
fixed additional info can not be save in page OpenVpn settings
2023-09-17 15:17:28 +05:00
vladimir.kuznetsov
f40bf2d9ba limited the length of the displayed server name
- added auto-selection of the first available protocol when changing the server on the PageShare page
2023-09-17 15:01:31 +05:00
ronoaer
9eebee3ce3 fixed additional info can not be save in page OpenVpn settings 2023-09-16 16:20:19 +08:00
ronoaer
8a3bdf136b added close button when drawer shown in the topright corner 2023-09-16 08:05:43 +08:00
Mykola Baibuz
f62076d3fd Android 8 support (#321) 2023-09-15 19:42:04 +01:00
pokamest
92f4d6b392 Merge pull request #327 from amnezia-vpn/feature/android-icon
Update Android icons
2023-09-14 23:39:10 +01:00
Mykola Baibuz
96ffd7e147 Update Android icons 2023-09-14 23:44:57 +03:00
Mykola Baibuz
07c38e9b6c WireGuard rework for MacOS and Windows (#314)
WireGuard rework for MacOS and Windows
2023-09-14 17:44:17 +01:00
vladimir.kuznetsov
c0aca97083 Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into HEAD 2023-09-14 21:26:13 +05:00
vladimir.kuznetsov
2fd25f53cc fixed auto-connection starting after starting the application 2023-09-14 15:35:24 +05:00
vladimir.kuznetsov
2b3383a163 removed the transition animation between tabs in the main menu
- fixed Drawer freezing when importing files from outside the application
2023-09-14 15:21:35 +05:00
pokamest
421a27ceae Merge pull request #326 from amnezia-vpn/feature/issue-template
Update issue templates
2023-09-13 17:24:32 -07:00
pokamest
10022451b4 Update issue templates 2023-09-14 01:20:38 +01:00
Nethius
3c8d923299 Merge pull request #322 from amnezia-vpn/bugfix/reconnect_server_when_changevp
reconnect to server when changed the protocol and status is connected…
2023-09-13 20:48:37 +05:00
Nethius
154044e32a Merge pull request #323 from amnezia-vpn/bugfix/linktext_cursor_sftp
the cursor changes to Qt.PointingHandCursor when hovering over links
2023-09-13 20:47:21 +05:00
ronoaer
bfc8c10f3d auto reconection when current-server's defaul container hase been changed 2023-09-13 20:49:44 +08:00
vladimir.kuznetsov
d93b5a7b5c fixed saving of configs for mobile platforms 2023-09-13 16:34:03 +05:00
vladimir.kuznetsov
4ae608ed93 added import backup file from outside for ios 2023-09-13 16:11:08 +05:00
vladimir.kuznetsov
e2aef1fc1d fixed display of installation errors on the initial installation screen 2023-09-13 11:09:29 +05:00
ronoaer
16cadfeae8 the cursor changes to Qt.PointingHandCursor when hovering over links 2023-09-13 09:39:17 +08:00
ronoaer
3c9b42b9f7 deleted unused code 2023-09-13 08:44:50 +08:00
ronoaer
9c0f27edb4 removed invalid codes 2023-09-13 08:01:14 +08:00
ronoaer
f81ee1b267 reconnect to server when changed the protocol and status is connected or connnecting 2023-09-12 21:38:36 +08:00
ronoaer
a964d955f4 fixed scroll stuck on textarea in page OpenVpnSettings 2023-09-11 23:49:50 +08:00
Nethius
f11c65c393 Merge pull request #319 from amnezia-vpn/fix_install_error_in_procotolpage
fixed the implicitWidth error in protocol installation page
2023-09-11 16:49:46 +05:00
vladimir.kuznetsov
f8e5e9f675 fixed display of cursorShape for all mouseArea 2023-09-11 16:48:56 +05:00
ronoaer
72eb36f5b3 fixed the implicitWidth error in protocol installation page 2023-09-11 18:55:50 +08:00
vladimir.kuznetsov
97c0fe1ece increased the application version to 4.0.5.1 2023-09-11 14:55:52 +05:00
vladimir.kuznetsov
844b552bf3 removed duplicate function routeMode 2023-09-11 14:45:10 +05:00
vladimir.kuznetsov
6bb85deca6 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-09-11 14:03:14 +05:00
vladimir.kuznetsov
551f7616f0 fixed the display of the protocol list in the settings when attempting to install a container that is already installed on the server 2023-09-11 13:56:49 +05:00
pokamest
285c508329 VPN mode fixes for Android and iOS 2023-09-10 17:40:18 -07:00
vladimir.kuznetsov
f751657903 fixed false triggering of swipes for the main menu drawer of PageHome 2023-09-09 22:41:36 +05:00
vladimir.kuznetsov
89096554e8 added constructor for MobileUtils.cpp 2023-09-09 18:31:04 +05:00
vladimir.kuznetsov
4bf6cce4ba fixed return type of sharedText function 2023-09-09 18:25:44 +05:00
vladimir.kuznetsov
85eae0b74a Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-09-09 15:01:03 +05:00
vladimir.kuznetsov
0a5657738e added a wait for the file dialog to close when sharing ios files 2023-09-09 15:00:34 +05:00
ronoaer
3aa0adbf39 fixed conflicts 2023-09-09 08:52:16 +08:00
Nethius
7dc21ce8a7 Merge pull request #317 from amnezia-vpn/adapt_mac_installer_wizard
adapted installer wizard to macos style
2023-09-09 01:30:45 +05:00
Nethius
6a6b200861 Merge pull request #316 from amnezia-vpn/fixed_protocol_reload_old_value
fixed: protocol reloads old value in settings page
2023-09-09 01:30:21 +05:00
vladimir.kuznetsov
1c7868312d added getting the path to the file for iOS 2023-09-09 01:29:28 +05:00
pokamest
90d1c16783 Merge pull request #315 from amnezia-vpn/installer_adapt_macos_wrap_text
updated installer-wizardstyle for adapting macos, especially text doe…
2023-09-08 12:29:31 -07:00
ronoaer
3cfca046ba adapted installer wizard to macos style 2023-09-08 21:40:55 +08:00
ronoaer
85414eb65f fixed protocol reloads old value in settings page 2023-09-08 21:31:47 +08:00
vladimir.kuznetsov
fdff57da7c fixed navigation during initial installation 2023-09-08 18:05:08 +05:00
ronoaer
7c223feef5 updated installer-wizardstyle for adapting macos, especially text does not wrapped in the page 'ready for install' 2023-09-08 16:05:24 +08:00
pokamest
3740cb2c30 Remove unnecessary qDebug() [no ci] 2023-09-07 10:56:26 -07:00
vladimir.kuznetsov
b5dd48ad7b reworking of getting the path to the file when saving/opening files 2023-09-07 22:45:01 +05:00
pokamest
e46025739a Merge pull request #312 from amnezia-vpn/dev-fixbug-cloak-protocol-config
fixed: text field can not be updated to memory, including site and port
2023-09-07 04:50:06 -07:00
ronoaer
66a3538d05 fixed: text field can not be updated to memory, including site and port 2023-09-07 07:44:51 +08:00
vladimir.kuznetsov
e1fa24c251 moved the qml filedialog opening code below the ios section 2023-09-06 22:26:37 +05:00
vladimir.kuznetsov
a76e22c021 Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-09-06 22:22:01 +05:00
vladimir.kuznetsov
c166327835 filedialog for qml moved to main.qml 2023-09-06 22:20:59 +05:00
vladimir.kuznetsov
4ab006f065 added swipe up for menu on PageHome 2023-09-06 13:37:37 +05:00
Mykola Baibuz
7eaaef6e75 Connection button status change for background start 2023-09-03 23:18:08 +03:00
Mykola Baibuz
c4f94efe24 Android fileSave fixes 2023-09-02 17:04:35 -04:00
pokamest
2eb729d712 Merge pull request #311 from amnezia-vpn/bugfix/crash_on_exit_fix
Crash on exit fix
2023-09-02 12:38:31 -07:00
pokamest
0343b6cf98 Crash on exit fix 2023-09-02 19:48:43 +01:00
vladimir.kuznetsov
7fc4ea0c68 Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-09-01 20:21:33 +05:00
Mykola Baibuz
195a3ab170 Save files for iOS 2023-09-01 17:29:48 +03:00
vladimir.kuznetsov
a96f485e3c added display of all protocols in the settings after installing a new container
- set the app's max height and width to 600/800
- expanded the description when removing containers
2023-09-01 17:39:23 +05:00
Mykola Baibuz
1b3a32f83f Import config from filesystem on iOS 2023-09-01 14:49:10 +03:00
Mykola Baibuz
cacf74af3c Fix iOS build 2023-09-01 01:08:44 +03:00
vladimir.kuznetsov
4e9f68acff returned the lost comma 2023-09-01 02:07:52 +05:00
vladimir.kuznetsov
b58295d1d6 added the ability to restore settings from backup on the initial screen
- fixed the display of services in the settings for mobile devices
2023-09-01 00:48:58 +05:00
vladimir.kuznetsov
cbcf187814 added missing include files 2023-08-31 21:49:36 +05:00
vladimir.kuznetsov
4baa003c0d removed old ui files 2023-08-31 16:00:41 +05:00
vladimir.kuznetsov
8cf8c3c122 Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-31 15:45:29 +05:00
vladimir.kuznetsov
e3e2c0ab6a Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-31 15:44:08 +05:00
vladimir.kuznetsov
e8862a3811 removed the use of QFileDialog 2023-08-31 15:42:59 +05:00
Mykola Baibuz
1c1a82696b Fix qrDecoder for Android 2023-08-30 17:23:55 -04:00
pokamest
a2893bac7e Fixes for sudo error "host not found" 2023-08-30 20:39:14 +01:00
Mykola Baibuz
0eda42f29f Savefile for iOS 2023-08-30 01:17:14 +03:00
pokamest
26f7310707 3.1.0 Release 2023-08-29 00:05:13 +01:00
pokamest
810da0db61 Fixes for iOS 2023-08-28 14:14:10 -07:00
vladimir.kuznetsov
8f6aa950cd fixed conflicts after merge 2023-08-28 22:03:28 +03:00
vladimir.kuznetsov
36a2482165 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-28 14:44:47 +03:00
vladimir.kuznetsov
639c18395b fixed display of notification about successful clearing of cached profiles
- limited the input for the Port field to only numeric values, in the range 1-65535
2023-08-28 14:18:41 +03:00
vladimir.kuznetsov
fe08fd3f0a moved the connect button to the center of the screen 2023-08-28 11:06:58 +03:00
pokamest
0822ee6b96 Merge pull request #301 from amnezia-vpn/bugfix/camera-usage-ios
Fix camera usage on iOS
2023-08-27 16:33:02 -07:00
Mykola Baibuz
96fdb9241a Fix camera usage on iOS 2023-08-27 23:13:22 +03:00
pokamest
0c6d193e0f iOS build fixes 2023-08-27 11:44:51 -07:00
pokamest
ece15c7394 Refactoring/ios (#300)
iOS app refactoring (native part):
- connection bugs fixed
- improved stability 
- logs from network extension
2023-08-27 18:46:41 +01:00
vladimir.kuznetsov
29bef052c7 minor ui fixes 2023-08-26 10:08:50 +03:00
pokamest
3ce1e40b43 Merge pull request #298 from amnezia-vpn/bugfix/android-stop-button
Fix stop button for Android
2023-08-25 14:40:35 -07:00
pokamest
290316e23e Merge pull request #299 from amnezia-vpn/bugfix/macos-installer
Fix MacOS artifact from GH actions
2023-08-25 14:39:35 -07:00
vladimir.kuznetsov
a74736b100 Merge branch 'bugfix/macos-installer' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-25 09:24:45 +05:00
vladimir.kuznetsov
3f7e7f2601 fixed native wireguard config import if there is no port in the Endpoint field 2023-08-25 09:20:42 +05:00
Mykola Baibuz
abefb011a5 Fix MacOS artifact from GH actions 2023-08-24 09:12:06 -04:00
vladimir.kuznetsov
259eff3fea upgraded app version 2023-08-24 16:25:51 +05:00
vladimir.kuznetsov
c271235d16 added confirmation dialog when clearing logs and notification after clearing 2023-08-24 16:22:55 +05:00
vladimir.kuznetsov
7539afa91e Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-24 14:54:22 +05:00
vladimir.kuznetsov
4c79905f5b added autostart and start minimized options
- added disabling split tunneling when selecting the wireguard protocol
- if for macos the application is minimized to tray, then now it is not displayed in the dock
2023-08-24 14:53:52 +05:00
Mykola Baibuz
b6d020e202 Update prebuilt (fix freezed connection after vpn over cloak android) 2023-08-23 21:14:36 -04:00
Mykola Baibuz
5a4dec3dc5 Fix stop button for Android 2023-08-23 17:16:40 -04:00
vladimir.kuznetsov
23ad006187 removed Widgets from service part 2023-08-23 00:20:59 +05:00
vladimir.kuznetsov
f7926847ac minor ui fixes 2023-08-22 14:37:29 +05:00
pokamest
895bd578e4 Merge pull request #292 from amnezia-vpn/feature/ios-wg-prebuilt
WG for iOS prebuilt
2023-08-21 03:14:38 -07:00
Mykola Baibuz
67a052b117 WG for iOS prebuilt 2023-08-20 17:47:16 -04:00
pokamest
3e41dae3ea MacOS 10.15 (Catalina) compatibility 2023-08-20 12:29:07 +01:00
vladimir.kuznetsov
420c616e9d added authResultReceiver to android.cmake 2023-08-20 13:43:27 +05:00
vladimir.kuznetsov
822009ec5f Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-20 13:38:07 +05:00
vladimir.kuznetsov
b5e1c78461 minor ui fixes 2023-08-20 13:36:54 +05:00
pokamest
bd0e892447 Merge pull request #289 from amnezia-vpn/refactoring-android
Refactoring android
2023-08-19 05:41:16 -07:00
albexk
92db453f81 Merge branch 'dev' into refactoring-android
# Conflicts:
#	client/CMakeLists.txt
2023-08-19 14:52:39 +03:00
vladimir.kuznetsov
0060f57b63 fixed selection of connection type on PageShare when changing protocol 2023-08-19 13:12:54 +05:00
albexk
2c517de5bb Move Android part of cmake to a separate file 2023-08-18 22:26:43 +03:00
albexk
9d5f7fdd9c Refactor and improve Android build script and GitHub action 2023-08-18 21:40:48 +03:00
vladimir.kuznetsov
ddaa5b784d minor ui fixes 2023-08-18 14:14:45 +05:00
pokamest
fadd9ff95d Merge pull request #288 from amnezia-vpn/bugfix/openvpn3-stability
Stability fixes in OpenVPN3 lib
2023-08-17 01:56:47 -07:00
vladimir.kuznetsov
a40f365a54 "added display of busy server package manager on the PageSetupWizardInstalling" 2023-08-16 23:48:25 +05:00
vladimir.kuznetsov
3964bffce4 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-16 23:47:21 +05:00
vladimir.kuznetsov
a8deb3593b dropdown list fixes to match design layout 2023-08-16 22:45:05 +05:00
pokamest
ba3ef98d1e Fix for server busy check (#287)
Fix for server busy check
2023-08-16 16:08:08 +01:00
Mykola Baibuz
59de0d47a3 Stability fixes in OpenVPN3 lib 2023-08-16 08:08:52 -04:00
vladimir.kuznetsov
e0d6e0117e Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-16 13:26:41 +05:00
vladimir.kuznetsov
e157160337 added disconnection from vpn when closing application for desktop
- many small ui fixes
2023-08-16 12:11:34 +05:00
pokamest
c7d2a3ffd4 Release 3.0.9 2023-08-13 15:22:24 +01:00
pokamest
2f897c9c98 Merge pull request #284 from amnezia-vpn/bugfix/sshclient_fix
Fix issue with SSH keys support
2023-08-13 03:51:58 -07:00
pokamest
de83db10d6 sshclient.cpp fix 2023-08-13 11:13:22 +01:00
pokamest
4c690dd3c6 Install scripts fixes (#275)
* Install scripts fixes
2023-08-13 11:10:41 +01:00
vladimir.kuznetsov
14fa0b4fd3 added qr code scanner for ios 2023-08-13 11:28:32 +05:00
pokamest
f8b55eb017 Merge pull request #283 from amnezia-vpn/feature/android-cmake-ss
Move SS libs from gradle to cmake
2023-08-12 04:06:15 -07:00
Mykola Baibuz
2b0bccf2d8 Move SS libs from gradle to cmake 2023-08-12 13:44:10 +03:00
vladimir.kuznetsov
c1c68cf72d fixed ability to share warguard in native format 2023-08-10 10:02:13 +05:00
pokamest
3db5c49009 Merge pull request #279 from amnezia-vpn/bugfix/android-qtcreator-build
Remove symlinks for android libs
2023-08-09 15:40:59 -07:00
Mykola Baibuz
87ffaceca3 Remove symlinks for android libs 2023-08-09 18:38:06 -04:00
vladimir.kuznetsov
591d98d8b6 moved vpnConnection to separate thread
- added tabbar blocking when installing/removing containers
2023-08-09 18:17:29 +05:00
vladimir.kuznetsov
e0d93eaa9f Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-09 10:33:34 +05:00
pokamest
5510ff7dce iOS connection fixes (#278)
iOS VPN connection fixes
2023-08-09 03:02:41 +01:00
pokamest
a1a6185fd6 Fixes for split tunneling (#272)
Fixes for split tunneling
2023-08-09 00:41:00 +01:00
pokamest
b71b87e6e9 Merge pull request #277 from amnezia-vpn/bugfix/openvpn-path-linux
Fix path to OpenVPN executable for Linux
2023-08-08 16:09:56 -07:00
Mykola Baibuz
41cc518e20 Fix path to OpenVPN executable
We have service that runs OpenVPN on Linux.  We need to make same
path for client and service.
2023-08-08 18:16:01 -04:00
pokamest
508356898f Fixes for linux (#273)
* Use prebuilt OpenVPN binary for Linux
2023-08-08 16:16:47 +01:00
vladimir.kuznetsov
0c40a954fa fixed include in sitesController for android build 2023-08-08 19:39:08 +05:00
vladimir.kuznetsov
784f99a900 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-08-08 19:12:17 +05:00
vladimir.kuznetsov
90ae0b3e44 added PageSettingsSplitTunneling
- added a call to the context menu when clicking the right mouse button for textInput
2023-08-08 19:10:14 +05:00
pokamest
520aaac31f CMake fixes for OpenSSL (#274)
* CMake fixes for OpenSSL
* Fix missed ldl link
* Some refactor for static libraries linkage
* Change library linkage order (GNU feature)
2023-08-08 14:13:35 +01:00
pokamest
8fe1370a74 Merge pull request #270 from amnezia-vpn/feature/macos-wg-prebuilt
Use prebuilt wireguard-go submodule
2023-08-07 11:55:49 -07:00
pokamest
c6ae89bf27 Merge pull request #269 from amnezia-vpn/bugfix/ios-openvpn-cloak-crash
Update OpenVPNAdapter to prevent crash OpenVPN-over-Cloak
2023-08-07 09:20:11 -07:00
Mykola Baibuz
822ef8829e Remove unused wireguard-go submodule 2023-08-06 16:24:39 -04:00
Mykola Baibuz
726e67ebb0 Use prebuilt binary for MacOS WireGuard 2023-08-06 16:21:01 -04:00
Mykola Baibuz
d4825b1d40 Update OpenVPNAdapter to prevent crash OpenVPN-over-Cloak 2023-08-05 14:56:42 -04:00
Mykola Baibuz
f58a16ca9d Prebuilt binaries for third-party submodules (#252)
* Add prebuilt submodule
* Remove Android native library
* Add links for Android prebuilt library
* Update OpenSSL to prebuilt binaries
* Setup links for prebuilt OpenSSL
* Set correct OpenSSL header dir
* Update prebuilt submodule
* Use static OpenSSL for linux build
* Use prebuilt binary from 3rd-prebuilt for Win installer
* Use prebuilt binary from 3rd-prebuilt for Linux installer
* Use prebuilt binary from 3rd-prebuilt for MacOS installer
* Use Android prebuilt openvpn libs
* Cleanup some unneeded code
* Add new maven repo for gradle-versions-plugin
* Use jitpack version of jsocks
* Fix some unnecessary header copy
* Fix issue with package name of original WG libs
* Change submodule path to https (3rd-prebuilt)
* Fix windows installer
* MacOS deploy fixes
* NetworkChange detection for OpenVPN protocol (#256)
* NetworkChange detection for OpenVPN protocol
* Update android native libs
* Always on VPN mode for OpenVPN, Cloak+OpenVPN
* Set foregroundService type
* Android 14 require to set foregroundServiceType
* Remove unused code and cleanup submodules
* Cleanup gradle build script
* Fix start button status
* Pull OpenSSL prebuilt for MacOS, iOS
* Update links for OpenSSL MacOS, iOS prebuilt
* Update OpenSSL binaries path
* Refactor some OpenSSL includes
* Update MacOS OpenVPN binary with statically linked dependency
* Use prebilt for LibSSH
* Android resources cleanup
* Set static runtime linux
* Use shared LibSSH for Android
* Update SS Android lib name
* Fix Linux install path and file permissions
* Feature/iOS GitHub actions (#265)
* Move Android cpp code to openvpn-pt-android repo
* Remove unused OpenVPN2 Android Libs
* Cleanup Gemfile

---------

Co-authored-by: Mazay B <pokamest@gmail.com>
2023-08-04 18:35:43 +01:00
vladimir.kuznetsov
2c429fd406 added removal of spaces when inserting ip addresses
- fixed server sharing when sharing a server available only for connection when choosing a server with full access
- removed the notification about an empty backup file when the user closes the file dialog without selecting anything
2023-08-02 21:46:02 +09:00
vladimir.kuznetsov
ebcca0c3b8 added processing of private ssh keys 2023-08-02 20:37:43 +09:00
vladimir.kuznetsov
925fd9f268 added display of installed services on the page PageSettingsServersList 2023-08-01 11:06:46 +09:00
vladimir.kuznetsov
0058edc24e added server availability check after entering credentials
- moved the protocol self-selection button to the PageSetupWizardEasy page
2023-07-31 20:38:13 +09:00
vladimir.kuznetsov
aa66133813 added 'insert' button and 'show password' button for PageSetupWizardCredentials 2023-07-31 14:29:49 +09:00
vladimir.kuznetsov
66f9a82f31 added icons for buttons in the drop-down window of connections sharing.
- corrections in texts
2023-07-31 12:54:59 +09:00
vladimir.kuznetsov
1092abe776 added output of notifications/errors after installation/import 2023-07-31 00:13:08 +09:00
vladimir.kuznetsov
0411792ca5 added qr-code decoder for android
- added color change for status and navigation bar for android
2023-07-25 16:56:10 +09:00
vladimir.kuznetsov
b9a13d3a32 changed all text to english 2023-07-24 16:33:58 +09:00
vladimir.kuznetsov
0a1359ed16 moved the platform-specific android code for the new ui 2023-07-24 16:31:04 +09:00
pokamest
9bd8c774ab Merge pull request #261 from amnezia-vpn/feature/browserstack
BrowserStack info added
2023-07-18 12:32:34 -07:00
pokamest
2943f93218 BrowserStack info added 2023-07-18 20:28:07 +01:00
vladimir.kuznetsov
5b8a0881b7 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-07-18 05:36:17 +03:00
vladimir.kuznetsov
5d677a9115 added pages for sftp and tor website settings 2023-07-18 11:15:04 +09:00
pokamest
26bf9aab26 iOS icons fixed [no ci] 2023-07-17 18:10:24 -07:00
pokamest
d9b4529932 Bugfix/ios icons (#260)
iOS icons updated  [no ci]
2023-07-16 15:41:15 +01:00
pokamest
35ecb8499d WireGuard for MacOS (#248)
* WireGuard for MacOS
* Fix openvpn block-outside-dns
2023-07-15 22:19:48 +01:00
pokamest
ed5dc7cdfd Fix for Cloak on iOS [no ci] 2023-07-15 13:00:55 -07:00
vladimir.kuznetsov
75489c00c2 added button 'Reset settings and remove all data from the application' 2023-07-14 22:59:49 +09:00
vladimir.kuznetsov
3aaa7b62ef added page to display raw config 2023-07-14 13:14:50 +09:00
vladimir.kuznetsov
c13b9754eb added protocol settings pages and models for openvpn, cloak and shadowsocks 2023-07-13 11:29:26 +09:00
vladimir.kuznetsov
a97417fd38 added config export in native format openvpn and wireguard 2023-07-05 10:15:38 +09:00
vladimir.kuznetsov
43261f8469 added busy indicator component
- replaced the image of the connect button with native rendering
2023-07-04 09:58:19 +09:00
vladimir.kuznetsov
b32935dd97 Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-06-30 18:15:13 +03:00
vladimir.kuznetsov
35660ff5e7 speed optimization of ui on windows 2023-06-30 18:14:47 +03:00
vladimir.kuznetsov
9b07909ed8 added FlickableType to PageSettingsServerProtocols and PageSettingsServerServices 2023-06-30 13:45:11 +09:00
vladimir.kuznetsov
b4eb317b00 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-06-30 05:00:20 +03:00
vladimir.kuznetsov
464d77dfb5 added functionality to change app language via settings 2023-06-30 10:40:43 +09:00
pokamest
a67ad12cde Merge pull request #255 from amnezia-vpn/bugfix/build_fixes
Build fixes and some refactoring
2023-06-29 17:58:57 -07:00
pokamest
0dba9b8268 Github actions fixes 2023-06-29 17:38:04 -07:00
Mazay B
4a4c9cd63f Build fixes and some refactoring 2023-06-30 00:21:56 +01:00
vladimir.kuznetsov
d0c9c1043c Merge remote-tracking branch 'remotes/origin/dev' into feature/new-gui 2023-06-27 13:38:06 +03:00
vladimir.kuznetsov
795405c47d added display of amnesia dns container activity on the main page 2023-06-27 19:07:42 +09:00
pokamest
e0c2f873f5 Merge pull request #253 from amnezia-vpn/bugfix/android_textfield
Workaround for bug https://bugreports.qt.io/browse/QTBUG-113461
2023-06-26 16:27:39 -07:00
Mazay B
1ec50cf6ad Workaround for bug https://bugreports.qt.io/browse/QTBUG-113461 2023-06-27 00:23:34 +01:00
vladimir.kuznetsov
2ef53c6df9 added separation for read/write and readonly servers for pageSettingsServerProtocols, PageSettingsServerServices, PageSettingsServerData
- added fields validations for pageSetupWizardCredentials
2023-06-23 15:24:40 +09:00
vladimir.kuznetsov
249be451f7 moved handling of connection states from qml in connectionController
- added a check for already installed containers before installing the server/container
- added a button to scan the server for installed containers
- added separation for read/write and readonly servers for pageHome
2023-06-21 20:56:00 +09:00
pokamest
34a228adbe Added AmneziaVPN svg logo 2023-06-20 18:19:48 +01:00
pokamest
9782eaaeea Update README.md 2023-06-20 17:29:34 +01:00
pokamest
50d3122bee Updated readme 2023-06-20 17:26:55 +01:00
vladimir.kuznetsov
3a264e6baf added a drawer to change the server name and moved the display of the exported config to a separate drawer 2023-06-20 10:25:24 +09:00
Mazay B
1b75b68373 Fix in AndroidController [NO CI] 2023-06-18 17:49:03 +01:00
vladimir.kuznetsov
4224e8314b Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-06-16 13:49:19 +09:00
vladimir.kuznetsov
7b14ad9616 added PageSettingsAbout, PageSettingsApplication, PageSettingsBackup, PageSettingsConnection, PageSettingsDns
- added SettingsController
2023-06-16 13:43:55 +09:00
vladimir.kuznetsov
be7386f0d7 added exportController and PageShare
- added a blank PageSettingsProtocol
2023-06-13 20:03:20 +09:00
vladimir.kuznetsov
cd3263db50 made libssh::ssh_connect a non-blocking feature
- extended error handling when connecting via ssh
2023-06-10 05:25:41 +03:00
vladimir.kuznetsov
3034019d5a Merge branch 'feature/new-gui' of github.com:amnezia-vpn/amnezia-client into feature/new-gui 2023-06-07 18:28:44 +08:00
vladimir.kuznetsov
1fd48a1cf8 added protocol settings page and openvpn settings page 2023-06-07 18:28:32 +08:00
vladimir.kuznetsov
c3f39ad24d added caching of servers and containers in models 2023-06-07 13:17:48 +03:00
vladimir.kuznetsov
68d9394d9f fixed windows build errors after refactoring 2023-06-05 17:49:20 +03:00
vladimir.kuznetsov
80fca589af added ConnectionController error handling 2023-06-05 22:40:35 +08:00
vladimir.kuznetsov
420c33d3ba added PageSetupWizardViewConfig
- added a popup with a question when deleting containers/servers
- added import from code and import error handling
2023-06-05 15:49:10 +08:00
vladimir.kuznetsov
de0cd976de added page transition effects
- added functionality for buttons on PageSettingsServerData page
2023-06-01 11:25:33 +08:00
pokamest
a116774104 Bugfix/macos fixes (#247)
* Icon for macos and tiny fixes
* Macos deploy build fix
2023-05-28 16:24:00 +01:00
vladimir.kuznetsov
1e180489a4 added display of vpn containers and services on the settings page
- added PageSettingsData and implementation of 'remove all containers'  button
2023-05-27 22:46:41 +08:00
vladimir.kuznetsov
e00656d757 added PageSettings and PageSettingsServersList.
- replaced PageLoader with PageType with stackView property.
- added error handling when installing a server/container
2023-05-25 15:40:17 +08:00
pokamest
adcc74ac8e Merge pull request #245 from amnezia-vpn/fix/ui_fixes
Tiny ui fixes
2023-05-24 08:17:40 -07:00
pokamest
3e0085b4a4 PopupWithQuestion.qml fix 2023-05-24 16:12:07 +01:00
pokamest
17fb2a98d6 Fix question when removing server from list 2023-05-24 12:18:40 +01:00
Mykola Baibuz
780efc2477 OpenVPN over Cloak for Android and iOS (#158)
OpenVPN over Cloak for Android and iOS
2023-05-23 23:50:36 +01:00
pokamest
7f02fe4157 Merge pull request #244 from amnezia-vpn/bugfix/ios_import_configs
Import configs for iOS
2023-05-23 08:10:46 -07:00
pokamest
f722576bf2 Merge pull request #241 from amnezia-vpn/bugfix/cloak_for_desktops_fix
Fixes for Cloak proto
2023-05-23 08:00:15 -07:00
pokamest
7fecc2cf4c Merge pull request #242 from i-ky/badge-link
Make build status badge into a link
2023-05-23 07:54:02 -07:00
pokamest
3519e070b4 Merge pull request #243 from i-ky/linguist
Mark client/3rd/ as vendored code
2023-05-23 07:53:17 -07:00
vladimir.kuznetsov
ca6b7fbeb2 added importController 2023-05-22 22:11:20 +08:00
i-ky
25d7e121c9 Mark client/3rd/ as vendored code 2023-05-22 14:21:02 +03:00
i-ky
882077f0aa Make build status badge into a link 2023-05-22 13:30:03 +03:00
vladimir.kuznetsov
0479113949 moved ContainersPageHomeListView and ConnectionTypeSelectionDrawer to separate components 2023-05-22 00:10:51 +08:00
pokamest
b5b69ff369 Fixes for Cloak proto 2023-05-20 18:44:19 +01:00
i-ky
f0ad76fff6 Gitpod integration (#240)
Add Gitpod configuration
2023-05-20 15:55:19 +01:00
amnezia-developer
e651ea7614 Add Qt Multimedia to project (#236)
Add Qt Multimedia to iOS cmake project
2023-05-17 20:38:28 +01:00
vladimir.kuznetsov
acca85b99a added installController with logic for server/container installation 2023-05-17 23:28:27 +08:00
pokamest
230f44f4e6 Import configs for iOS [WIP] 2023-05-15 17:57:35 -07:00
Nethius
19c42490e3 feature/versioning-for-desktop (#181)
Project refactoring and cleanup
2023-05-16 01:34:06 +01:00
vladimir.kuznetsov
03a0e2084a added PageLoader and pageController 2023-05-15 13:38:17 +08:00
vladimir.kuznetsov
116fa6777b added logic to the connect to vpn button 2023-05-14 21:11:19 +08:00
vladimir.kuznetsov
35d4222c7a added connectionController and ConnectionButton.qml 2023-05-12 23:54:31 +08:00
vladimir.kuznetsov
dd0de7e8be Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into origin/feature/new-gui 2023-05-12 11:54:28 +08:00
vladimir.kuznetsov
e3e7503a7c added saving the selected server and protocol to the config 2023-05-12 11:36:09 +08:00
Vladimir Kuznetsov
b66f4bf2be added display of protocols on PageHome 2023-05-11 14:50:50 +08:00
vladimir.kuznetsov
1c8dbae359 added PageHome, PageSettings, PageShare, PageStart
- renamed old PageStart to PageSetupWizardStart
- added various text types
- moved servers model to "global" scope
2023-05-06 06:52:23 +03:00
vladimir.kuznetsov
4f36349630 changed the way to create qml pages, now the page is created when you go to it
- added PageSetupWizardConfigSource, PageSetupWizardInstalling, PageSetupWizardProtocolSettings, PageSetupWizardTextKey
2023-05-03 19:06:16 +03:00
vladimir.kuznetsov
68b27451f2 Added scroll bar for DropDownType 2023-05-01 07:29:09 +03:00
vladimir.kuznetsov
c7acd63ea7 added SwitcherType and TabButtonType
- change CheckBoxType root type
- added PageTest
2023-04-29 19:09:16 +03:00
vladimir.kuznetsov
cfc17cf290 added mousearea to VerticalRadioButton 2023-04-26 18:37:56 +03:00
vladimir.kuznetsov
904e173037 added HorizontalRadioButton and VerticalRadioButton components 2023-04-26 08:30:02 +03:00
Mykola Baibuz
8a8d38a30f Prevent ipv6 leak (#224)
Prevent ipv6 leak for OpenVPN
2023-04-25 16:34:17 +01:00
vladimir.kuznetsov
a9ebf534c6 added DropDown component 2023-04-25 08:04:20 +03:00
pokamest
6429ff0603 Merge pull request #228 from amnezia-vpn/bugfix/openvpn-crl-verify
bugfix/openvpn-crl-verify
2023-04-21 12:43:35 +01:00
vladimir.kuznetsov
f5057dfac4 removed crl-verify from client config
- specified full path to crl in server config
- added crl generation when setting up a container
2023-04-21 07:44:35 +03:00
pokamest
00d61def0b Merge pull request #226 from amnezia-vpn/bugfix/sftp-files-permissions
bugfix/sftp-files-permissions
2023-04-19 16:19:47 +01:00
vladimir.kuznetsov
f5a26c7116 set the value S_IRWXU for windows, so that when copying via sftp, the necessary permissions for the file are set 2023-04-19 17:58:03 +03:00
pokamest
54fba99bed Merge pull request #225 from amnezia-vpn/bugfix/tcp-port-busy-check
in the port busy check, for tcp now only LISTEN ports are checked
2023-04-19 14:09:49 +01:00
vladimir.kuznetsov
7216a8b923 in the port busy check, for tcp now only LISTEN ports are checked 2023-04-19 06:39:50 +03:00
pokamest
97e322ba22 Merge pull request #223 from amnezia-vpn/bugfix/tcp-port-busy-check
in the port busy check, for tcp only the local port is now checked
2023-04-18 18:26:59 +01:00
vladimir.kuznetsov
fc603f11ce in the port busy check, for tcp only the local port is now checked 2023-04-18 20:00:40 +03:00
vladimir.kuznetsov
87f01007cc Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/new-gui 2023-04-18 15:47:11 +03:00
pokamest
10bca290c3 Merge pull request #221 from amnezia-vpn/bugfix/check-sudo-for-root
skipping sudo check for root user
2023-04-18 11:54:29 +01:00
vladimir.kuznetsov
3dabaeb2c9 skipping sudo check for root user 2023-04-18 05:48:37 +03:00
pokamest
cf74b879c6 Merge pull request #219 from amnezia-vpn/change/client-management-update-page
change/client-management-update-page
2023-04-16 14:41:28 +01:00
vladimir.kuznetsov
0ae2a1f177 now, when onUpdateAllPages is called, the ClientInfoLogic and ClientManagementLogic pages will not be updated
- moved the Client Management button to the Advanced Settings page
-
2023-04-16 07:32:32 +03:00
vladimir.kuznetsov
3d63d6c0f2 added PageSetupWizardCredentials and PageSetupWizardProtocols
- fixed hover and pressed effects for controls
2023-04-14 19:31:10 +03:00
vladimir.kuznetsov
905a3a30f3 added some new controls and started layout of pageStart and pageCredentials 2023-04-12 19:13:41 +03:00
pokamest
af29637163 Merge branch 'dev' 2023-04-11 18:00:54 +01:00
Josh Soref
7351fe9633 Spelling (#214)
Spelling fixed
2023-04-11 14:50:44 +01:00
pokamest
1a6b4a1188 Merge pull request #213 from amnezia-vpn/chore/qtssh-gitmodules
removed qtssh from gitmodules
2023-04-11 02:00:34 +01:00
vladimir.kuznetsov
ec96c1b534 added hover and pressed effects for CheckBoxType.qml 2023-04-10 06:43:36 +03:00
vladimir.kuznetsov
8751dd3797 removed qtssh from gitmodules 2023-04-09 05:47:27 +03:00
pokamest
9a6df25280 Merge pull request #149 from amnezia-vpn/feature/qt6-client-management-panel
feature/qt6-client-management-panel
2023-04-08 19:33:09 +01:00
vladimir.kuznetsov
ada8912a1f Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/qt6-client-management-panel 2023-04-08 19:03:10 +03:00
pokamest
de4245025c Merge pull request #189 from amnezia-vpn/feature/check-user-in-sudo
feature/check-user-in-sudo
2023-04-08 16:38:00 +01:00
vladimir.kuznetsov
f620f4a92e Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/check-user-in-sudo 2023-04-08 17:12:23 +03:00
vladimir.kuznetsov
c74c5e0c6d added CheckBoxType
- added hover effect to LabelWithButtonType
2023-04-07 20:50:55 +03:00
pokamest
2ca85c7829 Merge pull request #212 from bakhtiyork/feature/qt6-libssh-support
CI/CD iOS build fix
2023-04-07 17:23:31 +01:00
bakhtiyork
8374404b0f iOS - cmake: disabling testing and programs 2023-04-07 11:21:44 +05:00
pokamest
c453c6c294 Merge pull request #139 from amnezia-vpn/feature/qt6-libssh-support
feature/qt6-libssh-support
2023-04-06 20:09:03 +01:00
pokamest
a5e5c3d941 Merge pull request #210 from amnezia-vpn/dev
Pre-release 3.0.4
2023-04-06 20:05:51 +01:00
pokamest
c242a08653 Merge pull request #193 from bakhtiyork/feature/qt6-libssh-support
iOS - libssh with mbedtls build
2023-04-06 18:04:25 +01:00
bakhtiyork
f931603203 Disabling symbol versioning for iOS 2023-04-06 20:33:12 +05:00
vladimir.kuznetsov
167d57408d added CardType component
- added transition for BasicButtonType
2023-04-06 16:33:53 +03:00
bakhtiyork
ef03a3d9d4 FindMbedTLS.cmake - adding mbedtls targets export 2023-04-06 05:59:42 +05:00
vladimir.kuznetsov
ccfc9f2ad2 added error handling for key authentication 2023-04-05 09:45:03 +03:00
vladimir.kuznetsov
b3456ee96c fixed variable name in addAlreadyInstalledContainersGui() function 2023-04-05 06:20:10 +03:00
vladimir.kuznetsov
05cd4ac14b Merge branch 'feature/qt6-libssh-support' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-04-05 06:08:15 +03:00
vladimir.kuznetsov
ba2ecf9789 fixed cleanup of private/public keys after use 2023-04-05 06:07:36 +03:00
pokamest
020e6b1cb3 Merge branch 'dev' into feature/qt6-libssh-support 2023-04-05 03:40:55 +01:00
pokamest
2a7365730b getOpenFileName fix 2023-04-05 03:39:05 +01:00
pokamest
ad77d74f4b Merge branch 'dev' into feature/qt6-libssh-support 2023-04-05 03:26:08 +01:00
pokamest
ef8668dce4 Merge pull request #205 from amnezia-vpn/fix/build_desktop_on_apple_silicon
Fix to build Amnezia desktop app on Apple Silicon
2023-04-05 01:51:31 +01:00
pokamest
3fb34e28a4 Merge pull request #207 from amnezia-vpn/bugfix/add-server-with-same-credentials
bugfix/add-server-with-same-credentials
2023-04-05 01:50:11 +01:00
pokamest
871214f907 Merge pull request #206 from amnezia-vpn/bugfix/server-busy-default-port
bugfix/server-busy-default-port
2023-04-05 01:48:20 +01:00
pokamest
7e717754a3 getOpenFileName fix for Android 2023-04-05 01:43:42 +01:00
vladimir.kuznetsov
6e67946ae2 Removed the ability to add multiple servers with the same connection credentials via the "Add server" button 2023-04-04 19:13:39 +03:00
vladimir.kuznetsov
48d673c853 fixed getting default port and default transport protocol in isServerPortBusy function 2023-04-04 18:20:19 +03:00
Dmitriy Karpushin
a9bb6f8099 Fix to build at least x86_64 version of Amnezia desktop app on Apple Silicon 2023-04-04 17:10:58 +03:00
vladimir.kuznetsov
f8ef69b88a removed setPassphraseCallback() function from ServerController and libssh::Client 2023-04-04 13:32:37 +03:00
vladimir.kuznetsov
a005ed2a84 now an instance of the serverController class is created at the place of use 2023-04-04 10:22:25 +03:00
vladimir.kuznetsov
1aa859b10d moved passphraseCallback and passphraseDialog to startPage
- made some methods of the servercontroller class private
- returned a call to the checkSshConnection() function
2023-04-04 07:09:30 +03:00
vladimir.kuznetsov
4aba34c18b Merge remote-tracking branch 'remotes/origin/dev' into feature/qt6-libssh-support 2023-04-03 17:48:55 +03:00
vladimir.kuznetsov
5e099f522e added private key export without password to client config 2023-04-03 17:27:55 +03:00
pokamest
15c33014e7 Merge pull request #198 from amnezia-vpn/bugfix/qssh-too-many-open-connections
bugfix/qssh-too-many-open-connections
2023-04-02 13:43:30 +01:00
vladimir.kuznetsov
af5b9172ef removed unused disconnectFromHost() from ServerController 2023-04-02 15:19:59 +03:00
bakhtiyork
fe9e813c79 Custom cmake module path 2023-04-02 17:19:21 +05:00
vladimir.kuznetsov
51d7cdfd31 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into bugfix/qssh-too-many-open-connections 2023-04-02 14:48:26 +03:00
vladimir.kuznetsov
f3aef67be6 Added a form for entering a passphrase for a private ssh key and the corresponding logic for processing a private key 2023-04-02 09:09:20 +03:00
pokamest
449af8060a Merge pull request #204 from amnezia-vpn/fix/android_config_import
Android config import
2023-03-29 22:16:16 +01:00
pokamest
fa19f1f5a0 Merge pull request #200 from amnezia-vpn/bugfix/empty-server-list-settings-availability
bugfix/empty-server-list-settings-availability
2023-03-29 15:17:25 +02:00
Dmitriy Karpushin
9e461ef6e1 Fixed import from external applications 2023-03-29 16:16:54 +03:00
pokamest
1ba301ed16 Merge pull request #201 from amnezia-vpn/bugfix/reset-container-settings-after-adding-new-one
bugfix/reset-container-settings-after-adding-new-one
2023-03-29 15:16:34 +02:00
pokamest
7e663b05d5 Merge pull request #202 from amnezia-vpn/fix/android_various_fixes
Fix/android various fixes
2023-03-29 15:15:17 +02:00
Dmitriy Karpushin
2225a735ca Fixed typo 2023-03-29 12:01:18 +03:00
Dmitriy Karpushin
90c8fbb495 Update Room to fix build on Apple M1 2023-03-29 09:53:18 +03:00
vladimir.kuznetsov
2b14efd3f8 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into bugfix/qssh-too-many-open-connections 2023-03-29 09:44:28 +03:00
vladimir.kuznetsov
3261c36f97 changed the existsAnyServer value to properly display locked settings 2023-03-29 09:44:06 +03:00
vladimir.kuznetsov
c48d65525a set m_installCredentials when visiting the ServerContainers page 2023-03-29 09:44:00 +03:00
vladimir.kuznetsov
5fa6e755b2 changed the existsAnyServer value to properly display locked settings 2023-03-29 09:39:56 +03:00
vladimir.kuznetsov
8bbc0b9e1a set m_installCredentials when visiting the ServerContainers page 2023-03-29 09:38:00 +03:00
Dmitriy Karpushin
3a5317f16a Implementation of "migration manager" to fix placement of config files issue appeared after moving from Qt 5 to Qt 6 2023-03-29 09:31:24 +03:00
Dmitriy Karpushin
c0bb06bf49 Fix of copying to clipboard 2023-03-29 09:31:12 +03:00
Dmitriy Karpushin
8d45af2034 Files now saving with the file picker, not with the sharing mechanism 2023-03-29 09:31:02 +03:00
Dmitriy Karpushin
5f85bf62f5 Missing def check 2023-03-29 09:30:52 +03:00
Dmitriy Karpushin
8fa409d6c1 Restoration of bandwidth meter after closing of GUI 2023-03-29 09:30:45 +03:00
Dmitriy Karpushin
7167c2f20d Fix of "Connect" button state after restoring of an app 2023-03-29 09:29:55 +03:00
Dmitriy Karpushin
20846c8eff * correct behavior of back button on Android
* removing of annoying debug logs on Android
2023-03-29 09:29:06 +03:00
pokamest
1b44a01efd Merge pull request #195 from cyBerta/focus
Camera focus when reading QR
2023-03-28 15:21:54 +02:00
pokamest
c4104dcd33 Merge pull request #196 from cyBerta/android_dev_onboarding
Android dev onboarding documentation
2023-03-28 15:20:53 +02:00
vladimir.kuznetsov
c319c3f520 changed the way to get QSsh::SshConnection, now all resources are cleaned up after use, but the disconnectFromHost function becomes useless 2023-03-27 08:17:41 +03:00
cyberta
85025695df add a section about how to get started for Android developers 2023-03-26 13:59:12 +02:00
vladimir.kuznetsov
f6ca22ecdd Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-03-26 11:52:22 +03:00
cyberta
8d9594ba36 add auto-focus to CameraActivity 2023-03-25 23:56:55 +01:00
pokamest
fe7c66cf1d Merge pull request #194 from amnezia-vpn/bugfix/clear-server-from-amnezia
bugfix/clear-server-from-amnezia
2023-03-25 13:33:23 +00:00
vladimir.kuznetsov
b5aa940701 added removal of stopped containers 2023-03-25 15:50:12 +03:00
bakhtiyork
698dfb67d1 iOS - libssh with mbedtls build 2023-03-24 11:41:27 +05:00
vladimir.kuznetsov
8e61d77497 added new controls elements (BasicButtonType, ImageButtonType, LabelWithButtonType, TextFieldWithHeaderType) 2023-03-23 17:49:36 +03:00
pokamest
38f2f1a3e4 Merge pull request #179 from amnezia-vpn/feature/linux-wireguard-implementation
feature/linux-wireguard-implementation
2023-03-21 23:49:39 +00:00
pokamest
b98c6ca5c5 Merge pull request #192 from amnezia-vpn/bugfix/check-server-port-on-dns-container
bugfix/check-server-port-on-dns-container
2023-03-21 23:08:03 +00:00
vladimir.kuznetsov
5641874811 added skip port busy check for DNS container.
- added script execution error check when checking ports busy
2023-03-20 17:29:23 +03:00
pokamest
1dd34035c9 Merge pull request #190 from amnezia-vpn/bugfix/empty-port-when-check-server-ports
bugfix/empty-port-when-check-server-ports
2023-03-20 12:50:08 +00:00
vladimir.kuznetsov
6bf170e273 Merge branch 'bugfix/empty-port-when-check-server-ports' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-03-20 08:53:00 +03:00
vladimir.kuznetsov
084ac9b916 added a default port if it is not in the config when scanning the server for busy ports 2023-03-20 08:50:57 +03:00
vladimir.kuznetsov
cebf061f85 Merge branch 'feature/qt6-libssh-support' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-03-20 05:47:37 +03:00
vladimir.kuznetsov
5641db0026 uncommented static link for qtkeychain 2023-03-20 05:45:53 +03:00
vladimir.kuznetsov
a42ec8eddb Merge branch 'feature/qt6-libssh-support' of github.com:amnezia-vpn/desktop-client into feature/check-user-in-sudo 2023-03-19 18:04:55 +03:00
vladimir.kuznetsov
ea9917dacc added a script to check the user in the sudo group
- move isServerDpkgBusy to separate script
2023-03-19 17:26:43 +03:00
vladimir.kuznetsov
6272ae842c Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-03-19 17:23:18 +03:00
vladimir.kuznetsov
b000eda126 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-client-management-panel 2023-03-19 17:15:13 +03:00
vladimir.kuznetsov
9962bac50b changed using cp to QFile to copy wireguard config 2023-03-19 17:05:48 +03:00
vladimir.kuznetsov
f0c3f1b9ba Merge branch 'feature/linux-wireguard-implementation' of github.com:amnezia-vpn/desktop-client into feature/linux-wireguard-implementation 2023-03-19 15:32:07 +03:00
vladimir.kuznetsov
ec8eeef428 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/linux-wireguard-implementation 2023-03-19 15:06:17 +03:00
pokamest
7eb1a4b489 Fixed certutil path on Windows 2023-03-19 11:58:22 +00:00
pokamest
23b23f0e38 Merge branch 'dev' into feature/linux-wireguard-implementation 2023-03-17 16:18:56 +00:00
pokamest
cba78190a8 iOS build fix 2023-03-16 11:43:18 -07:00
pokamest
e097a49186 Merge pull request #184 from amnezia-vpn/bugfix/fake-web-site-label-wizard
bugfix/fake-web-site-label-wizard
2023-03-16 16:57:29 +00:00
pokamest
e895c784c7 Merge pull request #183 from amnezia-vpn/bugfix/installed-container-button
bugfix/installed-container-button
2023-03-16 16:56:30 +00:00
vladimir.kuznetsov
7e1bcf84f0 fixed saving site from "fake web site" field when configuring openvpn over cloak via wizard 2023-03-16 18:59:06 +03:00
vladimir.kuznetsov
a92f1b82d0 fixed a bug with incorrect port detection when clicking the "scan installed containers" button 2023-03-16 16:47:26 +03:00
vladimir.kuznetsov
433e6901c6 fixed a bug when existing containers were overwritten in the GUI when clicking the "scan installed containers" button 2023-03-16 16:46:29 +03:00
pokamest
e16d835727 CentOS docker autostart fix 2023-03-16 12:35:01 +00:00
pokamest
a5cf2d37d4 Merge pull request #180 from amnezia-vpn/fix/target_sdk_31
Support of targetSdk 31 with its behaviour changes
2023-03-06 12:02:15 +00:00
Dmitriy Karpushin
4bd6fbd445 Support of targetSdk 31 with its behaviour changes 2023-03-06 12:11:37 +03:00
vladimir.kuznetsov
8f18933713 moved the function of checking the availability of wireguard config to ipc client 2023-03-02 17:46:16 +03:00
vladimir.kuznetsov
caad670dbf added wireguard connection implementation for Linux 2023-03-02 10:19:57 +03:00
vladimir.kuznetsov
2d30f86cc6 removed unused qtssh folder 2023-02-28 06:15:01 +03:00
pokamest
1dd79d9e31 Merge pull request #169 from amnezia-vpn/feature/container-existence-on-container-setup
feature/container-existence-on-container-setup
2023-02-27 22:27:10 +00:00
vladimir.kuznetsov
4171afe275 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-client-management-panel 2023-02-27 19:59:01 +03:00
vladimir.kuznetsov
a287192649 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-02-27 19:53:53 +03:00
vladimir.kuznetsov
f2e9631af4 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/container-existence-on-container-setup 2023-02-27 19:42:47 +03:00
pokamest
c756ab70ae Merge pull request #168 from amnezia-vpn/feature/port-availability-on-container-setup
feature/port-availability-on-container-setup
2023-02-27 03:26:57 +00:00
pokamest
2e57fe0dfd Merge pull request #177 from amnezia-vpn/feature/android_qr_code_scanner
Qr-code scanner for Android
2023-02-27 00:23:33 +00:00
vladimir.kuznetsov
be39d28be7 renamed selectedServerIndex for android 2023-02-25 18:48:10 +03:00
vladimir.kuznetsov
23a292b8ff Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/container-existence-on-container-setup 2023-02-25 18:22:08 +03:00
vladimir.kuznetsov
cdbb247780 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/port-availability-on-container-setup 2023-02-25 18:21:23 +03:00
vladimir.kuznetsov
69d4f0ce10 removed ContainerProps::containerTypeToString 2023-02-25 18:17:25 +03:00
vladimir.kuznetsov
2580475f67 added a button to scan the server for already installed containers
- refactoring of old code, redundant sections of code removed
2023-02-25 17:59:22 +03:00
pokamest
138789149c Merge branch 'dev' into feature/qt6-libssh-support 2023-02-23 18:46:43 +00:00
pokamest
1be66659d3 Merge pull request #178 from amnezia-vpn/bugfix/linux-missing-lib
bugfix/linux-missing-lib
2023-02-23 18:11:48 +00:00
vladimir.kuznetsov
6d3ba0ae72 added installation of libxkbcommon-x11-0 package for linux runner 2023-02-23 17:32:32 +03:00
vladimir.kuznetsov
04f61677d7 static link for qtkeychain 2023-02-23 17:28:19 +03:00
Dmitriy Karpushin
0096e65fe6 Increased build tools version 2023-02-22 14:48:38 +03:00
Dmitriy Karpushin
b870306c5d Support of multiple-code config 2023-02-22 14:22:03 +03:00
vladimir.kuznetsov
480b2181f0 made error output in the same style
- some code style refactoring
2023-02-22 10:01:43 +03:00
vladimir.kuznetsov
ddc3fe7807 Added the advanced settings page
- added a button to scan the server for installed containers
- added a check on the presence of installed containers before configuring the server, if the containers are already installed, then we will add them to the GUI
- added new control element - PopupWarning.qml
2023-02-20 09:46:50 +03:00
Dmitriy Karpushin
a86e8659f7 CameraActivity with Google ML KIT for decoding QR codes 2023-02-17 16:38:44 +03:00
pokamest
ae10dd639b Merge branch 'dev' into feature/qt6-libssh-support 2023-02-17 01:47:25 +00:00
Shahzain Ali
a0141624b9 Wg fix (#172)
Build fix for iOS
2023-02-15 15:41:18 +00:00
vladimir.kuznetsov
dc137620eb Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/port-availability-on-container-setup 2023-02-14 18:03:19 +03:00
vladimir.kuznetsov
e9b92b216a added a check for port availability when installing up a container
- added wireguard service copying to debug build folder
2023-02-14 18:02:51 +03:00
Nethius
24bf057d17 Merge pull request #174 from amnezia-vpn/fix/qt6_libssh_andorid_build
Fixed libssh android build
2023-02-13 18:13:34 +03:00
Dmitriy Karpushin
b68c6b6807 Little refactoring 2023-02-13 10:42:47 +03:00
pokamest
34a268624b Merge pull request #166 from amnezia-vpn/bugfix/wrong-fields-type-shadowsocks-config
bugfix/wrong-fields-type-shadowsocks-config
2023-02-10 20:22:42 +00:00
Dmitriy Karpushin
cdd527f3ac little fix 2023-02-10 13:57:15 +03:00
pokamest
1f048a6d04 Merge branch 'dev' into bugfix/wrong-fields-type-shadowsocks-config 2023-02-09 13:10:26 +00:00
pokamest
58cf10ffb2 Merge pull request #173 from amnezia-vpn/feature/deploy-unpacked-binaries
feature/added-deploy-binaries-that-are-not-packed-into-the-installer
2023-02-09 13:08:37 +00:00
pokamest
1ef14e129f Update deploy.yml 2023-02-09 11:15:50 +00:00
Dmitriy Karpushin
7c4030aaef fix macos build 2023-02-08 19:09:24 +03:00
Dmitriy Karpushin
c1bf0f8799 [WIP] dynamic linking 2023-02-08 16:06:18 +03:00
vladimir.kuznetsov
4b0a4aa5d2 removed unused code 2023-02-08 16:06:18 +03:00
vladimir.kuznetsov
115be88e5d added check for nullptr in sshclient 2023-02-08 16:06:18 +03:00
vladimir.kuznetsov
268bd8f1a6 added deploy binaries that are not packed into the installer 2023-02-08 09:44:52 +03:00
pokamest
1d9ff17380 Merge pull request #170 from amnezia-vpn/bugfix/cmake-version
bugfix/cmake-version
2023-02-07 17:05:55 +00:00
vladimir.kuznetsov
0fa0d72300 increased required version of cmake for LINUX variable to work properly 2023-02-07 19:45:42 +03:00
pokamest
677d166b1e Merge pull request #164 from amnezia-vpn/feature/cloak-and-ss-in-linux-bundle
feature/cloak-and-ss-in-linux-bundle
2023-02-07 16:27:04 +00:00
vladimir.kuznetsov
b5778a9cb5 if the container already exists, then add it to the list of containers in the client 2023-02-07 10:39:18 +03:00
vladimir.kuznetsov
b2fd94d20e added a check for the existence of the container before installing it 2023-02-06 19:19:49 +03:00
vladimir.kuznetsov
16969bc39b added conversion of the local_port and server_port fields from string to number when saving the shadowsocks config 2023-02-06 08:39:56 +03:00
Dmitriy Karpushin
3943314142 Fix of android build 2023-02-03 19:07:09 +03:00
vladimir.kuznetsov
f7ee532add Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/cloak-and-ss-in-linux-bundle 2023-02-02 13:08:23 +03:00
pokamest
2fdab4c196 Merge pull request #165 from amnezia-vpn/bugfix/cloak-transport-protocol
bugfix/cloak-transport-protocol
2023-02-02 09:17:00 +00:00
vladimir.kuznetsov
e6a95370c1 removed unused code 2023-02-02 08:36:50 +03:00
vladimir.kuznetsov
92907bced3 hardcoded tcp for the openvpn-cloak container 2023-02-02 08:09:07 +03:00
Dmitriy Karpushin
ca30b8b62a Correct path for openssl static lib 2023-02-01 17:16:45 +03:00
vladimir.kuznetsov
da9ac6ff25 added check for nullptr in sshclient 2023-02-01 09:56:55 +03:00
Dmitriy Karpushin
475de5250e New HEAD of qtkeychain (qt6 support) 2023-01-31 18:02:04 +03:00
Dmitriy Karpushin
7a9860ac29 OpenSSL for android build 2023-01-31 17:12:52 +03:00
pokamest
32ca02bcc7 Crash fix on VPN connection 2023-01-31 01:38:49 +00:00
pokamest
ddefb99e5e Merge branch 'dev' into feature/qt6-libssh-support 2023-01-31 00:53:24 +00:00
pokamest
ca4d6e0b2f Android cmake build fix 2023-01-31 00:47:01 +00:00
pokamest
c3fc3a3132 Merge pull request #163 from amnezia-vpn/feature/confirm-on-clear-and-delete-server
feature/confirm-on-clear-and-delete-server
2023-01-30 20:45:35 +00:00
pokamest
78b8a1c36f Merge pull request #162 from amnezia-vpn/bugfix/cloak-transport-protocol
bugfix/cloak-transport-protocol
2023-01-30 20:43:15 +00:00
pokamest
638c3492d6 Merge pull request #159 from amnezia-vpn/bugfix/linux-uninstall
bugfix/linux-uninstall
2023-01-30 20:37:46 +00:00
vladimir.kuznetsov
4c1699935c added binaries for cloak and shadowsocks to Linux bundle 2023-01-30 12:41:51 +03:00
vladimir.kuznetsov
25829451c8 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-client-management-panel 2023-01-29 09:52:12 +03:00
vladimir.kuznetsov
74fbce8b96 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2023-01-29 09:43:03 +03:00
vladimir.kuznetsov
542039df01 Changed notification text for "Forget this server" action 2023-01-29 09:01:48 +03:00
vladimir.kuznetsov
d652ecff21 For the openvpn-cloak container, the choice of the transport protocol in the openvpn settings is blocked 2023-01-29 08:39:31 +03:00
vladimir.kuznetsov
00c4cf300a fixed the width of the buttons in popupWithQuestion 2023-01-27 19:56:39 +03:00
vladimir.kuznetsov
da47054497 changed element type to confirm container deletion from MessageDialog to PopupWithQuestion
- fixed "back" button availability for readonly servers
2023-01-27 18:37:08 +03:00
vladimir.kuznetsov
051a2a3ef2 Added popup to confirm actions "Clear server from Amnesia software" and "Forget this server" 2023-01-27 10:25:14 +03:00
vladimir.kuznetsov
ee609f3e8f fixed warning with QFutureWatcher
- renamed readWireguardConfiguration function to match what it does
2023-01-24 09:43:45 +03:00
vladimir.kuznetsov
eb66354c76 fixed path to maintenancetool in linux
- added x11 to runningOnLinux() function
2023-01-22 08:26:29 +03:00
vladimir.kuznetsov
c7fb7e58cf Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into bugfix/linux-uninstall 2023-01-21 10:35:29 +03:00
vladimir.kuznetsov
c2b02a45a2 fixed path to linux install folderfixed path to installed application in linux 2023-01-21 10:35:01 +03:00
pokamest
e7ed532545 Disable fastline for iOS while it not fixed 2023-01-19 21:08:57 +00:00
pokamest
2a031320c2 Merge pull request #156 from amnezia-vpn/bugfix/wrong-artifacts-size
added qtshadertools to all targets
2023-01-19 20:59:00 +00:00
vladimir.kuznetsov
d0379fdede added qtshadertools to all targets 2023-01-19 18:36:54 +03:00
vladimir.kuznetsov
45016b76e7 moved crl-verify crl.pem to openvpn config templates 2023-01-19 17:49:17 +03:00
pokamest
ee8cd8ef26 Merge pull request #118 from amnezia-vpn/qt_migration
Migration to Qt6
2023-01-19 13:09:00 +00:00
pokamest
18d89e9cad Merge pull request #152 from amnezia-vpn/feature/android_qt6_moving
Moving to Qt 6 and cmake on Android client
2023-01-19 12:51:02 +00:00
pokamest
623c8ca6b0 Merge pull request #155 from amnezia-vpn/feature/android_bandwidth_counter
Fix of bandwidth counter for Android
2023-01-19 12:38:55 +00:00
Dmitriy Karpushin
39736e865e Merge branch 'feature/android_qt6_moving' into feature/android_bandwidth_counter
# Conflicts:
#	client/platforms/android/android_controller.cpp
#	client/platforms/android/android_controller.h
2023-01-19 14:09:12 +03:00
vladimir.kuznetsov
8ea80a616e Merge branch 'qt_migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-client-management-panel 2023-01-18 20:06:01 +03:00
vladimir.kuznetsov
c5df7f9bb7 added diagrams describing the process of obtaining information about clients 2023-01-18 19:55:12 +03:00
Dmitriy Karpushin
92374966fb Removing of unnecessary command 2023-01-18 16:12:30 +03:00
Dmitriy Karpushin
6bebfb861c Little cleanup 2023-01-18 15:54:19 +03:00
Dmitriy Karpushin
30ae13b245 Fix of signing code 2023-01-18 15:38:06 +03:00
pokamest
891f990e35 Merge pull request #154 from amnezia-vpn/dev
Release 2.1.2
2023-01-18 12:22:18 +00:00
Dmitriy Karpushin
2118327ae0 Fixes in path of build 2023-01-18 14:47:11 +03:00
Dmitriy Karpushin
6aed2902a7 Fixes in path of build 2023-01-18 14:37:58 +03:00
Dmitriy Karpushin
e149e32ce1 Changing the set of highlights 2023-01-18 11:36:16 +03:00
Dmitriy Karpushin
41f2af8c4e Some highlights were added 2023-01-18 11:27:01 +03:00
Dmitriy Karpushin
016f808345 Removing of unnecessary command 2023-01-18 11:11:27 +03:00
Dmitriy Karpushin
bc69524654 Changing of path of keystore location 2023-01-18 11:06:58 +03:00
Dmitriy Karpushin
3c6280c419 Changing of path of keystore location 2023-01-18 10:54:24 +03:00
pokamest
9d01a52a4a Merge pull request #145 from amnezia-vpn/feature/qt6-server-busy-notification
feature/qt6-server-busy-notification
2023-01-18 00:43:13 +00:00
pokamest
a8273a8fdc Merge pull request #153 from amnezia-vpn/bugfix/some-ui-small-fixes
bugfix/some-ui-small-fixes
2023-01-18 00:41:11 +00:00
vladimir.kuznetsov
d6d3bf6943 moved certificate content acquisition from ClientManagementLogic to ClientInfoLogic 2023-01-17 21:04:15 +03:00
vladimir.kuznetsov
f6e8346841 moved getClientsList and setClientsList from serverController 2023-01-17 18:41:36 +03:00
vladimir.kuznetsov
b9717e9894 removed unused code 2023-01-17 17:11:45 +03:00
Dmitriy Karpushin
6b3209e6ee Changing of the way of keystore fetching 2023-01-17 16:59:34 +03:00
Dmitriy Karpushin
0a6da5ead1 Platform version fix 2023-01-17 16:23:34 +03:00
Dmitriy Karpushin
53441148b8 Revert of Gradle upgrade 2023-01-17 16:12:42 +03:00
Dmitriy Karpushin
732d018819 Revert "Shadowsocks manifest fix"
This reverts commit e261a8ba21.
2023-01-17 16:09:06 +03:00
Dmitriy Karpushin
e261a8ba21 Shadowsocks manifest fix 2023-01-17 15:53:54 +03:00
Dmitriy Karpushin
c3c87bff74 Fix of GitHub Actions build 2023-01-17 15:34:37 +03:00
Dmitriy Karpushin
c3f423aad5 Little cleanup 2023-01-17 15:34:37 +03:00
pokamest
580975fda1 Merge branch 'qt_migration' into feature/qt6-server-busy-notification 2023-01-16 18:13:07 +00:00
pokamest
9f114a1dad Tiny fix [no ci] 2023-01-16 18:12:30 +00:00
pokamest
0ae93d0657 Merge pull request #144 from amnezia-vpn/refactoring/logging
refactoring/logging
2023-01-16 17:29:24 +00:00
vladimir.kuznetsov
3a210c5bab added wireguard key revocation 2023-01-16 20:24:37 +03:00
pokamest
44d2627e2a Tiny fix [no ci] 2023-01-16 17:11:00 +00:00
pokamest
6e882760f1 Merge branch 'qt_migration' into refactoring/logging 2023-01-16 16:10:39 +00:00
pokamest
ff79ffd1c8 Android tag deploy fix 2023-01-16 15:10:57 +00:00
vladimir.kuznetsov
3175b0c4ff Changed the indentation of the "Installed Protocols and Services" heading on the "Server Containers" page 2023-01-16 16:20:12 +03:00
Dmitry Karpushin
21779395ef Merge branch 'qt_migration' into feature/android_qt6_moving 2023-01-16 14:58:01 +03:00
Dmitriy Karpushin
32cbb698ee Support of apk signing for tag-deploy workflow 2023-01-16 14:30:08 +03:00
vladimir.kuznetsov
3f99c52349 change Flickable to FlickableType for ClientManagement and ClientInfo pages 2023-01-16 12:37:14 +03:00
vladimir.kuznetsov
19a41b2792 swapped "Clear client cached profile" and "Clear server from Amnesia software" buttons 2023-01-15 18:47:16 +03:00
vladimir.kuznetsov
599910daea added openvpn certificate revocation 2023-01-15 18:09:05 +03:00
vladimir.kuznetsov
bee42ea2fb fixed double call onEditingFinished when pressing Enter 2023-01-14 18:30:08 +03:00
vladimir.kuznetsov
221ea5ebb0 Merge branch 'qt_migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-server-busy-notification 2023-01-13 16:59:03 +03:00
vladimir.kuznetsov
f24df9fb05 Merge branch 'qt_migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-client-management-panel 2023-01-12 20:28:13 +03:00
vladimir.kuznetsov
ce2a122d51 added busy indicator when saving a list of clients, on the client info panel 2023-01-12 20:20:24 +03:00
Dmitriy Karpushin
e8242aec85 Android build script fix 2023-01-12 15:36:31 +03:00
Dmitriy Karpushin
6ed9dcbe93 Workflow build script fix 2023-01-12 15:19:39 +03:00
Dmitriy Karpushin
58371e6e43 New trigger for a workflow 2023-01-12 15:12:55 +03:00
Dmitriy Karpushin
2d8957489e Trigger alternative syntax 2023-01-12 14:55:11 +03:00
Dmitriy Karpushin
1fd0794bfb Workflow file formatting fix 2023-01-12 14:30:25 +03:00
Dmitriy Karpushin
58da60985f Error fix 2023-01-12 14:21:14 +03:00
Dmitriy Karpushin
6b6a3cd38e [WIP] Android release workflow test 2023-01-12 14:16:05 +03:00
pokamest
4b1df16ecf Merge pull request #148 from amnezia-vpn/feature/github-actions-artifacts
feature/github-actions-artifacts
2023-01-12 01:22:41 +00:00
vladimir.kuznetsov
24ea686e4d added busy indicator when loading a list of clients, on the client management panel 2023-01-11 21:36:18 +03:00
vladimir.kuznetsov
a7030cdcb9 added saving the list of clients for wireguard
- added error handling when getting/saving a list of clients
2023-01-11 20:36:47 +03:00
vladimir.kuznetsov
8c137ecc52 added page to display WireGuard client information 2023-01-10 16:21:45 +03:00
Dmitriy Karpushin
20e44aa891 Re-enabled multi-abi build 2023-01-10 13:19:19 +03:00
vladimir.kuznetsov
118bb53c03 fixed path to linux installer 2023-01-09 16:41:24 +03:00
Dmitriy Karpushin
7c3be9f0b0 Update of NDK version 2023-01-09 14:21:10 +03:00
Dmitriy Karpushin
d1990a4263 Adopted GitHub Actions build config for Qt6 2023-01-09 13:46:45 +03:00
vladimir.kuznetsov
396422ee3a increased storage time for artifacts up to 3 days 2023-01-09 12:44:36 +03:00
vladimir.kuznetsov
f735b401df added deploy artifacts to github actions, artifact lifetime 1 day 2023-01-09 12:41:04 +03:00
vladimir.kuznetsov
a42beb86c0 added client management panel
- added classes for displaying the client management panel
- added class for displaying the client info
- added page to display a list of clients
- added page to display OpenVpn client information
- added diagram with OpenVpn certificate revocation process
2023-01-09 12:38:01 +03:00
pokamest
85020270d5 MacOS deploy fix 2023-01-08 17:21:51 -08:00
pokamest
b1b9044021 Merge branch 'qt_migration' into refactoring/logging 2023-01-08 23:17:11 +00:00
pokamest
8da30b216f Cleanup 2023-01-08 23:10:46 +00:00
pokamest
167d3caa5d Merge branch 'dev' into qt_migration 2023-01-08 23:00:13 +00:00
pokamest
3259e6f0e8 Merge pull request #128 from amnezia-vpn/feature/ovpn-config-import
added import of configs in openvpn and wireguard formats
2023-01-08 22:26:39 +00:00
pokamest
64526c5232 Various ui fixes 2023-01-08 21:24:06 +00:00
pokamest
d9630afafd Merge branch 'dev' into feature/ovpn-config-import 2023-01-08 19:36:00 +00:00
pokamest
c8c6e62aa0 Merge pull request #141 from amnezia-vpn/add-scrollbar-on-flickables
Show Scrollbars whenever the scroll is not obvious
2023-01-08 12:32:55 +00:00
pokamest
7f561c30b3 Buttons margins 2023-01-08 12:32:07 +00:00
pokamest
1d8f342417 QML refactoring 2023-01-07 13:40:35 +00:00
vladimir.kuznetsov
6ec090ea0d added a "Cancel" button to interrupt the server configuration process when it is found that it is busy installing other software 2023-01-02 17:32:27 +03:00
vladimir.kuznetsov
08a8eadb49 added display of a notification that the server is busy installing third-party software
- refactoring doInstallAction functions
2023-01-01 22:08:39 +03:00
Dmitriy Karpushin
3e2835bef6 Rolling back GitHub Actions config 2022-12-29 15:04:42 +03:00
vladimir.kuznetsov
686fc754b2 renamed log class in service project to logger 2022-12-28 17:56:31 +03:00
Dmitriy Karpushin
ea17124d6d Fix of build type for GitHub Actions 2022-12-28 16:35:25 +03:00
Dmitriy Karpushin
4000041308 Fix of build type 2022-12-28 15:55:03 +03:00
Dmitriy Karpushin
1a50ed0316 Increased java version on runner 2022-12-28 14:45:45 +03:00
Dmitriy Karpushin
42038cd6e7 Fixed filenames 2022-12-28 14:26:44 +03:00
Dmitriy Karpushin
44c5b41cc7 Little fix 2022-12-28 13:57:41 +03:00
Dmitriy Karpushin
da7bd91514 Little fix 2022-12-28 13:52:14 +03:00
Dmitriy Karpushin
0206623c6f Correct way to set up QT_HOST_PATH variable 2022-12-28 13:42:29 +03:00
vladimir.kuznetsov
3b2948d4dd renamed debug class to logger 2022-12-28 13:41:45 +03:00
Dmitriy Karpushin
918aeb670e Added QT_HOST_PATH variable 2022-12-28 13:37:56 +03:00
Dmitriy Karpushin
fd9fec48a2 Replacing of qmake on cmake for GitHub Actions 2022-12-28 13:10:34 +03:00
vladimir.kuznetsov
77e51b40b8 removed unused logger 2022-12-28 13:09:33 +03:00
vladimir.kuznetsov
195663c6e3 Added activation and deactivation of logging without restarting the application 2022-12-28 06:52:02 +03:00
vladimir.kuznetsov
ce4ca5c4d5 Added display of a notification about the inclusion of logging on the main screen 2022-12-28 06:50:46 +03:00
Dmitriy Karpushin
3e276c4111 GitHub Actions fix #2 2022-12-27 20:06:11 +03:00
Dmitriy Karpushin
41a4dc2fa2 GitHub Actions fix 2022-12-27 20:00:45 +03:00
Dmitriy Karpushin
7851047421 multi-abi support 2022-12-27 17:54:14 +03:00
Dmitriy Karpushin
a30e478cbd Fix of cmake build 2022-12-27 17:14:44 +03:00
Dmitriy Karpushin
ad4b3dfad1 [WIP] cmake build for android 2022-12-27 15:37:58 +03:00
Dmitriy Karpushin
ad7fc937a9 Added missing files 2022-12-27 11:10:01 +03:00
vladimir.kuznetsov
fd905ef308 added margin for scrollbars for almost all flickable elements 2022-12-26 19:07:05 +03:00
pokamest
3f257af7a9 Merge pull request #131 from amnezia-vpn/qmake-to-cmake-migration
Qmake to cmake migration
2022-12-26 14:52:40 +00:00
vladimir.kuznetsov
030bb8fe76 Merge branch 'qt_migration' of github.com:amnezia-vpn/desktop-client into qmake-to-cmake-migration 2022-12-26 17:29:52 +03:00
pokamest
131601d9d2 Merge pull request #142 from amnezia-vpn/qt-migration-cleanup
Qt migration cleanup
2022-12-26 14:16:03 +00:00
vladimir.kuznetsov
64317ffef5 fixed deploy service additional data for debug target 2022-12-26 17:15:45 +03:00
vladimir.kuznetsov
911e65af55 Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2022-12-26 17:08:27 +03:00
Dmitriy Karpushin
82165eaf37 1) Fixed theme
2) Fixed VPN connection
2022-12-26 14:00:45 +03:00
vladimir.kuznetsov
4a75f2ebca Moved ssh lib wrapper from SshSession to SshClient 2022-12-26 12:43:51 +03:00
vladimir.kuznetsov
be39b3be8c implementation of sending commands via ssh_channel_request_exec() 2022-12-26 10:12:42 +03:00
vladimir.kuznetsov
50e8aff8fa added ssh_channel_close() in ShhSession 2022-12-25 15:46:56 +03:00
pokamest
804a790392 FlickableType added 2022-12-24 16:41:53 +00:00
vladimir.kuznetsov
d04566a6c4 fix for macos build 2022-12-24 18:21:08 +03:00
Dmitriy Karpushin
6c614a4b3c Moving to Qt6:
1) removing of deprecated classes
2) update of IPC mechanism
2022-12-23 17:32:20 +03:00
vladimir.kuznetsov
3277717a7f Added error handling
Added write to channel in callbacks
2022-12-23 14:50:48 +03:00
vladimir.kuznetsov
f9b2829396 removed linking with botan and qssh 2022-12-23 10:13:06 +03:00
vladimir.kuznetsov
81cf108471 moved and formatted code for sftp to sshSession class 2022-12-22 19:55:30 +03:00
vladimir.kuznetsov
5075fe358e added callbacks for output from a remote host 2022-12-21 08:13:06 +03:00
vladimir.kuznetsov
c8085a368f added class to open ssh connection using libssh and write data to ssh channel 2022-12-20 13:43:46 +03:00
Shahzain Ali
8191c25dd7 Delete amnezia-ios-certificates 2022-12-20 00:37:30 +05:00
Shahzain Ali
dc4b2bd52e added submodule 2022-12-20 00:22:12 +05:00
Shahzain Ali
ca60afbcee Update deploy.yml 2022-12-19 17:06:47 +05:00
Shahzain Ali
374b74b710 Update deploy.yml 2022-12-19 17:03:33 +05:00
Shahzain Ali
ae0d3d78cd Testflight upload test 2022-12-19 17:02:25 +05:00
vladimir.kuznetsov
f9f197afd0 removed unused code 2022-12-18 19:36:19 +03:00
vladimir.kuznetsov
93c43ecbc3 removed unused qzxing folder 2022-12-18 18:27:20 +03:00
vladimir.kuznetsov
1fd1b0388b removed unused code 2022-12-18 18:27:08 +03:00
vladimir.kuznetsov
833364a94e added SortFilterProxyModel submodule 2022-12-18 18:11:41 +03:00
vladimir.kuznetsov
893c105bf2 removed SortFilterProxyModel sources 2022-12-18 18:07:32 +03:00
vladimir.kuznetsov
e481bd4ec5 added deploy artifacts to github actions, artifact lifetime 1 day 2022-12-18 09:45:26 +03:00
vladimir.kuznetsov
b0489aa61b Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2022-12-18 09:17:35 +03:00
vladimir.kuznetsov
376bc29e95 set OPENSSL_SSL_LIBRARY for ios 2022-12-17 22:18:14 +03:00
vladimir.kuznetsov
bd22e330a7 set OPENSSL_CRYPTO_LIBRARY for ios
- removed linking with brew openssl for ios
2022-12-17 22:02:38 +03:00
vladimir.kuznetsov
9ce7114f8c added variables for OpenSSL 2022-12-17 21:48:45 +03:00
vladimir.kuznetsov
1303da1c20 openedsl linking method changed 2022-12-17 21:34:59 +03:00
vladimir.kuznetsov
c6bb33fa84 added display of "pure" config if it was imported in native format
- changed the method of passing the isThirdPartyConfig parameter to page logic
- removed adding hostname to the server name when importing configs in native format
- fixed display of the "$proto settings" button when clicking on the protocol on the "Installed services" page
2022-12-17 21:00:48 +03:00
vladimir.kuznetsov
22939a6707 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/ovpn-config-import 2022-12-17 17:27:26 +03:00
Hamza ARBI
9222877306 Show Scrollbars whenever the scroll is not obvious 2022-12-17 12:06:19 +01:00
Shahzain Ali
5d8264e854 Update launch.png 2022-12-16 18:48:14 +05:00
pokamest
77124e098c Merge branch 'qt_migration' into qmake-to-cmake-migration 2022-12-16 04:45:43 -08:00
pokamest
bd0a70d024 Merge pull request #140 from amnezia-vpn/bugfix/drawer-clickability
Bugfix/drawer-clickability
2022-12-16 13:43:49 +01:00
Shahzain Ali
914700712e OpenSSL finding issue fixed. 2022-12-16 15:27:06 +05:00
vladimir.kuznetsov
80d792915a fixed clickability of "drawer" elements
- added Qt.PointingHandCursor to SelectContainer drawer
- fixed some warnings
2022-12-15 21:16:59 +03:00
Dmitriy Karpushin
54dc363231 iOS fix + Android connection status restoration fix 2022-12-15 18:46:15 +03:00
pokamest
36c436af50 gitignore fix 2022-12-15 11:26:25 +01:00
Shahzain Ali
73eb9259e2 Update CMakeLists.txt 2022-12-15 14:26:45 +05:00
pokamest
951d915326 libssh init 2022-12-14 21:50:52 +01:00
vladimir.kuznetsov
14c25480ce changed working directory to call openvpn.sh 2022-12-14 22:26:06 +03:00
vladimir.kuznetsov
77d87f8c50 set working directory to call openvpn.sh 2022-12-14 21:55:51 +03:00
vladimir.kuznetsov
ab389d4817 for osxtools and networkextension/CMakeLists.txt CMAKE_CURRENT_SOURCE_DIR changed to CLIENT_ROOT_DIR 2022-12-14 21:29:33 +03:00
vladimir.kuznetsov
58b9e0cd7c for osxtools and networkextension/CMakeLists.txt CMAKE_CURRENT_LIST_DIR changed to CMAKE_CURRENT_SOURCE_DIR 2022-12-14 21:16:24 +03:00
vladimir.kuznetsov
ed2f5af204 Removed "cd client" for ios, also changed CMAKE_SOURCE_DIR to CMAKE_CURRENT_LIST_DIR.
Removed duplicate deployment files for macos
2022-12-14 20:58:49 +03:00
vladimir.kuznetsov
5b2f1f8969 processing of 3rdparty libraries moved to a separate cmake file 2022-12-14 20:32:13 +03:00
vladimir.kuznetsov
a2122cb7d7 moved changes from .pro file 2022-12-14 19:55:14 +03:00
vladimir.kuznetsov
d680702b15 change path to cmake folder 2022-12-14 19:17:58 +03:00
vladimir.kuznetsov
d15de499dc Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into qmake-to-cmake-migration 2022-12-14 19:16:38 +03:00
vladimir.kuznetsov
bd382e3cc7 moved the cmake folder to client root folder 2022-12-14 19:16:12 +03:00
Dmitriy Karpushin
d417fa58ab OpenVPN bandwidth counter for Android 2022-12-14 18:52:19 +03:00
Shahzain Ali
ca9cb997b5 Fixed openVPN issue.
Now OpenVPN moved to main target and fixed search path issue, becuase I face below error while archiving. Invalid Bundle. The bundle at 'AmneziaVPN.app/PlugIns/AmneziaVPNNetworkExtension.appex' contains disallowed nested bundles.
2022-12-14 17:28:16 +05:00
Shahzain Ali
ebd920f3b2 Setting target membership on Media.xcassets 2022-12-14 16:56:20 +05:00
vladimir.kuznetsov
a611ddea2d removed environment OPENSSL_ROOT_DIR variable 2022-12-13 23:52:43 +03:00
vladimir.kuznetsov
75614e0bbb set environment OPENSSL_ROOT_DIR variable 2022-12-13 23:39:58 +03:00
vladimir.kuznetsov
dafef6463a added:
- set PKG_CONFIG_PATH for openssl
- use find_package for precompiled openssl

removed:
- set CMAKE_PREFIX_PATH for openssl
- renaming ios openssl libs after copying to bin dir
2022-12-13 21:39:02 +03:00
vladimir.kuznetsov
61d502eea4 removed find_package for openssl 2022-12-13 20:49:46 +03:00
vladimir.kuznetsov
71aa525dfd set CMAKE_PREFIX_PATH for openssl 2022-12-13 20:36:12 +03:00
vladimir.kuznetsov
c0e3875dfd renaming ios openssl libs after copying to bin dir 2022-12-13 20:23:17 +03:00
pokamest
9c188e0acd Merge branch 'qt_migration' into qmake-to-cmake-migration 2022-12-13 15:34:38 +01:00
pokamest
1de143362c Merge branch 'dev' into qt_migration 2022-12-13 15:09:05 +01:00
vladimir.kuznetsov
7e37b6c151 removed CMAKE_PREFIX_PATH for openssl 2022-12-12 22:22:08 +03:00
vladimir.kuznetsov
0fa84a8b84 set CMAKE_PREFIX_PATH for openssl 2022-12-12 21:39:27 +03:00
vladimir.kuznetsov
236ae57d01 use find_package for precompiled openssl 2022-12-12 20:50:23 +03:00
pokamest
7345f464a5 Merge pull request #138 from amnezia-vpn/feature/android_config_export_import
Export/import of configuration files on Android
2022-12-12 16:48:23 +01:00
pokamest
3c45f2abe2 Merge branch 'dev' into feature/ovpn-config-import 2022-12-12 14:42:12 +01:00
pokamest
9c5e1faf46 Build fixes 2022-12-12 14:41:54 +01:00
pokamest
ce02d3a829 Merge branch 'dev' into feature/ovpn-config-import 2022-12-12 14:01:57 +01:00
pokamest
1b80c59e65 Merge pull request #137 from amnezia-vpn/bugfix/config-without-containers-import
bugfix: import config without containers
2022-12-12 13:30:28 +01:00
Hamza ARBI
f20f528a11 Server selection always in range (#130)
* Server selection stays always in the list's range
* Removed the usage of QZxing module from PageQrDecoder page
* Fixed null spelling on qml instead of nil
2022-12-12 13:28:03 +01:00
dartsyms
814b66c04a Various fixes for iOS (#126)
* Readme update, solution for wireguard make in M1 machines,
* import file and restore enabled.
* xcode_patcher.rb fixed, Now no need to add openVPN framewrok in Embed frameworks manually.
* Now xcode_patcher.rb will add OpenVPN Framework to Embed Frameworks in main target, instead of Network extension.
* Update iosvpnprotocol.swift
* Protocol wasn't detected because it is working on localized description of tunnel, fixed cases.
* Code cleanup
* Speed issue fixed for wireguard.
* GetDeviceIp and bytes(speed of OpenVPN) fixed.
*Device IP method wasn't working as expected, so I replaced. and for speed in OpenVPN we need to handle message seperately for bytes.
*QR progress added with progressbar and text.
2022-12-12 13:16:12 +01:00
vladimir.kuznetsov
00ad2e7a80 added path to openssl libs for ios 2022-12-11 18:25:44 +03:00
vladimir.kuznetsov
8f7e5e491f fixed macos openssl lib types 2022-12-11 17:59:18 +03:00
vladimir.kuznetsov
19101176a7 added link_libraries() for zlib 2022-12-11 17:22:59 +03:00
vladimir.kuznetsov
0bc383fec2 Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2022-12-11 17:09:26 +03:00
vladimir.kuznetsov
4df918d6a5 added qtshadertools to actions and cmake
- cleaned up CMakeLists in client project
2022-12-11 10:26:31 +03:00
Shahzain Ali
d3cbd8cdae Update deploy.yml 2022-12-11 04:21:28 +05:00
Shahzain Ali
0fa5dc225c Reverting shadertools in cmake. 2022-12-11 04:19:24 +05:00
Shahzain Ali
b14f14c45a Update CMakeLists.txt 2022-12-11 04:09:45 +05:00
Shahzain Ali
0851f4fdd4 Added Qt6ShaderTools in cmake 2022-12-11 04:01:15 +05:00
Shahzain Ali
807b3370e7 Adding qtshadertools module in qt installation 2022-12-11 03:42:46 +05:00
Shahzain Ali
a0f114e15c Fixing openvpn 2022-12-11 03:22:59 +05:00
vladimir.kuznetsov
1401fcd97d disabled some libssh options 2022-12-10 20:15:05 +03:00
vladimir.kuznetsov
efcd291e65 Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2022-12-10 19:07:00 +03:00
vladimir.kuznetsov
f98792714e set working directory to call openvpn.sh 2022-12-10 18:46:17 +03:00
vladimir.kuznetsov
5649f85b58 set QT_HOST_PATH for ios target 2022-12-10 18:09:41 +03:00
vladimir.kuznetsov
cfaba932e0 changeGed libz lib name for linux target 2022-12-10 18:00:50 +03:00
vladimir.kuznetsov
b1db4e8a7a Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2022-12-10 17:58:57 +03:00
vladimir.kuznetsov
ab9c11e038 set ios root dir as CMAKE_PREFIX_PATH 2022-12-09 18:12:39 +03:00
vladimir.kuznetsov
4d621dcbfe set CMAKE_PREFIX_PATH in CMakeLists file 2022-12-09 17:44:57 +03:00
vladimir.kuznetsov
a45537cbf3 added DCMAKE_PREFIX_PATH to IOS target 2022-12-09 17:30:46 +03:00
vladimir.kuznetsov
2d3ac286ac skip section with openssl copy for linux 2022-12-09 16:18:02 +03:00
vladimir.kuznetsov
4e96b5d4a6 added libz lib name for linux target 2022-12-09 15:57:31 +03:00
Shahzain Ali
9294324732 fixing host path 2022-12-09 04:24:16 +05:00
Shahzain Ali
b92422594b Merge branch 'qmake-to-cmake-migration' of https://github.com/amnezia-vpn/desktop-client into qmake-to-cmake-migration 2022-12-09 04:13:37 +05:00
Shahzain Ali
ea2637b1b4 Setting QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON 2022-12-09 04:13:14 +05:00
Shahzain Ali
c97b4859c1 Update deploy.yml 2022-12-09 04:05:25 +05:00
Shahzain Ali
7a2f42de30 Update deploy.yml 2022-12-09 03:58:36 +05:00
Shahzain Ali
99f5f78fc7 Update deploy.yml 2022-12-09 03:48:12 +05:00
Shahzain Ali
668f0ca675 Update deploy.yml 2022-12-09 03:47:09 +05:00
Shahzain Ali
6a89a51ea6 added QT_TOOL_CHAIN for ios cmake 2022-12-09 03:38:29 +05:00
Shahzain Ali
df6b0f3945 Update deploy.yml 2022-12-09 03:11:31 +05:00
Shahzain Ali
65cf243373 Update deploy.yml 2022-12-09 03:10:26 +05:00
Shahzain Ali
2ef7813219 Update deploy.yml 2022-12-09 03:06:16 +05:00
Shahzain Ali
216efd74bf Update deploy.yml 2022-12-09 03:04:43 +05:00
Shahzain Ali
b9d027a44a Update deploy.yml 2022-12-09 03:03:17 +05:00
Shahzain Ali
9097dd9645 actions for ios using cmake 2022-12-09 02:59:35 +05:00
Shahzain Ali
d784e26913 MacOS issue fixed. 2022-12-09 02:33:46 +05:00
vladimir.kuznetsov
cb69298385 Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support 2022-12-08 21:41:33 +03:00
vladimir.kuznetsov
a8fc42a17e added copying OpenSSL libraries, for windows and macos, to the folder with binaries, because we have the wrong folder structure with the OpenSSL library 2022-12-08 21:40:51 +03:00
Shahzain Ali
005008814a icon added in cmake. 2022-12-08 21:34:55 +05:00
Shahzain Ali
ad3bbaedb3 getting openvpn.sh script message. 2022-12-08 18:22:07 +05:00
Dmitriy Karpushin
cad0dabe42 Export/import of configuration filed on Android 2022-12-08 11:51:28 +03:00
Shahzain Ali
48fa3c8aec Update CMakeLists.txt 2022-12-07 20:36:22 +05:00
Shahzain Ali
fb585cbac0 OpenVPN integrated successfully 2022-12-07 20:35:43 +05:00
Shahzain Ali
dd1adda1a6 postbuild command fix. 2022-12-07 00:19:02 +05:00
vladimir.kuznetsov
3742583508 added zlib to submodules. Added build and link zlib, libssh in CMakeLists.txt 2022-12-06 18:17:10 +03:00
Shahzain Ali
3c6cd623af version issues fixed 2022-12-06 19:18:38 +05:00
Shahzain Ali
70c6e69b36 updatinf info.plist for .vpn type. 2022-12-06 03:09:45 +05:00
Shahzain Ali
943e58d32a Wireguard working. 2022-12-06 02:47:46 +05:00
Shahzain Ali
5237058016 Added launcher 2022-12-06 02:18:45 +05:00
Shahzain Ali
b87c5f8a51 iOS building successfully
Need to remove postbuild commands most probably from osxtools.cmake
2022-12-06 00:42:48 +05:00
Shahzain Ali
43e7a03af4 Some fixes.
Now team is preselected in signing.
2022-12-05 20:47:12 +05:00
pokamest
19fce4975d Merge branch 'dev' into feature/ovpn-config-import 2022-12-04 22:04:51 +01:00
pokamest
a9217810e7 Remove travis builds and tiny refactoring 2022-12-04 21:54:22 +01:00
Mykola Baibuz
a87610c856 Use libssh for server setup script
That gives some advantages in supported key types.
2022-12-04 01:43:53 +03:00
vladimir.kuznetsov
0ec0cb1b19 feature: added libssh submodule 2022-12-04 01:43:34 +03:00
vladimir.kuznetsov
9b1678a06c Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into bugfix/config-without-containers-import 2022-12-03 15:26:32 +03:00
vladimir.kuznetsov
0da63062d7 bugfix: fixed transition to the "Installed services" page when importing a config that does not have installed containers 2022-12-03 15:23:52 +03:00
Shahzain Ali
c8dd12eb20 Some more progress in cmake
Still have errors, currently not using apple-compile.sh building completely using cmake.
2022-12-02 22:26:10 +05:00
Shahzain Ali
008592f13b Architecture change not needed for ios build
CMAKE_OSX_ARCHITECTURES not needed for ios, it is setting x86_64 for all targets in ios.
2022-12-02 15:07:05 +05:00
vladimir.kuznetsov
56b9972053 build script for macos now uses cmake 2022-12-01 20:26:00 +03:00
vladimir.kuznetsov
1335c94bbc added include directory for botan ios 2022-12-01 20:24:04 +03:00
vladimir.kuznetsov
21a6ab369e Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into qmake-to-cmake-migration 2022-12-01 20:11:56 +03:00
vladimir.kuznetsov
2a80117d42 Merge remote-tracking branch 'remotes/origin/qt6-github-actions' into qmake-to-cmake-migration 2022-12-01 20:05:36 +03:00
Shahzain Ali
e65d312503 Merge branch 'qmake-to-cmake-migration' of https://github.com/amnezia-vpn/desktop-client into qmake-to-cmake-migration 2022-12-01 20:40:00 +05:00
Shahzain Ali
5fc34e643c Adding network extenstionn, fixing cmake.
Botan cmake changes, cmake APPLE/IOS fixes, wireguard added, Currently removed openvpn implementation, once wireguard is stable then will add openVPN framework.
Current progress is it is generating xcode project using
mkdir build-ios
/Users/shahzainali/Qt/6.4.1/ios/bin/qt-cmake . -B build-ios -GXcode
Need to select team only for Network extension only. select AmneizaVPN to run.
current issue is related to Botan.
2022-12-01 20:26:45 +05:00
pokamest
3463a84903 Merge branch 'qt_migration' into qmake-to-cmake-migration 2022-11-30 15:02:55 +01:00
pokamest
48dc532de6 Merge branch 'dev' into qt_migration 2022-11-30 14:26:44 +01:00
Shahzain Ali
20cb62483f Moved all libraries to LIBS variable 2022-11-30 15:36:25 +05:00
pokamest
dcb5828313 GitHub actions (#133)
GitHub actions
2022-11-30 01:51:18 +01:00
pokamest
74860256b9 Merge pull request #136 from amnezia-vpn/bugfix/notarize-app-macos
fixed options parsing for enable macos NOTARIZE_APP
2022-11-30 01:21:19 +01:00
vladimir.kuznetsov
97457f17c1 fixed options parsing for enable macos NOTARIZE_APP 2022-11-29 22:11:02 +03:00
Shahzain Ali
de9167cae6 Frameworks, libcrypto, libssl and some properties added for iOS. 2022-11-29 18:00:59 +05:00
vladimir.kuznetsov
2e5171c205 added matrix for all android arch 2022-11-29 00:55:32 +03:00
Shahzain Ali
a0b5491178 Merge branch 'qt_migration' into qmake-to-cmake-migration 2022-11-28 19:23:28 +05:00
vladimir.kuznetsov
fc8ef8678b Merge remote-tracking branch 'remotes/origin/qt_migration' into qmake-to-cmake-migration 2022-11-28 14:50:20 +03:00
Shahzain Ali
2dc1f2ea5b Setting minimum version to 13
QT 6.4 required minimum ios 13
https://doc.qt.io/qt-6/supported-platforms.html
2022-11-28 15:56:48 +05:00
Shahzain Ali
7999527582 Update README.md 2022-11-28 15:44:55 +05:00
Shahzain Ali
14be6506ee Qt5 to QT6 fixes. 2022-11-28 15:36:33 +05:00
vladimir.kuznetsov
c85ad470ba qt version in github actions changed to 6.4.1 2022-11-27 12:08:48 +03:00
vladimir.kuznetsov
8b6afcc5ec removed unused qzxing folder 2022-11-27 01:35:13 +03:00
vladimir.kuznetsov
813dced6df added qt6 modules installation to github actions 2022-11-27 01:30:36 +03:00
vladimir.kuznetsov
0a39866045 for github actions added step to build android application 2022-11-27 01:21:42 +03:00
vladimir.kuznetsov
48734689d8 for github actions added step to build macos and linux application 2022-11-27 01:21:41 +03:00
vladimir.kuznetsov
dfe927dcbd for github actions added step to build ios application 2022-11-27 01:21:41 +03:00
vladimir.kuznetsov
ca158def31 temporarily turned off the deployment of artifacts 2022-11-27 01:21:41 +03:00
vladimir.kuznetsov
409386336d for github actions added steps to build x32/x64 windows application 2022-11-27 01:21:41 +03:00
vladimir.kuznetsov
eeed6c3474 chore/revert link to dev qtkeychain submodule 2022-11-27 01:21:40 +03:00
pokamest
3296cd6c39 GH actions 12 2022-11-27 01:21:40 +03:00
pokamest
60e25d9c67 GH actions 11 2022-11-27 01:21:40 +03:00
pokamest
ec65e2025e GH actions 10 2022-11-27 01:21:39 +03:00
pokamest
f09020c3bc GH actions 9 2022-11-27 01:21:39 +03:00
pokamest
91baaed96d GH actions 8 2022-11-27 01:21:39 +03:00
pokamest
64de64ce33 GH actions 7 2022-11-27 01:21:38 +03:00
pokamest
b685e7008e GH actions 6 2022-11-27 01:21:38 +03:00
pokamest
375b3d776c GH actions 5 2022-11-27 01:21:38 +03:00
pokamest
c1fddd7164 GH actions 4 2022-11-27 01:21:37 +03:00
pokamest
3af9bf9e12 GH actions 3 2022-11-27 01:21:37 +03:00
pokamest
9ef5d0c144 GH actions 3 2022-11-27 01:21:37 +03:00
pokamest
3d1b37dc85 gh actions 2 2022-11-27 01:21:36 +03:00
pokamest
80ce8347f6 GH actions 1 2022-11-27 01:21:36 +03:00
vladimir.kuznetsov
3eb7e1392d feature/added cmake support for linux 2022-11-20 21:25:15 +03:00
vladimir.kuznetsov
ac78a44d74 fixed padding in build script 2022-11-18 17:06:52 +03:00
vladimir.kuznetsov
87fed9fde3 fixed connection with qssh 2022-11-18 16:42:22 +03:00
vladimir.kuznetsov
2564430046 build script now uses cmake, also:
- fixed linking qt6keychain and SortFilterProxyModel
- added translations
2022-11-15 23:31:55 +03:00
vladimir.kuznetsov
663861dc09 for debug target added deploy files required to run the application on Windows, also:
- added deploy additional files for android
- fixed include android libraries
2022-11-15 14:16:36 +03:00
vladimir.kuznetsov
2d6a12101e in CMakeLists source files are common for all platforms, now added via FILE(GLOB) 2022-11-14 22:22:38 +03:00
vladimir.kuznetsov
e40110fa4c added platform specific commands to cmake files 2022-11-12 23:52:15 +03:00
vladimir.kuznetsov
6ac162f3cd added cmake files for client project 2022-11-09 23:54:30 +03:00
vladimir.kuznetsov
aea1d16e31 added files for linux and mac to CMakeLists for server and wireguard-service projects 2022-11-08 21:32:17 +03:00
vladimir.kuznetsov
16e26ef215 added CMakeLists for server and wireguard-service projects 2022-11-07 23:59:09 +03:00
vladimir.kuznetsov
7270e701d4 hostname is now added to the server name for imported openvpn and wireguard configs 2022-11-05 19:40:51 +03:00
pokamest
c8010d4d52 Merge pull request #125 from amnezia-vpn/qt_migration-settings-btn
Added Settings button on Start Page
2022-11-05 16:42:24 +03:00
vladimir.kuznetsov
6941b7463e added display of wireguard configs, such a config will be displayed as raw text 2022-11-04 23:31:39 +03:00
vladimir.kuznetsov
99a6cd82b2 added import of configs in wireguard format 2022-11-03 23:39:58 +03:00
vladimir.kuznetsov
1a44307664 added protocol_defs for new config keywords 2022-11-01 23:24:58 +03:00
vladimir.kuznetsov
53d7a92a0d added import of configs in .ovpn format
- on the "OpenVPN Settings" page, such a config will be displayed as raw text
2022-11-01 23:12:42 +03:00
Hamza ARBI
4ba1f47423 Disable Servers settings item when no server has been set
Fix the logic of *Add Server* to comeback to start page instead of push when no server is set
2022-10-30 22:53:45 +01:00
Hamza ARBI
c38e47b726 Update SvgImageType icon color when the item is disabled 2022-10-30 02:06:51 +01:00
Hamza ARBI
e6a4d79b86 Add settings button on PageStart
Disable some items when no Server has been set
2022-10-30 02:06:20 +01:00
pokamest
b62d0697be Merge pull request #123 from amnezia-vpn/openvpn_addditional_configs
OpenVPN additional config
2022-10-26 17:02:13 +03:00
vladimir.kuznetsov
f90ebbbb4e added inclusion of an additional client/server config when generating configs from templates
- fixed name in additional server config field
2022-10-26 14:06:03 +03:00
Hamza ARBI
ab39802512 Using Basic theme in first place 2022-10-24 14:05:28 +01:00
Hamza ARBI
84da67adda Using Basic style in the first place 2022-10-24 13:56:12 +01:00
Hamza ARBI
cfff3c6d97 Used Universal Theme to fix QtQuick Controls 2022-10-24 13:50:41 +01:00
Hamza ARBI
cc3d9e0d2d Fix all QML headers and change the deprecated QML components
* QZXing : Error while integrating it
2022-10-20 20:09:17 +01:00
pokamest
442e7eb015 Merge branch 'dev' into qt_migration 2022-10-15 19:46:26 +03:00
pokamest
59248b7c2e Merge pull request #114 from outspace/dev
Set security screen for Android app
2022-09-23 23:41:42 +03:00
Mykola Baibuz
f2d7a45b74 Set security screen for Android app
This will guarantee that even apps running with root privileges are unable to directly capture information displayed by the app on the screen.
2022-09-23 22:03:28 +03:00
pokamest
c79b6147ea Merge pull request #113 from outspace/dev
Add auth protection for ssh key export (Android)
2022-09-22 21:15:35 +03:00
Mykola Baibuz
d93be76505 Add auth protection for ssh key export
We use a builtin keyguard for ssh key export protection on Android.

This protection works only if some protection is set on the phone.

https://developer.android.com/reference/android/app/KeyguardManager#isDeviceSecure()
2022-09-19 12:32:06 +03:00
pokamest
5fff65db5a Tiny fixes 2022-09-19 00:44:00 +03:00
pokamest
53e240add7 Android manifest fix 2022-09-12 14:57:00 +03:00
pokamest
9cfc65eeda Version bump 2022-09-11 00:24:43 +03:00
pokamest
47c305d557 Merge pull request #111 from amnezia-vpn/qrcodegen
qzxing removed, Qrcodegen added
2022-09-10 19:58:19 +03:00
pokamest
c5ba89b054 Code cleanup 2022-09-10 19:57:44 +03:00
pokamest
de8977723a Merge branch 'dev' into qrcodegen 2022-09-09 15:36:45 +03:00
pokamest
8cea93de94 Travis build fix 2022-09-09 15:34:09 +03:00
pokamest
e25cbe54d9 Merge branch 'dev' into qrcodegen 2022-09-09 15:02:14 +03:00
pokamest
b356522f94 Secure settings crash fix 2022-09-09 15:01:11 +03:00
pokamest
7a6c1de5d5 QrCoreGen 2022-09-07 09:51:03 +03:00
pokamest
fb07adf7c1 Travis fix 2022-09-05 02:06:58 +03:00
pokamest
9ceadd44c9 Travis fix 2022-09-05 01:56:39 +03:00
pokamest
e1c529ab91 Travis ccache 2022-09-05 01:38:29 +03:00
pokamest
ce27af6083 Travis build fix 2022-09-05 00:33:27 +03:00
pokamest
ac7d224645 Travis build fix 2022-09-05 00:11:55 +03:00
pokamest
df26f492a7 Travis build fix 2022-09-04 23:27:00 +03:00
pokamest
448c01ca99 Travis build fix 2022-09-04 14:49:33 +03:00
pokamest
bd7a9e5444 Merge pull request #106 from karolsteve/dev
Fix Android build on Travis
2022-09-04 14:15:54 +03:00
pokamest
1e717710b6 Merge pull request #109 from amnezia-vpn/Linux_deploy_script
Linux deploy script
2022-09-03 16:33:37 +03:00
pokamest
3cb14ad3bc Tiny Linux build scripts fixes 2022-09-03 06:31:59 -07:00
leetthewire
4769a67936 Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into Linux_deploy_script 2022-09-03 06:22:20 +04:00
leetthewire
279f866bf5 completed build linux script 2022-09-03 06:21:37 +04:00
leetthewire
5cbe7600a6 updated gitignore 2022-09-03 06:21:14 +04:00
pokamest
cdb1a4c288 Fix for AVP-01-006 - inscure app config permissions 2022-09-02 12:39:46 -07:00
pokamest
7d09d41a7d Merge pull request #108 from amnezia-vpn/dev
Release 2.1.0
2022-09-02 14:08:31 +03:00
pokamest
340bbd8727 Merge pull request #107 from amnezia-vpn/Linux_libs_deps
Linux libraries dependency for service
2022-09-01 18:03:18 +03:00
leetthewire
53c916ea4f Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into Linux_libs_deps 2022-09-01 17:45:39 +04:00
leetthewire
6451337274 fixed service lib path 2022-09-01 17:45:15 +04:00
pokamest
294b75ce2d QtKeyChain usage fix 2022-08-31 13:29:28 -07:00
pokamest
0ca4f3b104 Fix for CommandLineParser 2022-08-31 16:54:46 +03:00
pokamest
ac74510d47 Some fixes for Qt6 Android 2022-08-31 15:18:33 +03:00
pokamest
33ec69d33a Merge pull request #102 from omortie/qt_migration
migrated the codebase to Qt6 and fixed some compatibility issues
2022-08-31 13:53:55 +03:00
Steve Tchatchouang
f6d329ac48 Fix Android job CI 2022-08-30 14:00:40 +01:00
Steve Tchatchouang
a56fbeb611 Fix android build script
Using correct qt binaries folder (gcc64 -> Android)
2022-08-30 13:58:03 +01:00
Mortie
8c20a67cfa migrated the codebase to Qt6 and fixed some compatibility issues
* used a Qt6 ported version of SortFilterProxyModel
* used an updated Qt6 compatible version of QXZing
* added a flag to windows linker to avoid WinMain problem of MSVCRTD
* renamed utils.cpp to utilities.cpp for avoiding confusion with the same file name in SortFilterProxyModel
2022-08-29 12:21:09 +04:30
pokamest
fffa4fc031 Merge pull request #101 from amnezia-vpn/openvpn_random_mgmt_port
Openvpn random mgmt port [AVP-01-010]
2022-08-29 03:00:06 +03:00
pokamest
3316b73ab6 Select random management port 2022-08-29 02:58:23 +03:00
pokamest
211f7b7965 Merge pull request #100 from amnezia-vpn/check_openvpn_config
Check openvpn config for scripts [AVP-01-014]
2022-08-29 02:08:14 +03:00
pokamest
3a5a7bf674 Check openvpn config for scripts
QML refactoring
2022-08-29 01:32:42 +03:00
pokamest
7c749a964c Merge pull request #94 from amnezia-vpn/AVP-01-011
AVP-01-011 (Privileged process access list)
2022-08-27 19:21:45 +03:00
pokamest
997c8c87d0 Cleanup 2022-08-27 18:41:44 +03:00
pokamest
ed6a417d7e Merge branch 'dev' into AVP-01-011 2022-08-27 18:31:20 +03:00
pokamest
4a54f545a4 Merge pull request #99 from amnezia-vpn/qtkeychain
QtKeyChain module added [AVP-01-005, AVP-01-015]
2022-08-27 18:18:22 +03:00
pokamest
789902b79a Secure settings rework 2022-08-27 17:35:43 +03:00
pokamest
266859af19 Build fix for iOS 2022-08-26 03:19:34 -07:00
pokamest
9cca1a4819 Merge pull request #97 from amnezia-vpn/secure-config-2
App refactoring + secure config for mobile devices [AVP-01-005, AVP-01-015]
2022-08-26 01:02:12 +03:00
pokamest
aae1da3aa8 Cleanup code 2022-08-26 00:58:24 +03:00
pokamest
aed688224b App refactoring finished 2022-08-26 00:35:03 +03:00
pokamest
3ce1ec708d App refactoring finished 2022-08-25 17:35:28 +03:00
pokamest
510a564797 App refactoring 2022-08-25 12:47:02 +03:00
pokamest
b36517babb Merge branch 'dev' into secure-config-2 2022-08-24 20:40:10 +03:00
pokamest
415d18338e Secure config WIP 2022-08-24 18:51:35 +03:00
pokamest
14384131f4 Secure config WIP 2022-08-24 07:38:13 -07:00
pokamest
b3d54ce57e PageServerContainers animation fixed [ci skip] 2022-08-24 16:58:00 +03:00
pokamest
b5890340e3 Secure settings rework 2022-08-23 22:47:23 +03:00
pokamest
050d987d3b Merge branch 'dev' into qt_migration 2022-08-20 17:27:57 +03:00
pokamest
c4651cd915 Travis build fix 2022-08-20 17:24:11 +03:00
pokamest
b5f97c0d94 Travis build fix 2022-08-20 00:51:57 +03:00
pokamest
35165ba2b8 Travis build fix 2022-08-19 23:56:45 +03:00
pokamest
aeb1dcdf15 Travis build fix 2022-08-19 23:26:34 +03:00
pokamest
37730744e7 Travis build fix 2022-08-19 22:45:03 +03:00
pokamest
f821fe0356 Travis ios build 2022-08-19 22:23:52 +03:00
pokamest
ba16fdb548 Travis build fix 2022-08-19 18:47:39 +03:00
pokamest
144e6f59c8 Travis build fix 2022-08-19 18:35:17 +03:00
pokamest
2e42c5e875 Travis builds for Linux and Android 2022-08-19 16:17:37 +03:00
pokamest
eec8743e2f Travis ci fix 2022-08-18 19:57:46 +03:00
pokamest
e5e5684e2e Travis ci fix 2022-08-18 19:02:05 +03:00
pokamest
efddc6ccec Travis build fix 2022-08-18 17:01:34 +03:00
pokamest
5aef46733b Travis build fix 2022-08-18 15:31:10 +03:00
pokamest
201782184c Travis build fix 2022-08-18 15:20:27 +03:00
pokamest
5f2ef046e1 Travis build fix 2022-08-18 15:10:54 +03:00
pokamest
42398950e4 Fix for iOS 2022-08-16 08:28:41 -07:00
pokamest
506c8af1ea MacOS build script renamed 2022-08-16 03:37:46 -07:00
pokamest
70d9c516af Old MacOS build script deleted 2022-08-16 03:36:40 -07:00
pokamest
11ad86b9db Merge pull request #92 from amnezia-vpn/Linux_deploy_refactored
Linux deploy refactored
2022-08-16 13:08:30 +03:00
pokamest
2e9cfa6973 Merge pull request #93 from amnezia-vpn/Linux_install_scripts
Fixed installing scripts for Linux
2022-08-16 13:07:15 +03:00
pokamest
13e2c325e1 Merge pull request #95 from amnezia-vpn/easyrsa_cleanup
Cleanup easyrsa
2022-08-16 13:02:27 +03:00
pokamest
7e428a273f Merge pull request #91 from amnezia-vpn/Linux_errors_for_containers
Error descriptions for containers
2022-08-16 13:00:48 +03:00
pokamest
aa4bd516a9 Merge pull request #90 from amnezia-vpn/Linux_fix_sh_permissions
AVP-01-001 (Fix permissions for Linux and MacOS)
2022-08-15 23:27:44 +03:00
pokamest
82f8675b68 Merge pull request #96 from amnezia-vpn/android_7_wireguard_fix
Fix: infinite reconnect when using wireguard on Android 7 and 7.1
2022-08-15 23:17:39 +03:00
dimmdev
fdcb994e7a Fix: infinite reconnect when using wireguard on Android 7 and 7.1 2022-08-15 08:16:08 +05:00
pokamest
e89fa23533 Permissions fix for MacOS 2022-08-11 06:12:30 -07:00
pokamest
21d4f0f569 Cleanup easyrsa 2022-08-11 12:30:42 +03:00
pokamest
625201e559 Fix write permissions on macOS nac Linux 2022-08-11 12:29:09 +03:00
leetthewire
d36378fcbf fixed installing scripts 2022-08-11 01:23:57 +04:00
leetthewire
929ecfd42b linux deploy refactored 2022-08-11 01:20:27 +04:00
leetthewire
44496e424a errors for containers 2022-08-11 01:14:37 +04:00
leetthewire
1eb789e847 fixed permissions of a sh script 2022-08-11 00:58:07 +04:00
leetthewire
1ab76617df prepared to commit permissions of a sh script 2022-08-11 00:57:42 +04:00
pokamest
3bff653bbb IpcServerProcess permit list 2022-08-10 22:15:00 +03:00
pokamest
4b7a8c6d6e Start Qt6 migration 2022-08-10 14:00:04 +03:00
pokamest
9236be7fbd Merge pull request #70 from amnezia-vpn/android_shadowsocks
ShadowSocks implementation for Android
2022-08-09 17:12:36 +03:00
pokamest
fd9b922b21 Merge branch 'dev' into android_shadowsocks 2022-08-09 17:11:11 +03:00
pokamest
eea88f6e11 Cleanup 2022-08-09 17:06:03 +03:00
pokamest
eb47c968ae Build fix - MobileUtils.cpp 2022-08-08 19:46:39 +03:00
pokamest
560019b26c Build fix - typo in client.pro 2022-08-08 19:12:00 +03:00
pokamest
589e07f869 wireguard-tools submodule updated 2022-08-08 14:27:07 +03:00
pokamest
585de53148 Secure settings refactoring 2022-08-06 19:47:29 +03:00
pokamest
1e85b25438 Backup/restore config 2022-08-05 18:59:47 +03:00
pokamest
71b57bfed1 Secure settings 2 2022-08-05 14:31:12 +03:00
eugenyorbitsoftcom
870cb26e01 new line 2022-08-05 14:15:11 +06:00
eugenyorbitsoftcom
9a180b098f try read and write chipher Settings 2022-08-04 11:49:00 +06:00
eugenyorbitsoftcom
06682c333f remove kSecAttrService 2022-08-03 10:52:59 +06:00
eugenyorbitsoftcom
18c0aa5c81 kSecClassGenericPassword 2022-08-03 10:46:59 +06:00
eugenyorbitsoftcom
e49b468fd5 writeToKeychain, readFromKeychain 2022-08-02 15:52:03 +06:00
eugenyorbitsoftcom
7e5748b3a6 fix building project 2022-08-01 16:30:57 +06:00
eugenyorbitsoftcom
e99aa86863 fix building project 2022-08-01 15:57:16 +06:00
eugenyorbitsoftcom
bc6ae1d1b5 Merge branch 'dev' into secure-config 2022-08-01 10:55:33 +06:00
pokamest
df94a87a51 Merge pull request #83 from amnezia-vpn/open-config-in-app
iOS features : Open config in app, share configs
2022-07-31 23:40:08 +03:00
pokamest
9f7b2de311 Merge branch 'dev' into open-config-in-app 2022-07-31 23:39:11 +03:00
pokamest
dab6e10881 Wordpress site in the Tor network 2022-07-30 16:20:41 +03:00
eugenyorbitsoftcom
3b78c3a929 chiperSettings 2022-07-29 14:58:22 +06:00
eugenyorbitsoftcom
7029968c47 SecureFormat AES-GCM 2022-07-29 10:36:54 +06:00
pokamest
a8fe4e6aab Docker images fix: log driver=none 2022-07-27 17:34:43 +03:00
pokamest
b93dd8cb9b Build fix 2022-07-27 03:22:46 +03:00
ddd
0ba614961d fixed AVP-01-001 WP2, permissions on update-resolv-conf.sh 2022-07-16 13:23:17 +04:00
eugenyorbitsoftcom
79c56d440c fix LD_RUNPATH_SEARCH_PATHS 2022-07-14 13:01:40 +06:00
eugenyorbitsoftcom
9601506270 share file for iOS 2022-07-13 16:08:55 +06:00
eugenyorbitsoftcom
9ed16b81e8 read imported file configuration 2022-07-11 16:08:57 +06:00
eugenyorbitsoftcom
1800c1ff12 added ability import amnezia vpn config 2022-07-11 11:06:01 +06:00
pokamest
a8067bee36 Merge pull request #78 from amnezia-vpn/ios-wireguard
Ios wireguard fix and version bump
2022-07-07 16:31:19 +03:00
Alex Kh
f879663033 Applied fix from spamming button issue solution, bumped app version, and build number 2022-07-07 17:26:40 +04:00
eugenyorbitsoftcom
d618af19d6 fix crash 2022-07-07 17:16:45 +04:00
Alex Kh
8aa61bf5bc Bump version 2022-07-06 23:17:02 +04:00
pokamest
cd70f4b1c9 Merge pull request #53 from amnezia-vpn/ios-wireguard
iOS initial support
2022-07-06 16:26:50 +03:00
pokamest
240e55029b Merge pull request #77 from amnezia-vpn/qr-code-native-ios
Qr code reader native for iOS
2022-07-06 16:23:19 +03:00
eugenyorbitsoftcom
9aabe7c72e QRCodeReader for iOS 2022-07-06 14:02:56 +06:00
eugenyorbitsoftcom
6744dce57e QRCodeReader (WIP) 2022-07-06 11:51:45 +06:00
Alex Kh
d38e40d53f Latest updates before starting anew 2 2022-06-30 21:10:43 +04:00
Alex Kh
aa1b561bc0 Latest updates before starting anew 2022-06-30 21:10:34 +04:00
pokamest
6674b7890c Merge pull request #71 from AlexKLWS/improve-build-process
Improve build process for iOS
2022-06-30 17:57:35 +03:00
pokamest
a3a62165e9 Merge pull request #73 from amnezia-vpn/linux_v2
Linux v2
2022-06-29 21:47:22 +03:00
pokamest
8eb5a62737 Disable QUERY_ALL_PACKAGES manifest for Android 2022-06-26 15:01:04 +03:00
pokamest
c5ef462937 v. 2.0.10 2022-06-11 15:52:44 +03:00
Pokamest Nikak
eca397b45f Docker fixes - FROM alpine:3.15 2022-06-10 16:19:29 +03:00
unknown
9f7a583c92 local path fix 2022-06-04 13:20:59 +03:00
leetthewire
a59077b94f cleaned up 2022-05-11 22:54:55 +00:00
leetthewire
d61bfaa993 Merge branch 'dev' of https://github.com/amnezia-vpn/desktop-client into linux_v2 2022-05-11 22:49:50 +00:00
leetthewire
a17690f88b linux data folder updated 2022-05-11 22:10:54 +00:00
leetthewire
271e948c1f clean up /platform/linux/ folder 2022-05-11 22:05:00 +00:00
leetthewire
ac7de6213a clean up /platform/linux/ folder 2022-05-11 22:04:01 +00:00
Alex Korzh
7ff6b64742 Replace die with killProcess in apple_compile 2022-04-29 18:02:38 +04:00
Alex Korzh
531e0ad19d Update README 2022-04-29 13:44:46 +04:00
Alex Korzh
cc7112fb66 Reduce path to non-homebrew path 2022-04-28 16:58:47 +04:00
Alex Korzh
cf08af31ac Ensure Tun2Socks go deps are installed and up to date with latest go 2022-04-28 16:32:38 +04:00
Alex Korzh
1fdcf3877e Remove unused xcode_patcher 2022-04-28 14:56:19 +04:00
Alex Korzh
0fadf035db Add potential go PATH to config build settings 2022-04-28 14:55:58 +04:00
Alex Korzh
58b1c4b511 Update xcode patcher to use WireGuardKitGo folder for iOS project 2022-04-28 14:08:28 +04:00
Alex Korzh
0cc8feac57 Improve Tun2Socks error message 2022-04-28 14:05:30 +04:00
Alex Korzh
ba1efd57a5 Create and use version file from WireGuardKitGo on iOS for consistency 2022-04-28 14:05:14 +04:00
aman
29656fb9a6 Shadowsocks protocol added 2022-04-26 23:49:20 +05:30
Alex Korzh
92d79ebeea Clean up comments 2022-04-24 19:40:02 +04:00
Alex Korzh
3a69107eac Clean up apple compile script 2022-04-24 19:37:56 +04:00
Alex Korzh
4bfb528526 Kill prepare process if any of steps failed 2022-04-24 19:25:43 +04:00
Alex Korzh
fe9dd1d014 Rename ios_compile to apple_compile since it could be used for macOS 2022-04-24 17:32:21 +04:00
Grigory Dobrov
4829c8b314 Merge branch 'fix_inf_windows' into dev 2022-04-17 08:33:46 +03:00
aman
59b4bf5267 Shadowsocks added as a library folder in android 2022-04-16 20:18:27 +05:30
leetthewire
c19f34570d first build 2022-04-14 16:41:39 -07:00
Grigory Dobrov
94d29796b8 fixed line endings for windows drivers *.inf files 2022-04-13 00:45:19 +03:00
leetthewire
e9f44ffcc6 maked first build 2022-04-02 08:02:27 -07:00
leetthewire
a261ab4f0c editing linux sources 2022-04-02 07:31:54 -07:00
aman
929bcf03a0 Android shadowsocks code added 2022-04-01 10:05:58 +05:30
pokamest
a6a69ab1b6 cert updated 2022-03-26 23:15:29 +03:00
leetthewire
39de79d3cd started to file updating for linux build 2022-03-25 12:32:36 -07:00
leetthewire
40ab540179 Merge branch 'dev' of https://github.com/amnezia-vpn/desktop-client into linux_v2 2022-03-22 03:41:29 -07:00
leetthewire
7d7b6f4475 prepared to build 2022-03-22 03:40:47 -07:00
aman
ccdd433e35 Shadowsocks open source code added 2022-03-17 11:38:48 +05:30
aman
4a6ea38ef8 so files for shadowsocks added 2022-03-16 00:41:45 +05:30
Alex Kh
b20e25f052 Move frameworks from extemsion to host app 2022-02-23 18:57:06 +04:00
Alex Kh
8591d4e96c Merge remote-tracking branch 'origin/dev' into ios-wireguard 2022-02-23 18:51:25 +04:00
pokamest
912051637a Android manifest fix, IPC refactoring 2022-02-22 02:08:57 +03:00
pokamest
c233f767f4 Multiple ui fixes, save file function reimpl 2022-02-15 17:08:55 +03:00
Alex Kh
e1293c2c74 Merge remote-tracking branch 'origin/dev' into ios-wireguard 2022-02-15 10:55:45 +04:00
aman
b63bf2465f Android service issue fixed - VPN is keep running when connected and ui closed 2022-02-13 22:52:04 +05:30
pokamest
505c9c6218 Various fixes 2022-02-09 15:23:20 +03:00
pokamest
14350240eb Merge branch 'dev' 2022-02-07 08:42:52 +03:00
pokamest
cb21991efa DNS container fix, Cloak binaries updated 2022-02-05 18:02:49 +03:00
pokamest
49e58c25f2 Installer version bump 2022-02-05 16:08:53 +03:00
pokamest
ac6000a2ae Svg icons, dns ui fix 2022-02-05 15:52:14 +03:00
pokamest
6d1c9edc24 Log panel added 2022-02-04 17:49:48 +03:00
pokamest
1a7fa3746d DNS service fixes for all containers 2022-02-02 02:12:29 +03:00
pokamest
f7a57ffeb4 Cloak container arm support, ss updated 2022-02-02 01:52:37 +03:00
pokamest
ad9d45a154 Dns selection implemented 2022-02-01 19:48:59 +03:00
pokamest
5fffb2afe3 Dns container to internal network 2022-01-31 16:08:22 +03:00
pokamest
1269114074 Cleanup berfore uninstall, post-uninstall refactoring 2022-01-31 00:10:51 +03:00
pokamest
d24f6ae064 Logs functions fixes 2022-01-30 17:35:57 +03:00
pokamest
95fe09489c Vpn and wizard pages fixes 2022-01-28 16:03:21 +03:00
pokamest
1a144da36d SFTP fixes for Macos 2022-01-24 14:29:37 -08:00
pokamest
8e26da1759 Macos build fixes 2022-01-23 15:25:53 -08:00
pokamest
daf53226c3 SFTP fixes 2022-01-24 02:01:56 +03:00
pokamest
2b9e615e51 Various fixes 2022-01-23 19:16:40 +03:00
pokamest
02acbecef5 Re-resolve sites after VPN Connected 2022-01-22 20:00:06 +03:00
pokamest
8f28964ce2 Tiny ui fixes 2022-01-22 18:19:57 +03:00
pokamest
495e74e2f0 Sites page fix 2022-01-22 18:19:38 +03:00
Alex Kh
543bd1a777 Merge remote-tracking branch 'origin/dev' into ios-wireguard 2022-01-06 21:08:50 +04:00
pokamest
8f23970ccc Gradle build bump 2022-01-04 17:12:32 +03:00
pokamest
9ec39658fe DNS container with EmerCoin DNS support 2022-01-03 18:30:53 +03:00
Alex Kh
7c0518843f ShadowSocks disabled for production while in debug/testing mode 2021-12-31 11:04:01 +04:00
Alex Kh
7131257354 missing files added 2021-12-31 10:58:36 +04:00
Alex Kh
db527be97c VPN over Shadowsocks, three providers added, still unstable (testing, not for production) 2021-12-31 10:57:58 +04:00
Alex Kh
7c46e42820 Merge remote-tracking branch 'origin/dev' into ios-wireguard 2021-12-31 10:56:40 +04:00
pokamest
9943e081d9 RegExp validators fix 2021-12-25 23:01:53 +03:00
pokamest
68a51c9c63 WireGuard protocol fix 2021-12-25 21:14:55 +03:00
Alex Kh
6a98cdf974 Insert assets on project generation stage, add static versioning (makes sense on project regeneration) 2021-12-23 15:38:02 +04:00
Alex Kh
9ca8c66c47 Tried to get rid of crashes on sequential vpn turn on/off 2021-12-23 13:13:55 +04:00
Alex Kh
56754d616b Added fastlane scripts, old ids cleaned up 2021-12-22 17:38:17 +04:00
pokamest
e7dd964825 ServerController fix 2021-12-22 13:41:09 +03:00
Alex Kh
39e348948c Merge conflicts in .gitmodules resolved 2021-12-21 23:21:10 +04:00
Alex Kh
6583090d4f [WIP] shadowsocks implementation added 2021-12-21 23:17:22 +04:00
pokamest
f20134415e IKEv2 class file renamed 2021-12-21 02:57:23 +03:00
pokamest
bd9b9600c1 Release 2.0.6 2021-12-21 00:35:18 +03:00
pokamest
5ae9873455 Destructor crash fix 2021-12-20 15:43:36 +03:00
pokamest
5776ca0384 Merge pull request #47 from amnezia-vpn/qr_rework
Qr rework
2021-12-20 03:23:48 +03:00
pokamest
f8f4b39965 qzxing submodule 2021-12-20 02:42:16 +03:00
pokamest
1d51419a11 QR codes rework 2021-12-20 02:29:23 +03:00
pokamest
5e1ca0c19f iOS icons asset 2021-12-16 11:54:07 -08:00
pokamest
b341224c92 AppStore icon fix 2021-12-16 15:04:59 +03:00
pokamest
3861f23af3 iOS icon fixed 2021-12-16 14:45:08 +03:00
pokamest
e7beff79d0 iOS icons 2021-12-16 14:38:41 +03:00
pokamest
2380875cbf Merge branch 'ios-wireguard' into dev 2021-12-15 06:06:08 -08:00
pokamest
343e6a50df resetIpStack added 2021-12-15 14:53:07 +03:00
pokamest
5aa47d35e7 Version to main screen 2021-12-14 12:50:57 +03:00
Alex Kh
40996888c9 [WIP] shadowsocks implementation prepare 2021-12-13 11:47:09 +04:00
pokamest
313ceed1d0 StartPageLogic fix 2021-12-12 14:42:25 +03:00
pokamest
ac07d62344 ui fixes 2021-12-11 14:44:24 +03:00
pokamest
2db1bbae4b WireGuard server script fix 2021-12-10 15:43:43 +03:00
Alex Kh
090e50e936 [WIP] protocol switching and relaunch crash issues (possibly) fixed 2021-12-09 12:59:56 +04:00
Alex Kh
b6bab0c723 [WIP] seamless protocol switching without leaving the app 2021-12-08 19:40:43 +04:00
Alex Kh
1a333f7968 [WIP] move connection state call to main thread 2021-12-08 17:10:15 +04:00
Alex Kh
87c00b3804 Merge branch 'ios-wireguard' of https://github.com/amnezia-vpn/desktop-client into ios-wireguard 2021-12-08 15:57:16 +04:00
Alex Kh
eba71469a4 [WIP] OpenVPN tunnel implementation 2021-12-08 15:55:36 +04:00
pokamest
4eef127744 VPN modes ui fix 2021-12-04 19:48:47 +03:00
pokamest
4c2941acf0 Merge pull request #45 from amnezia-vpn/ios-wireguard
Ios wireguard
2021-12-04 16:27:46 +03:00
pokamest
40791a9cd4 Merge branch 'dev' into ios-wireguard 2021-12-04 05:24:11 -08:00
pokamest
4d374581b5 isWorkingOnPlatform function added 2021-12-04 16:13:34 +03:00
Alex Kh
4976dc3a4c Added missing parameters for init and connect 2021-12-01 20:02:54 +04:00
pokamest
9e0fd7d51e iOS build fixes 2021-11-30 12:53:12 -08:00
pokamest
bf8b3c3b2f Merge branch 'dev' into ios-wireguard 2021-11-30 21:51:06 +03:00
Alex Kh
38336fdb02 Removed build folders from being tracked 2021-11-30 17:13:00 +04:00
Alex Kh
7c7f77adc6 [WIP] Added wireguard, prepare to test and debug 2021-11-30 16:56:24 +04:00
pokamest
d28a2ebc57 NotificationHandler systemtray 2021-11-28 17:28:25 +03:00
pokamest
67d413956d AndroidController reimpl 2021-11-26 17:43:02 +03:00
pokamest
e644575bc5 Merge branch 'dev' into ios_main 2021-11-22 03:41:38 -08:00
pokamest
0291ba8cb5 Server add fix 2021-11-22 14:40:23 +03:00
pokamest
622a390b23 Windows deploy fixed 2021-11-22 14:34:33 +03:00
pokamest
2e92705f9c build fix 2021-11-22 01:42:16 -08:00
pokamest
c6548afa1b Merge branch 'dev' into ios_main 2021-11-22 00:08:34 -08:00
pokamest
9e7deecb99 Version 2.0.1 2021-11-19 23:04:35 +03:00
pokamest
2773d7598b VPN connection routine fixed 2021-11-19 19:02:39 +03:00
pokamest
a9165aba25 VPN page fixes, TFTP page fix 2021-11-19 13:57:00 +03:00
pokamest
fd9d54d2dd Merge branch 'dev' into ios_main 2021-11-18 03:48:34 -08:00
pokamest
dde04ff979 IKEv2 fixes
TOR fixes
tray fix
2021-11-18 01:40:28 +03:00
pokamest
e0f42f4a0a ProtocolsModel bug fixes 2021-11-17 23:42:17 +03:00
pokamest
3a49d5fdc4 Tray fix 2021-11-17 20:24:45 +03:00
pokamest
9dee7bb7e7 UI fixes, VPN page fixes 2021-11-17 15:01:48 +03:00
pokamest
25428c9165 Share WireGuard page
Share IKEv2 page
2021-11-15 18:17:28 +03:00
pokamest
c6efc5b212 Share page fixes 2021-11-13 17:20:23 +03:00
pokamest
836075de10 Share pages refactoring 2021-11-13 16:09:08 +03:00
pokamest
396af917b5 Share page reimpl 2021-11-08 15:18:52 +03:00
pokamest
a89104127a Share page refactoring part 1 2021-11-06 13:47:52 +03:00
pokamest
ed26706ee7 WireguardConfigurator fix 2021-11-02 21:50:28 +03:00
pokamest
9de89e5544 qml ui fixws: ss and cloak 2021-10-28 15:31:54 +03:00
pokamest
d7f672ab0a ui fixes 2021-10-28 00:04:54 +03:00
pokamest
b124aabf69 Merge pull request #38 from amnezia-vpn/wireguard_embedded
change wireguard vpn protocol implementation on Windows from wg.exe t…
2021-10-27 01:32:42 +03:00
pokamest
6c07a583f8 Wireguard configurator fixed 2021-10-27 00:42:25 +03:00
pokamest
83256de752 Merge branch 'dev' into wireguard_embedded 2021-10-26 22:50:52 +03:00
pokamest
44f4d083bf VPN connection moved to separate thread 2021-10-26 12:59:20 +03:00
pokamest
1b1a5be607 Merge branch 'dev' into ikev2_fix_window_api_signal 2021-10-26 00:02:14 +03:00
Pavel Malyutin
6b93f79d2e dockerfiles: Added support of Shadowsocks for aarch64 2021-10-25 17:13:46 +03:00
pokamest
1ce26b3ada Merge pull request #43 from boscogh/master
dockerfiles: Added support of Shadowsocks for aarch64
2021-10-25 16:37:39 +03:00
DiepDTN
70f18151dd clean up thread and timer, now run Ikev2Protocol::setConnectionState() directly from WinAPI callback 2021-10-25 14:54:57 +07:00
alexkosh
4de38a295c Fix wireguard config 2021-10-23 23:06:50 +03:00
pokamest
7701efc704 iOS Wireguard 2021-10-23 04:26:47 -07:00
pokamest
421f665e85 Tiny fixes 2021-10-22 01:07:20 +03:00
pokamest
ca233be127 QML ui fixes 2021-10-21 19:49:53 +03:00
pokamest
377bac67be QML ui fixes 2021-10-21 18:10:28 +03:00
pokamest
1f97dd0111 Android splash 2021-10-21 15:04:09 +03:00
pokamest
f1fa22f4cf Android icon added 2021-10-21 14:45:08 +03:00
pokamest
a998dc21b0 WG configurator fix 2021-10-20 18:43:51 +03:00
pokamest
a0dbbfa04e Android libs fix 2021-10-20 17:37:54 +03:00
Pavel Malyutin
e7092ae769 dockerfiles: Added support of Shadowsocks for aarch64 2021-10-20 10:26:33 +00:00
pokamest
dd148b92c6 Merge pull request #41 from amnezia-vpn/feature/android-openvpn-protocol
Feature/android openvpn protocol
2021-10-18 19:07:30 +03:00
pokamest
65d110eb0a OpenSSL for ASndroid added 2021-10-18 18:49:15 +03:00
pokamest
78dec77c3c Merge branch 'dev' into feature/android-openvpn-protocol 2021-10-18 17:52:02 +03:00
Розов Никита Валерьевич
7723568cef adding dns addresses in route table for samsung devices 2021-10-18 17:01:55 +03:00
Розов Никита Валерьевич
ebfd50f30d add socket protect 2021-10-18 16:51:45 +03:00
pokamest
e571c1f95c botan dlls removed 2021-10-18 15:22:23 +03:00
pokamest
1b0e5e01fa Merge branch 'easyrsa_remove' into dev 2021-10-18 15:19:18 +03:00
pokamest
a426591282 iOS build fixes 2021-10-18 05:11:50 -07:00
pokamest
499ff590cd botan for IPhone added 2021-10-17 23:17:38 +03:00
pokamest
03aae3f787 OpenSSL lib for MacOS 2021-10-17 08:00:52 -07:00
pokamest
ca25e257ef OpenSSL libs added for Linux 2021-10-17 07:00:00 -07:00
pokamest
6e9c43c37b OpenVpnConfigurator fix 2021-10-17 06:43:30 -07:00
pokamest
1db253f1fd OpenVpnConfigurator fix 2021-10-17 16:41:16 +03:00
pokamest
67a55fee25 Easyrsa removed
Cert req reimplemented
OpenSSL libs added for Windows
2021-10-17 13:03:03 +03:00
Розов Никита Валерьевич
0f89c40a1d add tun reroute gw function 2021-10-16 19:25:07 +03:00
pokamest
64627abe6d OpenVPN libs added for Android 2021-10-16 18:33:18 +03:00
Розов Никита Валерьевич
5895b37a06 parcing config fix 2021-10-14 14:53:20 +03:00
pokamest
5292d294be OpenVpnConfigurator fix 2021-10-14 12:01:14 +03:00
Розов Никита Валерьевич
258d2c9ce3 update openvpn archive 2021-10-14 11:38:08 +03:00
Розов Никита Валерьевич
b5cc515e42 added swig files and libs to the project 2021-10-14 11:32:17 +03:00
Розов Никита Валерьевич
88d5e9cbc3 disconnection fix 2021-10-14 11:22:59 +03:00
Розов Никита Валерьевич
6a9cc9bf37 openvpn connection status fix 2021-10-14 10:14:01 +03:00
pokamest
cc7cee6d44 ikev2 test fix 3 2021-10-13 22:07:31 +03:00
pokamest
990db5967a ikev2 test2 2021-10-13 19:43:37 +03:00
Розов Никита Валерьевич
28ae7eeaee add disable openvpnconnection, refactoring 2021-10-13 18:33:43 +03:00
pokamest
ba8755a6d4 Merge branch 'dev' into wireguard_embedded 2021-10-13 16:57:03 +03:00
pokamest
b4007038fb ikev2 winapi test solution 2021-10-13 15:46:00 +03:00
pokamest
8c679a08c4 openvpn config export fix 2021-10-13 14:40:43 +03:00
Розов Никита Валерьевич
6c2e6ead2b fix merge conflicts 2021-10-11 16:54:20 +03:00
Розов Никита Валерьевич
f4a55d60a4 Merge branch 'dev' into feature/android-openvpn-protocol 2021-10-11 15:37:17 +03:00
Розов Никита Валерьевич
ab1e31b2ff openvpn connection logic fix 2021-10-11 15:36:40 +03:00
Розов Никита Валерьевич
1ceee8901e add openvpn connection logic draft 2021-10-09 20:17:19 +03:00
DiepDTN
6042317552 change wireguard vpn protocol implementation on Windows from wg.exe to wireguard windows embeddable-dll-service 2021-10-08 07:44:19 +07:00
pokamest
d275702080 Add protocol name to json connection config 2021-10-08 00:50:26 +03:00
pokamest
344d23bad1 Fix for android 2021-10-07 22:52:13 +03:00
pokamest
ba85b56e9f Various fixes 2021-10-07 22:21:04 +03:00
pokamest
64e5e02744 ikev2 impl for windows 2021-10-07 22:20:45 +03:00
Розов Никита Валерьевич
8084b2764a add return statement in android_vpnprotocol::start() 2021-10-07 18:53:37 +03:00
Розов Никита Валерьевич
c057786011 openvpn protocol linked to the project 2021-10-06 22:45:25 +03:00
Розов Никита Валерьевич
9e0e66a0ae add return statement in android_vpnprotocol::start() 2021-10-06 21:06:27 +03:00
pokamest
0168bfa67a remove unnecarry ui files 2021-10-05 14:59:52 +03:00
pokamest
d4b9557508 Refactoring 2021-10-05 12:22:13 +03:00
pokamest
9ecb703b99 refactoring 2021-10-04 21:13:07 +03:00
pokamest
fa151cd320 Ikev2 support 2021-10-04 19:07:49 +03:00
pokamest
a5bcf1a02d VPN configuration class fixes 2021-10-02 21:56:47 +03:00
pokamest
535e628eba Embded compiled WireGuard lib for Android 2021-10-02 15:09:20 +03:00
pokamest
edbfcda197 Fixes for android and wg 2021-10-01 12:18:48 -07:00
pokamest
b8e35ed66c Added missing file for wireguard for android 2021-10-01 12:03:40 +03:00
pokamest
c548db513a android fix 2021-10-01 03:01:48 +03:00
pokamest
476aabe671 android fix - libwg-go added 2021-09-30 21:09:48 +03:00
pokamest
969fc899a0 Android service fix 2021-09-30 19:44:26 +03:00
pokamest
b61d89d01b android fix 2021-09-30 18:56:49 +03:00
pokamest
bac7b3ab37 Android service wireguard build 2021-09-30 18:16:41 +03:00
pokamest
133a3e67d2 android .pro fix 2021-09-30 16:06:35 +03:00
pokamest
eb497be730 Native android service implemented 2021-09-30 15:56:48 +03:00
pokamest
d553d7f772 cloak container fix 2021-09-28 02:36:38 +03:00
pokamest
5932db24e1 refactoring 2021-09-28 02:19:52 +03:00
pokamest
ddca4f9068 Software verion 2.0.0
Билд выпущен при поддержке Теплицы социальных технологий
2021-09-24 14:01:53 +03:00
pokamest
b244158b95 website in tor network container improved
Sponsored by "Теплица социальных технологий", 2021
В рамках работы над задачами по хакатону 2021
2021-09-24 13:14:35 +03:00
pokamest
3bcc12869b Поддержка протокола Sftp (File Sharing) по ТЗ по гранту от Теплицы
социальных технологий (2021 год)
+ небольшой рефакторинг
2021-09-22 14:49:08 +03:00
pokamest
6ee203a21d Merge branch 'tor_site_container' into teplitsa_tz
Containers page refactoring
2021-09-21 01:49:28 +03:00
pokamest
157d7c4f23 Various types containers support 2021-09-20 21:51:28 +03:00
pokamest
0d9f1ba95b qml ui fixes 2021-09-19 14:31:38 +03:00
pokamest
a390f2e988 Qml Containers Page refact 2021-09-16 19:49:50 +03:00
pokamest
0faf6c8599 QML ServerContainers page refact 2021-09-16 16:19:14 +03:00
pokamest
9ae2e3fba2 ios fixes 2021-09-15 08:03:28 -07:00
pokamest
12b079df65 qml refactoring 2021-09-14 00:39:07 +03:00
pokamest
e920d9cdf3 esc and back button support 2021-09-13 17:36:48 +03:00
Pokamest Nikak
542f363e92 ServerContainers qml ui started to fix 2021-09-10 22:19:00 +03:00
Pokamest Nikak
40fa2d6779 NewServerSettings qml rework 2021-09-09 20:15:44 +03:00
Pokamest Nikak
3175bc1e48 QML Fixes 2021-09-08 21:24:09 +03:00
Pokamest Nikak
62262a3572 BackButton.qml added 2021-09-08 15:09:16 +03:00
Pokamest Nikak
6516a84986 refact fixes 2021-09-08 14:23:02 +03:00
Pokamest Nikak
16e887dcf0 AUTO_PROPERTY finished 2021-09-08 13:52:36 +03:00
Pokamest Nikak
63ffa4a212 AUTO_PROPERTY added 2021-09-07 22:11:43 +03:00
Pokamest Nikak
539bf2ee24 VpnLogic 2021-09-07 21:01:56 +03:00
Pokamest Nikak
deaeda59d0 ServerContainersLogic 2021-09-07 19:26:58 +03:00
Pokamest Nikak
4c0ff29488 NewServerConfiguringLogic
NewServerProtocolsLogic
2021-09-07 18:06:05 +03:00
pokamest
7c28fe2795 NewServerConfiguringLogic
NewServerProtocolsLogic
2021-09-07 11:48:25 +03:00
pokamest
deda2e158e ShadowSocksLogic
CloakLogic
2021-09-06 14:35:57 +03:00
pokamest
a6e5cfff8a OpenVpnLogic added 2021-09-06 13:41:45 +03:00
pokamest
d1ea625435 codestyle fixes 2021-09-06 12:39:46 +03:00
pokamest
ea551ab0a0 qml ui protocols separated 2021-09-06 12:30:26 +03:00
pokamest
d9ae10f5bc qml ui fixes 2021-09-06 12:29:56 +03:00
pokamest
d90211ef48 Wizard Logic added
TODO_REFACTs fixed
2021-09-06 11:44:03 +03:00
Pokamest Nikak
ace304914e share page refact 2 2021-09-04 15:21:36 +03:00
Pokamest Nikak
6dc13b2c00 start page refact 2021-09-04 12:53:58 +03:00
Pokamest Nikak
ca3617aa7d refact sharing 2021-09-04 11:26:16 +03:00
Pokamest Nikak
84ca7e8879 refact 2 2021-09-03 22:15:05 +03:00
Pokamest Nikak
135b96a280 QML gui refact started 2021-09-03 20:17:13 +03:00
pokamest
febf9cfafb Merge branch 'dev' into gui_qml 2021-08-19 01:51:02 +03:00
pokamest
27171ed974 qml ui fixes 2021-08-19 01:27:22 +03:00
pokamest
2c346fdc08 Merge pull request #33 from amnezia-vpn/Linux_fix_dirs_rsa_2
Linux bug fixes
2021-08-17 14:25:23 +03:00
leetthewire
229265cdd9 updated 2021-08-15 11:48:31 -07:00
pokamest
57234bc793 qml ui fixes 2021-08-13 18:40:03 +03:00
pokamest
d496d0cccd Botan linux fix 2021-08-13 07:04:11 -07:00
Ngoc Diep
c687bb39ef fix PageSites table error 2021-08-09 01:34:25 +07:00
Ngoc Diep
d1a3545912 port UI Logic to QML 2021-08-09 00:41:52 +07:00
pokamest
accdedfead botan build fix 2021-08-08 18:34:05 +03:00
pokamest
bedf669ca4 Botan switched to amalgamation build 2021-08-08 18:10:09 +03:00
pokamest
a9dc1b0603 Merge pull request #31 from amnezia-vpn/Linux_build_stable_2
updated linux build
2021-08-06 17:45:49 +03:00
leetthewire
9997fa8f3e updated linux build 2021-08-04 10:08:00 -07:00
pokamest
26524dd93a Merge pull request #29 from amnezia-vpn/update_botan_3
Update botan (final)
2021-08-03 17:34:26 +03:00
pokamest
bd586a1921 Botan for MacOS added 2021-08-03 07:32:04 -07:00
pokamest
dec04ccd06 Add botan for linux static lib 2021-08-03 06:36:03 -07:00
pokamest
64d4e96068 Add botan for linux 2021-08-03 06:34:37 -07:00
pokamest
6d83e16aa7 Android build config added 2021-08-01 19:57:04 +03:00
Ngoc Diep
8d36c31cb4 implement qml UI 2021-07-28 16:13:29 +07:00
pokamest
a49db653a1 botan.pri fix 2021-07-27 13:35:10 +03:00
pokamest
cd7884b508 Botan deploy fix (Windows x64) 2021-07-27 13:23:18 +03:00
pokamest
5bf2c1d6e1 Botan updated
QtSsh updated to https://github.com/sandsmark/QSsh
2021-07-27 09:33:49 +03:00
pokamest
08b2824ff0 tor site 2021-07-23 12:42:08 +03:00
pokamest
1baf36282e win32 deploy fix 2021-06-27 13:26:06 +03:00
pokamest
e45c7507f9 Merge pull request #22 from amnezia-vpn/linux_ui_fix
fixed UI for linux
2021-06-26 20:49:48 +03:00
leetthewire
148b1dacce fixed UI for linux
Signed-off-by: leetthewire <yaartjom@mail.ru>
2021-06-26 23:09:48 +00:00
pokamest
b8b0ffb626 Merge pull request #21 from amnezia-vpn/dev
Release 1.8.1
2021-06-24 16:48:50 +03:00
leetthewire
d17906c2a6 Service: Fixed bug with permanent addresses on interface (#20)
Windows Service: Fixed bug with permanent addresses on interface
2021-06-19 16:41:16 +03:00
pokamest
b1f7baa79f Various bug fixes 2021-06-19 16:38:35 +03:00
pokamest
973cbd83d9 Update README.md 2021-06-18 23:19:44 +03:00
pokamest
a599ed6e24 Update README.md 2021-06-18 23:19:07 +03:00
pokamest
a1cbf8824f Readme fix 2021-06-18 19:18:50 +03:00
pokamest
52450ef2f5 Release 1.8 2021-06-17 01:04:09 +03:00
pokamest
69170940c9 Merge pull request #19 from amnezia-vpn/cloak_ss_2
ShadowSocks over cloak
2021-06-17 00:53:48 +03:00
pokamest
e89caaee52 bump version 1.7.6 2021-06-17 00:51:15 +03:00
pokamest
0b3535ff13 hide wireguard settings 2021-06-16 22:40:34 +03:00
pokamest
e7a22ad159 Export shadowsocks over cloak config support 2021-06-16 22:25:08 +03:00
pokamest
74a517d985 Windows server 2012 support 2021-06-16 22:24:33 +03:00
pokamest
d57e56de70 Setup container more debugging 2021-06-16 22:24:13 +03:00
pokamest
e2f8f77adf Revert "Added threads suspend, Edited suspendWcmSvc() func for Windows. Based on old SuspendProcess func."
This reverts commit 999087337e.
2021-06-16 20:09:49 +03:00
pokamest
db543b62ba Macos build fix 2021-06-14 03:48:46 -07:00
Sike
999087337e Added threads suspend, Edited suspendWcmSvc() func for Windows. Based on old SuspendProcess func. 2021-06-14 02:34:21 +06:00
pokamest
6788f0b7eb Wireguard deploy files 2021-06-12 12:02:46 +03:00
pokamest
2f6fb0d557 Wireguard protocol + refactoring 2021-06-12 11:59:36 +03:00
pokamest
8bdfe1741a Win Routes fix 2021-06-10 17:58:28 +03:00
pokamest
739781ece3 Saving files before refreshing line endings 2021-06-06 17:27:58 +03:00
pokamest
7e74b95976 Readme updated 2021-06-06 16:25:22 +03:00
pokamest
531695bd0b Windows x32 deploy files added 2021-06-06 16:18:01 +03:00
pokamest
dd959e7b26 Custom routing fixes 2021-06-05 20:55:57 +03:00
pokamest
c4235a60c8 Macos fixes 2021-06-05 01:18:28 -07:00
pokamest
f75456060f build fix 2021-06-03 10:42:58 -07:00
pokamest
623aae3718 Macos build fix 2021-06-03 10:34:28 -07:00
pokamest
974832f7d9 Tiny fix 2021-06-03 20:27:46 +03:00
pokamest
d13df65bfb Tiny fixes 2021-06-03 20:23:44 +03:00
pokamest
80ada3f241 Travis fix 2021-06-03 00:29:51 +03:00
pokamest
aad3677d45 Travis fix 2021-06-02 22:34:29 +03:00
pokamest
8892d3c5d9 Travis fix 2021-06-02 21:35:44 +03:00
pokamest
da08bef2f9 Travis fix 2021-06-02 20:46:59 +03:00
pokamest
d79483e967 Travis fix 2021-06-02 20:25:00 +03:00
pokamest
906391f786 Travis fix 2021-06-02 19:24:50 +03:00
pokamest
48a4aa399b Travis fix 2021-06-02 19:05:26 +03:00
pokamest
a8dd319a9d Travis fix 2021-06-02 18:54:39 +03:00
pokamest
815686cba6 Travis fix 2021-06-02 18:41:08 +03:00
pokamest
7232a14926 Travis fix 2021-06-02 17:56:01 +03:00
pokamest
dd526959eb easyrsa fix 2021-06-02 17:51:04 +03:00
pokamest
fe6f89c551 travis fix 2021-06-02 01:32:25 +03:00
pokamest
16c754e004 Disable openvpn log append 2021-06-02 00:54:47 +03:00
pokamest
8792a8673a gitignore fix 2021-06-02 00:53:44 +03:00
pokamest
9376df8703 deploy fixes 2021-06-02 00:49:42 +03:00
pokamest
435ee58d40 Macos fix: routes delete 2021-06-01 08:45:26 -07:00
pokamest
9dbe15a0e3 custom sitet pre release 2021-06-01 18:18:09 +03:00
pokamest
34b97bdc24 Macos fixes for route functions 2021-05-27 15:01:15 -07:00
pokamest
6c74f30d79 Custom sites reimplemented 2021-05-27 22:18:36 +03:00
pokamest
97e918ae72 ui fixes 2021-05-22 16:14:26 +03:00
pokamest
d0c66a693b macos deploy script fixes 2021-05-21 05:33:40 -07:00
pokamest
0ea085cc02 - Crash fix if service not connected
- import fix
- disabled share button for readonly server
2021-05-20 15:59:58 +03:00
pokamest
7fd13faa59 cloak stop() fixed 2021-05-19 00:26:36 +03:00
pokamest
d4c0e519d9 ui fixes 2021-05-19 00:15:40 +03:00
pokamest
4ba964db47 win7 support fixes
wizard added
2021-05-18 15:50:52 +03:00
pokamest
45e5ec76dd Windows 7 tap support improved 2021-05-14 23:30:13 +03:00
pokamest
df27003998 win build fix 2021-05-14 23:29:09 +03:00
pokamest
9002568474 Macos cached config fix 2021-05-14 04:27:30 -07:00
pokamest
5c5411261a macos dns setup fixed 2021-05-13 08:23:56 -07:00
pokamest
acf878c8dd Macos route add reimplemented using system call 2021-05-13 08:20:38 -07:00
pokamest
491a09b175 macos autostart fix 2021-05-12 13:07:22 -07:00
pokamest
51f7e6811e macos ui fix 2021-05-12 02:49:36 -07:00
pokamest
eee6b8b10f main.cpp default font removed 2021-05-11 12:15:33 -07:00
pokamest
dc4a1c6eca macos fix 2021-05-11 09:36:43 -07:00
pokamest
02810ff844 bug fixes 2021-05-11 17:04:04 +03:00
pokamest
1bb2ef9e30 ui fixes 2021-05-10 20:51:38 +03:00
pokamest
df2a6dc278 cloak for macos fixed 2021-05-10 05:25:20 -07:00
pokamest
835f767c3f import/export fixes 2021-05-10 14:19:36 +03:00
pokamest
e3fb239de9 Config export 2021-05-10 02:33:31 +03:00
pokamest
de67f244da Multiprotocol support 2021-05-07 23:28:37 +03:00
pokamest
d424bb24cf refactoring
Protocol to DockerContainer
2021-04-26 23:19:19 +03:00
pokamest
615bba69e5 refactoring 2021-04-26 22:54:31 +03:00
pokamest
7bba7a9eab cygwin grep added 2021-04-20 02:11:14 +03:00
pokamest
a5e9cea22f Release 1.6 WIP 2021-04-20 02:09:47 +03:00
pokamest
f9affb083b Macos route delete fix 2021-04-19 14:34:47 +03:00
pokamest
85b6b06cc9 - no dockerhub
- trafic masking
2021-04-04 23:12:36 +03:00
pokamest
059c6404ab gitignore updated 2021-04-04 23:09:31 +03:00
pokamest
0d989a7fae meta version updated 2021-04-04 23:08:01 +03:00
pokamest
7dfc002316 cloak exe added 2021-04-04 23:06:54 +03:00
pokamest
8d8d392e84 cygwin updated to x64 2021-04-04 23:04:31 +03:00
pokamest
c6e75d5f86 server script fixes 2021-03-25 23:26:59 +03:00
pokamest
99bfd56ef4 minor release 1.5.3 2021-03-19 15:03:44 +03:00
pokamest
c2f6c7d939 route delete fixed (Windows) 2021-03-18 22:13:05 +03:00
pokamest
d831d68e73 ShadowSocks protocol fixes:
- remote for OpenVPN is set to real ip address
- remote ip will be added as alias in docker container
- ss-local graceful shutdown
- crash fixes
2021-03-18 18:45:08 +03:00
pokamest
84e4b776ac openvpn target host is 10.8.0.1 via ss route 2021-03-17 03:47:33 +03:00
pokamest
f9e1b2c6dc QR code lib added
ShadowSocks export
ui stylesheet fixes
ip:port regexp fixed
dns settings reset bug fixed
2021-03-17 03:45:38 +03:00
pokamest
54fca5bebc cygpcre-1.dll added 2021-03-16 22:15:27 +03:00
pokamest
c5ce417d79 macos close button fix 2021-03-14 12:52:19 -07:00
pokamest
6765142ebc ssh key auth fix 2021-03-14 12:51:52 -07:00
pokamest
ca898a6759 Ssh key auth support added
yum/apt install support
2021-03-14 21:19:11 +03:00
pokamest
a2bb382652 ShadowSocks password - sha256 2021-03-13 14:16:24 +03:00
pokamest
02f966bc67 Win7 fix
Connection import fix
2021-03-13 13:56:52 +03:00
pokamest
65acdc8c09 readme added 2021-03-09 18:48:59 +03:00
pokamest
407ea77a9e ssh connection strict check disabled 2021-03-09 18:45:41 +03:00
pokamest
3e4a9f54a7 cygwin binaries added 2021-03-09 18:44:45 +03:00
pokamest
6b77bd5f13 Server install fix 2021-03-08 18:17:50 +03:00
pokamest
fb6de25e5f Migrate to cygwin sh 2021-03-06 15:07:43 +03:00
pokamest
ffbe5107e2 Secondary instance fix 2021-03-06 14:59:55 +03:00
pokamest
40a5b2e3f3 sites list ui fix 2021-02-25 23:11:46 +03:00
pokamest
c683884868 sites list reimplement 2021-02-25 21:16:00 +03:00
pokamest
65961d8d2e vpnconnection.cpp crash fix
ss server sript fix
2021-02-25 18:05:42 +03:00
pokamest
7dc1f1e225 Utils ip address regexp 2021-02-25 18:03:24 +03:00
pokamest
a47ab15aef mainwindow.ui fix 2021-02-25 01:06:02 +03:00
pokamest
c74efdaa9b ui fix for macos 2021-02-24 13:41:32 -08:00
pokamest
39224c7bf7 SingleApplication 2021-02-24 13:38:23 -08:00
pokamest
96aa3d409d SingleApplication 2021-02-24 23:40:57 +03:00
pokamest
c63990f720 Auto start
Auto connect
Dns settings
ui fixes
2021-02-24 21:58:32 +03:00
pokamest
ad643bf76e new icon 2021-02-22 18:07:39 +03:00
pokamest
c7ea4966fd minor fixes:
-build_windows.bat
-win build fix
-qdebug fix
2021-02-22 16:31:43 +03:00
pokamest
8fd81be477 ShadowSocks fixes for MacOS 2021-02-21 09:44:53 -08:00
pokamest
a1cb4ac544 Custom routing done
ShadowSocks enabled by default
2021-02-18 15:00:41 +03:00
pokamest
f91854594c Merge branch 'dev' into service_refact 2021-02-11 19:17:16 +03:00
pokamest
f661ea1d46 Merge branch 'macos_build_fix' into dev 2021-02-10 10:44:37 -08:00
pokamest
f50eea3eaf macos signing fixes 2021-02-10 06:57:26 -08:00
pokamest
c15b57e690 windows travis fix 2021-02-10 00:07:12 +03:00
pokamest
5f7ef31345 win cert updated 2021-02-09 00:33:26 +03:00
pokamest
447410a27a Macos build fix (#6)
macos deploy fixes
2021-02-08 23:57:35 +03:00
pokamest
2aa9f9cca9 macos build fix 2021-02-08 12:42:48 -08:00
pokamest
cba27d354d macos deploy fixes 2021-02-08 21:10:34 +03:00
pokamest
b398f42ada ipc process fix 2021-02-03 20:05:50 +03:00
pokamest
b6571d99de Qt ro refact 2021-02-03 15:42:36 +03:00
pokamest
b2392c1943 Qt Remote objects done 2021-02-02 22:51:31 +03:00
pokamest
048a673d31 Qt remote objects IPC 2021-02-02 01:47:40 +03:00
pokamest
c4df9c004b Merge branch 'dev' into service_refact 2021-01-30 15:03:01 +03:00
pokamest
22b33a4f25 remote_obj 2021-01-20 23:07:23 +03:00
1079 changed files with 102436 additions and 95524 deletions

6
.gitattributes vendored Normal file
View File

@@ -0,0 +1,6 @@
deploy/data/windows/x64/tap/windows_7/OemVista.inf eol=crlf
deploy/data/windows/x64/tap/windows_10/OemVista.inf eol=crlf
deploy/data/windows/x32/tap/windows_7/OemVista.inf eol=crlf
deploy/data/windows/x32/tap/windows_10/OemVista.inf eol=crlf
client/3rd/* linguist-vendored
client/android/gradlew.bat eol=crlf

42
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,42 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Log files**
Attach log files to help explain your problem.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows 10]
- Version [e.g. 2.1.2]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Version [e.g. 2.1.2]
**Server (please complete the following information):**
- OS: [e.g. Ubuntu 22.04]
**Additional context**
Add any other context about the problem here.

434
.github/workflows/deploy.yml vendored Normal file
View File

@@ -0,0 +1,434 @@
name: 'Deploy workflow'
on:
push:
branches:
- '**'
env:
QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/ # https://download.qt.io/static/mirrorlist/
jobs:
Build-Linux-Ubuntu:
name: 'Build-Linux-Ubuntu'
runs-on: ubuntu-20.04
env:
QT_VERSION: 6.6.2
QIF_VERSION: 4.7
steps:
- name: 'Install Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'desktop'
arch: 'gcc_64'
modules: 'qtremoteobjects qt5compat qtshadertools qtcharts'
dir: ${{ runner.temp }}
setup-python: 'true'
tools: 'tools_ifw'
set-env: 'true'
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Build project'
run: |
sudo apt-get install libxkbcommon-x11-0
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64/bin
export QIF_BIN_DIR=${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin
bash deploy/build_linux.sh
- name: 'Pack installer'
run: cd deploy && tar -cf AmneziaVPN_Linux_Installer.tar AmneziaVPN_Linux_Installer.bin
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Linux_installer.tar
path: deploy/AmneziaVPN_Linux_Installer.tar
retention-days: 7
- name: 'Upload unpacked artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Linux_unpacked
path: deploy/AppDir
retention-days: 7
# ------------------------------------------------------
Build-Windows:
name: Build-Windows
runs-on: windows-latest
env:
QT_VERSION: 6.6.2
QIF_VERSION: 4.7
BUILD_ARCH: 64
steps:
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Install Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'windows'
target: 'desktop'
arch: 'win64_msvc2019_64'
modules: 'qtremoteobjects qt5compat qtshadertools qtcharts'
dir: ${{ runner.temp }}
setup-python: 'true'
tools: 'tools_ifw'
set-env: 'true'
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Setup mvsc'
uses: ilammy/msvc-dev-cmd@v1
with:
arch: 'x64'
- name: 'Build project'
shell: cmd
run: |
set BUILD_ARCH=${{ env.BUILD_ARCH }}
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2019_64\\bin"
set QIF_BIN_DIR="${{ runner.temp }}\\Qt\\Tools\\QtInstallerFramework\\${{ env.QIF_VERSION }}\\bin"
call deploy\\build_windows.bat
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Windows_installer
path: AmneziaVPN_x${{ env.BUILD_ARCH }}.exe
retention-days: 7
- name: 'Upload unpacked artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Windows_unpacked
path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release
retention-days: 7
# ------------------------------------------------------
Build-iOS:
name: 'Build-iOS'
runs-on: macos-13
env:
QT_VERSION: 6.6.2
CC: cc
CXX: c++
steps:
- name: 'Setup xcode'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '15.2'
- name: 'Install desktop Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'mac'
target: 'desktop'
modules: 'qtremoteobjects qt5compat qtshadertools qtmultimedia qtcharts'
arch: 'clang_64'
dir: ${{ runner.temp }}
set-env: 'true'
extra: '--base ${{ env.QT_MIRROR }}'
- name: 'Install iOS Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'mac'
target: 'ios'
modules: 'qtremoteobjects qt5compat qtshadertools qtmultimedia qtcharts'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install go'
uses: actions/setup-go@v5
with:
go-version: '1.20'
cache: false
- name: 'Setup gomobile'
run: |
export PATH=$PATH:~/go/bin
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Install dependencies'
run: pip install jsonschema jinja2
- name: 'Build project'
run: |
git submodule update --init --recursive
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/ios/bin"
export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
export PATH=$PATH:~/go/bin
sh deploy/build_ios.sh
env:
IOS_TRUST_CERT_BASE64: ${{ secrets.IOS_TRUST_CERT_BASE64 }}
IOS_SIGNING_CERT_BASE64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
IOS_SIGNING_CERT_PASSWORD: ${{ secrets.IOS_SIGNING_CERT_PASSWORD }}
APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_ISSUER_ID }}
APPSTORE_CONNECT_PRIVATE_KEY: ${{ secrets.APPSTORE_CONNECT_PRIVATE_KEY }}
IOS_APP_PROVISIONING_PROFILE: ${{ secrets.IOS_APP_PROVISIONING_PROFILE }}
IOS_NE_PROVISIONING_PROFILE: ${{ secrets.IOS_NE_PROVISIONING_PROFILE }}
# - name: 'Upload appstore .ipa and dSYMs to artifacts'
# uses: actions/upload-artifact@v4
# with:
# name: app-store ipa & dsyms
# path: |
# ${{ github.workspace }}/AmneziaVPN-iOS.ipa
# ${{ github.workspace }}/*.app.dSYM.zip
# retention-days: 7
# ------------------------------------------------------
Build-MacOS:
name: 'Build-MacOS'
runs-on: macos-latest
env:
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
QT_VERSION: 6.4.3
QIF_VERSION: 4.6
steps:
- name: 'Setup xcode'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3.1'
- name: 'Install Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'mac'
target: 'desktop'
arch: 'clang_64'
modules: 'qtremoteobjects qt5compat qtshadertools qtcharts'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}'
run: |
mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework
wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip
unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Build project'
run: |
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin"
bash deploy/build_macos.sh
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_MacOS_installer
path: AmneziaVPN.dmg
retention-days: 7
- name: 'Upload unpacked artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_MacOS_unpacked
path: deploy/build/client/AmneziaVPN.app
retention-days: 7
# ------------------------------------------------------
Build-Android:
name: 'Build-Android'
runs-on: ubuntu-latest
env:
ANDROID_BUILD_PLATFORM: android-34
QT_VERSION: 6.6.2
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools qtcharts'
steps:
- name: 'Install desktop Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'desktop'
arch: 'gcc_64'
modules: ${{ env.QT_MODULES }}
dir: ${{ runner.temp }}
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install android_x86_64 Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_x86_64'
modules: ${{ env.QT_MODULES }}
dir: ${{ runner.temp }}
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install android_x86 Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_x86'
modules: ${{ env.QT_MODULES }}
dir: ${{ runner.temp }}
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install android_armv7 Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_armv7'
modules: ${{ env.QT_MODULES }}
dir: ${{ runner.temp }}
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install android_arm64_v8a Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_arm64_v8a'
modules: ${{ env.QT_MODULES }}
dir: ${{ runner.temp }}
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Grant execute permission for qt-cmake'
shell: bash
run: |
chmod +x ${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/android_x86_64/bin/qt-cmake
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Setup Java'
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'
- name: 'Setup Android NDK'
id: setup-ndk
uses: nttld/setup-ndk@v1
with:
ndk-version: 'r26b'
- name: 'Decode keystore secret to file'
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_RELEASE_KEYSTORE_BASE64 }}
shell: bash
run: |
echo $KEYSTORE_BASE64 | base64 --decode > android.keystore
- name: 'Build project'
env:
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
QT_HOST_PATH: ${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64
ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android.keystore
ANDROID_KEYSTORE_KEY_ALIAS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_ALIAS }}
ANDROID_KEYSTORE_KEY_PASS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_PASS }}
shell: bash
run: ./deploy/build_android.sh --aab --apk all --build-platform ${{ env.ANDROID_BUILD_PLATFORM }}
- name: 'Upload x86_64 apk'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-x86_64
path: deploy/build/AmneziaVPN-x86_64-release.apk
compression-level: 0
retention-days: 7
- name: 'Upload x86 apk'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-x86
path: deploy/build/AmneziaVPN-x86-release.apk
compression-level: 0
retention-days: 7
- name: 'Upload arm64-v8a apk'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-arm64-v8a
path: deploy/build/AmneziaVPN-arm64-v8a-release.apk
compression-level: 0
retention-days: 7
- name: 'Upload armeabi-v7a apk'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-armeabi-v7a
path: deploy/build/AmneziaVPN-armeabi-v7a-release.apk
compression-level: 0
retention-days: 7
- name: 'Upload aab'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android
path: deploy/build/AmneziaVPN-release.aab
compression-level: 0
retention-days: 7

142
.github/workflows/tag-deploy.yml vendored Normal file
View File

@@ -0,0 +1,142 @@
name: 'Release deploy workflow'
on:
workflow_dispatch:
# push:
# tags:
# - **
jobs:
Build-Android-Release:
name: 'Build-Android-Release'
runs-on: ubuntu-latest
env:
QT_VERSION: 6.4.1
QIF_VERSION: 4.5
steps:
- name: 'Install desktop Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'desktop'
arch: 'gcc_64'
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z'
- name: 'Install android Qt x86_64'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_x86_64'
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z'
- name: 'Install android Qt x86'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_x86'
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z'
- name: 'Install android Qt arm_v7'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_armv7'
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z'
- name: 'Install android Qt arm_v8'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'linux'
target: 'android'
arch: 'android_arm64_v8a'
modules: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'true'
extra: '--external 7z'
- name: 'Get sources'
uses: actions/checkout@v3
with:
path: main
submodules: 'true'
fetch-depth: 10
- name: 'Preparations before keystore fetching'
run: |
mkdir keystore
- name: 'Getting keystore'
uses: actions/checkout@v3
with:
repository: amnezia-vpn/amnezia-android-certificates
ssh-key: ${{ secrets.ANDROID_CERTS_SSH_PRIVATE_KEY }}
path: keystore
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Setup Java'
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: 'Build project'
run: |
export QT_HOST_PATH="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64"
export NDK_VERSION=23c
export ANDROID_NDK_PLATFORM=android-23
export ANDROID_NDK_HOME=${{ runner.temp }}/android-ndk-r${NDK_VERSION}
export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
if [ ! -f $ANDROID_NDK_ROOT/ndk-build ]; then
wget https://dl.google.com/android/repository/android-ndk-r${NDK_VERSION}-linux.zip -qO ${{ runner.temp }}/ndk.zip &&
unzip -q -d ${{ runner.temp }} ${{ runner.temp }}/ndk.zip ;
fi
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/android_arm64_v8a/bin
cd main
bash deploy/build_android.sh
- name: 'Signing APK'
run: |
pwd
ANDROID_BUILD_TOOLS_VERSION=30.0.3
${ANDROID_HOME}/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/zipalign -f -v 4 AmneziaVPN-release-unsigned.apk AmneziaVPN-release-aligned.apk
${ANDROID_HOME}/build-tools/${ANDROID_BUILD_TOOLS_VERSION}/apksigner sign --out AmneziaVPN-release-signed.apk --ks keystore/debug.keystore --ks-key-alias ${{ secrets.DEBUG_ANDROID_KEYSTORE_KEY_ALIAS }} --ks-pass pass:${{secrets.DEBUG_ANDROID_KEYSTOTE_KEY_PASS }} AmneziaVPN-release-aligned.apk
- name: 'Upload'
uses: actions/upload-artifact@v3
with:
name: Release APK
path: ${{ runner.temp }}/main/AmneziaVPN-release-signed.apk

64
.github/workflows/tag-upload.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: 'Upload a new version'
on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+.[0-9]+'
jobs:
upload:
runs-on: ubuntu-latest
name: upload
steps:
- name: Checkout CMakeLists.txt
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
sparse-checkout: |
CMakeLists.txt
sparse-checkout-cone-mode: false
- name: Verify git tag
run: |
GIT_TAG=${{ github.ref_name }}
CMAKE_TAG=$(grep 'project.*VERSION' CMakeLists.txt | sed -E 's/.* ([0-9]+.[0-9]+.[0-9]+.[0-9]+)$/\1/')
if [[ "$GIT_TAG" == "$CMAKE_TAG" ]]; then
echo "Git tag ($GIT_TAG) and version in CMakeLists.txt ($CMAKE_TAG) are the same. Continuing..."
else
echo "Git tag ($GIT_TAG) and version in CMakeLists.txt ($CMAKE_TAG) are not the same! Cancelling..."
exit 1
fi
- name: Download artifacts from the "${{ github.ref_name }}" tag
uses: robinraju/release-downloader@v1.8
with:
tag: ${{ github.ref_name }}
fileName: "AmneziaVPN_(Linux_|)${{ github.ref_name }}*"
out-file-path: ${{ github.ref_name }}
- name: Upload beta version
uses: jakejarvis/s3-sync-action@master
if: contains(github.event.base_ref, 'dev')
with:
args: --include "AmneziaVPN*" --delete
env:
AWS_S3_BUCKET: updates
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }}
AWS_S3_ENDPOINT: https://${{ vars.CF_ACCOUNT_ID }}.r2.cloudflarestorage.com
SOURCE_DIR: ${{ github.ref_name }}
DEST_DIR: beta/${{ github.ref_name }}
- name: Upload stable version
uses: jakejarvis/s3-sync-action@master
if: contains(github.event.base_ref, 'master')
with:
args: --include "AmneziaVPN*" --delete
env:
AWS_S3_BUCKET: updates
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }}
AWS_S3_ENDPOINT: https://${{ vars.CF_ACCOUNT_ID }}.r2.cloudflarestorage.com
SOURCE_DIR: ${{ github.ref_name }}
DEST_DIR: stable/${{ github.ref_name }}

96
.gitignore vendored
View File

@@ -3,8 +3,13 @@
macOSPackage/
AmneziaVPN.dmg
AmneziaVPN.exe
AmneziaVPN_*.exe
deploy/build/*
winbuild.bat
deploy/build_32/*
deploy/build_64/*
winbuild*.bat
.cache/
# Qt-es
/.qmake.cache
@@ -19,7 +24,39 @@ qrc_*.cpp
ui_*.h
Makefile*
*build-*
compile_commands.json
# fastlane
client/fastlane/report.xml
client/fastlane/build/*
# Qt-es
client/Release-iphoneos/
client/Debug-iphoneos/
client/.xcode/
client/.qmake.cache
client/.qmake.stash
client/*.pro.user
client/*.pro.user.*
client/*.qbs.user
client/*.qbs.user.*
client/*.moc
client/moc_*.cpp
client/qrc_*.cpp
client/ui_*.h
client/ui_*.cpp
client/Makefile*
client/fastlane/build/
client/*build-*
client/AmneziaVPN.xcodeproj
client/Debug-iphonesimulator/
client/amneziavpn_plugin_import.cpp
client/amneziavpn_qml_plugin_import.cpp
client/qmlcache_loader.cpp
client/rep_ipc_interface_replica.h
client/resources_qmlcache.qrc
client/3rd/OpenVPNAdpter/build/
client/3rd/ShadowSocks/build/
# QtCreator
*.autosave
@@ -31,12 +68,69 @@ Makefile*
# QtCtreator CMake
CMakeLists.txt.user*
# Linux files
*.7z
deploy/AppDir
deploy/Tools
deploy/AmneziaVPN*Installer*
# MACOS files
.DS_Store
client/.DS_Store
._.DS_Store
._*
*.dmg
# tmp files
*.*~
######################### Android
# Built application files
*.apk
*.aar
*.ap_
*.aab
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Android Profiling
*.hprof
client/3rd/ShadowSocks/ss_ios.xcconfig
# UML generated pics
out/
# CMake files
CMakeFiles/

View File

@@ -1,27 +0,0 @@
variables:
GIT_STRATEGY: clone
stages:
- build
build-windows:
stage: build
tags:
- windows
script:
- cmd.exe /k "deploy\windows-env.bat && cd deploy && windows.bat"
artifacts:
name: artifacts-windows
paths:
- AmneziaVPN.exe
build-macos:
stage: build
tags:
- macos
script:
- cd deploy && ./macos.sh
artifacts:
name: artifacts-macos
paths:
- AmneziaVPN.dmg

18
.gitmodules vendored
View File

@@ -1,3 +1,15 @@
[submodule "3rd/QtSsh"]
path = 3rd/QtSsh
url = https://github.com/amnezia-vpn/QtSsh.git
[submodule "client/3rd/OpenVPNAdapter"]
path = client/3rd/OpenVPNAdapter
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
[submodule "client/3rd/qtkeychain"]
path = client/3rd/qtkeychain
url = https://github.com/frankosterfeld/qtkeychain.git
[submodule "client/3rd/SortFilterProxyModel"]
path = client/3rd/SortFilterProxyModel
url = https://github.com/mitchcurtis/SortFilterProxyModel.git
[submodule "client/3rd-prebuilt"]
path = client/3rd-prebuilt
url = https://github.com/amnezia-vpn/3rd-prebuilt
[submodule "client/3rd/amneziawg-apple"]
path = client/3rd/amneziawg-apple
url = https://github.com/amnezia-vpn/amneziawg-apple

47
.gitpod.Dockerfile vendored Normal file
View File

@@ -0,0 +1,47 @@
FROM gitpod/workspace-full-vnc
USER gitpod
RUN sudo apt-get -q update \
&& sudo apt-get install -yq \
build-essential \
libgl1-mesa-dev \
libgstreamer-gl1.0-0 \
libpulse-dev \
libsecret-1-dev \
libxcb-glx0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-render0 \
libxcb-shape0 \
libxcb-shm0 \
libxcb-sync1 \
libxcb-util1 \
libxcb-xfixes0 \
libxcb-xinerama0 \
libxcb1 \
libxkbcommon-dev \
libxkbcommon-x11-0 \
libxcb-xkb-dev \
p7zip-full \
&& sudo rm -rf /var/lib/apt/lists/*
RUN sudo pip3 install aqtinstall
ARG QT_VERSION=6.4.1
ARG QT_ARCH=gcc_64
ARG QT_DIR=/opt/qt
RUN sudo aqt install-qt --outputdir ${QT_DIR} linux desktop ${QT_VERSION} ${QT_ARCH} --modules \
qtremoteobjects \
qt5compat \
qtshadertools
ENV QT_BIN_DIR=${QT_DIR}/${QT_VERSION}/${QT_ARCH}/bin
ARG QIF_VERSION=4.5
ARG QIF_DIR=/opt/qif
RUN sudo aqt install-tool --outputdir ${QIF_DIR} linux desktop tools_ifw
ENV QIF_BIN_DIR=${QIF_DIR}/Tools/QtInstallerFramework/${QIF_VERSION}/bin

8
.gitpod.yml Normal file
View File

@@ -0,0 +1,8 @@
tasks:
- init: >-
deploy/build_linux.sh
image:
file: .gitpod.Dockerfile
vscode:
extensions:
- llvm-vs-code-extensions.vscode-clangd

View File

@@ -1,96 +0,0 @@
language: cpp
branches:
only:
- master
- dev
- /\d+\.\d+/
jobs:
include:
- name: MacOS
os: osx
osx_image: xcode12.2
env:
- QT_VERSION=5.15.1
before_install:
- export CERTIFICATE_P12=deploy/PrivacyTechAppleCert.p12
- export KEYCHAIN=build.keychain
- security create-keychain -p $MAC_CERT_PW $KEYCHAIN
- security default-keychain -s $KEYCHAIN
- security unlock-keychain -p $MAC_CERT_PW $KEYCHAIN
- security import $CERTIFICATE_P12 -k $KEYCHAIN -P $MAC_CERT_PW -T /usr/bin/codesign
script:
- |
if [ ! -f $HOME/Qt/$QT_VERSION/clang_64/bin/qmake ]; then \
brew install p7zip && \
pip3 install aqtinstall requests py7zr && \
python3 -m aqt install --outputdir $HOME/Qt $QT_VERSION mac desktop clang_64 -m qtbase && \
python3 -m aqt tool --outputdir $HOME/Qt mac tools_ifw 4.0.1 qt.tools.ifw.40;
fi
- bash deploy/build_macos.sh
deploy:
provider: releases
token: $GH_TOKEN
skip_cleanup: true
file:
- "AmneziaVPN.dmg"
on:
tags: true
branch: master
- name: Windows
os: windows
env:
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
before_install:
- if [ ! -f /C/Qt/5.14.2/msvc2017/bin/qmake ]; then choco install python --version 3.9.1; fi
script:
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build"
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools"
- |
if [ ! -f /C/Qt/5.14.2/msvc2017/bin/qmake ]; then \
pip3 install aqtinstall requests py7zr && \
python -m aqt install --outputdir /C/Qt 5.14.2 windows desktop win32_msvc2017 -m qtbase && \
python -m aqt tool --outputdir /C/Qt windows tools_ifw 4.0.1 qt.tools.ifw.40; \
fi
- echo 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat"' > winbuild.bat
- echo -e "\r\n" >> winbuild.bat
- echo 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat"' >> winbuild.bat
- echo -e "\r\n" >> winbuild.bat
- echo -e "set WIN_CERT_PW=$WIN_CERT_PW" >> winbuild.bat
- echo -e "\r\n" >> winbuild.bat
- echo -e "call deploy\\\build_windows.bat" >> winbuild.bat
- cmd //c winbuild.bat
deploy:
provider: releases
token: $GH_TOKEN
skip_cleanup: true
file:
- "AmneziaVPN.exe"
on:
tags: true
branch: master
deploy:
skip_cleanup: true
before_cache:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
# Cache only .git files under "/usr/local/Homebrew" so "brew update" does not take 5min every build
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; fi
cache:
directories:
- $HOME/Qt
- /C/Qt
- $HOME/Library/Caches/Homebrew

View File

@@ -1,2 +0,0 @@
TEMPLATE = subdirs
SUBDIRS = client service platform

44
CMakeLists.txt Normal file
View File

@@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(PROJECT AmneziaVPN)
project(${PROJECT} VERSION 4.5.3.0
DESCRIPTION "AmneziaVPN"
HOMEPAGE_URL "https://amnezia.org/"
)
string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}")
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
set(APP_ANDROID_VERSION_CODE 52)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(MZ_PLATFORM_NAME "linux")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(MZ_PLATFORM_NAME "windows")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(MZ_PLATFORM_NAME "macos")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
set(MZ_PLATFORM_NAME "android")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
set(MZ_PLATFORM_NAME "ios")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
set(MZ_PLATFORM_NAME "wasm")
endif()
set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE AND NOT IOS)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
endif()
add_subdirectory(client)
if(NOT IOS AND NOT ANDROID)
add_subdirectory(service)
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)
endif()

154
README.md
View File

@@ -1,2 +1,154 @@
# Amnezia
# Amnezia VPN
## _The best client for self-hosted VPN_
[![Build Status](https://github.com/amnezia-vpn/amnezia-client/actions/workflows/deploy.yml/badge.svg?branch=dev)](https://github.com/amnezia-vpn/amnezia-client/actions/workflows/deploy.yml?query=branch:dev)
[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/amnezia-vpn/amnezia-client)
Amnezia is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
## Features
- Very easy to use - enter your IP address, SSH login, and password, and Amnezia will automatically install VPN docker containers to your server and connect to the VPN.
- OpenVPN, ShadowSocks, WireGuard, and IKEv2 protocols support.
- Masking VPN with OpenVPN over Cloak plugin
- Split tunneling support - add any sites to the client to enable VPN only for them (only for desktops)
- Windows, MacOS, Linux, Android, iOS releases.
## Links
[https://amnezia.org](https://amnezia.org) - project website
[https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
[https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
[https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
## Tech
AmneziaVPN uses several open-source projects to work:
- [OpenSSL](https://www.openssl.org/)
- [OpenVPN](https://openvpn.net/)
- [ShadowSocks](https://shadowsocks.org/)
- [Qt](https://www.qt.io/)
- [LibSsh](https://libssh.org) - forked from Qt Creator
- and more...
## Checking out the source code
Make sure to pull all submodules after checking out the repo.
```bash
git submodule update --init --recursive
```
## Development
Want to contribute? Welcome!
### Building sources and deployment
Check deploy folder for build scripts.
### How to build an iOS app from source code on MacOS
1. First, make sure you have [XCode](https://developer.apple.com/xcode/) installed, at least version 14 or higher.
2. We use QT to generate the XCode project. We need QT version 6.6.1. Install QT for MacOS [here](https://doc.qt.io/qt-6/macos.html) or [QT Online Installer](https://www.qt.io/download-open-source). Required modules:
- MacOS
- iOS
- Qt 5 Compatibility Module
- Qt Shader Tools
- Additional Libraries:
- Qt Charts
- Qt Image Formats
- Qt Multimedia
- Qt Remote Objects
3. Install CMake if required. We recommend CMake version 3.25. You can install CMake [here](https://cmake.org/download/)
4. You also need to install go >= v1.16. If you don't have it installed already,
download go from the [official website](https://golang.org/dl/) or use Homebrew.
The latest version is recommended. Install gomobile
```bash
export PATH=$PATH:~/go/bin
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
```
5. Build the project
```bash
export QT_BIN_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/ios/bin"
export QT_MACOS_ROOT_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/macos"
export QT_IOS_BIN=$QT_BIN_DIR
export PATH=$PATH:~/go/bin
mkdir build-ios
$QT_IOS_BIN/qt-cmake . -B build-ios -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR
```
Replace PATH-TO-QT-FOLDER and QT-VERSION to your environment
If you get `gomobile: command not found` make sure to set PATH to the location
of the bin folder where gomobile was installed. Usually, it's in `GOPATH`.
```bash
export PATH=$(PATH):/path/to/GOPATH/bin
```
6. Open the XCode project. You can then run /test/archive/ship the app.
If the build fails with the following error
```
make: ***
[$(PROJECTDIR)/client/build/AmneziaVPN.build/Debug-iphoneos/wireguard-go-bridge/goroot/.prepared]
Error 1
```
Add a user-defined variable to both AmneziaVPN and WireGuardNetworkExtension targets' build settings with
key `PATH` and value `${PATH}/path/to/bin/folder/with/go/executable`, e.g. `${PATH}:/usr/local/go/bin`.
if the above error persists on your M1 Mac, then most probably you need to install arch based CMake
```
arch -arm64 brew install cmake
```
Build might fail with the "source files not found" error the first time you try it, because the modern XCode build system compiles dependencies in parallel, and some dependencies end up being built after the ones that
require them. In this case, simply restart the build.
## How to build the Android app
_Tested on Mac OS_
The Android app has the following requirements:
* JDK 11
* Android platform SDK 33
* CMake 3.25.0
After you have installed QT, QT Creator, and Android Studio, you need to configure QT Creator correctly. Click in the top menu bar on `QT Creator` -> `Preferences` -> `Devices` and select the tab `Android`.
* set path to JDK 11
* set path to Android SDK ($ANDROID_HOME)
In case you get errors regarding missing SDK or 'SDK manager not running', you cannot fix them by correcting the paths. If you have some spare GBs on your disk, you can let QT Creator install all requirements by choosing an empty folder for `Android SDK location` and clicking on `Set Up SDK`. Be aware: This will install a second Android SDK and NDK on your machine! 
Double-check that the right CMake version is configured:  Click on `QT Creator` -> `Preferences` and click on the side menu on `Kits`. Under the center content view's `Kits` tab, you'll find an entry for `CMake Tool`. If the default selected CMake version is lower than 3.25.0, install on your system CMake >= 3.25.0 and choose `System CMake at <path>` from the drop-down list. If this entry is missing, you either have not installed CMake yet or QT Creator hasn't found the path to it. In that case, click in the preferences window on the side menu item `CMake`, then on the tab `Tools` in the center content view, and finally on the button `Add` to set the path to your installed CMake. 
Please make sure that you have selected Android Platform SDK 33 for your project: click in the main view's side menu on `Projects`, and on the left, you'll see a section `Build & Run` showing different Android build targets. You can select any of them, Amnezia VPN's project setup is designed in a way that all Android targets will be built. Click on the targets submenu item `Build` and scroll in the center content view to `Build Steps`. Click on `Details` at the end of the headline `Build Android APK` (the `Details` button might be hidden in case the QT Creator Window is not running in full screen!). Here we are: Choose `android-33` as `Android Build Platform SDK`.
That's it! You should be ready to compile the project from QT Creator!
### Development flow
After you've hit the build button, QT-Creator copies the whole project to a folder in the repository parent directory. The folder should look something like `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>`.
If you want to develop Amnezia VPNs Android components written in Kotlin, such as components using system APIs, you need to import the generated project in Android Studio with `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>/client/android-build` as the projects root directory. While you should be able to compile the generated project from Android Studio, you cannot work directly in the repository's Android project. So whenever you are confident with your work in the generated project, you'll need to copy and paste the affected files to the corresponding path in the repository's Android project so that you can add and commit your changes!
You may face compiling issues in QT Creator after you've worked in Android Studio on the generated project. Just do a `./gradlew clean` in the generated project's root directory (`<path>/client/android-build/.`) and you should be good to go.
## License
GPL v3.0
## Donate
Bitcoin: bc1qn9rhsffuxwnhcuuu4qzrwp4upkrq94xnh8r26u
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
payeer.com: P2561305
ko-fi.com: [https://ko-fi.com/amnezia_vpn](https://ko-fi.com/amnezia_vpn)
## Acknowledgments
This project is tested with BrowserStack.
We express our gratitude to [BrowserStack](https://www.browserstack.com) for supporting our project.

1
client/3rd-prebuilt Submodule

Submodule client/3rd-prebuilt added at c969f28b84

1
client/3rd/OpenVPNAdapter vendored Submodule

View File

@@ -0,0 +1,20 @@
include_directories(${CMAKE_CURRENT_LIST_DIR})
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/include/QAead.h
${CMAKE_CURRENT_LIST_DIR}/include/QBlockCipher.h
${CMAKE_CURRENT_LIST_DIR}/include/QCryptoError.h
${CMAKE_CURRENT_LIST_DIR}/include/QRsa.h
${CMAKE_CURRENT_LIST_DIR}/include/QSimpleCrypto_global.h
${CMAKE_CURRENT_LIST_DIR}/include/QX509.h
${CMAKE_CURRENT_LIST_DIR}/include/QX509Store.h
)
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/sources/QAead.cpp
${CMAKE_CURRENT_LIST_DIR}/sources/QBlockCipher.cpp
${CMAKE_CURRENT_LIST_DIR}/sources/QCryptoError.cpp
${CMAKE_CURRENT_LIST_DIR}/sources/QRsa.cpp
${CMAKE_CURRENT_LIST_DIR}/sources/QX509.cpp
${CMAKE_CURRENT_LIST_DIR}/sources/QX509Store.cpp
)

View File

@@ -0,0 +1,18 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/include/QAead.h \
$$PWD/include/QBlockCipher.h \
$$PWD/include/QCryptoError.h \
$$PWD/include/QRsa.h \
$$PWD/include/QSimpleCrypto_global.h \
$$PWD/include/QX509.h \
$$PWD/include/QX509Store.h
SOURCES += \
$$PWD/sources/QAead.cpp \
$$PWD/sources/QBlockCipher.cpp \
$$PWD/sources/QCryptoError.cpp \
$$PWD/sources/QRsa.cpp \
$$PWD/sources/QX509.cpp \
$$PWD/sources/QX509Store.cpp

View File

@@ -0,0 +1,87 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QAEAD_H
#define QAEAD_H
#include "QSimpleCrypto_global.h"
#include <QObject>
#include <memory>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QAead {
public:
QAead();
///
/// \brief encryptAesGcm - Function encrypts data with Gcm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray encryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_gcm());
///
/// \brief decryptAesGcm - Function decrypts data with Gcm algorithm.
/// \param data - Data that will be decrypted
/// \param key - AES key
/// \param iv - Initialization vector
/// \param tag - Authorization tag
/// \param aad - Additional authenticated data. Must be nullptr, if not used
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm()
/// \return Returns decrypted data or "", if error happened.
///
QByteArray decryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_gcm());
///
/// \brief encryptAesCcm - Function encrypts data with Ccm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray encryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_ccm());
///
/// \brief decryptAesCcm - Function decrypts data with Ccm algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray decryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_ccm());
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QAEAD_H

View File

@@ -0,0 +1,84 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QBLOCKCIPHER_H
#define QBLOCKCIPHER_H
#include "QSimpleCrypto_global.h"
#include <QObject>
#include <memory>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QBlockCipher {
#define Aes128Rounds 10
#define Aes192Rounds 12
#define Aes256Rounds 14
public:
QBlockCipher();
///
/// \brief generateRandomBytes - Function generates random bytes by size.
/// \param size - Size of generated bytes.
/// \return Returns random bytes.
///
QByteArray generateRandomBytes(const int& size);
QByteArray generateSecureRandomBytes(const int& size);
///
/// \brief encryptAesBlockCipher - Function encrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Encryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray encryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv = "", const int& rounds = Aes256Rounds,
const EVP_CIPHER* cipher = EVP_aes_256_cbc(), const EVP_MD* md = EVP_sha512());
///
/// \brief decryptAesBlockCipher - Function decrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Decryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray decryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv = "", const int& rounds = Aes256Rounds,
const EVP_CIPHER* cipher = EVP_aes_256_cbc(), const EVP_MD* md = EVP_sha512());
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QBLOCKCIPHER_H

View File

@@ -0,0 +1,45 @@
#ifndef QCRYPTOERROR_H
#define QCRYPTOERROR_H
#include <QObject>
#include "QSimpleCrypto_global.h"
/// TODO: Add Special error code for each error.
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QCryptoError : public QObject {
Q_OBJECT
public:
explicit QCryptoError(QObject* parent = nullptr);
///
/// \brief setError - Sets error information
/// \param errorCode - Error code.
/// \param errorSummary - Error summary.
///
inline void setError(const quint8 errorCode, const QString& errorSummary)
{
m_currentErrorCode = errorCode;
m_errorSummary = errorSummary;
}
///
/// \brief lastError - Returns last error.
/// \return Returns eror ID and error Text.
///
inline QPair<quint8, QString> lastError() const
{
return QPair<quint8, QString>(m_currentErrorCode, m_errorSummary);
}
private:
quint8 m_currentErrorCode;
QString m_errorSummary;
};
}
#endif // QCRYPTOERROR_H

View File

@@ -0,0 +1,104 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QRSA_H
#define QRSA_H
#include "QSimpleCrypto_global.h"
#include <QFile>
#include <QObject>
#include <memory>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QRsa {
#define PublicEncrypt 0
#define PrivateEncrypt 1
#define PublicDecrypt 2
#define PrivateDecrypt 3
public:
QRsa();
///
/// \brief generateRsaKeys - Function generate Rsa Keys and returns them in OpenSSL structure.
/// \param bits - RSA key size.
/// \param rsaBigNumber - The exponent is an odd number, typically 3, 17 or 65537.
/// \return Returns 'OpenSSL RSA structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'RSA_free()' to avoid memory leak.
///
RSA* generateRsaKeys(const int& bits, const int& rsaBigNumber);
///
/// \brief savePublicKey - Saves to file RSA public key.
/// \param rsa - OpenSSL RSA structure.
/// \param publicKeyFileName - Public key file name.
///
void savePublicKey(RSA *rsa, const QByteArray& publicKeyFileName);
///
/// \brief savePrivateKey - Saves to file RSA private key.
/// \param rsa - OpenSSL RSA structure.
/// \param privateKeyFileName - Private key file name.
/// \param password - Private key password.
/// \param cipher - Can be used with 'OpenSSL EVP_CIPHER' (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
///
void savePrivateKey(RSA* rsa, const QByteArray& privateKeyFileName, QByteArray password = "", const EVP_CIPHER* cipher = nullptr);
///
/// \brief getPublicKeyFromFile - Gets RSA public key from a file.
/// \param filePath - File path to public key file.
/// \return Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* getPublicKeyFromFile(const QByteArray& filePath);
///
/// \brief getPrivateKeyFromFile - Gets RSA private key from a file.
/// \param filePath - File path to private key file.
/// \param password - Private key password.
/// \return - Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* getPrivateKeyFromFile(const QByteArray& filePath, const QByteArray& password = "");
///
/// \brief encrypt - Encrypt data with RSA algorithm.
/// \param plaintext - Text that must be encrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param encryptType - Public or private encrypt type. (PUBLIC_ENCRYPT, PRIVATE_ENCRYPT).
/// \param padding - OpenSSL RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return Returns encrypted data or "", if error happened.
///
QByteArray encrypt(QByteArray plainText, RSA* rsa, const int& encryptType = PublicEncrypt, const int& padding = RSA_PKCS1_PADDING);
///
/// \brief decrypt - Decrypt data with RSA algorithm.
/// \param cipherText - Text that must be decrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param decryptType - Public or private type. (PUBLIC_DECRYPT, PRIVATE_DECRYPT).
/// \param padding - RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return - Returns decrypted data or "", if error happened.
///
QByteArray decrypt(QByteArray cipherText, RSA* rsa, const int& decryptType = PrivateDecrypt, const int& padding = RSA_PKCS1_PADDING);
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QRSA_H

View File

@@ -0,0 +1,9 @@
#ifndef QSIMPLECRYPTO_GLOBAL_H
#define QSIMPLECRYPTO_GLOBAL_H
#include <QtCore/qglobal.h>
#include <stdexcept>
#define QSIMPLECRYPTO_EXPORT
#endif // QSIMPLECRYPTO_GLOBAL_H

View File

@@ -0,0 +1,87 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QX509_H
#define QX509_H
#include "QSimpleCrypto_global.h"
#include <QMap>
#include <QObject>
#include <memory>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QX509 {
#define oneYear 31536000L
#define x509LastVersion 2
public:
QX509();
///
/// \brief loadCertificateFromFile - Function load X509 from file and returns OpenSSL structure.
/// \param fileName - File path to certificate.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* loadCertificateFromFile(const QByteArray& fileName);
///
/// \brief signCertificate - Function signs X509 certificate and returns signed X509 OpenSSL structure.
/// \param endCertificate - Certificate that will be signed
/// \param caCertificate - CA certificate that will sign end certificate
/// \param caPrivateKey - CA certificate private key
/// \param fileName - With that name certificate will be saved. Leave "", if don't need to save it
/// \return Returns OpenSSL X509 structure or nullptr, if error happened.
///
X509* signCertificate(X509* endCertificate, X509* caCertificate, EVP_PKEY* caPrivateKey, const QByteArray& fileName = "");
///
/// \brief verifyCertificate - Function verifies X509 certificate and returns verified X509 OpenSSL structure.
/// \param x509 - OpenSSL X509. That certificate will be verified.
/// \param store - Trusted certificate must be added to X509_Store with 'addCertificateToStore(X509_STORE* ctx, X509* x509)'.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened
///
X509* verifyCertificate(X509* x509, X509_STORE* store);
///
/// \brief generateSelfSignedCertificate - Function generatesand returns self signed X509.
/// \param rsa - OpenSSL RSA.
/// \param additionalData - Certificate information.
/// \param certificateFileName - With that name certificate will be saved. Leave "", if don't need to save it.
/// \param md - OpenSSL EVP_MD structure. Example: EVP_sha512().
/// \param serialNumber - X509 certificate serial number.
/// \param version - X509 certificate version.
/// \param notBefore - X509 start date.
/// \param notAfter - X509 end date.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* generateSelfSignedCertificate(RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
const QByteArray& certificateFileName = "", const EVP_MD* md = EVP_sha512(),
const long& serialNumber = 1, const long& version = x509LastVersion,
const long& notBefore = 0, const long& notAfter = oneYear);
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QX509_H

View File

@@ -0,0 +1,120 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QX509STORE_H
#define QX509STORE_H
#include "QSimpleCrypto_global.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <memory>
#include <openssl/err.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QX509Store {
public:
QX509Store();
///
/// \brief addCertificateToStore
/// \param store - OpenSSL X509_STORE.
/// \param x509 - OpenSSL X509.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool addCertificateToStore(X509_STORE* store, X509* x509);
///
/// \brief addLookup
/// \param store - OpenSSL X509_STORE.
/// \param method - OpenSSL X509_LOOKUP_METHOD. Example: X509_LOOKUP_file.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool addLookup(X509_STORE* store, X509_LOOKUP_METHOD* method);
///
/// \brief setCertificateDepth
/// \param store - OpenSSL X509_STORE.
/// \param depth - That is the maximum number of untrusted CA certificates that can appear in a chain. Example: 0.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setDepth(X509_STORE* store, const int& depth);
///
/// \brief setFlag
/// \param store - OpenSSL X509_STORE.
/// \param flag - The verification flags consists of zero or more of the following flags ored together. Example: X509_V_FLAG_CRL_CHECK.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setFlag(X509_STORE* store, const unsigned long& flag);
///
/// \brief setFlag
/// \param store - OpenSSL X509_STORE.
/// \param purpose - Verification purpose in param to purpose. Example: X509_PURPOSE_ANY.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setPurpose(X509_STORE* store, const int& purpose);
///
/// \brief setTrust
/// \param store - OpenSSL X509_STORE.
/// \param trust - Trust Level. Example: X509_TRUST_SSL_SERVER.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setTrust(X509_STORE* store, const int& trust);
///
/// \brief setDefaultPaths
/// \param store - OpenSSL X509_STORE.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setDefaultPaths(X509_STORE* store);
///
/// \brief loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileName - File name. Example: "caCertificate.pem".
/// \param dirPath - Path to file. Example: "path/To/File".
/// \return Returns 'true' on success and 'false', if error happened.
///
bool loadLocations(X509_STORE* store, const QByteArray& fileName, const QByteArray& dirPath);
///
/// \brief loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param file - Qt QFile that will be loaded.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool loadLocations(X509_STORE* store, const QFile& file);
///
/// \brief loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileInfo - Qt QFileInfo.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool loadLocations(X509_STORE* store, const QFileInfo& fileInfo);
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
}
#endif // QX509STORE_H

View File

@@ -0,0 +1,364 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QAead.h"
QSimpleCrypto::QAead::QAead()
{
}
///
/// \brief QSimpleCrypto::QAEAD::encryptAesGcm - Function encrypts data with Gcm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::encryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (encryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int plainTextLength = data.size();
int cipherTextLength = 0;
/* Initialize cipherText. Here encrypted data will be stored */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[plainTextLength]() };
if (cipherText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'ciphertext'.");
}
/* Initialize encryption operation. */
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_GCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Check if aad need to be used */
// if (aad.length() > 0) {
// /* Provide any AAD data. This can be called zero or more times as required */
// if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
// throw std::runtime_error("Couldn't provide aad data. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
// }
/*
* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), plainTextLength)) {
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the encryption. Normally cipher text bytes may be written at
* this stage, but this does not occur in GCM mode
*/
if (!EVP_EncryptFinal_ex(encryptionCipher.get(), cipherText.get(), &plainTextLength)) {
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Get tag */
// if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_GCM_GET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
// throw std::runtime_error("Couldn't get tag. EVP_CIPHER_CTX_ctrl(. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/* Finilize data to be readable with qt */
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength);
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QAEAD::decryptAesGcm - Function decrypts data with Gcm algorithm.
/// \param data - Data that will be decrypted
/// \param key - AES key
/// \param iv - Initialization vector
/// \param tag - Authorization tag
/// \param aad - Additional authenticated data. Must be nullptr, if not used
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm()
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::decryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (decryptionCipher.get() == nullptr) {
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int cipherTextLength = data.size();
int plainTextLength = 0;
/* Initialize plainText. Here decrypted data will be stored */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherTextLength]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'plaintext'.");
}
/* Initialize decryption operation. */
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_GCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Check if aad need to be used */
// if (aad.length() > 0) {
// /* Provide any AAD data. This can be called zero or more times as required */
// if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
// throw std::runtime_error("Couldn't provide aad data. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
// }
/*
* Provide the message to be decrypted, and obtain the plain text output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), cipherTextLength)) {
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
// if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_GCM_SET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
// throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/*
* Finalize the decryption. A positive return value indicates success,
* anything else is a failure - the plain text is not trustworthy.
*/
if (!EVP_DecryptFinal_ex(decryptionCipher.get(), plainText.get(), &cipherTextLength)) {
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength);
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QAEAD::encryptAesCcm - Function encrypts data with Ccm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::encryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (encryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int plainTextLength = data.size();
int cipherTextLength = 0;
/* Initialize cipherText. Here encrypted data will be stored */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[plainTextLength]() };
if (cipherText.get() == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'ciphertext'.");
}
/* Initialize encryption operation. */
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set tag length */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_SET_TAG, tag->length(), nullptr)) {
throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Check if aad need to be used */
if (aad.length() > 0) {
/* Provide the total plain text length */
if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, nullptr, plainTextLength)) {
throw std::runtime_error("Couldn't provide total plaintext length. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Provide any AAD data. This can be called zero or more times as required */
if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
throw std::runtime_error("Couldn't provide aad data. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
/*
* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), plainTextLength)) {
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the encryption. Normally ciphertext bytes may be written at
* this stage, but this does not occur in GCM mode
*/
if (!EVP_EncryptFinal_ex(encryptionCipher.get(), cipherText.get(), &plainTextLength)) {
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Get tag */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_GET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
throw std::runtime_error("Couldn't get tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength);
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QAEAD::decryptAesCcm - Function decrypts data with Ccm algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::decryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (decryptionCipher.get() == nullptr) {
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int cipherTextLength = data.size();
int plainTextLength = 0;
/* Initialize plainText. Here decrypted data will be stored */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherTextLength]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'plaintext'.");
}
/* Initialize decryption operation. */
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_CCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set expected tag value. Works in OpenSSL 1.0.1d and later */
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_CCM_SET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Check if aad need to be used */
if (aad.length() > 0) {
/* Provide the total ciphertext length */
if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, nullptr, cipherTextLength)) {
throw std::runtime_error("Couldn't provide total plaintext length. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Provide any AAD data. This can be called zero or more times as required */
if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
throw std::runtime_error("Couldn't provide aad data. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
/*
* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), cipherTextLength)) {
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the decryption. A positive return value indicates success,
* anything else is a failure - the plaintext is not trustworthy.
*/
if (!EVP_DecryptFinal_ex(decryptionCipher.get(), plainText.get(), &cipherTextLength)) {
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength);
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}

View File

@@ -0,0 +1,193 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QBlockCipher.h"
QSimpleCrypto::QBlockCipher::QBlockCipher()
{
}
///
/// \brief QSimpleCrypto::QBlockCipher::generateRandomBytes - Function generates random bytes by size.
/// \param size - Size of generated bytes.
/// \return Returns random bytes.
///
QByteArray QSimpleCrypto::QBlockCipher::generateRandomBytes(const int& size)
{
unsigned char arr[sizeof(size)];
RAND_bytes(arr, sizeof(size));
QByteArray buffer = QByteArray(reinterpret_cast<char*>(arr), size);
return buffer;
}
QByteArray QSimpleCrypto::QBlockCipher::generateSecureRandomBytes(const int &size)
{
unsigned char arr[sizeof(size)];
RAND_priv_bytes(arr, sizeof(size));
QByteArray buffer = QByteArray(reinterpret_cast<char*>(arr), size);
return buffer;
}
///
/// \brief QSimpleCrypto::QBlockCipher::encryptAesBlockCipher - Function encrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Encryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QBlockCipher::encryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv,
const int& rounds, const EVP_CIPHER* cipher, const EVP_MD* md)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (encryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Reinterpret values for multi use */
unsigned char* m_key = reinterpret_cast<unsigned char*>(key.data());
unsigned char* m_iv = reinterpret_cast<unsigned char*>(iv.data());
/* Set data length */
int cipherTextLength(data.size() + AES_BLOCK_SIZE);
int finalLength = 0;
/* Initialize cipcherText. Here encrypted data will be stored */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[cipherTextLength]() };
if (cipherText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'cipherText'.");
}
// Bug here
// /* Start encryption with password based encryption routine */
// if (!EVP_BytesToKey(cipher, md, reinterpret_cast<unsigned char*>(salt.data()), reinterpret_cast<unsigned char*>(password.data()), password.length(), rounds, m_key, m_iv)) {
// throw std::runtime_error("Couldn't start encryption routine. EVP_BytesToKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/* Initialize encryption operation. */
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, m_key, m_iv)) {
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), data.size())) {
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finalize the encryption. Normally ciphertext bytes may be written at this stage */
if (!EVP_EncryptFinal(encryptionCipher.get(), cipherText.get() + cipherTextLength, &finalLength)) {
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength + finalLength);
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QBlockCipher::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QBlockCipher::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QBlockCipher::encryptAesBlockCipher - Function decrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Decryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QBlockCipher::decryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv,
const int& rounds, const EVP_CIPHER* cipher, const EVP_MD* md)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (decryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Reinterpret values for multi use */
unsigned char* m_key = reinterpret_cast<unsigned char*>(key.data());
unsigned char* m_iv = reinterpret_cast<unsigned char*>(iv.data());
/* Set data length */
int plainTextLength(data.size());
int finalLength = 0;
/* Initialize plainText. Here decrypted data will be stored */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[plainTextLength + AES_BLOCK_SIZE]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for \'plainText\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// Bug here
// /* Start encryption with password based encryption routine */
// if (!EVP_BytesToKey(cipher, md, reinterpret_cast<const unsigned char*>(salt.data()), reinterpret_cast<const unsigned char*>(password.data()), password.length(), rounds, m_key, m_iv)) {
// throw std::runtime_error("Couldn't start decryption routine. EVP_BytesToKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/* Initialize decryption operation. */
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, m_key, m_iv)) {
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), data.size())) {
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the decryption. A positive return value indicates success,
* anything else is a failure - the plaintext is not trustworthy.
*/
if (!EVP_DecryptFinal(decryptionCipher.get(), plainText.get() + plainTextLength, &finalLength)) {
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength + finalLength);
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QBlockCipher::error.setError(1, exception.what());
return QByteArray(exception.what());
} catch (...) {
QSimpleCrypto::QBlockCipher::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}

View File

@@ -0,0 +1,6 @@
#include "include/QCryptoError.h"
QSimpleCrypto::QCryptoError::QCryptoError(QObject* parent)
: QObject(parent)
{
}

View File

@@ -0,0 +1,274 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QRsa.h"
QSimpleCrypto::QRsa::QRsa()
{
}
///
/// \brief QSimpleCrypto::QRSA::generateRsaKeys - Function generate Rsa Keys and returns them in OpenSSL structure.
/// \param bits - RSA key size.
/// \param rsaBigNumber - The exponent is an odd number, typically 3, 17 or 65537.
/// \return Returns 'OpenSSL RSA structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'RSA_free()' to avoid memory leak.
///
RSA* QSimpleCrypto::QRsa::generateRsaKeys(const int& bits, const int& rsaBigNumber)
{
try {
/* Initialize big number */
std::unique_ptr<BIGNUM, void (*)(BIGNUM*)> bigNumber { BN_new(), BN_free };
if (bigNumber == nullptr) {
throw std::runtime_error("Couldn't initialize \'bigNumber\'. BN_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return nullptr;
}
/* Set big number */
if (!BN_set_word(bigNumber.get(), rsaBigNumber)) {
throw std::runtime_error("Couldn't set bigNumber. BN_set_word(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize RSA */
RSA* rsa = nullptr;
if (!(rsa = RSA_new())) {
throw std::runtime_error("Couldn't initialize x509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Generate key pair and store it in RSA */
if (!RSA_generate_key_ex(rsa, bits, bigNumber.get(), nullptr)) {
throw std::runtime_error("Couldn't generate RSA. RSA_generate_key_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return rsa;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QRSA::savePublicKey - Saves to file RSA public key.
/// \param rsa - OpenSSL RSA structure.
/// \param publicKeyFileName - Public key file name.
///
void QSimpleCrypto::QRsa::savePublicKey(RSA* rsa, const QByteArray& publicKeyFileName)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPublicKey { BIO_new_file(publicKeyFileName.data(), "w+"), BIO_free_all };
if (bioPublicKey == nullptr) {
throw std::runtime_error("Couldn't initialize \'bioPublicKey\'. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write public key on file */
if (!PEM_write_bio_RSA_PUBKEY(bioPublicKey.get(), rsa)) {
throw std::runtime_error("Couldn't save public key. PEM_write_bio_RSAPublicKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return;
}
}
///
/// \brief QSimpleCrypto::QRSA::savePrivateKey - Saves to file RSA private key.
/// \param rsa - OpenSSL RSA structure.
/// \param privateKeyFileName - Private key file name.
/// \param password - Private key password.
/// \param cipher - Can be used with 'OpenSSL EVP_CIPHER' (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
///
void QSimpleCrypto::QRsa::savePrivateKey(RSA* rsa, const QByteArray& privateKeyFileName, QByteArray password, const EVP_CIPHER* cipher)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPrivateKey { BIO_new_file(privateKeyFileName.data(), "w+"), BIO_free_all };
if (bioPrivateKey == nullptr) {
throw std::runtime_error("Couldn't initialize bioPrivateKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write private key to file */
if (!PEM_write_bio_RSAPrivateKey(bioPrivateKey.get(), rsa, cipher, reinterpret_cast<unsigned char*>(password.data()), password.size(), nullptr, nullptr)) {
throw std::runtime_error("Couldn't save private key. PEM_write_bio_RSAPrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return;
}
}
///
/// \brief QSimpleCrypto::QRSA::getPublicKeyFromFile - Gets RSA public key from a file.
/// \param filePath - File path to public key file.
/// \return Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* QSimpleCrypto::QRsa::getPublicKeyFromFile(const QByteArray& filePath)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPublicKey { BIO_new_file(filePath.data(), "r"), BIO_free_all };
if (bioPublicKey == nullptr) {
throw std::runtime_error("Couldn't initialize bioPublicKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize EVP_PKEY */
EVP_PKEY* keyStore = nullptr;
if (!(keyStore = EVP_PKEY_new())) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write private key to file */
if (!PEM_read_bio_PUBKEY(bioPublicKey.get(), &keyStore, nullptr, nullptr)) {
throw std::runtime_error("Couldn't read private key. PEM_read_bio_PrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return keyStore;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QRSA::getPrivateKeyFromFile - Gets RSA private key from a file.
/// \param filePath - File path to private key file.
/// \param password - Private key password.
/// \return - Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* QSimpleCrypto::QRsa::getPrivateKeyFromFile(const QByteArray& filePath, const QByteArray& password)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPrivateKey { BIO_new_file(filePath.data(), "r"), BIO_free_all };
if (bioPrivateKey == nullptr) {
throw std::runtime_error("Couldn't initialize bioPrivateKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize EVP_PKEY */
EVP_PKEY* keyStore = nullptr;
if (!(keyStore = EVP_PKEY_new())) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write private key to file */
if (!PEM_read_bio_PrivateKey(bioPrivateKey.get(), &keyStore, nullptr, (void*)password.data())) {
throw std::runtime_error("Couldn't read private key. PEM_read_bio_PrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return keyStore;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QRSA::encrypt - Encrypt data with RSA algorithm.
/// \param plaintext - Text that must be encrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param encryptType - Public or private encrypt type. (PUBLIC_ENCRYPT, PRIVATE_ENCRYPT).
/// \param padding - OpenSSL RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return Returns encrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QRsa::encrypt(QByteArray plainText, RSA* rsa, const int& encryptType, const int& padding)
{
try {
/* Initialize array. Here encrypted data will be saved */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[RSA_size(rsa)]() };
if (cipherText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'cipherText'.");
}
/* Result of encryption operation */
short int result = 0;
/* Execute encryption operation */
if (encryptType == PublicDecrypt) {
result = RSA_public_encrypt(plainText.size(), reinterpret_cast<unsigned char*>(plainText.data()), cipherText.get(), rsa, padding);
} else if (encryptType == PrivateDecrypt) {
result = RSA_private_encrypt(plainText.size(), reinterpret_cast<unsigned char*>(plainText.data()), cipherText.get(), rsa, padding);
}
/* Check for result */
if (result <= -1) {
throw std::runtime_error("Couldn't encrypt data. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Get encrypted data */
const QByteArray& encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), RSA_size(rsa));
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return "";
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return "";
}
}
///
/// \brief QSimpleCrypto::QRSA::decrypt - Decrypt data with RSA algorithm.
/// \param cipherText - Text that must be decrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param decryptType - Public or private type. (PUBLIC_DECRYPT, PRIVATE_DECRYPT).
/// \param padding - RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return - Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QRsa::decrypt(QByteArray cipherText, RSA* rsa, const int& decryptType, const int& padding)
{
try {
/* Initialize array. Here decrypted data will be saved */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherText.size()]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'plainText'.");
}
/* Result of decryption operation */
short int result = 0;
/* Execute decryption operation */
if (decryptType == PublicDecrypt) {
result = RSA_public_decrypt(RSA_size(rsa), reinterpret_cast<unsigned char*>(cipherText.data()), plainText.get(), rsa, padding);
} else if (decryptType == PrivateDecrypt) {
result = RSA_private_decrypt(RSA_size(rsa), reinterpret_cast<unsigned char*>(cipherText.data()), plainText.get(), rsa, padding);
}
/* Check for result */
if (result <= -1) {
throw std::runtime_error("Couldn't decrypt data. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Get decrypted data */
const QByteArray& decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()));
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return "";
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return "";
}
}

View File

@@ -0,0 +1,234 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QX509.h"
QSimpleCrypto::QX509::QX509()
{
}
///
/// \brief QSimpleCrypto::QX509::loadCertificateFromFile - Function load X509 from file and returns OpenSSL structure.
/// \param fileName - File path to certificate.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* QSimpleCrypto::QX509::loadCertificateFromFile(const QByteArray& fileName)
{
try {
/* Initialize X509 */
X509* x509 = nullptr;
if (!(x509 = X509_new())) {
throw std::runtime_error("Couldn't initialize X509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(fileName.data(), "r+"), BIO_free_all };
if (certFile == nullptr) {
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Read file */
if (!PEM_read_bio_X509(certFile.get(), &x509, nullptr, nullptr)) {
throw std::runtime_error("Couldn't read certificate file from disk. PEM_read_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return x509;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QX509::signCertificate - Function signs X509 certificate and returns signed X509 OpenSSL structure.
/// \param endCertificate - Certificate that will be signed
/// \param caCertificate - CA certificate that will sign end certificate
/// \param caPrivateKey - CA certificate private key
/// \param fileName - With that name certificate will be saved. Leave "", if don't need to save it
/// \return Returns OpenSSL X509 structure or nullptr, if error happened.
///
X509* QSimpleCrypto::QX509::signCertificate(X509* endCertificate, X509* caCertificate, EVP_PKEY* caPrivateKey, const QByteArray& fileName)
{
try {
/* Set issuer to CA's subject. */
if (!X509_set_issuer_name(endCertificate, X509_get_subject_name(caCertificate))) {
throw std::runtime_error("Couldn't set issuer name for X509. X509_set_issuer_name(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Sign the certificate with key. */
if (!X509_sign(endCertificate, caPrivateKey, EVP_sha256())) {
throw std::runtime_error("Couldn't sign X509. X509_sign(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write certificate file on disk. If needed */
if (!fileName.isEmpty()) {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(fileName.data(), "w+"), BIO_free_all };
if (certFile == nullptr) {
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write file on disk */
if (!PEM_write_bio_X509(certFile.get(), endCertificate)) {
throw std::runtime_error("Couldn't write certificate file on disk. PEM_write_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
return endCertificate;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QX509::verifyCertificate - Function verifies X509 certificate and returns verified X509 OpenSSL structure.
/// \param x509 - OpenSSL X509. That certificate will be verified.
/// \param store - Trusted certificate must be added to X509_Store with 'addCertificateToStore(X509_STORE* ctx, X509* x509)'.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened
///
X509* QSimpleCrypto::QX509::verifyCertificate(X509* x509, X509_STORE* store)
{
try {
/* Initialize X509_STORE_CTX */
std::unique_ptr<X509_STORE_CTX, void (*)(X509_STORE_CTX*)> ctx { X509_STORE_CTX_new(), X509_STORE_CTX_free };
if (ctx == nullptr) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set up CTX for a subsequent verification operation */
if (!X509_STORE_CTX_init(ctx.get(), store, x509, nullptr)) {
throw std::runtime_error("Couldn't initialize X509_STORE_CTX. X509_STORE_CTX_init(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Verify X509 */
if (!X509_verify_cert(ctx.get())) {
throw std::runtime_error("Couldn't verify cert. X509_verify_cert(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return x509;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QX509::generateSelfSignedCertificate - Function generatesand returns self signed X509.
/// \param rsa - OpenSSL RSA.
/// \param additionalData - Certificate information.
/// \param certificateFileName - With that name certificate will be saved. Leave "", if don't need to save it.
/// \param md - OpenSSL EVP_MD structure. Example: EVP_sha512().
/// \param serialNumber - X509 certificate serial number.
/// \param version - X509 certificate version.
/// \param notBefore - X509 start date.
/// \param notAfter - X509 end date.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* QSimpleCrypto::QX509::generateSelfSignedCertificate(RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
const QByteArray& certificateFileName, const EVP_MD* md,
const long& serialNumber, const long& version,
const long& notBefore, const long& notAfter)
{
try {
/* Initialize X509 */
X509* x509 = nullptr;
if (!(x509 = X509_new())) {
throw std::runtime_error("Couldn't initialize X509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize EVP_PKEY */
std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY*)> keyStore { EVP_PKEY_new(), EVP_PKEY_free };
if (keyStore == nullptr) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Sign rsa key */
if (!EVP_PKEY_assign_RSA(keyStore.get(), rsa)) {
throw std::runtime_error("Couldn't assign rsa. EVP_PKEY_assign_RSA(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set certificate serial number. */
if (!ASN1_INTEGER_set(X509_get_serialNumber(x509), serialNumber)) {
throw std::runtime_error("Couldn't set serial number. ASN1_INTEGER_set(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set certificate version */
if (!X509_set_version(x509, version)) {
throw std::runtime_error("Couldn't set version. X509_set_version(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set certificate creation and expiration date */
X509_gmtime_adj(X509_get_notBefore(x509), notBefore);
X509_gmtime_adj(X509_get_notAfter(x509), notAfter);
/* Set certificate public key */
if (!X509_set_pubkey(x509, keyStore.get())) {
throw std::runtime_error("Couldn't set public key. X509_set_pubkey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize X509_NAME */
X509_NAME* x509Name = X509_get_subject_name(x509);
if (x509Name == nullptr) {
throw std::runtime_error("Couldn't initialize X509_NAME. X509_NAME(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Add additional data to certificate */
QMapIterator<QByteArray, QByteArray> certificateInformationList(additionalData);
while (certificateInformationList.hasNext()) {
/* Read next item in list */
certificateInformationList.next();
/* Set additional data */
if (!X509_NAME_add_entry_by_txt(x509Name, certificateInformationList.key().data(), MBSTRING_UTF8, reinterpret_cast<const unsigned char*>(certificateInformationList.value().data()), -1, -1, 0)) {
throw std::runtime_error("Couldn't set additional information. X509_NAME_add_entry_by_txt(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
/* Set certificate info */
if (!X509_set_issuer_name(x509, x509Name)) {
throw std::runtime_error("Couldn't set issuer name. X509_set_issuer_name(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Sign certificate */
if (!X509_sign(x509, keyStore.get(), md)) {
throw std::runtime_error("Couldn't sign X509. X509_sign(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write certificate file on disk. If needed */
if (!certificateFileName.isEmpty()) {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(certificateFileName.data(), "w+"), BIO_free_all };
if (certFile == nullptr) {
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write file on disk */
if (!PEM_write_bio_X509(certFile.get(), x509)) {
throw std::runtime_error("Couldn't write certificate file on disk. PEM_write_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
return x509;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}

View File

@@ -0,0 +1,176 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QX509Store.h"
QSimpleCrypto::QX509Store::QX509Store()
{
}
///
/// \brief QSimpleCrypto::QX509::addCertificateToStore
/// \param store - OpenSSL X509_STORE.
/// \param x509 - OpenSSL X509.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::addCertificateToStore(X509_STORE* store, X509* x509)
{
if (!X509_STORE_add_cert(store, x509)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't add certificate to X509_STORE. X509_STORE_add_cert(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::addLookup
/// \param store - OpenSSL X509_STORE.
/// \param method - OpenSSL X509_LOOKUP_METHOD. Example: X509_LOOKUP_file.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::addLookup(X509_STORE* store, X509_LOOKUP_METHOD* method)
{
if (!X509_STORE_add_lookup(store, method)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't add lookup to X509_STORE. X509_STORE_add_lookup(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setCertificateDepth
/// \param store - OpenSSL X509_STORE.
/// \param depth - That is the maximum number of untrusted CA certificates that can appear in a chain. Example: 0.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setDepth(X509_STORE* store, const int& depth)
{
if (!X509_STORE_set_depth(store, depth)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set depth for X509_STORE. X509_STORE_set_depth(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setFlag
/// \param store - OpenSSL X509_STORE.
/// \param flag - The verification flags consists of zero or more of the following flags ored together. Example: X509_V_FLAG_CRL_CHECK.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setFlag(X509_STORE* store, const unsigned long& flag)
{
if (!X509_STORE_set_flags(store, flag)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set flag for X509_STORE. X509_STORE_set_flags(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setFlag
/// \param store - OpenSSL X509_STORE.
/// \param purpose - Verification purpose in param to purpose. Example: X509_PURPOSE_ANY.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setPurpose(X509_STORE* store, const int& purpose)
{
if (!X509_STORE_set_purpose(store, purpose)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set purpose for X509_STORE. X509_STORE_set_purpose(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setTrust
/// \param store - OpenSSL X509_STORE.
/// \param trust - Trust Level. Example: X509_TRUST_SSL_SERVER.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setTrust(X509_STORE* store, const int& trust)
{
if (!X509_STORE_set_trust(store, trust)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set trust for X509_STORE. X509_STORE_set_trust(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setDefaultPaths
/// \param store - OpenSSL X509_STORE.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setDefaultPaths(X509_STORE* store)
{
if (!X509_STORE_set_default_paths(store)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set default paths for X509_STORE. X509_STORE_set_default_paths(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileName - File name. Example: "caCertificate.pem".
/// \param dirPath - Path to file. Example: "path/To/File".
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QByteArray& fileName, const QByteArray& dirPath)
{
if (!X509_STORE_load_locations(store, fileName, dirPath)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param file - Qt QFile that will be loaded.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QFile& file)
{
/* Initialize QFileInfo to read information about file */
QFileInfo info(file);
if (!X509_STORE_load_locations(store, info.fileName().toLocal8Bit(), info.absoluteDir().path().toLocal8Bit())) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileInfo - Qt QFileInfo.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QFileInfo& fileInfo)
{
if (!X509_STORE_load_locations(store, fileInfo.fileName().toLocal8Bit(), fileInfo.absoluteDir().path().toLocal8Bit())) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}

View File

@@ -1,50 +0,0 @@
# User settings
*.user
macOSPackage/
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.dll
*.dylib
# Qt-es
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
qrc_*.cpp
ui_*.h
Makefile*
*build-*
# QtCreator
*.autosave
# QtCtreator Qml
*.qmlproject.user
*.qmlproject.user.*
# QtCtreator CMake
CMakeLists.txt.user*
# MACOS files
.DS_Store
._.DS_Store
._*
# tmp files
*.*~
# Certificates
*.p12

View File

@@ -1,3 +0,0 @@
load(qt_build_config)
MODULE_VERSION = 4.3.1

View File

@@ -1 +0,0 @@
load(qt_parts)

View File

@@ -1,46 +0,0 @@
# QSsh
this project is base on Qt-creator-open-source-4.3.1
project is at
`http://code.qt.io/cgit/qt-creator/qt-creator.git/`
you can download code zip at
`http://download.qt.io/official_releases/qtcreator/4.3/4.3.1/`
## Getting Started
> * For linux user, if your Qt is installed through package manager tools such "apt-get", make sure that you have installed the Qt5 develop package *qtbase5-private-dev*
### Usage(1): Use QtSsh as Qt5's addon module
#### Building the module
> **Note**: Perl is needed in this step.
* Download the source code.
* Put the source code in any directory you like
* Go to top directory of the project in a terminal and run
```
qmake
make
make install
```
The library, the header files, and others will be installed to your system.
#### Import the module
` QT += ssh`
#### Include Headerfile
` #include<QtSsh/sshconnection.h>`
#### Close qtc.ssh log
` QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false")`

View File

@@ -1,2 +0,0 @@
TEMPLATE = subdirs
SUBDIRS = gitlab

View File

@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/">
<file>Qml/Main.qml</file>
</qresource>
</RCC>

View File

@@ -1,51 +0,0 @@
import QtQuick 2.0
import QtQuick.Controls 2.0
import Ssh 1.0
Item {
width: 1024
height: 768
TextField {
id: input
x: 104
y: 44
width: 482
height: 40
implicitWidth: 200
selectByMouse: true
text: "https://www.zhihu.com"
}
function get(url) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
console.log(xhr.responseXML, xhr.responseText.toString())
} else if (xhr.readyState === XMLHttpRequest) {
}
}
xhr.open('GET', url)
xhr.send()
}
Button {
x: 627
y: 44
text: "get"
onClicked: {
get(input.text)
}
}
Button {
id: button
x: 104
y: 170
text: qsTr("Ssh")
onClicked: ssh.connectToHost()
}
Ssh {
id: ssh
}
}

View File

@@ -1,17 +0,0 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include "Ssh.hpp"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<Ssh> ("Ssh", 1, 0, "Ssh");
QQuickView view;
view.setSource(QUrl("qrc:/Qml/Main.qml"));
view.show();
return app.exec();
}

View File

@@ -1,61 +0,0 @@
#include "Ssh.hpp"
#include <QDir>
#include <QDebug>
#include <QLoggingCategory>
Ssh::Ssh(QObject *parent) : QObject(parent) {
//关掉qtc.ssh中的各种打印信息
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
mParams.host="ftb.autoio.org";
mParams.userName = "ftb";
mParams.port = 11122;
mParams.privateKeyFile = QDir::homePath() + QStringLiteral("/.ssh/id_rsa");
mParams.timeout = 5;
mParams.authenticationType = SshConnectionParameters::AuthenticationTypePublicKey;
mParams.options = SshIgnoreDefaultProxy;
mParams.hostKeyCheckingMode = SshHostKeyCheckingNone;
mConnections = std::make_shared<SshConnection>(mParams);
connect(mConnections.get(), &SshConnection::error, [&](QSsh::SshError){
qWarning() << "Error: " << mConnections->errorString();
});
connect(mConnections.get(), &SshConnection::connected, [&](){
qWarning() << "Connected";
create();
});
connect(mConnections.get(), &SshConnection::disconnected, [](){
qWarning() << "Disconnected";
});
connect(mConnections.get(), &SshConnection::dataAvailable, [](const QString &message){
qWarning() << "Message: " << message;
});
}
void Ssh::connectToHost() {
mConnections->connectToHost();
}
void Ssh::create() {
mRemoteProcess = mConnections->createRemoteProcess(QString::fromLatin1("/bin/ls -a").toUtf8());
if (!mRemoteProcess) {
qWarning() << QLatin1String("Error: UnmRemoteProcess SSH connection creates remote process.");
return;
}
connect(mRemoteProcess.data(), &SshRemoteProcess::started, [&](){
qWarning() << "started";
});
connect(mRemoteProcess.data(), &SshRemoteProcess::readyReadStandardOutput, [&](){
qWarning() << "StandardOutput";
qWarning() << QString::fromLatin1(mRemoteProcess->readAllStandardOutput()).split('\n');
});
connect(mRemoteProcess.data(), &SshRemoteProcess::readyReadStandardError, [&](){
qWarning() << "StandardError" << mRemoteProcess->readAllStandardError();
});
connect(mRemoteProcess.data(), &SshRemoteProcess::closed, [&](int exitStatus){
qWarning() << "Exit" << exitStatus;
});
mRemoteProcess->start();
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include <memory>
#include <cstdlib>
#include <functional>
#include <QObject>
#include <QtSsh/sshconnection.h>
#include <QtSsh/sshremoteprocess.h>
using namespace QSsh;
class Ssh : public QObject {
Q_OBJECT
public:
explicit Ssh(QObject *parent = nullptr);
Q_INVOKABLE void connectToHost();
void create();
private:
SshConnectionParameters mParams;
std::shared_ptr<SshConnection> mConnections;
QSharedPointer<SshRemoteProcess> mRemoteProcess;
};

View File

@@ -1,29 +0,0 @@
QT += quick network ssh
CONFIG += c++11
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
#DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += Src/Main.cpp \
Src/Ssh.cpp
RESOURCES += Qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
HEADERS += \
Src/Ssh.hpp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,50 +0,0 @@
INCLUDEPATH *= $$PWD/..
HEADERS += $$PWD/botan.h
SOURCES += $$PWD/botan.cpp
CONFIG += exceptions
DEPENDPATH += .
DEFINES += BOTAN_DLL=
unix:DEFINES += BOTAN_TARGET_OS_HAS_GETTIMEOFDAY BOTAN_HAS_ALLOC_MMAP \
BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM BOTAN_HAS_ENTROPY_SRC_EGD BOTAN_HAS_ENTROPY_SRC_FTW \
BOTAN_HAS_ENTROPY_SRC_UNIX BOTAN_HAS_MUTEX_PTHREAD BOTAN_HAS_PIPE_UNIXFD_IO
*linux*:DEFINES += BOTAN_TARGET_OS_IS_LINUX BOTAN_TARGET_OS_HAS_CLOCK_GETTIME \
BOTAN_TARGET_OS_HAS_DLOPEN BOTAN_TARGET_OS_HAS_GMTIME_R BOTAN_TARGET_OS_HAS_POSIX_MLOCK \
BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE BOTAN_HAS_DYNAMIC_LOADER
macx:DEFINES += BOTAN_TARGET_OS_IS_DARWIN
*g++*:DEFINES += BOTAN_BUILD_COMPILER_IS_GCC
*clang*:DEFINES += BOTAN_BUILD_COMPILER_IS_CLANG
*icc*:DEFINES += BOTAN_BUILD_COMPILER_IS_INTEL
CONFIG(x86_64):DEFINES += BOTAN_TARGET_ARCH_IS_X86_64
win32 {
DEFINES += BOTAN_TARGET_OS_IS_WINDOWS \
BOTAN_TARGET_OS_HAS_LOADLIBRARY BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME \
BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK \
BOTAN_HAS_ENTROPY_SRC_CAPI BOTAN_HAS_ENTROPY_SRC_WIN32 \
BOTAN_HAS_MUTEX_WIN32
msvc {
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHs
QMAKE_CXXFLAGS += -wd4251 -wd4290 -wd4250 -wd4297 -wd4267 -wd4334
DEFINES += BOTAN_BUILD_COMPILER_IS_MSVC BOTAN_TARGET_OS_HAS_GMTIME_S _SCL_SECURE_NO_WARNINGS
} else {
QMAKE_CFLAGS += -fpermissive -finline-functions -Wno-long-long
QMAKE_CXXFLAGS += -fpermissive -finline-functions -Wno-long-long
}
LIBS += -ladvapi32 -luser32
}
unix:*-g++* {
QMAKE_CFLAGS += -fPIC -fpermissive -finline-functions -Wno-long-long
QMAKE_CXXFLAGS += -fPIC -fpermissive -finline-functions -Wno-long-long
}
linux*|freebsd* {
LIBS += -lrt $$QMAKE_LIBS_DYNLOAD
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,49 +0,0 @@
.. _license:
.. highlight:: none
License
========================================
Botan (http://botan.randombit.net/) is distributed under these terms::
Copyright (C) 1999-2011 Jack Lloyd
2001 Peter J Jones
2004-2007 Justin Karneges
2004 Vaclav Ovsik
2005 Matthew Gregan
2005-2006 Matt Johnston
2006 Luca Piccarreta
2007 Yves Jerschow
2007-2008 FlexSecure GmbH
2007-2008 Technische Universitat Darmstadt
2007-2008 Falko Strenzke
2007-2008 Martin Doering
2007 Manuel Hartl
2007 Christoph Ludwig
2007 Patrick Sona
2010 Olivier de Gaalon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,15 +0,0 @@
Botan 1.10.2, 2012-06-17
http://botan.randombit.net/
Botan is a C++ class library for performing a wide variety of
cryptographic operations. It is released under the 2 clause BSD
license; see doc/license.txt for the specifics. You can file bugs in
Bugzilla (http://bugs.randombit.net/) or by sending a report to the
botan-devel mailing list. More information about the mailing list is
at http://lists.randombit.net/mailman/listinfo/botan-devel/
You can find documentation online at http://botan.randombit.net/ as
well as in the doc directory in the distribution. Several examples can
be found in doc/examples as well.
Jack Lloyd (lloyd@randombit.net)

View File

@@ -1,3 +0,0 @@
TEMPLATE = subdirs
SUBDIRS = ssh

View File

@@ -1,972 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftpchannel.h"
#include "sftpchannel_p.h"
#include "sshexception_p.h"
#include "sshincomingpacket_p.h"
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
#include <QDir>
#include <QFile>
/*!
\class QSsh::SftpChannel
\brief The SftpChannel class provides SFTP operations.
Objects are created via SshConnection::createSftpChannel().
The channel needs to be initialized with
a call to initialize() and is closed via closeChannel(). After closing
a channel, no more operations are possible. It cannot be re-opened
using initialize(); use SshConnection::createSftpChannel() if you need
a new one.
After the initialized() signal has been emitted, operations can be started.
All SFTP operations are asynchronous (non-blocking) and can be in-flight
simultaneously (though callers must ensure that concurrently running jobs
are independent of each other, e.g. they must not write to the same file).
Operations are identified by their job id, which is returned by
the respective member function. If the function can right away detect that
the operation cannot succeed, it returns SftpInvalidJob. If an error occurs
later, the finished() signal is emitted for the respective job with a
non-empty error string.
Note that directory names must not have a trailing slash.
*/
namespace QSsh {
namespace Internal {
namespace {
const quint32 ProtocolVersion = 3;
QString errorMessage(const QString &serverMessage,
const QString &alternativeMessage)
{
return serverMessage.isEmpty() ? alternativeMessage : serverMessage;
}
QString errorMessage(const SftpStatusResponse &response,
const QString &alternativeMessage)
{
return response.status == SSH_FX_OK ? QString()
: errorMessage(response.errorString, alternativeMessage);
}
} // anonymous namespace
} // namespace Internal
SftpChannel::SftpChannel(quint32 channelId,
Internal::SshSendFacility &sendFacility)
: d(new Internal::SftpChannelPrivate(channelId, sendFacility, this))
{
connect(d, &Internal::SftpChannelPrivate::initialized,
this, &SftpChannel::initialized, Qt::QueuedConnection);
connect(d, &Internal::SftpChannelPrivate::channelError,
this, &SftpChannel::channelError, Qt::QueuedConnection);
connect(d, &Internal::SftpChannelPrivate::dataAvailable,
this, &SftpChannel::dataAvailable, Qt::QueuedConnection);
connect(d, &Internal::SftpChannelPrivate::fileInfoAvailable,
this, &SftpChannel::fileInfoAvailable, Qt::QueuedConnection);
connect(d, &Internal::SftpChannelPrivate::finished,
this, &SftpChannel::finished, Qt::QueuedConnection);
connect(d, &Internal::SftpChannelPrivate::closed,
this, &SftpChannel::closed, Qt::QueuedConnection);
}
SftpChannel::State SftpChannel::state() const
{
switch (d->channelState()) {
case Internal::AbstractSshChannel::Inactive:
return Uninitialized;
case Internal::AbstractSshChannel::SessionRequested:
return Initializing;
case Internal::AbstractSshChannel::CloseRequested:
return Closing;
case Internal::AbstractSshChannel::Closed:
return Closed;
case Internal::AbstractSshChannel::SessionEstablished:
return d->m_sftpState == Internal::SftpChannelPrivate::Initialized
? Initialized : Initializing;
default:
Q_ASSERT(!"Oh no, we forgot to handle a channel state!");
return Closed; // For the compiler.
}
}
void SftpChannel::initialize()
{
d->requestSessionStart();
d->m_sftpState = Internal::SftpChannelPrivate::SubsystemRequested;
}
void SftpChannel::closeChannel()
{
d->closeChannel();
}
SftpJobId SftpChannel::statFile(const QString &path)
{
return d->createJob(Internal::SftpStatFile::Ptr(
new Internal::SftpStatFile(++d->m_nextJobId, path)));
}
SftpJobId SftpChannel::listDirectory(const QString &path)
{
return d->createJob(Internal::SftpListDir::Ptr(
new Internal::SftpListDir(++d->m_nextJobId, path)));
}
SftpJobId SftpChannel::createDirectory(const QString &path)
{
return d->createJob(Internal::SftpMakeDir::Ptr(
new Internal::SftpMakeDir(++d->m_nextJobId, path)));
}
SftpJobId SftpChannel::removeDirectory(const QString &path)
{
return d->createJob(Internal::SftpRmDir::Ptr(
new Internal::SftpRmDir(++d->m_nextJobId, path)));
}
SftpJobId SftpChannel::removeFile(const QString &path)
{
return d->createJob(Internal::SftpRm::Ptr(
new Internal::SftpRm(++d->m_nextJobId, path)));
}
SftpJobId SftpChannel::renameFileOrDirectory(const QString &oldPath,
const QString &newPath)
{
return d->createJob(Internal::SftpRename::Ptr(
new Internal::SftpRename(++d->m_nextJobId, oldPath, newPath)));
}
SftpJobId SftpChannel::createLink(const QString &filePath, const QString &target)
{
return d->createJob(Internal::SftpCreateLink::Ptr(
new Internal::SftpCreateLink(++d->m_nextJobId, filePath, target)));
}
SftpJobId SftpChannel::createFile(const QString &path, SftpOverwriteMode mode)
{
return d->createJob(Internal::SftpCreateFile::Ptr(
new Internal::SftpCreateFile(++d->m_nextJobId, path, mode)));
}
SftpJobId SftpChannel::uploadFile(const QString &localFilePath,
const QString &remoteFilePath, SftpOverwriteMode mode)
{
QSharedPointer<QFile> localFile(new QFile(localFilePath));
if (!localFile->open(QIODevice::ReadOnly))
return SftpInvalidJob;
return d->createJob(Internal::SftpUploadFile::Ptr(
new Internal::SftpUploadFile(++d->m_nextJobId, remoteFilePath, localFile, mode)));
}
SftpJobId SftpChannel::downloadFile(const QString &remoteFilePath,
const QString &localFilePath, SftpOverwriteMode mode)
{
QSharedPointer<QFile> localFile(new QFile(localFilePath));
if (mode == SftpSkipExisting && localFile->exists())
return SftpInvalidJob;
QIODevice::OpenMode openMode = QIODevice::WriteOnly;
if (mode == SftpOverwriteExisting)
openMode |= QIODevice::Truncate;
else if (mode == SftpAppendToExisting)
openMode |= QIODevice::Append;
if (!localFile->open(openMode))
return SftpInvalidJob;
return d->createJob(Internal::SftpDownload::Ptr(
new Internal::SftpDownload(++d->m_nextJobId, remoteFilePath, localFile)));
}
SftpJobId SftpChannel::uploadDir(const QString &localDirPath,
const QString &remoteParentDirPath)
{
if (state() != Initialized)
return SftpInvalidJob;
const QDir localDir(localDirPath);
if (!localDir.exists() || !localDir.isReadable())
return SftpInvalidJob;
const Internal::SftpUploadDir::Ptr uploadDirOp(
new Internal::SftpUploadDir(++d->m_nextJobId));
const QString remoteDirPath
= remoteParentDirPath + QLatin1Char('/') + localDir.dirName();
const Internal::SftpMakeDir::Ptr mkdirOp(
new Internal::SftpMakeDir(++d->m_nextJobId, remoteDirPath, uploadDirOp));
uploadDirOp->mkdirsInProgress.insert(mkdirOp,
Internal::SftpUploadDir::Dir(localDirPath, remoteDirPath));
d->createJob(mkdirOp);
return uploadDirOp->jobId;
}
SftpChannel::~SftpChannel()
{
delete d;
}
namespace Internal {
SftpChannelPrivate::SftpChannelPrivate(quint32 channelId,
SshSendFacility &sendFacility, SftpChannel *sftp)
: AbstractSshChannel(channelId, sendFacility),
m_nextJobId(0), m_sftpState(Inactive), m_sftp(sftp)
{
}
SftpJobId SftpChannelPrivate::createJob(const AbstractSftpOperation::Ptr &job)
{
if (m_sftp->state() != SftpChannel::Initialized)
return SftpInvalidJob;
m_jobs.insert(job->jobId, job);
sendData(job->initialPacket(m_outgoingPacket).rawData());
return job->jobId;
}
void SftpChannelPrivate::handleChannelSuccess()
{
if (channelState() == CloseRequested)
return;
qCDebug(sshLog, "sftp subsystem initialized");
sendData(m_outgoingPacket.generateInit(ProtocolVersion).rawData());
m_sftpState = InitSent;
}
void SftpChannelPrivate::handleChannelFailure()
{
if (channelState() == CloseRequested)
return;
if (m_sftpState != SubsystemRequested) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_FAILURE packet.");
}
emit channelError(tr("Server could not start SFTP subsystem."));
closeChannel();
}
void SftpChannelPrivate::handleChannelDataInternal(const QByteArray &data)
{
if (channelState() == CloseRequested)
return;
m_incomingData += data;
m_incomingPacket.consumeData(m_incomingData);
while (m_incomingPacket.isComplete()) {
handleCurrentPacket();
m_incomingPacket.clear();
m_incomingPacket.consumeData(m_incomingData);
}
}
void SftpChannelPrivate::handleChannelExtendedDataInternal(quint32 type,
const QByteArray &data)
{
qCWarning(sshLog, "Unexpected extended data '%s' of type %d on SFTP channel.",
data.data(), type);
}
void SftpChannelPrivate::handleExitStatus(const SshChannelExitStatus &exitStatus)
{
qCDebug(sshLog, "Remote SFTP service exited with exit code %d", exitStatus.exitStatus);
if (channelState() == CloseRequested || channelState() == Closed)
return;
emit channelError(tr("The SFTP server finished unexpectedly with exit code %1.")
.arg(exitStatus.exitStatus));
// Note: According to the specs, the server must close the channel after this happens,
// but OpenSSH doesn't do that, so we need to initiate the closing procedure ourselves.
closeChannel();
}
void SftpChannelPrivate::handleExitSignal(const SshChannelExitSignal &signal)
{
emit channelError(tr("The SFTP server crashed: %1.").arg(signal.error));
closeChannel(); // See above.
}
void SftpChannelPrivate::handleCurrentPacket()
{
qCDebug(sshLog, "Handling SFTP packet of type %d", m_incomingPacket.type());
switch (m_incomingPacket.type()) {
case SSH_FXP_VERSION:
handleServerVersion();
break;
case SSH_FXP_HANDLE:
handleHandle();
break;
case SSH_FXP_NAME:
handleName();
break;
case SSH_FXP_STATUS:
handleStatus();
break;
case SSH_FXP_DATA:
handleReadData();
break;
case SSH_FXP_ATTRS:
handleAttrs();
break;
default:
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet.",
tr("Unexpected packet of type %1.").arg(m_incomingPacket.type()));
}
}
void SftpChannelPrivate::handleServerVersion()
{
checkChannelActive();
if (m_sftpState != InitSent) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_VERSION packet.");
}
qCDebug(sshLog, "sftp init received");
const quint32 serverVersion = m_incomingPacket.extractServerVersion();
if (serverVersion != ProtocolVersion) {
emit channelError(tr("Protocol version mismatch: Expected %1, got %2")
.arg(serverVersion).arg(ProtocolVersion));
closeChannel();
} else {
m_sftpState = Initialized;
emit initialized();
}
}
void SftpChannelPrivate::handleHandle()
{
const SftpHandleResponse &response = m_incomingPacket.asHandleResponse();
JobMap::Iterator it = lookupJob(response.requestId);
const QSharedPointer<AbstractSftpOperationWithHandle> job
= it.value().dynamicCast<AbstractSftpOperationWithHandle>();
if (job.isNull()) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_HANDLE packet.");
}
if (job->state != AbstractSftpOperationWithHandle::OpenRequested) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_HANDLE packet.");
}
job->remoteHandle = response.handle;
job->state = AbstractSftpOperationWithHandle::Open;
switch (it.value()->type()) {
case AbstractSftpOperation::ListDir:
handleLsHandle(it);
break;
case AbstractSftpOperation::CreateFile:
handleCreateFileHandle(it);
break;
case AbstractSftpOperation::Download:
handleGetHandle(it);
break;
case AbstractSftpOperation::UploadFile:
handlePutHandle(it);
break;
default:
Q_ASSERT(!"Oh no, I forgot to handle an SFTP operation type!");
}
}
void SftpChannelPrivate::handleLsHandle(const JobMap::Iterator &it)
{
SftpListDir::Ptr op = it.value().staticCast<SftpListDir>();
sendData(m_outgoingPacket.generateReadDir(op->remoteHandle,
op->jobId).rawData());
}
void SftpChannelPrivate::handleCreateFileHandle(const JobMap::Iterator &it)
{
SftpCreateFile::Ptr op = it.value().staticCast<SftpCreateFile>();
sendData(m_outgoingPacket.generateCloseHandle(op->remoteHandle,
op->jobId).rawData());
}
void SftpChannelPrivate::handleGetHandle(const JobMap::Iterator &it)
{
SftpDownload::Ptr op = it.value().staticCast<SftpDownload>();
sendData(m_outgoingPacket.generateFstat(op->remoteHandle,
op->jobId).rawData());
op->statRequested = true;
}
void SftpChannelPrivate::handlePutHandle(const JobMap::Iterator &it)
{
SftpUploadFile::Ptr op = it.value().staticCast<SftpUploadFile>();
if (op->parentJob && op->parentJob->hasError)
sendTransferCloseHandle(op, it.key());
// OpenSSH does not implement the RFC's append functionality, so we
// have to emulate it.
if (op->mode == SftpAppendToExisting) {
sendData(m_outgoingPacket.generateFstat(op->remoteHandle,
op->jobId).rawData());
op->statRequested = true;
} else {
spawnWriteRequests(it);
}
}
void SftpChannelPrivate::handleStatus()
{
const SftpStatusResponse &response = m_incomingPacket.asStatusResponse();
qCDebug(sshLog, "%s: status = %d", Q_FUNC_INFO, response.status);
JobMap::Iterator it = lookupJob(response.requestId);
switch (it.value()->type()) {
case AbstractSftpOperation::ListDir:
handleLsStatus(it, response);
break;
case AbstractSftpOperation::Download:
handleGetStatus(it, response);
break;
case AbstractSftpOperation::UploadFile:
handlePutStatus(it, response);
break;
case AbstractSftpOperation::MakeDir:
handleMkdirStatus(it, response);
break;
case AbstractSftpOperation::StatFile:
case AbstractSftpOperation::RmDir:
case AbstractSftpOperation::Rm:
case AbstractSftpOperation::Rename:
case AbstractSftpOperation::CreateFile:
case AbstractSftpOperation::CreateLink:
handleStatusGeneric(it, response);
break;
}
}
void SftpChannelPrivate::handleStatusGeneric(const JobMap::Iterator &it,
const SftpStatusResponse &response)
{
AbstractSftpOperation::Ptr op = it.value();
const QString error = errorMessage(response, tr("Unknown error."));
emit finished(op->jobId, error);
m_jobs.erase(it);
}
void SftpChannelPrivate::handleMkdirStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response)
{
SftpMakeDir::Ptr op = it.value().staticCast<SftpMakeDir>();
QSharedPointer<SftpUploadDir> parentJob = op->parentJob;
if (parentJob == SftpUploadDir::Ptr()) {
handleStatusGeneric(it, response);
return;
}
if (parentJob->hasError) {
m_jobs.erase(it);
return;
}
typedef QMap<SftpMakeDir::Ptr, SftpUploadDir::Dir>::Iterator DirIt;
DirIt dirIt = parentJob->mkdirsInProgress.find(op);
Q_ASSERT(dirIt != parentJob->mkdirsInProgress.end());
const QString &remoteDir = dirIt.value().remoteDir;
if (response.status == SSH_FX_OK) {
emit dataAvailable(parentJob->jobId,
tr("Created remote directory \"%1\".").arg(remoteDir));
} else if (response.status == SSH_FX_FAILURE) {
emit dataAvailable(parentJob->jobId,
tr("Remote directory \"%1\" already exists.").arg(remoteDir));
} else {
parentJob->setError();
emit finished(parentJob->jobId,
tr("Error creating directory \"%1\": %2")
.arg(remoteDir, response.errorString));
m_jobs.erase(it);
return;
}
QDir localDir(dirIt.value().localDir);
const QFileInfoList &dirInfos
= localDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QFileInfo &dirInfo, dirInfos) {
const QString remoteSubDir = remoteDir + QLatin1Char('/') + dirInfo.fileName();
const SftpMakeDir::Ptr mkdirOp(
new SftpMakeDir(++m_nextJobId, remoteSubDir, parentJob));
parentJob->mkdirsInProgress.insert(mkdirOp,
SftpUploadDir::Dir(dirInfo.absoluteFilePath(), remoteSubDir));
createJob(mkdirOp);
}
const QFileInfoList &fileInfos = localDir.entryInfoList(QDir::Files);
foreach (const QFileInfo &fileInfo, fileInfos) {
QSharedPointer<QFile> localFile(new QFile(fileInfo.absoluteFilePath()));
if (!localFile->open(QIODevice::ReadOnly)) {
parentJob->setError();
emit finished(parentJob->jobId,
tr("Could not open local file \"%1\": %2")
.arg(fileInfo.absoluteFilePath(), localFile->errorString()));
m_jobs.erase(it);
return;
}
const QString remoteFilePath = remoteDir + QLatin1Char('/') + fileInfo.fileName();
SftpUploadFile::Ptr uploadFileOp(new SftpUploadFile(++m_nextJobId,
remoteFilePath, localFile, SftpOverwriteExisting, parentJob));
createJob(uploadFileOp);
parentJob->uploadsInProgress.append(uploadFileOp);
}
parentJob->mkdirsInProgress.erase(dirIt);
if (parentJob->mkdirsInProgress.isEmpty()
&& parentJob->uploadsInProgress.isEmpty())
emit finished(parentJob->jobId);
m_jobs.erase(it);
}
void SftpChannelPrivate::handleLsStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response)
{
SftpListDir::Ptr op = it.value().staticCast<SftpListDir>();
switch (op->state) {
case SftpListDir::OpenRequested:
emit finished(op->jobId, errorMessage(response.errorString,
tr("Remote directory could not be opened for reading.")));
m_jobs.erase(it);
break;
case SftpListDir::Open:
if (response.status != SSH_FX_EOF)
reportRequestError(op, errorMessage(response.errorString,
tr("Failed to list remote directory contents.")));
op->state = SftpListDir::CloseRequested;
sendData(m_outgoingPacket.generateCloseHandle(op->remoteHandle,
op->jobId).rawData());
break;
case SftpListDir::CloseRequested:
if (!op->hasError) {
const QString error = errorMessage(response,
tr("Failed to close remote directory."));
emit finished(op->jobId, error);
}
m_jobs.erase(it);
break;
default:
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_STATUS packet.");
}
}
void SftpChannelPrivate::handleGetStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response)
{
SftpDownload::Ptr op = it.value().staticCast<SftpDownload>();
switch (op->state) {
case SftpDownload::OpenRequested:
emit finished(op->jobId,
errorMessage(response.errorString,
tr("Failed to open remote file for reading.")));
m_jobs.erase(it);
break;
case SftpDownload::Open:
if (op->statRequested) {
reportRequestError(op, errorMessage(response.errorString,
tr("Failed to retrieve information on the remote file ('stat' failed).")));
sendTransferCloseHandle(op, response.requestId);
} else {
if ((response.status != SSH_FX_EOF || response.requestId != op->eofId)
&& !op->hasError)
reportRequestError(op, errorMessage(response.errorString,
tr("Failed to read remote file.")));
finishTransferRequest(it);
}
break;
case SftpDownload::CloseRequested:
Q_ASSERT(op->inFlightCount == 1);
if (!op->hasError) {
if (response.status == SSH_FX_OK)
emit finished(op->jobId);
else
reportRequestError(op, errorMessage(response.errorString,
tr("Failed to close remote file.")));
}
removeTransferRequest(it);
break;
default:
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_STATUS packet.");
}
}
void SftpChannelPrivate::handlePutStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response)
{
SftpUploadFile::Ptr job = it.value().staticCast<SftpUploadFile>();
switch (job->state) {
case SftpUploadFile::OpenRequested: {
bool emitError = false;
if (job->parentJob) {
if (!job->parentJob->hasError) {
job->parentJob->setError();
emitError = true;
}
} else {
emitError = true;
}
if (emitError) {
emit finished(job->jobId,
errorMessage(response.errorString,
tr("Failed to open remote file for writing.")));
}
m_jobs.erase(it);
break;
}
case SftpUploadFile::Open:
if (job->hasError || (job->parentJob && job->parentJob->hasError)) {
job->hasError = true;
finishTransferRequest(it);
return;
}
if (response.status == SSH_FX_OK) {
sendWriteRequest(it);
} else {
if (job->parentJob)
job->parentJob->setError();
reportRequestError(job, errorMessage(response.errorString,
tr("Failed to write remote file.")));
finishTransferRequest(it);
}
break;
case SftpUploadFile::CloseRequested:
Q_ASSERT(job->inFlightCount == 1);
if (job->hasError || (job->parentJob && job->parentJob->hasError)) {
m_jobs.erase(it);
return;
}
if (response.status == SSH_FX_OK) {
if (job->parentJob) {
job->parentJob->uploadsInProgress.removeOne(job);
if (job->parentJob->mkdirsInProgress.isEmpty()
&& job->parentJob->uploadsInProgress.isEmpty())
emit finished(job->parentJob->jobId);
} else {
emit finished(job->jobId);
}
} else {
const QString error = errorMessage(response.errorString,
tr("Failed to close remote file."));
if (job->parentJob) {
job->parentJob->setError();
emit finished(job->parentJob->jobId, error);
} else {
emit finished(job->jobId, error);
}
}
m_jobs.erase(it);
break;
default:
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_STATUS packet.");
}
}
void SftpChannelPrivate::handleName()
{
const SftpNameResponse &response = m_incomingPacket.asNameResponse();
JobMap::Iterator it = lookupJob(response.requestId);
switch (it.value()->type()) {
case AbstractSftpOperation::ListDir: {
SftpListDir::Ptr op = it.value().staticCast<SftpListDir>();
if (op->state != SftpListDir::Open) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_NAME packet.");
}
QList<SftpFileInfo> fileInfoList;
for (int i = 0; i < response.files.count(); ++i) {
const SftpFile &file = response.files.at(i);
SftpFileInfo fileInfo;
fileInfo.name = file.fileName;
attributesToFileInfo(file.attributes, fileInfo);
fileInfoList << fileInfo;
}
emit fileInfoAvailable(op->jobId, fileInfoList);
sendData(m_outgoingPacket.generateReadDir(op->remoteHandle,
op->jobId).rawData());
break;
}
default:
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_NAME packet.");
}
}
void SftpChannelPrivate::handleReadData()
{
const SftpDataResponse &response = m_incomingPacket.asDataResponse();
JobMap::Iterator it = lookupJob(response.requestId);
if (it.value()->type() != AbstractSftpOperation::Download) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_DATA packet.");
}
SftpDownload::Ptr op = it.value().staticCast<SftpDownload>();
if (op->hasError) {
finishTransferRequest(it);
return;
}
if (!op->localFile->seek(op->offsets[response.requestId])) {
reportRequestError(op, op->localFile->errorString());
finishTransferRequest(it);
return;
}
if (op->localFile->write(response.data) != response.data.size()) {
reportRequestError(op, op->localFile->errorString());
finishTransferRequest(it);
return;
}
if (op->offset >= op->fileSize && op->fileSize != 0)
finishTransferRequest(it);
else
sendReadRequest(op, response.requestId);
}
void SftpChannelPrivate::handleAttrs()
{
const SftpAttrsResponse &response = m_incomingPacket.asAttrsResponse();
JobMap::Iterator it = lookupJob(response.requestId);
SftpStatFile::Ptr statOp = it.value().dynamicCast<SftpStatFile>();
if (statOp) {
SftpFileInfo fileInfo;
fileInfo.name = QFileInfo(statOp->path).fileName();
attributesToFileInfo(response.attrs, fileInfo);
emit fileInfoAvailable(it.key(), QList<SftpFileInfo>() << fileInfo);
emit finished(it.key());
m_jobs.erase(it);
return;
}
AbstractSftpTransfer::Ptr transfer
= it.value().dynamicCast<AbstractSftpTransfer>();
if (!transfer || transfer->state != AbstractSftpTransfer::Open
|| !transfer->statRequested) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_FXP_ATTRS packet.");
}
Q_ASSERT(transfer->type() == AbstractSftpOperation::UploadFile
|| transfer->type() == AbstractSftpOperation::Download);
if (transfer->type() == AbstractSftpOperation::Download) {
SftpDownload::Ptr op = transfer.staticCast<SftpDownload>();
if (response.attrs.sizePresent) {
op->fileSize = response.attrs.size;
} else {
op->fileSize = 0;
op->eofId = op->jobId;
}
op->statRequested = false;
spawnReadRequests(op);
} else {
SftpUploadFile::Ptr op = transfer.staticCast<SftpUploadFile>();
if (op->parentJob && op->parentJob->hasError) {
op->hasError = true;
sendTransferCloseHandle(op, op->jobId);
return;
}
if (response.attrs.sizePresent) {
op->offset = response.attrs.size;
spawnWriteRequests(it);
} else {
if (op->parentJob)
op->parentJob->setError();
reportRequestError(op, tr("Cannot append to remote file: "
"Server does not support the file size attribute."));
sendTransferCloseHandle(op, op->jobId);
}
}
}
SftpChannelPrivate::JobMap::Iterator SftpChannelPrivate::lookupJob(SftpJobId id)
{
JobMap::Iterator it = m_jobs.find(id);
if (it == m_jobs.end()) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid request id in SFTP packet.");
}
return it;
}
void SftpChannelPrivate::closeHook()
{
for (JobMap::ConstIterator it = m_jobs.constBegin(); it != m_jobs.constEnd(); ++it)
emit finished(it.key(), tr("SFTP channel closed unexpectedly."));
m_jobs.clear();
m_incomingData.clear();
m_incomingPacket.clear();
emit closed();
}
void SftpChannelPrivate::handleOpenSuccessInternal()
{
qCDebug(sshLog, "SFTP session started");
m_sendFacility.sendSftpPacket(remoteChannel());
m_sftpState = SubsystemRequested;
}
void SftpChannelPrivate::handleOpenFailureInternal(const QString &reason)
{
if (channelState() != SessionRequested) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
}
emit channelError(tr("Server could not start session: %1").arg(reason));
}
void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job,
quint32 requestId)
{
Q_ASSERT(job->eofId == SftpInvalidJob);
sendData(m_outgoingPacket.generateReadFile(job->remoteHandle, job->offset,
AbstractSftpPacket::MaxDataSize, requestId).rawData());
job->offsets[requestId] = job->offset;
job->offset += AbstractSftpPacket::MaxDataSize;
if (job->offset >= job->fileSize)
job->eofId = requestId;
}
void SftpChannelPrivate::reportRequestError(const AbstractSftpOperationWithHandle::Ptr &job,
const QString &error)
{
emit finished(job->jobId, error);
job->hasError = true;
}
void SftpChannelPrivate::finishTransferRequest(const JobMap::Iterator &it)
{
AbstractSftpTransfer::Ptr job = it.value().staticCast<AbstractSftpTransfer>();
if (job->inFlightCount == 1)
sendTransferCloseHandle(job, it.key());
else
removeTransferRequest(it);
}
void SftpChannelPrivate::sendTransferCloseHandle(const AbstractSftpTransfer::Ptr &job,
quint32 requestId)
{
sendData(m_outgoingPacket.generateCloseHandle(job->remoteHandle,
requestId).rawData());
job->state = SftpDownload::CloseRequested;
}
void SftpChannelPrivate::attributesToFileInfo(const SftpFileAttributes &attributes,
SftpFileInfo &fileInfo) const
{
if (attributes.sizePresent) {
fileInfo.sizeValid = true;
fileInfo.size = attributes.size;
}
if (attributes.permissionsPresent) {
if (attributes.permissions & 0x8000) // S_IFREG
fileInfo.type = FileTypeRegular;
else if (attributes.permissions & 0x4000) // S_IFDIR
fileInfo.type = FileTypeDirectory;
else
fileInfo.type = FileTypeOther;
fileInfo.permissionsValid = true;
fileInfo.permissions = 0;
if (attributes.permissions & 00001) // S_IXOTH
fileInfo.permissions |= QFile::ExeOther;
if (attributes.permissions & 00002) // S_IWOTH
fileInfo.permissions |= QFile::WriteOther;
if (attributes.permissions & 00004) // S_IROTH
fileInfo.permissions |= QFile::ReadOther;
if (attributes.permissions & 00010) // S_IXGRP
fileInfo.permissions |= QFile::ExeGroup;
if (attributes.permissions & 00020) // S_IWGRP
fileInfo.permissions |= QFile::WriteGroup;
if (attributes.permissions & 00040) // S_IRGRP
fileInfo.permissions |= QFile::ReadGroup;
if (attributes.permissions & 00100) // S_IXUSR
fileInfo.permissions |= QFile::ExeUser | QFile::ExeOwner;
if (attributes.permissions & 00200) // S_IWUSR
fileInfo.permissions |= QFile::WriteUser | QFile::WriteOwner;
if (attributes.permissions & 00400) // S_IRUSR
fileInfo.permissions |= QFile::ReadUser | QFile::ReadOwner;
}
}
void SftpChannelPrivate::removeTransferRequest(const JobMap::Iterator &it)
{
--it.value().staticCast<AbstractSftpTransfer>()->inFlightCount;
m_jobs.erase(it);
}
void SftpChannelPrivate::sendWriteRequest(const JobMap::Iterator &it)
{
SftpUploadFile::Ptr job = it.value().staticCast<SftpUploadFile>();
QByteArray data = job->localFile->read(AbstractSftpPacket::MaxDataSize);
if (job->localFile->error() != QFile::NoError) {
if (job->parentJob)
job->parentJob->setError();
reportRequestError(job, tr("Error reading local file: %1")
.arg(job->localFile->errorString()));
finishTransferRequest(it);
} else if (data.isEmpty()) {
finishTransferRequest(it);
} else {
sendData(m_outgoingPacket.generateWriteFile(job->remoteHandle,
job->offset, data, it.key()).rawData());
job->offset += AbstractSftpPacket::MaxDataSize;
}
}
void SftpChannelPrivate::spawnWriteRequests(const JobMap::Iterator &it)
{
SftpUploadFile::Ptr op = it.value().staticCast<SftpUploadFile>();
op->calculateInFlightCount(AbstractSftpPacket::MaxDataSize);
sendWriteRequest(it);
for (int i = 1; !op->hasError && i < op->inFlightCount; ++i)
sendWriteRequest(m_jobs.insert(++m_nextJobId, op));
}
void SftpChannelPrivate::spawnReadRequests(const SftpDownload::Ptr &job)
{
job->calculateInFlightCount(AbstractSftpPacket::MaxDataSize);
sendReadRequest(job, job->jobId);
for (int i = 1; i < job->inFlightCount; ++i) {
const quint32 requestId = ++m_nextJobId;
m_jobs.insert(requestId, job);
sendReadRequest(job, requestId);
}
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,103 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sftpdefs.h"
#include "sftpincomingpacket_p.h"
#include "ssh_global.h"
#include <QByteArray>
#include <QObject>
#include <QSharedPointer>
#include <QString>
namespace QSsh {
namespace Internal {
class SftpChannelPrivate;
class SshChannelManager;
class SshSendFacility;
} // namespace Internal
class QSSH_EXPORT SftpChannel : public QObject
{
Q_OBJECT
friend class Internal::SftpChannelPrivate;
friend class Internal::SshChannelManager;
public:
typedef QSharedPointer<SftpChannel> Ptr;
enum State { Uninitialized, Initializing, Initialized, Closing, Closed };
State state() const;
void initialize();
void closeChannel();
SftpJobId statFile(const QString &path);
SftpJobId listDirectory(const QString &dirPath);
SftpJobId createDirectory(const QString &dirPath);
SftpJobId removeDirectory(const QString &dirPath);
SftpJobId removeFile(const QString &filePath);
SftpJobId renameFileOrDirectory(const QString &oldPath,
const QString &newPath);
SftpJobId createFile(const QString &filePath, SftpOverwriteMode mode);
SftpJobId createLink(const QString &filePath, const QString &target);
SftpJobId uploadFile(const QString &localFilePath,
const QString &remoteFilePath, SftpOverwriteMode mode);
SftpJobId downloadFile(const QString &remoteFilePath,
const QString &localFilePath, SftpOverwriteMode mode);
SftpJobId uploadDir(const QString &localDirPath,
const QString &remoteParentDirPath);
~SftpChannel();
signals:
void initialized();
void channelError(const QString &reason);
void closed();
// error.isEmpty <=> finished successfully
void finished(QSsh::SftpJobId job, const QString &error = QString());
// TODO: Also emit for each file copied by uploadDir().
void dataAvailable(QSsh::SftpJobId job, const QString &data);
/*
* This signal is emitted as a result of:
* - statFile() (with the list having exactly one element)
* - listDirectory() (potentially more than once)
*/
void fileInfoAvailable(QSsh::SftpJobId job, const QList<QSsh::SftpFileInfo> &fileInfoList);
private:
SftpChannel(quint32 channelId, Internal::SshSendFacility &sendFacility);
Internal::SftpChannelPrivate *d;
};
} // namespace QSsh

View File

@@ -1,124 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sftpdefs.h"
#include "sftpincomingpacket_p.h"
#include "sftpoperation_p.h"
#include "sftpoutgoingpacket_p.h"
#include "sshchannel_p.h"
#include <QByteArray>
#include <QMap>
namespace QSsh {
class SftpChannel;
namespace Internal {
class SftpChannelPrivate : public AbstractSshChannel
{
Q_OBJECT
friend class QSsh::SftpChannel;
public:
enum SftpState { Inactive, SubsystemRequested, InitSent, Initialized };
signals:
void initialized();
void channelError(const QString &reason);
void closed();
void finished(QSsh::SftpJobId job, const QString &error = QString());
void dataAvailable(QSsh::SftpJobId job, const QString &data);
void fileInfoAvailable(QSsh::SftpJobId job, const QList<QSsh::SftpFileInfo> &fileInfoList);
private:
typedef QMap<SftpJobId, AbstractSftpOperation::Ptr> JobMap;
SftpChannelPrivate(quint32 channelId, SshSendFacility &sendFacility,
SftpChannel *sftp);
SftpJobId createJob(const AbstractSftpOperation::Ptr &job);
virtual void handleChannelSuccess();
virtual void handleChannelFailure();
virtual void handleOpenSuccessInternal();
virtual void handleOpenFailureInternal(const QString &reason);
virtual void handleChannelDataInternal(const QByteArray &data);
virtual void handleChannelExtendedDataInternal(quint32 type,
const QByteArray &data);
virtual void handleExitStatus(const SshChannelExitStatus &exitStatus);
virtual void handleExitSignal(const SshChannelExitSignal &signal);
virtual void closeHook();
void handleCurrentPacket();
void handleServerVersion();
void handleHandle();
void handleStatus();
void handleName();
void handleReadData();
void handleAttrs();
void handleStatusGeneric(const JobMap::Iterator &it,
const SftpStatusResponse &response);
void handleMkdirStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response);
void handleLsStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response);
void handleGetStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response);
void handlePutStatus(const JobMap::Iterator &it,
const SftpStatusResponse &response);
void handleLsHandle(const JobMap::Iterator &it);
void handleCreateFileHandle(const JobMap::Iterator &it);
void handleGetHandle(const JobMap::Iterator &it);
void handlePutHandle(const JobMap::Iterator &it);
void spawnReadRequests(const SftpDownload::Ptr &job);
void spawnWriteRequests(const JobMap::Iterator &it);
void sendReadRequest(const SftpDownload::Ptr &job, quint32 requestId);
void sendWriteRequest(const JobMap::Iterator &it);
void finishTransferRequest(const JobMap::Iterator &it);
void removeTransferRequest(const JobMap::Iterator &it);
void reportRequestError(const AbstractSftpOperationWithHandle::Ptr &job,
const QString &error);
void sendTransferCloseHandle(const AbstractSftpTransfer::Ptr &job,
quint32 requestId);
void attributesToFileInfo(const SftpFileAttributes &attributes, SftpFileInfo &fileInfo) const;
JobMap::Iterator lookupJob(SftpJobId id);
JobMap m_jobs;
SftpOutgoingPacket m_outgoingPacket;
SftpIncomingPacket m_incomingPacket;
QByteArray m_incomingData;
SftpJobId m_nextJobId;
SftpState m_sftpState;
SftpChannel *m_sftp;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,28 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftpdefs.h"
namespace QSsh { const SftpJobId SftpInvalidJob = 0; }

View File

@@ -1,59 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssh_global.h"
#include <QFile>
#include <QString>
namespace QSsh {
typedef quint32 SftpJobId;
QSSH_EXPORT extern const SftpJobId SftpInvalidJob;
enum SftpOverwriteMode {
SftpOverwriteExisting, SftpAppendToExisting, SftpSkipExisting
};
enum SftpFileType { FileTypeRegular, FileTypeDirectory, FileTypeOther, FileTypeUnknown };
class QSSH_EXPORT SftpFileInfo
{
public:
SftpFileInfo() : type(FileTypeUnknown), sizeValid(false), permissionsValid(false) { }
QString name;
SftpFileType type;
quint64 size;
QFile::Permissions permissions;
// The RFC allows an SFTP server not to support any file attributes beyond the name.
bool sizeValid;
bool permissionsValid;
};
} // namespace QSsh

View File

@@ -1,383 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftpfilesystemmodel.h"
#include "sftpchannel.h"
#include "sshconnection.h"
#include "sshconnectionmanager.h"
#include <QFileInfo>
#include <QHash>
#include <QIcon>
#include <QList>
#include <QString>
namespace QSsh {
namespace Internal {
namespace {
class SftpDirNode;
class SftpFileNode
{
public:
SftpFileNode() : parent(0) { }
virtual ~SftpFileNode() { }
QString path;
SftpFileInfo fileInfo;
SftpDirNode *parent;
};
class SftpDirNode : public SftpFileNode
{
public:
SftpDirNode() : lsState(LsNotYetCalled) { }
~SftpDirNode() { qDeleteAll(children); }
enum { LsNotYetCalled, LsRunning, LsFinished } lsState;
QList<SftpFileNode *> children;
};
typedef QHash<SftpJobId, SftpDirNode *> DirNodeHash;
SftpFileNode *indexToFileNode(const QModelIndex &index)
{
return static_cast<SftpFileNode *>(index.internalPointer());
}
SftpDirNode *indexToDirNode(const QModelIndex &index)
{
SftpFileNode * const fileNode = indexToFileNode(index);
QSSH_ASSERT(fileNode);
return dynamic_cast<SftpDirNode *>(fileNode);
}
} // anonymous namespace
class SftpFileSystemModelPrivate
{
public:
SshConnection *sshConnection;
SftpChannel::Ptr sftpChannel;
QString rootDirectory;
SftpFileNode *rootNode;
SftpJobId statJobId;
DirNodeHash lsOps;
QList<SftpJobId> externalJobs;
};
} // namespace Internal
using namespace Internal;
SftpFileSystemModel::SftpFileSystemModel(QObject *parent)
: QAbstractItemModel(parent), d(new SftpFileSystemModelPrivate)
{
d->sshConnection = 0;
d->rootDirectory = QLatin1Char('/');
d->rootNode = 0;
d->statJobId = SftpInvalidJob;
}
SftpFileSystemModel::~SftpFileSystemModel()
{
shutDown();
delete d;
}
void SftpFileSystemModel::setSshConnection(const SshConnectionParameters &sshParams)
{
QSSH_ASSERT_AND_RETURN(!d->sshConnection);
d->sshConnection = QSsh::acquireConnection(sshParams);
connect(d->sshConnection, &SshConnection::error,
this, &SftpFileSystemModel::handleSshConnectionFailure);
if (d->sshConnection->state() == SshConnection::Connected) {
handleSshConnectionEstablished();
return;
}
connect(d->sshConnection, &SshConnection::connected,
this, &SftpFileSystemModel::handleSshConnectionEstablished);
if (d->sshConnection->state() == SshConnection::Unconnected)
d->sshConnection->connectToHost();
}
void SftpFileSystemModel::setRootDirectory(const QString &path)
{
beginResetModel();
d->rootDirectory = path;
delete d->rootNode;
d->rootNode = 0;
d->lsOps.clear();
d->statJobId = SftpInvalidJob;
endResetModel();
statRootDirectory();
}
QString SftpFileSystemModel::rootDirectory() const
{
return d->rootDirectory;
}
SftpJobId SftpFileSystemModel::downloadFile(const QModelIndex &index, const QString &targetFilePath)
{
QSSH_ASSERT_AND_RETURN_VALUE(d->rootNode, SftpInvalidJob);
const SftpFileNode * const fileNode = indexToFileNode(index);
QSSH_ASSERT_AND_RETURN_VALUE(fileNode, SftpInvalidJob);
QSSH_ASSERT_AND_RETURN_VALUE(fileNode->fileInfo.type == FileTypeRegular, SftpInvalidJob);
const SftpJobId jobId = d->sftpChannel->downloadFile(fileNode->path, targetFilePath,
SftpOverwriteExisting);
if (jobId != SftpInvalidJob)
d->externalJobs << jobId;
return jobId;
}
int SftpFileSystemModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 2; // type + name
}
QVariant SftpFileSystemModel::data(const QModelIndex &index, int role) const
{
const SftpFileNode * const node = indexToFileNode(index);
if (index.column() == 0 && role == Qt::DecorationRole) {
switch (node->fileInfo.type) {
case FileTypeRegular:
case FileTypeOther:
return QIcon(":/utils/images/unknownfile.png");
case FileTypeDirectory:
return QIcon(":/utils/images/dir.png");
case FileTypeUnknown:
return QIcon(":/utils/images/help.png"); // Shows a question mark.
}
}
if (index.column() == 1) {
if (role == Qt::DisplayRole)
return node->fileInfo.name;
if (role == PathRole)
return node->path;
}
return QVariant();
}
Qt::ItemFlags SftpFileSystemModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
QVariant SftpFileSystemModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation != Qt::Horizontal)
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
if (section == 0)
return tr("File Type");
if (section == 1)
return tr("File Name");
return QVariant();
}
QModelIndex SftpFileSystemModel::index(int row, int column, const QModelIndex &parent) const
{
if (row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount(parent))
return QModelIndex();
if (!d->rootNode)
return QModelIndex();
if (!parent.isValid())
return createIndex(row, column, d->rootNode);
const SftpDirNode * const parentNode = indexToDirNode(parent);
QSSH_ASSERT_AND_RETURN_VALUE(parentNode, QModelIndex());
QSSH_ASSERT_AND_RETURN_VALUE(row < parentNode->children.count(), QModelIndex());
SftpFileNode * const childNode = parentNode->children.at(row);
return createIndex(row, column, childNode);
}
QModelIndex SftpFileSystemModel::parent(const QModelIndex &child) const
{
if (!child.isValid()) // Don't assert on this, since the model tester tries it.
return QModelIndex();
const SftpFileNode * const childNode = indexToFileNode(child);
QSSH_ASSERT_AND_RETURN_VALUE(childNode, QModelIndex());
if (childNode == d->rootNode)
return QModelIndex();
SftpDirNode * const parentNode = childNode->parent;
if (parentNode == d->rootNode)
return createIndex(0, 0, d->rootNode);
const SftpDirNode * const grandParentNode = parentNode->parent;
QSSH_ASSERT_AND_RETURN_VALUE(grandParentNode, QModelIndex());
return createIndex(grandParentNode->children.indexOf(parentNode), 0, parentNode);
}
int SftpFileSystemModel::rowCount(const QModelIndex &parent) const
{
if (!d->rootNode)
return 0;
if (!parent.isValid())
return 1;
if (parent.column() != 0)
return 0;
SftpDirNode * const dirNode = indexToDirNode(parent);
if (!dirNode)
return 0;
if (dirNode->lsState != SftpDirNode::LsNotYetCalled)
return dirNode->children.count();
d->lsOps.insert(d->sftpChannel->listDirectory(dirNode->path), dirNode);
dirNode->lsState = SftpDirNode::LsRunning;
return 0;
}
void SftpFileSystemModel::statRootDirectory()
{
d->statJobId = d->sftpChannel->statFile(d->rootDirectory);
}
void SftpFileSystemModel::shutDown()
{
if (d->sftpChannel) {
disconnect(d->sftpChannel.data(), 0, this, 0);
d->sftpChannel->closeChannel();
d->sftpChannel.clear();
}
if (d->sshConnection) {
disconnect(d->sshConnection, 0, this, 0);
QSsh::releaseConnection(d->sshConnection);
d->sshConnection = 0;
}
delete d->rootNode;
d->rootNode = 0;
}
void SftpFileSystemModel::handleSshConnectionFailure()
{
emit connectionError(d->sshConnection->errorString());
beginResetModel();
shutDown();
endResetModel();
}
void SftpFileSystemModel::handleSftpChannelInitialized()
{
connect(d->sftpChannel.data(),
&SftpChannel::fileInfoAvailable,
this, &SftpFileSystemModel::handleFileInfo);
connect(d->sftpChannel.data(), &SftpChannel::finished,
this, &SftpFileSystemModel::handleSftpJobFinished);
statRootDirectory();
}
void SftpFileSystemModel::handleSshConnectionEstablished()
{
d->sftpChannel = d->sshConnection->createSftpChannel();
connect(d->sftpChannel.data(), &SftpChannel::initialized,
this, &SftpFileSystemModel::handleSftpChannelInitialized);
connect(d->sftpChannel.data(), &SftpChannel::channelError,
this, &SftpFileSystemModel::handleSftpChannelError);
d->sftpChannel->initialize();
}
void SftpFileSystemModel::handleSftpChannelError(const QString &reason)
{
emit connectionError(reason);
beginResetModel();
shutDown();
endResetModel();
}
void SftpFileSystemModel::handleFileInfo(SftpJobId jobId, const QList<SftpFileInfo> &fileInfoList)
{
if (jobId == d->statJobId) {
QSSH_ASSERT_AND_RETURN(!d->rootNode);
beginInsertRows(QModelIndex(), 0, 0);
d->rootNode = new SftpDirNode;
d->rootNode->path = d->rootDirectory;
d->rootNode->fileInfo = fileInfoList.first();
d->rootNode->fileInfo.name = d->rootDirectory == QLatin1String("/")
? d->rootDirectory : QFileInfo(d->rootDirectory).fileName();
endInsertRows();
return;
}
SftpDirNode * const parentNode = d->lsOps.value(jobId);
QSSH_ASSERT_AND_RETURN(parentNode);
QList<SftpFileInfo> filteredList;
foreach (const SftpFileInfo &fi, fileInfoList) {
if (fi.name != QLatin1String(".") && fi.name != QLatin1String(".."))
filteredList << fi;
}
if (filteredList.isEmpty())
return;
// In theory beginInsertRows() should suffice, but that fails to have an effect
// if rowCount() returned 0 earlier.
emit layoutAboutToBeChanged();
foreach (const SftpFileInfo &fileInfo, filteredList) {
SftpFileNode *childNode;
if (fileInfo.type == FileTypeDirectory)
childNode = new SftpDirNode;
else
childNode = new SftpFileNode;
childNode->path = parentNode->path;
if (!childNode->path.endsWith(QLatin1Char('/')))
childNode->path += QLatin1Char('/');
childNode->path += fileInfo.name;
childNode->fileInfo = fileInfo;
childNode->parent = parentNode;
parentNode->children << childNode;
}
emit layoutChanged(); // Should be endInsertRows(), see above.
}
void SftpFileSystemModel::handleSftpJobFinished(SftpJobId jobId, const QString &errorMessage)
{
if (jobId == d->statJobId) {
d->statJobId = SftpInvalidJob;
if (!errorMessage.isEmpty())
emit sftpOperationFailed(tr("Error getting \"stat\" info about \"%1\": %2")
.arg(rootDirectory(), errorMessage));
return;
}
DirNodeHash::Iterator it = d->lsOps.find(jobId);
if (it != d->lsOps.end()) {
QSSH_ASSERT(it.value()->lsState == SftpDirNode::LsRunning);
it.value()->lsState = SftpDirNode::LsFinished;
if (!errorMessage.isEmpty())
emit sftpOperationFailed(tr("Error listing contents of directory \"%1\": %2")
.arg(it.value()->path, errorMessage));
d->lsOps.erase(it);
return;
}
const int jobIndex = d->externalJobs.indexOf(jobId);
QSSH_ASSERT_AND_RETURN(jobIndex != -1);
d->externalJobs.removeAt(jobIndex);
emit sftpOperationFinished(jobId, errorMessage);
}
} // namespace QSsh

View File

@@ -1,100 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sftpdefs.h"
#include "ssh_global.h"
#include <QAbstractItemModel>
namespace QSsh {
class SshConnectionParameters;
namespace Internal { class SftpFileSystemModelPrivate; }
// Very simple read-only model. Symbolic links are not followed.
class QSSH_EXPORT SftpFileSystemModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit SftpFileSystemModel(QObject *parent = 0);
~SftpFileSystemModel();
/*
* Once this is called, an SFTP connection is established and the model is populated.
* The effect of additional calls is undefined.
*/
void setSshConnection(const SshConnectionParameters &sshParams);
void setRootDirectory(const QString &path); // Default is "/".
QString rootDirectory() const;
SftpJobId downloadFile(const QModelIndex &index, const QString &targetFilePath);
// Use this to get the full path of a file or directory.
static const int PathRole = Qt::UserRole;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
signals:
/*
* E.g. "Permission denied". Note that this can happen without direct user intervention,
* due to e.g. the view calling rowCount() on a non-readable directory. This signal should
* therefore not result in a message box or similar, since it might occur very often.
*/
void sftpOperationFailed(const QString &errorMessage);
/*
* This error is not recoverable. The model will not have any content after
* the signal has been emitted.
*/
void connectionError(const QString &errorMessage);
// Success <=> error.isEmpty().
void sftpOperationFinished(QSsh::SftpJobId, const QString &error);
private:
void handleSshConnectionEstablished();
void handleSshConnectionFailure();
void handleSftpChannelInitialized();
void handleSftpChannelError(const QString &reason);
void handleFileInfo(QSsh::SftpJobId jobId, const QList<QSsh::SftpFileInfo> &fileInfoList);
void handleSftpJobFinished(QSsh::SftpJobId jobId, const QString &errorMessage);
int columnCount(const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
void statRootDirectory();
void shutDown();
Internal::SftpFileSystemModelPrivate * const d;
};
} // namespace QSsh;

View File

@@ -1,217 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftpincomingpacket_p.h"
#include "sshexception_p.h"
#include "sshlogging_p.h"
#include "sshpacketparser_p.h"
namespace QSsh {
namespace Internal {
SftpIncomingPacket::SftpIncomingPacket() : m_length(0)
{
}
void SftpIncomingPacket::consumeData(QByteArray &newData)
{
qCDebug(sshLog, "%s: current data size = %d, new data size = %d", Q_FUNC_INFO,
m_data.size(), newData.size());
if (isComplete() || dataSize() + newData.size() < sizeof m_length)
return;
if (dataSize() < sizeof m_length) {
moveFirstBytes(m_data, newData, sizeof m_length - m_data.size());
m_length = SshPacketParser::asUint32(m_data, static_cast<quint32>(0));
if (m_length < static_cast<quint32>(TypeOffset + 1)
|| m_length > MaxPacketSize) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid length field in SFTP packet.");
}
}
moveFirstBytes(m_data, newData,
qMin<quint32>(m_length - dataSize() + 4, newData.size()));
}
void SftpIncomingPacket::moveFirstBytes(QByteArray &target, QByteArray &source,
int n)
{
target.append(source.left(n));
source.remove(0, n);
}
bool SftpIncomingPacket::isComplete() const
{
return m_length == dataSize() - 4;
}
void SftpIncomingPacket::clear()
{
m_data.clear();
m_length = 0;
}
quint32 SftpIncomingPacket::extractServerVersion() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_FXP_VERSION);
try {
return SshPacketParser::asUint32(m_data, TypeOffset + 1);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_FXP_VERSION packet.");
}
}
SftpHandleResponse SftpIncomingPacket::asHandleResponse() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_FXP_HANDLE);
try {
SftpHandleResponse response;
quint32 offset = RequestIdOffset;
response.requestId = SshPacketParser::asUint32(m_data, &offset);
response.handle = SshPacketParser::asString(m_data, &offset);
return response;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_FXP_HANDLE packet");
}
}
SftpStatusResponse SftpIncomingPacket::asStatusResponse() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_FXP_STATUS);
try {
SftpStatusResponse response;
quint32 offset = RequestIdOffset;
response.requestId = SshPacketParser::asUint32(m_data, &offset);
response.status = static_cast<SftpStatusCode>(SshPacketParser::asUint32(m_data, &offset));
response.errorString = SshPacketParser::asUserString(m_data, &offset);
response.language = SshPacketParser::asString(m_data, &offset);
return response;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_FXP_STATUS packet.");
}
}
SftpNameResponse SftpIncomingPacket::asNameResponse() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_FXP_NAME);
try {
SftpNameResponse response;
quint32 offset = RequestIdOffset;
response.requestId = SshPacketParser::asUint32(m_data, &offset);
const quint32 count = SshPacketParser::asUint32(m_data, &offset);
for (quint32 i = 0; i < count; ++i)
response.files << asFile(offset);
return response;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_FXP_NAME packet.");
}
}
SftpDataResponse SftpIncomingPacket::asDataResponse() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_FXP_DATA);
try {
SftpDataResponse response;
quint32 offset = RequestIdOffset;
response.requestId = SshPacketParser::asUint32(m_data, &offset);
response.data = SshPacketParser::asString(m_data, &offset);
return response;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_FXP_DATA packet.");
}
}
SftpAttrsResponse SftpIncomingPacket::asAttrsResponse() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_FXP_ATTRS);
try {
SftpAttrsResponse response;
quint32 offset = RequestIdOffset;
response.requestId = SshPacketParser::asUint32(m_data, &offset);
response.attrs = asFileAttributes(offset);
return response;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_FXP_ATTRS packet.");
}
}
SftpFile SftpIncomingPacket::asFile(quint32 &offset) const
{
SftpFile file;
file.fileName
= QString::fromUtf8(SshPacketParser::asString(m_data, &offset));
file.longName
= QString::fromUtf8(SshPacketParser::asString(m_data, &offset));
file.attributes = asFileAttributes(offset);
return file;
}
SftpFileAttributes SftpIncomingPacket::asFileAttributes(quint32 &offset) const
{
SftpFileAttributes attributes;
const quint32 flags = SshPacketParser::asUint32(m_data, &offset);
attributes.sizePresent = flags & SSH_FILEXFER_ATTR_SIZE;
attributes.timesPresent = flags & SSH_FILEXFER_ATTR_ACMODTIME;
attributes.uidAndGidPresent = flags & SSH_FILEXFER_ATTR_UIDGID;
attributes.permissionsPresent = flags & SSH_FILEXFER_ATTR_PERMISSIONS;
if (attributes.sizePresent)
attributes.size = SshPacketParser::asUint64(m_data, &offset);
if (attributes.uidAndGidPresent) {
attributes.uid = SshPacketParser::asUint32(m_data, &offset);
attributes.gid = SshPacketParser::asUint32(m_data, &offset);
}
if (attributes.permissionsPresent)
attributes.permissions = SshPacketParser::asUint32(m_data, &offset);
if (attributes.timesPresent) {
attributes.atime = SshPacketParser::asUint32(m_data, &offset);
attributes.mtime = SshPacketParser::asUint32(m_data, &offset);
}
if (flags & SSH_FILEXFER_ATTR_EXTENDED) {
const quint32 count = SshPacketParser::asUint32(m_data, &offset);
for (quint32 i = 0; i < count; ++i) {
SshPacketParser::asString(m_data, &offset);
SshPacketParser::asString(m_data, &offset);
}
}
return attributes;
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,104 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sftppacket_p.h"
namespace QSsh {
namespace Internal {
struct SftpHandleResponse {
quint32 requestId;
QByteArray handle;
};
struct SftpStatusResponse {
quint32 requestId;
SftpStatusCode status;
QString errorString;
QByteArray language;
};
struct SftpFileAttributes {
bool sizePresent;
bool timesPresent;
bool uidAndGidPresent;
bool permissionsPresent;
quint64 size;
quint32 uid;
quint32 gid;
quint32 permissions;
quint32 atime;
quint32 mtime;
};
struct SftpFile {
QString fileName;
QString longName; // Not present in later RFCs, so we don't expose this to the user.
SftpFileAttributes attributes;
};
struct SftpNameResponse {
quint32 requestId;
QList<SftpFile> files;
};
struct SftpDataResponse {
quint32 requestId;
QByteArray data;
};
struct SftpAttrsResponse {
quint32 requestId;
SftpFileAttributes attrs;
};
class SftpIncomingPacket : public AbstractSftpPacket
{
public:
SftpIncomingPacket();
void consumeData(QByteArray &data);
void clear();
bool isComplete() const;
quint32 extractServerVersion() const;
SftpHandleResponse asHandleResponse() const;
SftpStatusResponse asStatusResponse() const;
SftpNameResponse asNameResponse() const;
SftpDataResponse asDataResponse() const;
SftpAttrsResponse asAttrsResponse() const;
private:
void moveFirstBytes(QByteArray &target, QByteArray &source, int n);
SftpFileAttributes asFileAttributes(quint32 &offset) const;
SftpFile asFile(quint32 &offset) const;
quint32 m_length;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,220 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftpoperation_p.h"
#include "sftpoutgoingpacket_p.h"
#include <QFile>
namespace QSsh {
namespace Internal {
AbstractSftpOperation::AbstractSftpOperation(SftpJobId jobId) : jobId(jobId)
{
}
AbstractSftpOperation::~AbstractSftpOperation() { }
SftpStatFile::SftpStatFile(SftpJobId jobId, const QString &path)
: AbstractSftpOperation(jobId), path(path)
{
}
SftpOutgoingPacket &SftpStatFile::initialPacket(SftpOutgoingPacket &packet)
{
return packet.generateStat(path, jobId);
}
SftpMakeDir::SftpMakeDir(SftpJobId jobId, const QString &path,
const SftpUploadDir::Ptr &parentJob)
: AbstractSftpOperation(jobId), parentJob(parentJob), remoteDir(path)
{
}
SftpOutgoingPacket &SftpMakeDir::initialPacket(SftpOutgoingPacket &packet)
{
return packet.generateMkDir(remoteDir, jobId);
}
SftpRmDir::SftpRmDir(SftpJobId id, const QString &path)
: AbstractSftpOperation(id), remoteDir(path)
{
}
SftpOutgoingPacket &SftpRmDir::initialPacket(SftpOutgoingPacket &packet)
{
return packet.generateRmDir(remoteDir, jobId);
}
SftpRm::SftpRm(SftpJobId jobId, const QString &path)
: AbstractSftpOperation(jobId), remoteFile(path) {}
SftpOutgoingPacket &SftpRm::initialPacket(SftpOutgoingPacket &packet)
{
return packet.generateRm(remoteFile, jobId);
}
SftpRename::SftpRename(SftpJobId jobId, const QString &oldPath,
const QString &newPath)
: AbstractSftpOperation(jobId), oldPath(oldPath), newPath(newPath)
{
}
SftpOutgoingPacket &SftpRename::initialPacket(SftpOutgoingPacket &packet)
{
return packet.generateRename(oldPath, newPath, jobId);
}
SftpCreateLink::SftpCreateLink(SftpJobId jobId, const QString &filePath, const QString &target)
: AbstractSftpOperation(jobId), filePath(filePath), target(target)
{
}
SftpOutgoingPacket &SftpCreateLink::initialPacket(SftpOutgoingPacket &packet)
{
return packet.generateCreateLink(filePath, target, jobId);
}
AbstractSftpOperationWithHandle::AbstractSftpOperationWithHandle(SftpJobId jobId,
const QString &remotePath)
: AbstractSftpOperation(jobId),
remotePath(remotePath), state(Inactive), hasError(false)
{
}
AbstractSftpOperationWithHandle::~AbstractSftpOperationWithHandle() { }
SftpListDir::SftpListDir(SftpJobId jobId, const QString &path)
: AbstractSftpOperationWithHandle(jobId, path)
{
}
SftpOutgoingPacket &SftpListDir::initialPacket(SftpOutgoingPacket &packet)
{
state = OpenRequested;
return packet.generateOpenDir(remotePath, jobId);
}
SftpCreateFile::SftpCreateFile(SftpJobId jobId, const QString &path,
SftpOverwriteMode mode)
: AbstractSftpOperationWithHandle(jobId, path), mode(mode)
{
}
SftpOutgoingPacket & SftpCreateFile::initialPacket(SftpOutgoingPacket &packet)
{
state = OpenRequested;
return packet.generateOpenFileForWriting(remotePath, mode,
SftpOutgoingPacket::DefaultPermissions, jobId);
}
const int AbstractSftpTransfer::MaxInFlightCount = 10; // Experimentally found to be enough.
AbstractSftpTransfer::AbstractSftpTransfer(SftpJobId jobId, const QString &remotePath,
const QSharedPointer<QFile> &localFile)
: AbstractSftpOperationWithHandle(jobId, remotePath),
localFile(localFile), fileSize(0), offset(0), inFlightCount(0),
statRequested(false)
{
}
AbstractSftpTransfer::~AbstractSftpTransfer() {}
void AbstractSftpTransfer::calculateInFlightCount(quint32 chunkSize)
{
if (fileSize == 0) {
inFlightCount = 1;
} else {
inFlightCount = fileSize / chunkSize;
if (fileSize % chunkSize)
++inFlightCount;
if (inFlightCount > MaxInFlightCount)
inFlightCount = MaxInFlightCount;
}
}
SftpDownload::SftpDownload(SftpJobId jobId, const QString &remotePath,
const QSharedPointer<QFile> &localFile)
: AbstractSftpTransfer(jobId, remotePath, localFile), eofId(SftpInvalidJob)
{
}
SftpOutgoingPacket &SftpDownload::initialPacket(SftpOutgoingPacket &packet)
{
state = OpenRequested;
return packet.generateOpenFileForReading(remotePath, jobId);
}
SftpUploadFile::SftpUploadFile(SftpJobId jobId, const QString &remotePath,
const QSharedPointer<QFile> &localFile, SftpOverwriteMode mode,
const SftpUploadDir::Ptr &parentJob)
: AbstractSftpTransfer(jobId, remotePath, localFile),
parentJob(parentJob), mode(mode)
{
fileSize = localFile->size();
}
SftpOutgoingPacket &SftpUploadFile::initialPacket(SftpOutgoingPacket &packet)
{
state = OpenRequested;
quint32 permissions = 0;
const QFile::Permissions &qtPermissions = localFile->permissions();
if (qtPermissions & QFile::ExeOther)
permissions |= 1 << 0;
if (qtPermissions & QFile::WriteOther)
permissions |= 1 << 1;
if (qtPermissions & QFile::ReadOther)
permissions |= 1 << 2;
if (qtPermissions & QFile::ExeGroup)
permissions |= 1<< 3;
if (qtPermissions & QFile::WriteGroup)
permissions |= 1<< 4;
if (qtPermissions & QFile::ReadGroup)
permissions |= 1<< 5;
if (qtPermissions & QFile::ExeOwner)
permissions |= 1<< 6;
if (qtPermissions & QFile::WriteOwner)
permissions |= 1<< 7;
if (qtPermissions & QFile::ReadOwner)
permissions |= 1<< 8;
return packet.generateOpenFileForWriting(remotePath, mode, permissions, jobId);
}
SftpUploadDir::~SftpUploadDir() {}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,244 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sftpdefs.h"
#include <QByteArray>
#include <QList>
#include <QMap>
#include <QSharedPointer>
QT_BEGIN_NAMESPACE
class QFile;
QT_END_NAMESPACE
namespace QSsh {
namespace Internal {
class SftpOutgoingPacket;
struct AbstractSftpOperation
{
typedef QSharedPointer<AbstractSftpOperation> Ptr;
enum Type {
StatFile, ListDir, MakeDir, RmDir, Rm, Rename, CreateLink, CreateFile, Download, UploadFile
};
AbstractSftpOperation(SftpJobId jobId);
virtual ~AbstractSftpOperation();
virtual Type type() const = 0;
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet) = 0;
const SftpJobId jobId;
private:
AbstractSftpOperation(const AbstractSftpOperation &);
AbstractSftpOperation &operator=(const AbstractSftpOperation &);
};
struct SftpUploadDir;
struct SftpStatFile : public AbstractSftpOperation
{
typedef QSharedPointer<SftpStatFile> Ptr;
SftpStatFile(SftpJobId jobId, const QString &path);
virtual Type type() const { return StatFile; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QString path;
};
struct SftpMakeDir : public AbstractSftpOperation
{
typedef QSharedPointer<SftpMakeDir> Ptr;
SftpMakeDir(SftpJobId jobId, const QString &path,
const QSharedPointer<SftpUploadDir> &parentJob = QSharedPointer<SftpUploadDir>());
virtual Type type() const { return MakeDir; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QSharedPointer<SftpUploadDir> parentJob;
const QString remoteDir;
};
struct SftpRmDir : public AbstractSftpOperation
{
typedef QSharedPointer<SftpRmDir> Ptr;
SftpRmDir(SftpJobId id, const QString &path);
virtual Type type() const { return RmDir; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QString remoteDir;
};
struct SftpRm : public AbstractSftpOperation
{
typedef QSharedPointer<SftpRm> Ptr;
SftpRm(SftpJobId jobId, const QString &path);
virtual Type type() const { return Rm; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QString remoteFile;
};
struct SftpRename : public AbstractSftpOperation
{
typedef QSharedPointer<SftpRename> Ptr;
SftpRename(SftpJobId jobId, const QString &oldPath, const QString &newPath);
virtual Type type() const { return Rename; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QString oldPath;
const QString newPath;
};
struct SftpCreateLink : public AbstractSftpOperation
{
typedef QSharedPointer<SftpCreateLink> Ptr;
SftpCreateLink(SftpJobId jobId, const QString &filePath, const QString &target);
virtual Type type() const { return CreateLink; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QString filePath;
const QString target;
};
struct AbstractSftpOperationWithHandle : public AbstractSftpOperation
{
typedef QSharedPointer<AbstractSftpOperationWithHandle> Ptr;
enum State { Inactive, OpenRequested, Open, CloseRequested };
AbstractSftpOperationWithHandle(SftpJobId jobId, const QString &remotePath);
~AbstractSftpOperationWithHandle();
const QString remotePath;
QByteArray remoteHandle;
State state;
bool hasError;
};
struct SftpListDir : public AbstractSftpOperationWithHandle
{
typedef QSharedPointer<SftpListDir> Ptr;
SftpListDir(SftpJobId jobId, const QString &path);
virtual Type type() const { return ListDir; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
};
struct SftpCreateFile : public AbstractSftpOperationWithHandle
{
typedef QSharedPointer<SftpCreateFile> Ptr;
SftpCreateFile(SftpJobId jobId, const QString &path, SftpOverwriteMode mode);
virtual Type type() const { return CreateFile; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const SftpOverwriteMode mode;
};
struct AbstractSftpTransfer : public AbstractSftpOperationWithHandle
{
typedef QSharedPointer<AbstractSftpTransfer> Ptr;
AbstractSftpTransfer(SftpJobId jobId, const QString &remotePath,
const QSharedPointer<QFile> &localFile);
~AbstractSftpTransfer();
void calculateInFlightCount(quint32 chunkSize);
static const int MaxInFlightCount;
const QSharedPointer<QFile> localFile;
quint64 fileSize;
quint64 offset;
int inFlightCount;
bool statRequested;
};
struct SftpDownload : public AbstractSftpTransfer
{
typedef QSharedPointer<SftpDownload> Ptr;
SftpDownload(SftpJobId jobId, const QString &remotePath,
const QSharedPointer<QFile> &localFile);
virtual Type type() const { return Download; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
QMap<quint32, quint64> offsets;
SftpJobId eofId;
};
struct SftpUploadFile : public AbstractSftpTransfer
{
typedef QSharedPointer<SftpUploadFile> Ptr;
SftpUploadFile(SftpJobId jobId, const QString &remotePath,
const QSharedPointer<QFile> &localFile, SftpOverwriteMode mode,
const QSharedPointer<SftpUploadDir> &parentJob = QSharedPointer<SftpUploadDir>());
virtual Type type() const { return UploadFile; }
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
const QSharedPointer<SftpUploadDir> parentJob;
SftpOverwriteMode mode;
};
// Composite operation.
struct SftpUploadDir
{
typedef QSharedPointer<SftpUploadDir> Ptr;
struct Dir {
Dir(const QString &l, const QString &r) : localDir(l), remoteDir(r) {}
QString localDir;
QString remoteDir;
};
SftpUploadDir(SftpJobId jobId) : jobId(jobId), hasError(false) {}
~SftpUploadDir();
void setError()
{
hasError = true;
uploadsInProgress.clear();
mkdirsInProgress.clear();
}
const SftpJobId jobId;
bool hasError;
QList<SftpUploadFile::Ptr> uploadsInProgress;
QMap<SftpMakeDir::Ptr, Dir> mkdirsInProgress;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,220 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftpoutgoingpacket_p.h"
#include "sshlogging_p.h"
#include "sshpacket_p.h"
#include <QtEndian>
#include <limits>
namespace QSsh {
namespace Internal {
namespace {
const quint32 DefaultAttributes = 0;
const quint32 SSH_FXF_READ = 0x00000001;
const quint32 SSH_FXF_WRITE = 0x00000002;
const quint32 SSH_FXF_APPEND = 0x00000004;
const quint32 SSH_FXF_CREAT = 0x00000008;
const quint32 SSH_FXF_TRUNC = 0x00000010;
const quint32 SSH_FXF_EXCL = 0x00000020;
}
SftpOutgoingPacket::SftpOutgoingPacket()
{
}
SftpOutgoingPacket &SftpOutgoingPacket::generateInit(quint32 version)
{
return init(SSH_FXP_INIT, 0).appendInt(version).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateStat(const QString &path, quint32 requestId)
{
return init(SSH_FXP_LSTAT, requestId).appendString(path).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateOpenDir(const QString &path,
quint32 requestId)
{
return init(SSH_FXP_OPENDIR, requestId).appendString(path).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateReadDir(const QByteArray &handle,
quint32 requestId)
{
return init(SSH_FXP_READDIR, requestId).appendString(handle).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateCloseHandle(const QByteArray &handle,
quint32 requestId)
{
return init(SSH_FXP_CLOSE, requestId).appendString(handle).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateMkDir(const QString &path,
quint32 requestId)
{
return init(SSH_FXP_MKDIR, requestId).appendString(path)
.appendInt(DefaultAttributes).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateRmDir(const QString &path,
quint32 requestId)
{
return init(SSH_FXP_RMDIR, requestId).appendString(path).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateRm(const QString &path,
quint32 requestId)
{
return init(SSH_FXP_REMOVE, requestId).appendString(path).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateRename(const QString &oldPath,
const QString &newPath, quint32 requestId)
{
return init(SSH_FXP_RENAME, requestId).appendString(oldPath)
.appendString(newPath).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFileForWriting(const QString &path,
SftpOverwriteMode mode, quint32 permissions, quint32 requestId)
{
QList<quint32> attributes;
if (permissions != DefaultPermissions)
attributes << SSH_FILEXFER_ATTR_PERMISSIONS << permissions;
else
attributes << DefaultAttributes;
return generateOpenFile(path, Write, mode, attributes, requestId);
}
SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFileForReading(const QString &path,
quint32 requestId)
{
// Note: Overwrite mode is irrelevant and will be ignored.
return generateOpenFile(path, Read, SftpSkipExisting, QList<quint32>() << DefaultAttributes,
requestId);
}
SftpOutgoingPacket &SftpOutgoingPacket::generateReadFile(const QByteArray &handle,
quint64 offset, quint32 length, quint32 requestId)
{
return init(SSH_FXP_READ, requestId).appendString(handle).appendInt64(offset)
.appendInt(length).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateFstat(const QByteArray &handle,
quint32 requestId)
{
return init(SSH_FXP_FSTAT, requestId).appendString(handle).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateWriteFile(const QByteArray &handle,
quint64 offset, const QByteArray &data, quint32 requestId)
{
return init(SSH_FXP_WRITE, requestId).appendString(handle)
.appendInt64(offset).appendString(data).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateCreateLink(const QString &filePath,
const QString &target, quint32 requestId)
{
return init(SSH_FXP_SYMLINK, requestId).appendString(filePath).appendString(target).finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::generateOpenFile(const QString &path,
OpenType openType, SftpOverwriteMode mode, const QList<quint32> &attributes, quint32 requestId)
{
quint32 pFlags = 0;
switch (openType) {
case Read:
pFlags = SSH_FXF_READ;
break;
case Write:
pFlags = SSH_FXF_WRITE | SSH_FXF_CREAT;
switch (mode) {
case SftpOverwriteExisting: pFlags |= SSH_FXF_TRUNC; break;
case SftpAppendToExisting: pFlags |= SSH_FXF_APPEND; break;
case SftpSkipExisting: pFlags |= SSH_FXF_EXCL; break;
}
break;
}
init(SSH_FXP_OPEN, requestId).appendString(path).appendInt(pFlags);
foreach (const quint32 attribute, attributes)
appendInt(attribute);
return finalize();
}
SftpOutgoingPacket &SftpOutgoingPacket::init(SftpPacketType type,
quint32 requestId)
{
m_data.resize(TypeOffset + 1);
m_data[TypeOffset] = type;
if (type != SSH_FXP_INIT) {
appendInt(requestId);
qCDebug(sshLog, "Generating SFTP packet of type %d with request id %u", type, requestId);
}
return *this;
}
SftpOutgoingPacket &SftpOutgoingPacket::appendInt(quint32 val)
{
m_data.append(AbstractSshPacket::encodeInt(val));
return *this;
}
SftpOutgoingPacket &SftpOutgoingPacket::appendInt64(quint64 value)
{
m_data.append(AbstractSshPacket::encodeInt(value));
return *this;
}
SftpOutgoingPacket &SftpOutgoingPacket::appendString(const QString &string)
{
m_data.append(AbstractSshPacket::encodeString(string.toUtf8()));
return *this;
}
SftpOutgoingPacket &SftpOutgoingPacket::appendString(const QByteArray &string)
{
m_data += AbstractSshPacket::encodeString(string);
return *this;
}
SftpOutgoingPacket &SftpOutgoingPacket::finalize()
{
AbstractSshPacket::setLengthField(m_data);
return *this;
}
const quint32 SftpOutgoingPacket::DefaultPermissions = std::numeric_limits<quint32>::max();
} // namespace Internal
} // namespace QSsh

View File

@@ -1,84 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sftppacket_p.h"
#include "sftpdefs.h"
namespace QSsh {
namespace Internal {
class SftpOutgoingPacket : public AbstractSftpPacket
{
public:
SftpOutgoingPacket();
SftpOutgoingPacket &generateInit(quint32 version);
SftpOutgoingPacket &generateStat(const QString &path, quint32 requestId);
SftpOutgoingPacket &generateOpenDir(const QString &path, quint32 requestId);
SftpOutgoingPacket &generateReadDir(const QByteArray &handle,
quint32 requestId);
SftpOutgoingPacket &generateCloseHandle(const QByteArray &handle,
quint32 requestId);
SftpOutgoingPacket &generateMkDir(const QString &path, quint32 requestId);
SftpOutgoingPacket &generateRmDir(const QString &path, quint32 requestId);
SftpOutgoingPacket &generateRm(const QString &path, quint32 requestId);
SftpOutgoingPacket &generateRename(const QString &oldPath,
const QString &newPath, quint32 requestId);
SftpOutgoingPacket &generateOpenFileForWriting(const QString &path,
SftpOverwriteMode mode, quint32 permissions, quint32 requestId);
SftpOutgoingPacket &generateOpenFileForReading(const QString &path,
quint32 requestId);
SftpOutgoingPacket &generateReadFile(const QByteArray &handle,
quint64 offset, quint32 length, quint32 requestId);
SftpOutgoingPacket &generateFstat(const QByteArray &handle,
quint32 requestId);
SftpOutgoingPacket &generateWriteFile(const QByteArray &handle,
quint64 offset, const QByteArray &data, quint32 requestId);
// Note: OpenSSH's SFTP server has a bug that reverses the filePath and target
// arguments, so this operation is not portable.
SftpOutgoingPacket &generateCreateLink(const QString &filePath, const QString &target,
quint32 requestId);
static const quint32 DefaultPermissions;
private:
static QByteArray encodeString(const QString &string);
enum OpenType { Read, Write };
SftpOutgoingPacket &generateOpenFile(const QString &path, OpenType openType,
SftpOverwriteMode mode, const QList<quint32> &attributes, quint32 requestId);
SftpOutgoingPacket &init(SftpPacketType type, quint32 requestId);
SftpOutgoingPacket &appendInt(quint32 value);
SftpOutgoingPacket &appendInt64(quint64 value);
SftpOutgoingPacket &appendString(const QString &string);
SftpOutgoingPacket &appendString(const QByteArray &string);
SftpOutgoingPacket &finalize();
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,49 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sftppacket_p.h"
#include "sshpacketparser_p.h"
namespace QSsh {
namespace Internal {
const quint32 AbstractSftpPacket::MaxDataSize = 32000;
const quint32 AbstractSftpPacket::MaxPacketSize = 34000;
const int AbstractSftpPacket::TypeOffset = 4;
const int AbstractSftpPacket::RequestIdOffset = TypeOffset + 1;
const int AbstractSftpPacket::PayloadOffset = RequestIdOffset + 4;
AbstractSftpPacket::AbstractSftpPacket()
{
}
quint32 AbstractSftpPacket::requestId() const
{
return SshPacketParser::asUint32(m_data, RequestIdOffset);
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QByteArray>
#include <QList>
#include <QString>
namespace QSsh {
namespace Internal {
enum SftpPacketType {
SSH_FXP_INIT = 1,
SSH_FXP_VERSION = 2,
SSH_FXP_OPEN = 3,
SSH_FXP_CLOSE = 4,
SSH_FXP_READ = 5,
SSH_FXP_WRITE = 6,
SSH_FXP_LSTAT = 7,
SSH_FXP_FSTAT = 8,
SSH_FXP_SETSTAT = 9,
SSH_FXP_FSETSTAT = 10,
SSH_FXP_OPENDIR = 11,
SSH_FXP_READDIR = 12,
SSH_FXP_REMOVE = 13,
SSH_FXP_MKDIR = 14,
SSH_FXP_RMDIR = 15,
SSH_FXP_REALPATH = 16,
SSH_FXP_STAT = 17,
SSH_FXP_RENAME = 18,
SSH_FXP_READLINK = 19,
SSH_FXP_SYMLINK = 20, // Removed from later protocol versions. Try not to use.
SSH_FXP_STATUS = 101,
SSH_FXP_HANDLE = 102,
SSH_FXP_DATA = 103,
SSH_FXP_NAME = 104,
SSH_FXP_ATTRS = 105,
SSH_FXP_EXTENDED = 200,
SSH_FXP_EXTENDED_REPLY = 201
};
enum SftpStatusCode {
SSH_FX_OK = 0,
SSH_FX_EOF = 1,
SSH_FX_NO_SUCH_FILE = 2,
SSH_FX_PERMISSION_DENIED = 3,
SSH_FX_FAILURE = 4,
SSH_FX_BAD_MESSAGE = 5,
SSH_FX_NO_CONNECTION = 6,
SSH_FX_CONNECTION_LOST = 7,
SSH_FX_OP_UNSUPPORTED = 8
};
enum SftpAttributeType {
SSH_FILEXFER_ATTR_SIZE = 0x00000001,
SSH_FILEXFER_ATTR_UIDGID = 0x00000002,
SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004,
SSH_FILEXFER_ATTR_ACMODTIME = 0x00000008,
SSH_FILEXFER_ATTR_EXTENDED = 0x80000000
};
class AbstractSftpPacket
{
public:
AbstractSftpPacket();
quint32 requestId() const;
const QByteArray &rawData() const { return m_data; }
SftpPacketType type() const { return static_cast<SftpPacketType>(m_data.at(TypeOffset)); }
static const quint32 MaxDataSize; // "Pure" data size per read/writepacket.
static const quint32 MaxPacketSize;
protected:
quint32 dataSize() const { return static_cast<quint32>(m_data.size()); }
static const int TypeOffset;
static const int RequestIdOffset;
static const int PayloadOffset;
QByteArray m_data;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,81 +0,0 @@
QT += gui network widgets
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
SOURCES += $$PWD/sshsendfacility.cpp \
$$PWD/sshremoteprocess.cpp \
$$PWD/sshpacketparser.cpp \
$$PWD/sshpacket.cpp \
$$PWD/sshoutgoingpacket.cpp \
$$PWD/sshkeygenerator.cpp \
$$PWD/sshkeyexchange.cpp \
$$PWD/sshincomingpacket.cpp \
$$PWD/sshcryptofacility.cpp \
$$PWD/sshconnection.cpp \
$$PWD/sshchannelmanager.cpp \
$$PWD/sshchannel.cpp \
$$PWD/sshcapabilities.cpp \
$$PWD/sftppacket.cpp \
$$PWD/sftpoutgoingpacket.cpp \
$$PWD/sftpoperation.cpp \
$$PWD/sftpincomingpacket.cpp \
$$PWD/sftpdefs.cpp \
$$PWD/sftpchannel.cpp \
$$PWD/sshremoteprocessrunner.cpp \
$$PWD/sshconnectionmanager.cpp \
$$PWD/sshkeypasswordretriever.cpp \
$$PWD/sftpfilesystemmodel.cpp \
$$PWD/sshkeycreationdialog.cpp \
$$PWD/sshinit.cpp \
$$PWD/sshdirecttcpiptunnel.cpp \
$$PWD/sshlogging.cpp \
$$PWD/sshhostkeydatabase.cpp \
$$PWD/sshtcpipforwardserver.cpp \
$$PWD/sshtcpiptunnel.cpp \
$$PWD/sshforwardedtcpiptunnel.cpp
HEADERS += $$PWD/sshsendfacility_p.h \
$$PWD/sshremoteprocess.h \
$$PWD/sshremoteprocess_p.h \
$$PWD/sshpacketparser_p.h \
$$PWD/sshpacket_p.h \
$$PWD/sshoutgoingpacket_p.h \
$$PWD/sshkeygenerator.h \
$$PWD/sshkeyexchange_p.h \
$$PWD/sshincomingpacket_p.h \
$$PWD/sshexception_p.h \
$$PWD/ssherrors.h \
$$PWD/sshcryptofacility_p.h \
$$PWD/sshconnection.h \
$$PWD/sshconnection_p.h \
$$PWD/sshchannelmanager_p.h \
$$PWD/sshchannel_p.h \
$$PWD/sshcapabilities_p.h \
$$PWD/sshbotanconversions_p.h \
$$PWD/sftppacket_p.h \
$$PWD/sftpoutgoingpacket_p.h \
$$PWD/sftpoperation_p.h \
$$PWD/sftpincomingpacket_p.h \
$$PWD/sftpdefs.h \
$$PWD/sftpchannel.h \
$$PWD/sftpchannel_p.h \
$$PWD/sshremoteprocessrunner.h \
$$PWD/sshconnectionmanager.h \
$$PWD/sshpseudoterminal.h \
$$PWD/sshkeypasswordretriever_p.h \
$$PWD/sftpfilesystemmodel.h \
$$PWD/sshkeycreationdialog.h \
$$PWD/ssh_global.h \
$$PWD/sshdirecttcpiptunnel_p.h \
$$PWD/sshinit_p.h \
$$PWD/sshdirecttcpiptunnel.h \
$$PWD/sshlogging_p.h \
$$PWD/sshhostkeydatabase.h \
$$PWD/sshtcpipforwardserver.h \
$$PWD/sshtcpipforwardserver_p.h \
$$PWD/sshtcpiptunnel_p.h \
$$PWD/sshforwardedtcpiptunnel.h \
$$PWD/sshforwardedtcpiptunnel_p.h
FORMS += $$PWD/sshkeycreationdialog.ui

View File

@@ -1,8 +0,0 @@
TARGET = QtSsh
load(qt_module)
DEFINES += QTCSSH_LIBRARY
include($$PWD/ssh.pri)
include($$PWD/../botan/botan.pri)

View File

@@ -1 +0,0 @@
QTC_LIB_NAME = QtcSsh

View File

@@ -1,41 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QtGlobal>
//#if defined(QTCSSH_LIBRARY)
//# define QSSH_EXPORT Q_DECL_EXPORT
//#else
//# define QSSH_EXPORT Q_DECL_IMPORT
//#endif
#define QSSH_EXPORT
#define QSSH_PRINT_WARNING qWarning("Soft assert at %s:%d", __FILE__, __LINE__)
#define QSSH_ASSERT(cond) do { if (!(cond)) { QSSH_PRINT_WARNING; } } while (false)
#define QSSH_ASSERT_AND_RETURN(cond) do { if (!(cond)) { QSSH_PRINT_WARNING; return; } } while (false)
#define QSSH_ASSERT_AND_RETURN_VALUE(cond, value) do { if (!(cond)) { QSSH_PRINT_WARNING; return value; } } while (false)

View File

@@ -1,132 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sshcapabilities_p.h"
#include "sshexception_p.h"
#include <botan/botan.h>
namespace QSsh {
namespace Internal {
inline const Botan::byte *convertByteArray(const QByteArray &a)
{
return reinterpret_cast<const Botan::byte *>(a.constData());
}
inline Botan::byte *convertByteArray(QByteArray &a)
{
return reinterpret_cast<Botan::byte *>(a.data());
}
inline QByteArray convertByteArray(const Botan::SecureVector<Botan::byte> &v)
{
return QByteArray(reinterpret_cast<const char *>(v.begin()), static_cast<int>(v.size()));
}
inline const char *botanKeyExchangeAlgoName(const QByteArray &rfcAlgoName)
{
if (rfcAlgoName == SshCapabilities::DiffieHellmanGroup1Sha1)
return "modp/ietf/1024";
if (rfcAlgoName == SshCapabilities::DiffieHellmanGroup14Sha1)
return "modp/ietf/2048";
if (rfcAlgoName == SshCapabilities::EcdhNistp256)
return "secp256r1";
if (rfcAlgoName == SshCapabilities::EcdhNistp384)
return "secp384r1";
if (rfcAlgoName == SshCapabilities::EcdhNistp521)
return "secp521r1";
throw SshClientException(SshInternalError, SSH_TR("Unexpected key exchange algorithm \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName)));
}
inline const char *botanCryptAlgoName(const QByteArray &rfcAlgoName)
{
if (rfcAlgoName == SshCapabilities::CryptAlgoAes128Cbc
|| rfcAlgoName == SshCapabilities::CryptAlgoAes128Ctr) {
return "AES-128";
}
if (rfcAlgoName == SshCapabilities::CryptAlgo3DesCbc
|| rfcAlgoName == SshCapabilities::CryptAlgo3DesCtr) {
return "TripleDES";
}
if (rfcAlgoName == SshCapabilities::CryptAlgoAes192Ctr) {
return "AES-192";
}
if (rfcAlgoName == SshCapabilities::CryptAlgoAes256Ctr) {
return "AES-256";
}
throw SshClientException(SshInternalError, SSH_TR("Unexpected cipher \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName)));
}
inline const char *botanEmsaAlgoName(const QByteArray &rfcAlgoName)
{
if (rfcAlgoName == SshCapabilities::PubKeyDss)
return "EMSA1(SHA-1)";
if (rfcAlgoName == SshCapabilities::PubKeyRsa)
return "EMSA3(SHA-1)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa256)
return "EMSA1_BSI(SHA-256)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa384)
return "EMSA1_BSI(SHA-384)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa521)
return "EMSA1_BSI(SHA-512)";
throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName)));
}
inline const char *botanHMacAlgoName(const QByteArray &rfcAlgoName)
{
if (rfcAlgoName == SshCapabilities::HMacSha1)
return "SHA-1";
if (rfcAlgoName == SshCapabilities::HMacSha256)
return "SHA-256";
if (rfcAlgoName == SshCapabilities::HMacSha384)
return "SHA-384";
if (rfcAlgoName == SshCapabilities::HMacSha512)
return "SHA-512";
throw SshClientException(SshInternalError, SSH_TR("Unexpected hashing algorithm \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName)));
}
inline quint32 botanHMacKeyLen(const QByteArray &rfcAlgoName)
{
if (rfcAlgoName == SshCapabilities::HMacSha1)
return 20;
if (rfcAlgoName == SshCapabilities::HMacSha256)
return 32;
if (rfcAlgoName == SshCapabilities::HMacSha384)
return 48;
if (rfcAlgoName == SshCapabilities::HMacSha512)
return 64;
throw SshClientException(SshInternalError, SSH_TR("Unexpected hashing algorithm \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName)));
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,170 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshcapabilities_p.h"
#include "sshexception_p.h"
#include <QCoreApplication>
#include <QString>
namespace QSsh {
namespace Internal {
namespace {
QByteArray listAsByteArray(const QList<QByteArray> &list)
{
QByteArray array;
foreach (const QByteArray &elem, list)
array += elem + ',';
if (!array.isEmpty())
array.remove(array.count() - 1, 1);
return array;
}
} // anonymous namspace
const QByteArray SshCapabilities::DiffieHellmanGroup1Sha1("diffie-hellman-group1-sha1");
const QByteArray SshCapabilities::DiffieHellmanGroup14Sha1("diffie-hellman-group14-sha1");
const QByteArray SshCapabilities::EcdhKexNamePrefix("ecdh-sha2-nistp");
const QByteArray SshCapabilities::EcdhNistp256 = EcdhKexNamePrefix + "256";
const QByteArray SshCapabilities::EcdhNistp384 = EcdhKexNamePrefix + "384";
const QByteArray SshCapabilities::EcdhNistp521 = EcdhKexNamePrefix + "521";
const QList<QByteArray> SshCapabilities::KeyExchangeMethods = QList<QByteArray>()
<< SshCapabilities::EcdhNistp256
<< SshCapabilities::EcdhNistp384
<< SshCapabilities::EcdhNistp521
<< SshCapabilities::DiffieHellmanGroup1Sha1
<< SshCapabilities::DiffieHellmanGroup14Sha1;
const QByteArray SshCapabilities::PubKeyDss("ssh-dss");
const QByteArray SshCapabilities::PubKeyRsa("ssh-rsa");
const QByteArray SshCapabilities::PubKeyEcdsaPrefix("ecdsa-sha2-nistp");
const QByteArray SshCapabilities::PubKeyEcdsa256 = SshCapabilities::PubKeyEcdsaPrefix + "256";
const QByteArray SshCapabilities::PubKeyEcdsa384 = SshCapabilities::PubKeyEcdsaPrefix + "384";
const QByteArray SshCapabilities::PubKeyEcdsa521 = SshCapabilities::PubKeyEcdsaPrefix + "521";
const QList<QByteArray> SshCapabilities::PublicKeyAlgorithms = QList<QByteArray>()
<< SshCapabilities::PubKeyEcdsa256
<< SshCapabilities::PubKeyEcdsa384
<< SshCapabilities::PubKeyEcdsa521
<< SshCapabilities::PubKeyRsa
<< SshCapabilities::PubKeyDss;
const QByteArray SshCapabilities::CryptAlgo3DesCbc("3des-cbc");
const QByteArray SshCapabilities::CryptAlgo3DesCtr("3des-ctr");
const QByteArray SshCapabilities::CryptAlgoAes128Cbc("aes128-cbc");
const QByteArray SshCapabilities::CryptAlgoAes128Ctr("aes128-ctr");
const QByteArray SshCapabilities::CryptAlgoAes192Ctr("aes192-ctr");
const QByteArray SshCapabilities::CryptAlgoAes256Ctr("aes256-ctr");
const QList<QByteArray> SshCapabilities::EncryptionAlgorithms
= QList<QByteArray>() << SshCapabilities::CryptAlgoAes256Ctr
<< SshCapabilities::CryptAlgoAes192Ctr
<< SshCapabilities::CryptAlgoAes128Ctr
<< SshCapabilities::CryptAlgo3DesCtr
<< SshCapabilities::CryptAlgoAes128Cbc
<< SshCapabilities::CryptAlgo3DesCbc;
const QByteArray SshCapabilities::HMacSha1("hmac-sha1");
const QByteArray SshCapabilities::HMacSha196("hmac-sha1-96");
const QByteArray SshCapabilities::HMacSha256("hmac-sha2-256");
const QByteArray SshCapabilities::HMacSha384("hmac-sha2-384");
const QByteArray SshCapabilities::HMacSha512("hmac-sha2-512");
const QList<QByteArray> SshCapabilities::MacAlgorithms
= QList<QByteArray>() /* << SshCapabilities::HMacSha196 */
<< SshCapabilities::HMacSha256
<< SshCapabilities::HMacSha384
<< SshCapabilities::HMacSha512
<< SshCapabilities::HMacSha1;
const QList<QByteArray> SshCapabilities::CompressionAlgorithms
= QList<QByteArray>() << "none";
const QByteArray SshCapabilities::SshConnectionService("ssh-connection");
QList<QByteArray> SshCapabilities::commonCapabilities(const QList<QByteArray> &myCapabilities,
const QList<QByteArray> &serverCapabilities)
{
QList<QByteArray> capabilities;
foreach (const QByteArray &myCapability, myCapabilities) {
if (serverCapabilities.contains(myCapability))
capabilities << myCapability;
}
if (!capabilities.isEmpty())
return capabilities;
throw SshServerException(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
"Server and client capabilities do not match.",
QCoreApplication::translate("SshConnection",
"Server and client capabilities don't match. "
"Client list was: %1.\nServer list was %2.")
.arg(QString::fromLocal8Bit(listAsByteArray(myCapabilities).data()))
.arg(QString::fromLocal8Bit(listAsByteArray(serverCapabilities).data())));
}
QByteArray SshCapabilities::findBestMatch(const QList<QByteArray> &myCapabilities,
const QList<QByteArray> &serverCapabilities)
{
return commonCapabilities(myCapabilities, serverCapabilities).first();
}
int SshCapabilities::ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo)
{
if (ecdsaAlgo == PubKeyEcdsa256)
return 32;
if (ecdsaAlgo == PubKeyEcdsa384)
return 48;
if (ecdsaAlgo == PubKeyEcdsa521)
return 66;
throw SshClientException(SshInternalError, SSH_TR("Unexpected ecdsa algorithm \"%1\"")
.arg(QString::fromLatin1(ecdsaAlgo)));
}
QByteArray SshCapabilities::ecdsaPubKeyAlgoForKeyWidth(int keyWidthInBytes)
{
if (keyWidthInBytes <= 32)
return PubKeyEcdsa256;
if (keyWidthInBytes <= 48)
return PubKeyEcdsa384;
if (keyWidthInBytes <= 66)
return PubKeyEcdsa521;
throw SshClientException(SshInternalError, SSH_TR("Unexpected ecdsa key size (%1 bytes)")
.arg(keyWidthInBytes));
}
const char *SshCapabilities::oid(const QByteArray &ecdsaAlgo)
{
if (ecdsaAlgo == PubKeyEcdsa256)
return "secp256r1";
if (ecdsaAlgo == PubKeyEcdsa384)
return "secp384r1";
if (ecdsaAlgo == PubKeyEcdsa521)
return "secp521r1";
throw SshClientException(SshInternalError, SSH_TR("Unexpected ecdsa algorithm \"%1\"")
.arg(QString::fromLatin1(ecdsaAlgo)));
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,83 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QByteArray>
#include <QList>
namespace QSsh {
namespace Internal {
class SshCapabilities
{
public:
static const QByteArray DiffieHellmanGroup1Sha1;
static const QByteArray DiffieHellmanGroup14Sha1;
static const QByteArray EcdhKexNamePrefix;
static const QByteArray EcdhNistp256;
static const QByteArray EcdhNistp384;
static const QByteArray EcdhNistp521; // sic
static const QList<QByteArray> KeyExchangeMethods;
static const QByteArray PubKeyDss;
static const QByteArray PubKeyRsa;
static const QByteArray PubKeyEcdsaPrefix;
static const QByteArray PubKeyEcdsa256;
static const QByteArray PubKeyEcdsa384;
static const QByteArray PubKeyEcdsa521;
static const QList<QByteArray> PublicKeyAlgorithms;
static const QByteArray CryptAlgo3DesCbc;
static const QByteArray CryptAlgo3DesCtr;
static const QByteArray CryptAlgoAes128Cbc;
static const QByteArray CryptAlgoAes128Ctr;
static const QByteArray CryptAlgoAes192Ctr;
static const QByteArray CryptAlgoAes256Ctr;
static const QList<QByteArray> EncryptionAlgorithms;
static const QByteArray HMacSha1;
static const QByteArray HMacSha196;
static const QByteArray HMacSha256;
static const QByteArray HMacSha384;
static const QByteArray HMacSha512;
static const QList<QByteArray> MacAlgorithms;
static const QList<QByteArray> CompressionAlgorithms;
static const QByteArray SshConnectionService;
static QList<QByteArray> commonCapabilities(const QList<QByteArray> &myCapabilities,
const QList<QByteArray> &serverCapabilities);
static QByteArray findBestMatch(const QList<QByteArray> &myCapabilities,
const QList<QByteArray> &serverCapabilities);
static int ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo);
static QByteArray ecdsaPubKeyAlgoForKeyWidth(int keyWidthInBytes);
static const char *oid(const QByteArray &ecdsaAlgo);
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,280 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshchannel_p.h"
#include "sshincomingpacket_p.h"
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
#include <botan/botan.h>
#include <QTimer>
namespace QSsh {
namespace Internal {
// "Payload length" (RFC 4253, 6.1), i.e. minus packet type, channel number
// and length field for string.
const quint32 MinMaxPacketSize = 32768 - sizeof(quint32) - sizeof(quint32) - 1;
const quint32 NoChannel = 0xffffffffu;
AbstractSshChannel::AbstractSshChannel(quint32 channelId,
SshSendFacility &sendFacility)
: m_sendFacility(sendFacility),
m_localChannel(channelId), m_remoteChannel(NoChannel),
m_localWindowSize(initialWindowSize()), m_remoteWindowSize(0),
m_state(Inactive)
{
m_timeoutTimer.setSingleShot(true);
connect(&m_timeoutTimer, &QTimer::timeout, this, &AbstractSshChannel::timeout);
}
AbstractSshChannel::~AbstractSshChannel()
{
}
void AbstractSshChannel::setChannelState(ChannelState state)
{
m_state = state;
if (state == Closed)
closeHook();
}
void AbstractSshChannel::requestSessionStart()
{
// Note: We are just being paranoid here about the Botan exceptions,
// which are extremely unlikely to happen, because if there was a problem
// with our cryptography stuff, it would have hit us before, on
// establishing the connection.
try {
m_sendFacility.sendSessionPacket(m_localChannel, initialWindowSize(), maxPacketSize());
setChannelState(SessionRequested);
m_timeoutTimer.start(ReplyTimeout);
} catch (const std::exception &e) {
qCWarning(sshLog, "Botan error: %s", e.what());
closeChannel();
}
}
void AbstractSshChannel::sendData(const QByteArray &data)
{
try {
m_sendBuffer += data;
flushSendBuffer();
} catch (const std::exception &e) {
qCWarning(sshLog, "Botan error: %s", e.what());
closeChannel();
}
}
quint32 AbstractSshChannel::initialWindowSize()
{
return maxPacketSize();
}
quint32 AbstractSshChannel::maxPacketSize()
{
return 16 * 1024 * 1024;
}
void AbstractSshChannel::handleWindowAdjust(quint32 bytesToAdd)
{
checkChannelActive();
const quint64 newValue = m_remoteWindowSize + bytesToAdd;
if (newValue > 0xffffffffu) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Illegal window size requested.");
}
m_remoteWindowSize = newValue;
flushSendBuffer();
}
void AbstractSshChannel::flushSendBuffer()
{
while (true) {
const quint32 bytesToSend = qMin(m_remoteMaxPacketSize,
qMin<quint32>(m_remoteWindowSize, m_sendBuffer.size()));
if (bytesToSend == 0)
break;
const QByteArray &data = m_sendBuffer.left(bytesToSend);
m_sendFacility.sendChannelDataPacket(m_remoteChannel, data);
m_sendBuffer.remove(0, bytesToSend);
m_remoteWindowSize -= bytesToSend;
}
}
void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId,
quint32 remoteWindowSize, quint32 remoteMaxPacketSize)
{
const ChannelState oldState = m_state;
switch (oldState) {
case CloseRequested: // closeChannel() was called while we were in SessionRequested state
case SessionRequested:
break; // Ok, continue.
default:
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet.");
}
m_timeoutTimer.stop();
if (remoteMaxPacketSize < MinMaxPacketSize) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Maximum packet size too low.");
}
qCDebug(sshLog, "Channel opened. remote channel id: %u, remote window size: %u, "
"remote max packet size: %u",
remoteChannelId, remoteWindowSize, remoteMaxPacketSize);
m_remoteChannel = remoteChannelId;
m_remoteWindowSize = remoteWindowSize;
m_remoteMaxPacketSize = remoteMaxPacketSize;
setChannelState(SessionEstablished);
if (oldState == CloseRequested)
closeChannel();
else
handleOpenSuccessInternal();
}
void AbstractSshChannel::handleOpenFailure(const QString &reason)
{
switch (m_state) {
case SessionRequested:
break; // Ok, continue.
case CloseRequested:
return; // Late server reply; we requested a channel close in the meantime.
default:
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
}
m_timeoutTimer.stop();
qCDebug(sshLog, "Channel open request failed for channel %u", m_localChannel);
handleOpenFailureInternal(reason);
}
void AbstractSshChannel::handleChannelEof()
{
if (m_state == Inactive || m_state == Closed) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_EOF message.");
}
m_localWindowSize = 0;
emit eof();
}
void AbstractSshChannel::handleChannelClose()
{
qCDebug(sshLog, "Receiving CLOSE for channel %u", m_localChannel);
if (channelState() == Inactive || channelState() == Closed) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_CLOSE message.");
}
closeChannel();
setChannelState(Closed);
}
void AbstractSshChannel::handleChannelData(const QByteArray &data)
{
const int bytesToDeliver = handleChannelOrExtendedChannelData(data);
handleChannelDataInternal(bytesToDeliver == data.size()
? data : data.left(bytesToDeliver));
}
void AbstractSshChannel::handleChannelExtendedData(quint32 type, const QByteArray &data)
{
const int bytesToDeliver = handleChannelOrExtendedChannelData(data);
handleChannelExtendedDataInternal(type, bytesToDeliver == data.size()
? data : data.left(bytesToDeliver));
}
void AbstractSshChannel::handleChannelRequest(const SshIncomingPacket &packet)
{
checkChannelActive();
const QByteArray &requestType = packet.extractChannelRequestType();
if (requestType == SshIncomingPacket::ExitStatusType)
handleExitStatus(packet.extractChannelExitStatus());
else if (requestType == SshIncomingPacket::ExitSignalType)
handleExitSignal(packet.extractChannelExitSignal());
else if (requestType != "eow@openssh.com") // Suppress warning for this one, as it's sent all the time.
qCWarning(sshLog, "Ignoring unknown request type '%s'", requestType.data());
}
int AbstractSshChannel::handleChannelOrExtendedChannelData(const QByteArray &data)
{
checkChannelActive();
const int bytesToDeliver = qMin<quint32>(data.size(), maxDataSize());
if (bytesToDeliver != data.size())
qCWarning(sshLog, "Misbehaving server does not respect local window, clipping.");
m_localWindowSize -= bytesToDeliver;
if (m_localWindowSize < maxPacketSize()) {
m_localWindowSize += maxPacketSize();
m_sendFacility.sendWindowAdjustPacket(m_remoteChannel, maxPacketSize());
}
return bytesToDeliver;
}
void AbstractSshChannel::closeChannel()
{
if (m_state == CloseRequested) {
m_timeoutTimer.stop();
} else if (m_state != Closed) {
if (m_state == Inactive) {
setChannelState(Closed);
} else {
const ChannelState oldState = m_state;
setChannelState(CloseRequested);
if (m_remoteChannel != NoChannel) {
m_sendFacility.sendChannelEofPacket(m_remoteChannel);
m_sendFacility.sendChannelClosePacket(m_remoteChannel);
} else {
QSSH_ASSERT(oldState == SessionRequested);
}
}
}
}
void AbstractSshChannel::checkChannelActive()
{
if (channelState() == Inactive || channelState() == Closed)
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Channel not open.");
}
quint32 AbstractSshChannel::maxDataSize() const
{
return qMin(m_localWindowSize, maxPacketSize());
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,117 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QByteArray>
#include <QObject>
#include <QString>
#include <QTimer>
namespace QSsh {
namespace Internal {
struct SshChannelExitSignal;
struct SshChannelExitStatus;
class SshIncomingPacket;
class SshSendFacility;
class AbstractSshChannel : public QObject
{
Q_OBJECT
public:
enum ChannelState {
Inactive, SessionRequested, SessionEstablished, CloseRequested, Closed
};
quint32 localChannelId() const { return m_localChannel; }
quint32 remoteChannel() const { return m_remoteChannel; }
virtual void handleChannelSuccess() = 0;
virtual void handleChannelFailure() = 0;
void handleOpenSuccess(quint32 remoteChannelId, quint32 remoteWindowSize,
quint32 remoteMaxPacketSize);
void handleOpenFailure(const QString &reason);
void handleWindowAdjust(quint32 bytesToAdd);
void handleChannelEof();
void handleChannelClose();
void handleChannelData(const QByteArray &data);
void handleChannelExtendedData(quint32 type, const QByteArray &data);
void handleChannelRequest(const SshIncomingPacket &packet);
void closeChannel();
virtual ~AbstractSshChannel();
static const int ReplyTimeout = 10000; // milli seconds
ChannelState channelState() const { return m_state; }
signals:
void timeout();
void eof();
protected:
AbstractSshChannel(quint32 channelId, SshSendFacility &sendFacility);
void setChannelState(ChannelState state);
void requestSessionStart();
void sendData(const QByteArray &data);
static quint32 initialWindowSize();
static quint32 maxPacketSize();
quint32 maxDataSize() const;
void checkChannelActive();
SshSendFacility &m_sendFacility;
QTimer m_timeoutTimer;
private:
virtual void handleOpenSuccessInternal() = 0;
virtual void handleOpenFailureInternal(const QString &reason) = 0;
virtual void handleChannelDataInternal(const QByteArray &data) = 0;
virtual void handleChannelExtendedDataInternal(quint32 type,
const QByteArray &data) = 0;
virtual void handleExitStatus(const SshChannelExitStatus &exitStatus) = 0;
virtual void handleExitSignal(const SshChannelExitSignal &signal) = 0;
virtual void closeHook() = 0;
void flushSendBuffer();
int handleChannelOrExtendedChannelData(const QByteArray &data);
const quint32 m_localChannel;
quint32 m_remoteChannel;
quint32 m_localWindowSize;
quint32 m_remoteWindowSize;
quint32 m_remoteMaxPacketSize;
ChannelState m_state;
QByteArray m_sendBuffer;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,328 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshchannelmanager_p.h"
#include "sftpchannel.h"
#include "sftpchannel_p.h"
#include "sshdirecttcpiptunnel.h"
#include "sshdirecttcpiptunnel_p.h"
#include "sshforwardedtcpiptunnel.h"
#include "sshforwardedtcpiptunnel_p.h"
#include "sshincomingpacket_p.h"
#include "sshlogging_p.h"
#include "sshremoteprocess.h"
#include "sshremoteprocess_p.h"
#include "sshsendfacility_p.h"
#include "sshtcpipforwardserver.h"
#include "sshtcpipforwardserver_p.h"
#include <QList>
namespace QSsh {
namespace Internal {
SshChannelManager::SshChannelManager(SshSendFacility &sendFacility,
QObject *parent)
: QObject(parent), m_sendFacility(sendFacility), m_nextLocalChannelId(0)
{
}
void SshChannelManager::handleChannelRequest(const SshIncomingPacket &packet)
{
lookupChannel(packet.extractRecipientChannel())
->handleChannelRequest(packet);
}
void SshChannelManager::handleChannelOpen(const SshIncomingPacket &packet)
{
SshChannelOpen channelOpen = packet.extractChannelOpen();
SshTcpIpForwardServer::Ptr server;
foreach (const SshTcpIpForwardServer::Ptr &candidate, m_listeningForwardServers) {
if (candidate->port() == channelOpen.remotePort
&& candidate->bindAddress().toUtf8() == channelOpen.remoteAddress) {
server = candidate;
break;
}
};
if (server.isNull()) {
// Apparently the server knows a remoteAddress we are not aware of. There are plenty of ways
// to make that happen: /etc/hosts on the server, different writings for localhost,
// different DNS servers, ...
// Rather than trying to figure that out, we just use the first listening forwarder with the
// same port.
foreach (const SshTcpIpForwardServer::Ptr &candidate, m_listeningForwardServers) {
if (candidate->port() == channelOpen.remotePort) {
server = candidate;
break;
}
};
}
if (server.isNull()) {
SshOpenFailureType reason = (channelOpen.remotePort == 0) ?
SSH_OPEN_UNKNOWN_CHANNEL_TYPE : SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
try {
m_sendFacility.sendChannelOpenFailurePacket(channelOpen.remoteChannel, reason,
QByteArray());
} catch (const std::exception &e) {
qCWarning(sshLog, "Botan error: %s", e.what());
}
return;
}
SshForwardedTcpIpTunnel::Ptr tunnel(new SshForwardedTcpIpTunnel(m_nextLocalChannelId++,
m_sendFacility));
tunnel->d->handleOpenSuccess(channelOpen.remoteChannel, channelOpen.remoteWindowSize,
channelOpen.remoteMaxPacketSize);
tunnel->open(QIODevice::ReadWrite);
server->setNewConnection(tunnel);
insertChannel(tunnel->d, tunnel);
}
void SshChannelManager::handleChannelOpenFailure(const SshIncomingPacket &packet)
{
const SshChannelOpenFailure &failure = packet.extractChannelOpenFailure();
ChannelIterator it = lookupChannelAsIterator(failure.localChannel);
try {
it.value()->handleOpenFailure(failure.reasonString);
} catch (const SshServerException &e) {
removeChannel(it);
throw e;
}
removeChannel(it);
}
void SshChannelManager::handleChannelOpenConfirmation(const SshIncomingPacket &packet)
{
const SshChannelOpenConfirmation &confirmation
= packet.extractChannelOpenConfirmation();
lookupChannel(confirmation.localChannel)->handleOpenSuccess(confirmation.remoteChannel,
confirmation.remoteWindowSize, confirmation.remoteMaxPacketSize);
}
void SshChannelManager::handleChannelSuccess(const SshIncomingPacket &packet)
{
lookupChannel(packet.extractRecipientChannel())->handleChannelSuccess();
}
void SshChannelManager::handleChannelFailure(const SshIncomingPacket &packet)
{
lookupChannel(packet.extractRecipientChannel())->handleChannelFailure();
}
void SshChannelManager::handleChannelWindowAdjust(const SshIncomingPacket &packet)
{
const SshChannelWindowAdjust adjust = packet.extractWindowAdjust();
lookupChannel(adjust.localChannel)->handleWindowAdjust(adjust.bytesToAdd);
}
void SshChannelManager::handleChannelData(const SshIncomingPacket &packet)
{
const SshChannelData &data = packet.extractChannelData();
lookupChannel(data.localChannel)->handleChannelData(data.data);
}
void SshChannelManager::handleChannelExtendedData(const SshIncomingPacket &packet)
{
const SshChannelExtendedData &data = packet.extractChannelExtendedData();
lookupChannel(data.localChannel)->handleChannelExtendedData(data.type, data.data);
}
void SshChannelManager::handleChannelEof(const SshIncomingPacket &packet)
{
AbstractSshChannel * const channel
= lookupChannel(packet.extractRecipientChannel(), true);
if (channel)
channel->handleChannelEof();
}
void SshChannelManager::handleChannelClose(const SshIncomingPacket &packet)
{
const quint32 channelId = packet.extractRecipientChannel();
ChannelIterator it = lookupChannelAsIterator(channelId, true);
if (it != m_channels.end()) {
it.value()->handleChannelClose();
removeChannel(it);
}
}
void SshChannelManager::handleRequestSuccess(const SshIncomingPacket &packet)
{
if (m_waitingForwardServers.isEmpty()) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected request success packet.",
tr("Unexpected request success packet."));
}
SshTcpIpForwardServer::Ptr server = m_waitingForwardServers.takeFirst();
if (server->state() == SshTcpIpForwardServer::Closing) {
server->setClosed();
} else if (server->state() == SshTcpIpForwardServer::Initializing) {
quint16 port = server->port();
if (port == 0)
port = packet.extractRequestSuccess().bindPort;
server->setListening(port);
m_listeningForwardServers.append(server);
} else {
QSSH_ASSERT(false);
}
}
void SshChannelManager::handleRequestFailure(const SshIncomingPacket &packet)
{
Q_UNUSED(packet);
if (m_waitingForwardServers.isEmpty()) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected request failure packet.",
tr("Unexpected request failure packet."));
}
SshTcpIpForwardServer::Ptr tunnel = m_waitingForwardServers.takeFirst();
tunnel->setClosed();
}
SshChannelManager::ChannelIterator SshChannelManager::lookupChannelAsIterator(quint32 channelId,
bool allowNotFound)
{
ChannelIterator it = m_channels.find(channelId);
if (it == m_channels.end() && !allowNotFound) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid channel id.",
tr("Invalid channel id %1").arg(channelId));
}
return it;
}
AbstractSshChannel *SshChannelManager::lookupChannel(quint32 channelId,
bool allowNotFound)
{
ChannelIterator it = lookupChannelAsIterator(channelId, allowNotFound);
return it == m_channels.end() ? 0 : it.value();
}
QSsh::SshRemoteProcess::Ptr SshChannelManager::createRemoteProcess(const QByteArray &command)
{
SshRemoteProcess::Ptr proc(new SshRemoteProcess(command, m_nextLocalChannelId++, m_sendFacility));
insertChannel(proc->d, proc);
return proc;
}
QSsh::SshRemoteProcess::Ptr SshChannelManager::createRemoteShell()
{
SshRemoteProcess::Ptr proc(new SshRemoteProcess(m_nextLocalChannelId++, m_sendFacility));
insertChannel(proc->d, proc);
return proc;
}
QSsh::SftpChannel::Ptr SshChannelManager::createSftpChannel()
{
SftpChannel::Ptr sftp(new SftpChannel(m_nextLocalChannelId++, m_sendFacility));
insertChannel(sftp->d, sftp);
return sftp;
}
SshDirectTcpIpTunnel::Ptr SshChannelManager::createDirectTunnel(const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort)
{
SshDirectTcpIpTunnel::Ptr tunnel(new SshDirectTcpIpTunnel(m_nextLocalChannelId++,
originatingHost, originatingPort, remoteHost, remotePort, m_sendFacility));
insertChannel(tunnel->d, tunnel);
return tunnel;
}
SshTcpIpForwardServer::Ptr SshChannelManager::createForwardServer(const QString &remoteHost,
quint16 remotePort)
{
SshTcpIpForwardServer::Ptr server(new SshTcpIpForwardServer(remoteHost, remotePort,
m_sendFacility));
connect(server.data(), &SshTcpIpForwardServer::stateChanged,
this, [this, server](SshTcpIpForwardServer::State state) {
switch (state) {
case SshTcpIpForwardServer::Closing:
m_listeningForwardServers.removeOne(server);
// fall through
case SshTcpIpForwardServer::Initializing:
m_waitingForwardServers.append(server);
break;
case SshTcpIpForwardServer::Listening:
case SshTcpIpForwardServer::Inactive:
break;
}
});
return server;
}
void SshChannelManager::insertChannel(AbstractSshChannel *priv,
const QSharedPointer<QObject> &pub)
{
connect(priv, &AbstractSshChannel::timeout, this, &SshChannelManager::timeout);
m_channels.insert(priv->localChannelId(), priv);
m_sessions.insert(priv, pub);
}
int SshChannelManager::closeAllChannels(CloseAllMode mode)
{
int count = 0;
for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it) {
AbstractSshChannel * const channel = it.value();
QSSH_ASSERT(channel->channelState() != AbstractSshChannel::Closed);
if (channel->channelState() != AbstractSshChannel::CloseRequested) {
channel->closeChannel();
++count;
}
}
if (mode == CloseAllAndReset) {
m_channels.clear();
m_sessions.clear();
}
return count;
}
int SshChannelManager::channelCount() const
{
return m_channels.count();
}
void SshChannelManager::removeChannel(ChannelIterator it)
{
if (it == m_channels.end()) {
throw SshClientException(SshInternalError,
QLatin1String("Internal error: Unexpected channel lookup failure"));
}
const int removeCount = m_sessions.remove(it.value());
if (removeCount != 1) {
throw SshClientException(SshInternalError,
QString::fromLatin1("Internal error: Unexpected session count %1 for channel.")
.arg(removeCount));
}
m_channels.erase(it);
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,99 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QHash>
#include <QObject>
#include <QSharedPointer>
namespace QSsh {
class SftpChannel;
class SshDirectTcpIpTunnel;
class SshRemoteProcess;
class SshTcpIpForwardServer;
namespace Internal {
class AbstractSshChannel;
class SshIncomingPacket;
class SshSendFacility;
class SshChannelManager : public QObject
{
Q_OBJECT
public:
SshChannelManager(SshSendFacility &sendFacility, QObject *parent);
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
QSharedPointer<SshRemoteProcess> createRemoteShell();
QSharedPointer<SftpChannel> createSftpChannel();
QSharedPointer<SshDirectTcpIpTunnel> createDirectTunnel(const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort);
QSharedPointer<SshTcpIpForwardServer> createForwardServer(const QString &remoteHost,
quint16 remotePort);
int channelCount() const;
enum CloseAllMode { CloseAllRegular, CloseAllAndReset };
int closeAllChannels(CloseAllMode mode);
void handleChannelRequest(const SshIncomingPacket &packet);
void handleChannelOpen(const SshIncomingPacket &packet);
void handleChannelOpenFailure(const SshIncomingPacket &packet);
void handleChannelOpenConfirmation(const SshIncomingPacket &packet);
void handleChannelSuccess(const SshIncomingPacket &packet);
void handleChannelFailure(const SshIncomingPacket &packet);
void handleChannelWindowAdjust(const SshIncomingPacket &packet);
void handleChannelData(const SshIncomingPacket &packet);
void handleChannelExtendedData(const SshIncomingPacket &packet);
void handleChannelEof(const SshIncomingPacket &packet);
void handleChannelClose(const SshIncomingPacket &packet);
void handleRequestSuccess(const SshIncomingPacket &packet);
void handleRequestFailure(const SshIncomingPacket &packet);
signals:
void timeout();
private:
typedef QHash<quint32, AbstractSshChannel *>::Iterator ChannelIterator;
ChannelIterator lookupChannelAsIterator(quint32 channelId,
bool allowNotFound = false);
AbstractSshChannel *lookupChannel(quint32 channelId,
bool allowNotFound = false);
void removeChannel(ChannelIterator it);
void insertChannel(AbstractSshChannel *priv,
const QSharedPointer<QObject> &pub);
SshSendFacility &m_sendFacility;
QHash<quint32, AbstractSshChannel *> m_channels;
QHash<AbstractSshChannel *, QSharedPointer<QObject> > m_sessions;
quint32 m_nextLocalChannelId;
QList<QSharedPointer<SshTcpIpForwardServer>> m_waitingForwardServers;
QList<QSharedPointer<SshTcpIpForwardServer>> m_listeningForwardServers;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,864 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshconnection.h"
#include "sshconnection_p.h"
#include "sftpchannel.h"
#include "sshcapabilities_p.h"
#include "sshchannelmanager_p.h"
#include "sshcryptofacility_p.h"
#include "sshdirecttcpiptunnel.h"
#include "sshtcpipforwardserver.h"
#include "sshexception_p.h"
#include "sshinit_p.h"
#include "sshkeyexchange_p.h"
#include "sshlogging_p.h"
#include "sshremoteprocess.h"
#include <botan/botan.h>
#include <QFile>
#include <QMutex>
#include <QMutexLocker>
#include <QNetworkProxy>
#include <QRegExp>
#include <QTcpSocket>
/*!
\class QSsh::SshConnection
\brief The SshConnection class provides an SSH connection, implementing
protocol version 2.0.
It can spawn channels for remote execution and SFTP operations (version 3).
It operates asynchronously (non-blocking) and is not thread-safe.
*/
namespace QSsh {
const QByteArray ClientId("SSH-2.0-QtCreator\r\n");
SshConnectionParameters::SshConnectionParameters() :
timeout(0), authenticationType(AuthenticationTypePublicKey), port(0),
hostKeyCheckingMode(SshHostKeyCheckingNone)
{
options |= SshIgnoreDefaultProxy;
options |= SshEnableStrictConformanceChecks;
}
static inline bool equals(const SshConnectionParameters &p1, const SshConnectionParameters &p2)
{
return p1.host == p2.host && p1.userName == p2.userName
&& p1.authenticationType == p2.authenticationType
&& (p1.authenticationType == SshConnectionParameters::AuthenticationTypePassword ?
p1.password == p2.password : p1.privateKeyFile == p2.privateKeyFile)
&& p1.hostKeyCheckingMode == p2.hostKeyCheckingMode
&& p1.timeout == p2.timeout && p1.port == p2.port;
}
bool operator==(const SshConnectionParameters &p1, const SshConnectionParameters &p2)
{
return equals(p1, p2);
}
bool operator!=(const SshConnectionParameters &p1, const SshConnectionParameters &p2)
{
return !equals(p1, p2);
}
SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject *parent)
: QObject(parent)
{
Internal::initSsh();
qRegisterMetaType<QSsh::SshError>("QSsh::SshError");
qRegisterMetaType<QSsh::SftpJobId>("QSsh::SftpJobId");
qRegisterMetaType<QSsh::SftpFileInfo>("QSsh::SftpFileInfo");
qRegisterMetaType<QList <QSsh::SftpFileInfo> >("QList<QSsh::SftpFileInfo>");
d = new Internal::SshConnectionPrivate(this, serverInfo);
connect(d, &Internal::SshConnectionPrivate::connected, this, &SshConnection::connected,
Qt::QueuedConnection);
connect(d, &Internal::SshConnectionPrivate::dataAvailable, this,
&SshConnection::dataAvailable, Qt::QueuedConnection);
connect(d, &Internal::SshConnectionPrivate::disconnected, this, &SshConnection::disconnected,
Qt::QueuedConnection);
connect(d, &Internal::SshConnectionPrivate::error, this,
&SshConnection::error, Qt::QueuedConnection);
}
void SshConnection::connectToHost()
{
d->connectToHost();
}
void SshConnection::disconnectFromHost()
{
d->closeConnection(Internal::SSH_DISCONNECT_BY_APPLICATION, SshNoError, "",
QString());
}
SshConnection::State SshConnection::state() const
{
switch (d->state()) {
case Internal::SocketUnconnected:
return Unconnected;
case Internal::ConnectionEstablished:
return Connected;
default:
return Connecting;
}
}
SshError SshConnection::errorState() const
{
return d->errorState();
}
QString SshConnection::errorString() const
{
return d->errorString();
}
SshConnectionParameters SshConnection::connectionParameters() const
{
return d->m_connParams;
}
SshConnectionInfo SshConnection::connectionInfo() const
{
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, SshConnectionInfo());
return SshConnectionInfo(d->m_socket->localAddress(), d->m_socket->localPort(),
d->m_socket->peerAddress(), d->m_socket->peerPort());
}
SshConnection::~SshConnection()
{
disconnect();
disconnectFromHost();
delete d;
}
QSharedPointer<SshRemoteProcess> SshConnection::createRemoteProcess(const QByteArray &command)
{
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, QSharedPointer<SshRemoteProcess>());
return d->createRemoteProcess(command);
}
QSharedPointer<SshRemoteProcess> SshConnection::createRemoteShell()
{
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, QSharedPointer<SshRemoteProcess>());
return d->createRemoteShell();
}
QSharedPointer<SftpChannel> SshConnection::createSftpChannel()
{
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, QSharedPointer<SftpChannel>());
return d->createSftpChannel();
}
SshDirectTcpIpTunnel::Ptr SshConnection::createDirectTunnel(const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort)
{
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, SshDirectTcpIpTunnel::Ptr());
return d->createDirectTunnel(originatingHost, originatingPort, remoteHost, remotePort);
}
QSharedPointer<SshTcpIpForwardServer> SshConnection::createForwardServer(const QString &remoteHost,
quint16 remotePort)
{
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, SshTcpIpForwardServer::Ptr());
return d->createForwardServer(remoteHost, remotePort);
}
int SshConnection::closeAllChannels()
{
try {
return d->m_channelManager->closeAllChannels(Internal::SshChannelManager::CloseAllRegular);
} catch (const std::exception &e) {
qCWarning(Internal::sshLog, "%s: %s", Q_FUNC_INFO, e.what());
return -1;
}
}
int SshConnection::channelCount() const
{
return d->m_channelManager->channelCount();
}
namespace Internal {
SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn,
const SshConnectionParameters &serverInfo)
: m_socket(new QTcpSocket(this)), m_state(SocketUnconnected),
m_sendFacility(m_socket),
m_channelManager(new SshChannelManager(m_sendFacility, this)),
m_connParams(serverInfo), m_error(SshNoError), m_ignoreNextPacket(false),
m_conn(conn)
{
setupPacketHandlers();
m_socket->setProxy((m_connParams.options & SshIgnoreDefaultProxy)
? QNetworkProxy::NoProxy : QNetworkProxy::DefaultProxy);
m_timeoutTimer.setSingleShot(true);
m_timeoutTimer.setInterval(m_connParams.timeout * 1000);
m_keepAliveTimer.setSingleShot(true);
m_keepAliveTimer.setInterval(10000);
connect(m_channelManager, &SshChannelManager::timeout,
this, &SshConnectionPrivate::handleTimeout);
}
SshConnectionPrivate::~SshConnectionPrivate()
{
disconnect();
}
void SshConnectionPrivate::setupPacketHandlers()
{
typedef SshConnectionPrivate This;
setupPacketHandler(SSH_MSG_KEXINIT, StateList() << SocketConnected
<< ConnectionEstablished, &This::handleKeyExchangeInitPacket);
setupPacketHandler(SSH_MSG_KEXDH_REPLY, StateList() << SocketConnected
<< ConnectionEstablished, &This::handleKeyExchangeReplyPacket);
setupPacketHandler(SSH_MSG_NEWKEYS, StateList() << SocketConnected
<< ConnectionEstablished, &This::handleNewKeysPacket);
setupPacketHandler(SSH_MSG_SERVICE_ACCEPT,
StateList() << UserAuthServiceRequested,
&This::handleServiceAcceptPacket);
if (m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypePassword
|| m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypeTryAllPasswordBasedMethods) {
setupPacketHandler(SSH_MSG_USERAUTH_PASSWD_CHANGEREQ,
StateList() << UserAuthRequested, &This::handlePasswordExpiredPacket);
}
setupPacketHandler(SSH_MSG_GLOBAL_REQUEST,
StateList() << ConnectionEstablished, &This::handleGlobalRequest);
const StateList authReqList = StateList() << UserAuthRequested;
setupPacketHandler(SSH_MSG_USERAUTH_BANNER, authReqList,
&This::handleUserAuthBannerPacket);
setupPacketHandler(SSH_MSG_USERAUTH_SUCCESS, authReqList,
&This::handleUserAuthSuccessPacket);
setupPacketHandler(SSH_MSG_USERAUTH_FAILURE, authReqList,
&This::handleUserAuthFailurePacket);
if (m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypeKeyboardInteractive
|| m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypeTryAllPasswordBasedMethods) {
setupPacketHandler(SSH_MSG_USERAUTH_INFO_REQUEST, authReqList,
&This::handleUserAuthInfoRequestPacket);
}
const StateList connectedList
= StateList() << ConnectionEstablished;
setupPacketHandler(SSH_MSG_CHANNEL_REQUEST, connectedList,
&This::handleChannelRequest);
setupPacketHandler(SSH_MSG_CHANNEL_OPEN, connectedList,
&This::handleChannelOpen);
setupPacketHandler(SSH_MSG_CHANNEL_OPEN_FAILURE, connectedList,
&This::handleChannelOpenFailure);
setupPacketHandler(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, connectedList,
&This::handleChannelOpenConfirmation);
setupPacketHandler(SSH_MSG_CHANNEL_SUCCESS, connectedList,
&This::handleChannelSuccess);
setupPacketHandler(SSH_MSG_CHANNEL_FAILURE, connectedList,
&This::handleChannelFailure);
setupPacketHandler(SSH_MSG_CHANNEL_WINDOW_ADJUST, connectedList,
&This::handleChannelWindowAdjust);
setupPacketHandler(SSH_MSG_CHANNEL_DATA, connectedList,
&This::handleChannelData);
setupPacketHandler(SSH_MSG_CHANNEL_EXTENDED_DATA, connectedList,
&This::handleChannelExtendedData);
const StateList connectedOrClosedList
= StateList() << SocketUnconnected << ConnectionEstablished;
setupPacketHandler(SSH_MSG_CHANNEL_EOF, connectedOrClosedList,
&This::handleChannelEof);
setupPacketHandler(SSH_MSG_CHANNEL_CLOSE, connectedOrClosedList,
&This::handleChannelClose);
setupPacketHandler(SSH_MSG_DISCONNECT, StateList() << SocketConnected
<< UserAuthServiceRequested << UserAuthRequested
<< ConnectionEstablished, &This::handleDisconnect);
setupPacketHandler(SSH_MSG_UNIMPLEMENTED,
StateList() << ConnectionEstablished, &This::handleUnimplementedPacket);
setupPacketHandler(SSH_MSG_REQUEST_SUCCESS, connectedList,
&This::handleRequestSuccess);
setupPacketHandler(SSH_MSG_REQUEST_FAILURE, connectedList,
&This::handleRequestFailure);
}
void SshConnectionPrivate::setupPacketHandler(SshPacketType type,
const SshConnectionPrivate::StateList &states,
SshConnectionPrivate::PacketHandler handler)
{
m_packetHandlers.insert(type, HandlerInStates(states, handler));
}
void SshConnectionPrivate::handleSocketConnected()
{
m_state = SocketConnected;
sendData(ClientId);
}
void SshConnectionPrivate::handleIncomingData()
{
if (m_state == SocketUnconnected)
return; // For stuff queued in the event loop after we've called closeConnection();
try {
if (!canUseSocket())
return;
m_incomingData += m_socket->readAll();
qCDebug(sshLog, "state = %d, remote data size = %d", m_state, m_incomingData.count());
if (m_serverId.isEmpty())
handleServerId();
handlePackets();
} catch (const SshServerException &e) {
closeConnection(e.error, SshProtocolError, e.errorStringServer,
tr("SSH Protocol error: %1").arg(e.errorStringUser));
} catch (const SshClientException &e) {
closeConnection(SSH_DISCONNECT_BY_APPLICATION, e.error, "",
e.errorString);
} catch (const std::exception &e) {
closeConnection(SSH_DISCONNECT_BY_APPLICATION, SshInternalError, "",
tr("Botan library exception: %1").arg(QString::fromLatin1(e.what())));
}
}
// RFC 4253, 4.2.
void SshConnectionPrivate::handleServerId()
{
qCDebug(sshLog, "%s: incoming data size = %d, incoming data = '%s'",
Q_FUNC_INFO, m_incomingData.count(), m_incomingData.data());
const int newLinePos = m_incomingData.indexOf('\n');
if (newLinePos == -1)
return; // Not enough data yet.
// Lines not starting with "SSH-" are ignored.
if (!m_incomingData.startsWith("SSH-")) {
m_incomingData.remove(0, newLinePos + 1);
m_serverHasSentDataBeforeId = true;
return;
}
if (newLinePos > 255 - 1) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Identification string too long.",
tr("Server identification string is %n characters long, but the maximum "
"allowed length is 255.", 0, newLinePos + 1));
}
const bool hasCarriageReturn = m_incomingData.at(newLinePos - 1) == '\r';
m_serverId = m_incomingData.left(newLinePos);
if (hasCarriageReturn)
m_serverId.chop(1);
m_incomingData.remove(0, newLinePos + 1);
if (m_serverId.contains('\0')) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Identification string contains illegal NUL character.",
tr("Server identification string contains illegal NUL character."));
}
// "printable US-ASCII characters, with the exception of whitespace characters
// and the minus sign"
QString legalString = QLatin1String("[]!\"#$!&'()*+,./0-9:;<=>?@A-Z[\\\\^_`a-z{|}~]+");
const QRegExp versionIdpattern(QString::fromLatin1("SSH-(%1)-%1(?: .+)?").arg(legalString));
if (!versionIdpattern.exactMatch(QString::fromLatin1(m_serverId))) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Identification string is invalid.",
tr("Server Identification string \"%1\" is invalid.")
.arg(QString::fromLatin1(m_serverId)));
}
const QString serverProtoVersion = versionIdpattern.cap(1);
if (serverProtoVersion != QLatin1String("2.0") && serverProtoVersion != QLatin1String("1.99")) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
"Invalid protocol version.",
tr("Server protocol version is \"%1\", but needs to be 2.0 or 1.99.")
.arg(serverProtoVersion));
}
if (m_connParams.options & SshEnableStrictConformanceChecks) {
if (serverProtoVersion == QLatin1String("2.0") && !hasCarriageReturn) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Identification string is invalid.",
tr("Server identification string is invalid (missing carriage return)."));
}
if (serverProtoVersion == QLatin1String("1.99") && m_serverHasSentDataBeforeId) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"No extra data preceding identification string allowed for 1.99.",
tr("Server reports protocol version 1.99, but sends data "
"before the identification string, which is not allowed."));
}
}
m_keyExchange.reset(new SshKeyExchange(m_connParams, m_sendFacility));
m_keyExchange->sendKexInitPacket(m_serverId);
m_keyExchangeState = KexInitSent;
}
void SshConnectionPrivate::handlePackets()
{
m_incomingPacket.consumeData(m_incomingData);
while (m_incomingPacket.isComplete()) {
handleCurrentPacket();
m_incomingPacket.clear();
m_incomingPacket.consumeData(m_incomingData);
}
}
void SshConnectionPrivate::handleCurrentPacket()
{
Q_ASSERT(m_incomingPacket.isComplete());
Q_ASSERT(m_keyExchangeState == DhInitSent || !m_ignoreNextPacket);
if (m_ignoreNextPacket) {
m_ignoreNextPacket = false;
return;
}
QHash<SshPacketType, HandlerInStates>::ConstIterator it
= m_packetHandlers.constFind(m_incomingPacket.type());
if (it == m_packetHandlers.constEnd()) {
m_sendFacility.sendMsgUnimplementedPacket(m_incomingPacket.serverSeqNr());
return;
}
if (!it.value().first.contains(m_state)) {
handleUnexpectedPacket();
return;
}
(this->*it.value().second)();
}
void SshConnectionPrivate::handleKeyExchangeInitPacket()
{
if (m_keyExchangeState != NoKeyExchange
&& m_keyExchangeState != KexInitSent) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet.", tr("Unexpected packet of type %1.")
.arg(m_incomingPacket.type()));
}
// Server-initiated re-exchange.
if (m_keyExchangeState == NoKeyExchange) {
m_keyExchange.reset(new SshKeyExchange(m_connParams, m_sendFacility));
m_keyExchange->sendKexInitPacket(m_serverId);
}
// If the server sends a guessed packet, the guess must be wrong,
// because the algorithms we support require us to initiate the
// key exchange.
if (m_keyExchange->sendDhInitPacket(m_incomingPacket))
m_ignoreNextPacket = true;
m_keyExchangeState = DhInitSent;
}
void SshConnectionPrivate::handleKeyExchangeReplyPacket()
{
if (m_keyExchangeState != DhInitSent) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet.", tr("Unexpected packet of type %1.")
.arg(m_incomingPacket.type()));
}
m_keyExchange->sendNewKeysPacket(m_incomingPacket,
ClientId.left(ClientId.size() - 2));
m_sendFacility.recreateKeys(*m_keyExchange);
m_keyExchangeState = NewKeysSent;
}
void SshConnectionPrivate::handleNewKeysPacket()
{
if (m_keyExchangeState != NewKeysSent) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet.", tr("Unexpected packet of type %1.")
.arg(m_incomingPacket.type()));
}
m_incomingPacket.recreateKeys(*m_keyExchange);
m_keyExchange.reset();
m_keyExchangeState = NoKeyExchange;
if (m_state == SocketConnected) {
m_sendFacility.sendUserAuthServiceRequestPacket();
m_state = UserAuthServiceRequested;
}
}
void SshConnectionPrivate::handleServiceAcceptPacket()
{
switch (m_connParams.authenticationType) {
case SshConnectionParameters::AuthenticationTypeTryAllPasswordBasedMethods:
m_triedAllPasswordBasedMethods = false;
// Fall-through.
case SshConnectionParameters::AuthenticationTypePassword:
m_sendFacility.sendUserAuthByPasswordRequestPacket(m_connParams.userName.toUtf8(),
SshCapabilities::SshConnectionService, m_connParams.password.toUtf8());
break;
case SshConnectionParameters::AuthenticationTypeKeyboardInteractive:
m_sendFacility.sendUserAuthByKeyboardInteractiveRequestPacket(m_connParams.userName.toUtf8(),
SshCapabilities::SshConnectionService);
break;
case SshConnectionParameters::AuthenticationTypePublicKey:
m_sendFacility.sendUserAuthByPublicKeyRequestPacket(m_connParams.userName.toUtf8(),
SshCapabilities::SshConnectionService);
break;
}
m_state = UserAuthRequested;
}
void SshConnectionPrivate::handlePasswordExpiredPacket()
{
if (m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypeTryAllPasswordBasedMethods
&& m_triedAllPasswordBasedMethods) {
// This means we just tried to authorize via "keyboard-interactive", in which case
// this type of packet is not allowed.
handleUnexpectedPacket();
return;
}
throw SshClientException(SshAuthenticationError, tr("Password expired."));
}
void SshConnectionPrivate::handleUserAuthInfoRequestPacket()
{
if (m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypeTryAllPasswordBasedMethods
&& !m_triedAllPasswordBasedMethods) {
// This means we just tried to authorize via "password", in which case
// this type of packet is not allowed.
handleUnexpectedPacket();
return;
}
const SshUserAuthInfoRequestPacket requestPacket
= m_incomingPacket.extractUserAuthInfoRequest();
QStringList responses;
responses.reserve(requestPacket.prompts.count());
// Not very interactive, admittedly, but we don't want to be for now.
for (int i = 0; i < requestPacket.prompts.count(); ++i)
responses << m_connParams.password;
m_sendFacility.sendUserAuthInfoResponsePacket(responses);
}
void SshConnectionPrivate::handleUserAuthBannerPacket()
{
emit dataAvailable(m_incomingPacket.extractUserAuthBanner().message);
}
void SshConnectionPrivate::handleUnexpectedPacket()
{
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet.", tr("Unexpected packet of type %1.")
.arg(m_incomingPacket.type()));
}
void SshConnectionPrivate::handleGlobalRequest()
{
m_sendFacility.sendRequestFailurePacket();
}
void SshConnectionPrivate::handleUserAuthSuccessPacket()
{
m_state = ConnectionEstablished;
m_timeoutTimer.stop();
emit connected();
m_lastInvalidMsgSeqNr = InvalidSeqNr;
connect(&m_keepAliveTimer, &QTimer::timeout, this, &SshConnectionPrivate::sendKeepAlivePacket);
m_keepAliveTimer.start();
}
void SshConnectionPrivate::handleUserAuthFailurePacket()
{
// TODO: Evaluate "authentications that can continue" field and act on it.
if (m_connParams.authenticationType
== SshConnectionParameters::AuthenticationTypeTryAllPasswordBasedMethods
&& !m_triedAllPasswordBasedMethods) {
m_triedAllPasswordBasedMethods = true;
m_sendFacility.sendUserAuthByKeyboardInteractiveRequestPacket(
m_connParams.userName.toUtf8(),
SshCapabilities::SshConnectionService);
return;
}
m_timeoutTimer.stop();
const QString errorMsg = m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypePublicKey
? tr("Server rejected key.") : tr("Server rejected password.");
throw SshClientException(SshAuthenticationError, errorMsg);
}
void SshConnectionPrivate::handleDebugPacket()
{
const SshDebug &msg = m_incomingPacket.extractDebug();
if (msg.display)
emit dataAvailable(msg.message);
}
void SshConnectionPrivate::handleUnimplementedPacket()
{
const SshUnimplemented &msg = m_incomingPacket.extractUnimplemented();
if (msg.invalidMsgSeqNr != m_lastInvalidMsgSeqNr) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet", tr("The server sent an unexpected SSH packet "
"of type SSH_MSG_UNIMPLEMENTED."));
}
m_lastInvalidMsgSeqNr = InvalidSeqNr;
m_timeoutTimer.stop();
m_keepAliveTimer.start();
}
void SshConnectionPrivate::handleChannelRequest()
{
m_channelManager->handleChannelRequest(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelOpen()
{
m_channelManager->handleChannelOpen(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelOpenFailure()
{
m_channelManager->handleChannelOpenFailure(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelOpenConfirmation()
{
m_channelManager->handleChannelOpenConfirmation(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelSuccess()
{
m_channelManager->handleChannelSuccess(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelFailure()
{
m_channelManager->handleChannelFailure(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelWindowAdjust()
{
m_channelManager->handleChannelWindowAdjust(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelData()
{
m_channelManager->handleChannelData(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelExtendedData()
{
m_channelManager->handleChannelExtendedData(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelEof()
{
m_channelManager->handleChannelEof(m_incomingPacket);
}
void SshConnectionPrivate::handleChannelClose()
{
m_channelManager->handleChannelClose(m_incomingPacket);
}
void SshConnectionPrivate::handleDisconnect()
{
const SshDisconnect msg = m_incomingPacket.extractDisconnect();
throw SshServerException(SSH_DISCONNECT_CONNECTION_LOST,
"", tr("Server closed connection: %1").arg(msg.description));
}
void SshConnectionPrivate::handleRequestSuccess()
{
m_channelManager->handleRequestSuccess(m_incomingPacket);
}
void SshConnectionPrivate::handleRequestFailure()
{
m_channelManager->handleRequestFailure(m_incomingPacket);
}
void SshConnectionPrivate::sendData(const QByteArray &data)
{
if (canUseSocket())
m_socket->write(data);
}
void SshConnectionPrivate::handleSocketDisconnected()
{
closeConnection(SSH_DISCONNECT_CONNECTION_LOST, SshClosedByServerError,
"Connection closed unexpectedly.",
tr("Connection closed unexpectedly."));
}
void SshConnectionPrivate::handleSocketError()
{
if (m_error == SshNoError) {
closeConnection(SSH_DISCONNECT_CONNECTION_LOST, SshSocketError,
"Network error", m_socket->errorString());
}
}
void SshConnectionPrivate::handleTimeout()
{
closeConnection(SSH_DISCONNECT_BY_APPLICATION, SshTimeoutError, "",
tr("Timeout waiting for reply from server."));
}
void SshConnectionPrivate::sendKeepAlivePacket()
{
// This type of message is not allowed during key exchange.
if (m_keyExchangeState != NoKeyExchange) {
m_keepAliveTimer.start();
return;
}
Q_ASSERT(m_lastInvalidMsgSeqNr == InvalidSeqNr);
m_lastInvalidMsgSeqNr = m_sendFacility.nextClientSeqNr();
m_sendFacility.sendInvalidPacket();
m_timeoutTimer.start();
}
void SshConnectionPrivate::connectToHost()
{
QSSH_ASSERT_AND_RETURN(m_state == SocketUnconnected);
m_incomingData.clear();
m_incomingPacket.reset();
m_sendFacility.reset();
m_error = SshNoError;
m_ignoreNextPacket = false;
m_errorString.clear();
m_serverId.clear();
m_serverHasSentDataBeforeId = false;
try {
if (m_connParams.authenticationType == SshConnectionParameters::AuthenticationTypePublicKey)
createPrivateKey();
} catch (const SshClientException &ex) {
m_error = ex.error;
m_errorString = ex.errorString;
emit error(m_error);
return;
}
connect(m_socket, &QAbstractSocket::connected,
this, &SshConnectionPrivate::handleSocketConnected);
connect(m_socket, &QIODevice::readyRead,
this, &SshConnectionPrivate::handleIncomingData);
connect(m_socket,
static_cast<void (QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),
this, &SshConnectionPrivate::handleSocketError);
connect(m_socket, &QAbstractSocket::disconnected,
this, &SshConnectionPrivate::handleSocketDisconnected);
connect(&m_timeoutTimer, &QTimer::timeout, this, &SshConnectionPrivate::handleTimeout);
m_state = SocketConnecting;
m_keyExchangeState = NoKeyExchange;
m_timeoutTimer.start();
m_socket->connectToHost(m_connParams.host, m_connParams.port);
}
void SshConnectionPrivate::closeConnection(SshErrorCode sshError,
SshError userError, const QByteArray &serverErrorString,
const QString &userErrorString)
{
// Prevent endless loops by recursive exceptions.
if (m_state == SocketUnconnected || m_error != SshNoError)
return;
m_error = userError;
m_errorString = userErrorString;
m_timeoutTimer.stop();
disconnect(m_socket, 0, this, 0);
disconnect(&m_timeoutTimer, 0, this, 0);
m_keepAliveTimer.stop();
disconnect(&m_keepAliveTimer, 0, this, 0);
try {
m_channelManager->closeAllChannels(SshChannelManager::CloseAllAndReset);
m_sendFacility.sendDisconnectPacket(sshError, serverErrorString);
} catch (...) {} // Nothing sensible to be done here.
if (m_error != SshNoError)
emit error(userError);
if (m_state == ConnectionEstablished)
emit disconnected();
if (canUseSocket())
m_socket->disconnectFromHost();
m_state = SocketUnconnected;
}
bool SshConnectionPrivate::canUseSocket() const
{
return m_socket->isValid()
&& m_socket->state() == QAbstractSocket::ConnectedState;
}
void SshConnectionPrivate::createPrivateKey()
{
if (m_connParams.privateKeyFile.isEmpty())
throw SshClientException(SshKeyFileError, tr("No private key file given."));
QFile keyFile(m_connParams.privateKeyFile);
if (!keyFile.open(QIODevice::ReadOnly)) {
throw SshClientException(SshKeyFileError,
tr("Private key file error: %1").arg(keyFile.errorString()));
}
m_sendFacility.createAuthenticationKey(keyFile.readAll());
}
QSharedPointer<SshRemoteProcess> SshConnectionPrivate::createRemoteProcess(const QByteArray &command)
{
return m_channelManager->createRemoteProcess(command);
}
QSharedPointer<SshRemoteProcess> SshConnectionPrivate::createRemoteShell()
{
return m_channelManager->createRemoteShell();
}
QSharedPointer<SftpChannel> SshConnectionPrivate::createSftpChannel()
{
return m_channelManager->createSftpChannel();
}
SshDirectTcpIpTunnel::Ptr SshConnectionPrivate::createDirectTunnel(const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort)
{
return m_channelManager->createDirectTunnel(originatingHost, originatingPort, remoteHost,
remotePort);
}
SshTcpIpForwardServer::Ptr SshConnectionPrivate::createForwardServer(const QString &bindAddress,
quint16 bindPort)
{
return m_channelManager->createForwardServer(bindAddress, bindPort);
}
const quint64 SshConnectionPrivate::InvalidSeqNr = static_cast<quint64>(-1);
} // namespace Internal
} // namespace QSsh

View File

@@ -1,145 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssherrors.h"
#include "sshhostkeydatabase.h"
#include "ssh_global.h"
#include <QByteArray>
#include <QFlags>
#include <QObject>
#include <QSharedPointer>
#include <QString>
#include <QHostAddress>
namespace QSsh {
class SftpChannel;
class SshDirectTcpIpTunnel;
class SshRemoteProcess;
class SshTcpIpForwardServer;
namespace Internal { class SshConnectionPrivate; }
enum SshConnectionOption {
SshIgnoreDefaultProxy = 0x1,
SshEnableStrictConformanceChecks = 0x2
};
Q_DECLARE_FLAGS(SshConnectionOptions, SshConnectionOption)
enum SshHostKeyCheckingMode {
SshHostKeyCheckingNone,
SshHostKeyCheckingStrict,
SshHostKeyCheckingAllowNoMatch,
SshHostKeyCheckingAllowMismatch
};
class QSSH_EXPORT SshConnectionParameters
{
public:
enum AuthenticationType {
AuthenticationTypePassword,
AuthenticationTypePublicKey,
AuthenticationTypeKeyboardInteractive,
// Some servers disable "password", others disable "keyboard-interactive".
AuthenticationTypeTryAllPasswordBasedMethods
};
SshConnectionParameters();
QString host;
QString userName;
QString password;
QString privateKeyFile;
int timeout; // In seconds.
AuthenticationType authenticationType;
quint16 port;
SshConnectionOptions options;
SshHostKeyCheckingMode hostKeyCheckingMode;
SshHostKeyDatabasePtr hostKeyDatabase;
};
QSSH_EXPORT bool operator==(const SshConnectionParameters &p1, const SshConnectionParameters &p2);
QSSH_EXPORT bool operator!=(const SshConnectionParameters &p1, const SshConnectionParameters &p2);
class QSSH_EXPORT SshConnectionInfo
{
public:
SshConnectionInfo() : localPort(0), peerPort(0) {}
SshConnectionInfo(const QHostAddress &la, quint16 lp, const QHostAddress &pa, quint16 pp)
: localAddress(la), localPort(lp), peerAddress(pa), peerPort(pp) {}
QHostAddress localAddress;
quint16 localPort;
QHostAddress peerAddress;
quint16 peerPort;
};
class QSSH_EXPORT SshConnection : public QObject
{
Q_OBJECT
public:
enum State { Unconnected, Connecting, Connected };
explicit SshConnection(const SshConnectionParameters &serverInfo, QObject *parent = 0);
void connectToHost();
void disconnectFromHost();
State state() const;
SshError errorState() const;
QString errorString() const;
SshConnectionParameters connectionParameters() const;
SshConnectionInfo connectionInfo() const;
~SshConnection();
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
QSharedPointer<SshRemoteProcess> createRemoteShell();
QSharedPointer<SftpChannel> createSftpChannel();
QSharedPointer<SshDirectTcpIpTunnel> createDirectTunnel(const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort);
QSharedPointer<SshTcpIpForwardServer> createForwardServer(const QString &remoteHost,
quint16 remotePort);
// -1 if an error occurred, number of channels closed otherwise.
int closeAllChannels();
int channelCount() const;
signals:
void connected();
void disconnected();
void dataAvailable(const QString &message);
void error(QSsh::SshError);
private:
Internal::SshConnectionPrivate *d;
};
} // namespace QSsh

View File

@@ -1,179 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sshconnection.h"
#include "sshexception_p.h"
#include "sshincomingpacket_p.h"
#include "sshsendfacility_p.h"
#include <QHash>
#include <QList>
#include <QObject>
#include <QPair>
#include <QScopedPointer>
#include <QTimer>
QT_BEGIN_NAMESPACE
class QTcpSocket;
QT_END_NAMESPACE
namespace QSsh {
class SftpChannel;
class SshRemoteProcess;
class SshDirectTcpIpTunnel;
class SshTcpIpForwardServer;
namespace Internal {
class SshChannelManager;
// NOTE: When you add stuff here, don't forget to update m_packetHandlers.
enum SshStateInternal {
SocketUnconnected, // initial and after disconnect
SocketConnecting, // After connectToHost()
SocketConnected, // After socket's connected() signal
UserAuthServiceRequested,
UserAuthRequested,
ConnectionEstablished // After service has been started
// ...
};
enum SshKeyExchangeState {
NoKeyExchange,
KexInitSent,
DhInitSent,
NewKeysSent,
KeyExchangeSuccess // After server's DH_REPLY message
};
class SshConnectionPrivate : public QObject
{
Q_OBJECT
friend class QSsh::SshConnection;
public:
SshConnectionPrivate(SshConnection *conn,
const SshConnectionParameters &serverInfo);
~SshConnectionPrivate();
void connectToHost();
void closeConnection(SshErrorCode sshError, SshError userError,
const QByteArray &serverErrorString, const QString &userErrorString);
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
QSharedPointer<SshRemoteProcess> createRemoteShell();
QSharedPointer<SftpChannel> createSftpChannel();
QSharedPointer<SshDirectTcpIpTunnel> createDirectTunnel(const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort);
QSharedPointer<SshTcpIpForwardServer> createForwardServer(const QString &remoteHost,
quint16 remotePort);
SshStateInternal state() const { return m_state; }
SshError errorState() const { return m_error; }
QString errorString() const { return m_errorString; }
signals:
void connected();
void disconnected();
void dataAvailable(const QString &message);
void error(QSsh::SshError);
private:
void handleSocketConnected();
void handleIncomingData();
void handleSocketError();
void handleSocketDisconnected();
void handleTimeout();
void sendKeepAlivePacket();
void handleServerId();
void handlePackets();
void handleCurrentPacket();
void handleKeyExchangeInitPacket();
void handleKeyExchangeReplyPacket();
void handleNewKeysPacket();
void handleServiceAcceptPacket();
void handlePasswordExpiredPacket();
void handleUserAuthInfoRequestPacket();
void handleUserAuthSuccessPacket();
void handleUserAuthFailurePacket();
void handleUserAuthBannerPacket();
void handleUnexpectedPacket();
void handleGlobalRequest();
void handleDebugPacket();
void handleUnimplementedPacket();
void handleChannelRequest();
void handleChannelOpen();
void handleChannelOpenFailure();
void handleChannelOpenConfirmation();
void handleChannelSuccess();
void handleChannelFailure();
void handleChannelWindowAdjust();
void handleChannelData();
void handleChannelExtendedData();
void handleChannelEof();
void handleChannelClose();
void handleDisconnect();
void handleRequestSuccess();
void handleRequestFailure();
bool canUseSocket() const;
void createPrivateKey();
void sendData(const QByteArray &data);
typedef void (SshConnectionPrivate::*PacketHandler)();
typedef QList<SshStateInternal> StateList;
void setupPacketHandlers();
void setupPacketHandler(SshPacketType type, const StateList &states,
PacketHandler handler);
typedef QPair<StateList, PacketHandler> HandlerInStates;
QHash<SshPacketType, HandlerInStates> m_packetHandlers;
static const quint64 InvalidSeqNr;
QTcpSocket *m_socket;
SshStateInternal m_state;
SshKeyExchangeState m_keyExchangeState;
SshIncomingPacket m_incomingPacket;
SshSendFacility m_sendFacility;
SshChannelManager * const m_channelManager;
const SshConnectionParameters m_connParams;
QByteArray m_incomingData;
SshError m_error;
QString m_errorString;
QScopedPointer<SshKeyExchange> m_keyExchange;
QTimer m_timeoutTimer;
QTimer m_keepAliveTimer;
bool m_ignoreNextPacket;
SshConnection *m_conn;
quint64 m_lastInvalidMsgSeqNr;
QByteArray m_serverId;
bool m_serverHasSentDataBeforeId;
bool m_triedAllPasswordBasedMethods;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,270 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshconnectionmanager.h"
#include "sshconnection.h"
#include <QCoreApplication>
#include <QList>
#include <QMutex>
#include <QMutexLocker>
#include <QObject>
#include <QThread>
#include <QTimer>
namespace QSsh {
namespace Internal {
class UnaquiredConnection {
public:
UnaquiredConnection(SshConnection *conn) : connection(conn), scheduledForRemoval(false) {}
SshConnection *connection;
bool scheduledForRemoval;
};
bool operator==(const UnaquiredConnection &c1, const UnaquiredConnection &c2) {
return c1.connection == c2.connection;
}
bool operator!=(const UnaquiredConnection &c1, const UnaquiredConnection &c2) {
return !(c1 == c2);
}
class SshConnectionManager : public QObject
{
Q_OBJECT
public:
SshConnectionManager()
{
moveToThread(QCoreApplication::instance()->thread());
connect(&m_removalTimer, &QTimer::timeout,
this, &SshConnectionManager::removeInactiveConnections);
m_removalTimer.start(150000); // For a total timeout of five minutes.
}
~SshConnectionManager()
{
foreach (const UnaquiredConnection &connection, m_unacquiredConnections) {
disconnect(connection.connection, 0, this, 0);
delete connection.connection;
}
QSSH_ASSERT(m_acquiredConnections.isEmpty());
QSSH_ASSERT(m_deprecatedConnections.isEmpty());
}
SshConnection *acquireConnection(const SshConnectionParameters &sshParams)
{
QMutexLocker locker(&m_listMutex);
// Check in-use connections:
foreach (SshConnection * const connection, m_acquiredConnections) {
if (connection->connectionParameters() != sshParams)
continue;
if (connection->thread() != QThread::currentThread())
continue;
if (m_deprecatedConnections.contains(connection)) // we were asked to no longer use this one...
continue;
m_acquiredConnections.append(connection);
return connection;
}
// Check cached open connections:
foreach (const UnaquiredConnection &c, m_unacquiredConnections) {
SshConnection * const connection = c.connection;
if (connection->state() != SshConnection::Connected
|| connection->connectionParameters() != sshParams)
continue;
if (connection->thread() != QThread::currentThread()) {
if (connection->channelCount() != 0)
continue;
QMetaObject::invokeMethod(this, "switchToCallerThread",
Qt::BlockingQueuedConnection,
Q_ARG(SshConnection *, connection),
Q_ARG(QObject *, QThread::currentThread()));
}
m_unacquiredConnections.removeOne(c);
m_acquiredConnections.append(connection);
return connection;
}
// create a new connection:
SshConnection * const connection = new SshConnection(sshParams);
connect(connection, &SshConnection::disconnected,
this, &SshConnectionManager::cleanup);
m_acquiredConnections.append(connection);
return connection;
}
void releaseConnection(SshConnection *connection)
{
QMutexLocker locker(&m_listMutex);
const bool wasAquired = m_acquiredConnections.removeOne(connection);
QSSH_ASSERT_AND_RETURN(wasAquired);
if (m_acquiredConnections.contains(connection))
return;
bool doDelete = false;
connection->moveToThread(QCoreApplication::instance()->thread());
if (m_deprecatedConnections.removeOne(connection)
|| connection->state() != SshConnection::Connected) {
doDelete = true;
} else {
QSSH_ASSERT_AND_RETURN(!m_unacquiredConnections.contains(UnaquiredConnection(connection)));
// It can happen that two or more connections with the same parameters were acquired
// if the clients were running in different threads. Only keep one of them in
// such a case.
bool haveConnection = false;
foreach (const UnaquiredConnection &c, m_unacquiredConnections) {
if (c.connection->connectionParameters() == connection->connectionParameters()) {
haveConnection = true;
break;
}
}
if (!haveConnection) {
connection->closeAllChannels(); // Clean up after neglectful clients.
m_unacquiredConnections.append(UnaquiredConnection(connection));
} else {
doDelete = true;
}
}
if (doDelete) {
disconnect(connection, 0, this, 0);
m_deprecatedConnections.removeAll(connection);
connection->deleteLater();
}
}
void forceNewConnection(const SshConnectionParameters &sshParams)
{
QMutexLocker locker(&m_listMutex);
for (int i = 0; i < m_unacquiredConnections.count(); ++i) {
SshConnection * const connection = m_unacquiredConnections.at(i).connection;
if (connection->connectionParameters() == sshParams) {
disconnect(connection, 0, this, 0);
delete connection;
m_unacquiredConnections.removeAt(i);
break;
}
}
foreach (SshConnection * const connection, m_acquiredConnections) {
if (connection->connectionParameters() == sshParams) {
if (!m_deprecatedConnections.contains(connection))
m_deprecatedConnections.append(connection);
}
}
}
private:
Q_INVOKABLE void switchToCallerThread(SshConnection *connection, QObject *threadObj)
{
connection->moveToThread(qobject_cast<QThread *>(threadObj));
}
void cleanup()
{
QMutexLocker locker(&m_listMutex);
SshConnection *currentConnection = qobject_cast<SshConnection *>(sender());
if (!currentConnection)
return;
if (m_unacquiredConnections.removeOne(UnaquiredConnection(currentConnection))) {
disconnect(currentConnection, 0, this, 0);
currentConnection->deleteLater();
}
}
void removeInactiveConnections()
{
QMutexLocker locker(&m_listMutex);
for (int i = m_unacquiredConnections.count() - 1; i >= 0; --i) {
UnaquiredConnection &c = m_unacquiredConnections[i];
if (c.scheduledForRemoval) {
disconnect(c.connection, 0, this, 0);
c.connection->deleteLater();
m_unacquiredConnections.removeAt(i);
} else {
c.scheduledForRemoval = true;
}
}
}
private:
// We expect the number of concurrently open connections to be small.
// If that turns out to not be the case, we can still use a data
// structure with faster access.
QList<UnaquiredConnection> m_unacquiredConnections;
// Can contain the same connection more than once; this acts as a reference count.
QList<SshConnection *> m_acquiredConnections;
QList<SshConnection *> m_deprecatedConnections;
QMutex m_listMutex;
QTimer m_removalTimer;
};
} // namespace Internal
static QMutex instanceMutex;
static Internal::SshConnectionManager &instance()
{
static Internal::SshConnectionManager manager;
return manager;
}
SshConnection *acquireConnection(const SshConnectionParameters &sshParams)
{
QMutexLocker locker(&instanceMutex);
return instance().acquireConnection(sshParams);
}
void releaseConnection(SshConnection *connection)
{
QMutexLocker locker(&instanceMutex);
instance().releaseConnection(connection);
}
void forceNewConnection(const SshConnectionParameters &sshParams)
{
QMutexLocker locker(&instanceMutex);
instance().forceNewConnection(sshParams);
}
} // namespace QSsh
#include "sshconnectionmanager.moc"

View File

@@ -1,41 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssh_global.h"
namespace QSsh {
class SshConnection;
class SshConnectionParameters;
QSSH_EXPORT SshConnection *acquireConnection(const SshConnectionParameters &sshParams);
QSSH_EXPORT void releaseConnection(SshConnection *connection);
// Make sure the next acquireConnection with the given parameters will return a new connection.
QSSH_EXPORT void forceNewConnection(const SshConnectionParameters &sshParams);
} // namespace QSsh

View File

@@ -1,439 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshcryptofacility_p.h"
#include "sshbotanconversions_p.h"
#include "sshcapabilities_p.h"
#include "sshexception_p.h"
#include "sshkeyexchange_p.h"
#include "sshkeypasswordretriever_p.h"
#include "sshlogging_p.h"
#include "sshpacket_p.h"
#include <botan/botan.h>
#include <QDebug>
#include <QList>
#include <string>
using namespace Botan;
namespace QSsh {
namespace Internal {
SshAbstractCryptoFacility::SshAbstractCryptoFacility()
: m_cipherBlockSize(0), m_macLength(0)
{
}
SshAbstractCryptoFacility::~SshAbstractCryptoFacility() {}
void SshAbstractCryptoFacility::clearKeys()
{
m_cipherBlockSize = 0;
m_macLength = 0;
m_sessionId.clear();
m_pipe.reset(0);
m_hMac.reset(0);
}
SshAbstractCryptoFacility::Mode SshAbstractCryptoFacility::getMode(const QByteArray &algoName)
{
if (algoName.endsWith("-ctr"))
return CtrMode;
if (algoName.endsWith("-cbc"))
return CbcMode;
throw SshClientException(SshInternalError, SSH_TR("Unexpected cipher \"%1\"")
.arg(QString::fromLatin1(algoName)));
}
void SshAbstractCryptoFacility::recreateKeys(const SshKeyExchange &kex)
{
checkInvariant();
if (m_sessionId.isEmpty())
m_sessionId = kex.h();
Algorithm_Factory &af = global_state().algorithm_factory();
const QByteArray &rfcCryptAlgoName = cryptAlgoName(kex);
BlockCipher * const cipher
= af.prototype_block_cipher(botanCryptAlgoName(rfcCryptAlgoName))->clone();
m_cipherBlockSize = static_cast<quint32>(cipher->block_size());
const QByteArray ivData = generateHash(kex, ivChar(), m_cipherBlockSize);
const InitializationVector iv(convertByteArray(ivData), m_cipherBlockSize);
const quint32 keySize = static_cast<quint32>(cipher->key_spec().maximum_keylength());
const QByteArray cryptKeyData = generateHash(kex, keyChar(), keySize);
SymmetricKey cryptKey(convertByteArray(cryptKeyData), keySize);
Keyed_Filter * const cipherMode
= makeCipherMode(cipher, getMode(rfcCryptAlgoName), iv, cryptKey);
m_pipe.reset(new Pipe(cipherMode));
m_macLength = botanHMacKeyLen(hMacAlgoName(kex));
const QByteArray hMacKeyData = generateHash(kex, macChar(), macLength());
SymmetricKey hMacKey(convertByteArray(hMacKeyData), macLength());
const HashFunction * const hMacProto
= af.prototype_hash_function(botanHMacAlgoName(hMacAlgoName(kex)));
m_hMac.reset(new HMAC(hMacProto->clone()));
m_hMac->set_key(hMacKey);
}
void SshAbstractCryptoFacility::convert(QByteArray &data, quint32 offset,
quint32 dataSize) const
{
Q_ASSERT(offset + dataSize <= static_cast<quint32>(data.size()));
checkInvariant();
// Session id empty => No key exchange has happened yet.
if (dataSize == 0 || m_sessionId.isEmpty())
return;
if (dataSize % cipherBlockSize() != 0) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid packet size");
}
m_pipe->process_msg(reinterpret_cast<const byte *>(data.constData()) + offset,
dataSize);
// Can't use Pipe::LAST_MESSAGE because of a VC bug.
quint32 bytesRead = static_cast<quint32>(m_pipe->read(
reinterpret_cast<byte *>(data.data()) + offset, dataSize, m_pipe->message_count() - 1));
if (bytesRead != dataSize) {
throw SshClientException(SshInternalError,
QLatin1String("Internal error: Botan::Pipe::read() returned unexpected value"));
}
}
Keyed_Filter *SshAbstractCryptoFacility::makeCtrCipherMode(BlockCipher *cipher,
const InitializationVector &iv, const SymmetricKey &key)
{
StreamCipher_Filter * const filter = new StreamCipher_Filter(new CTR_BE(cipher));
filter->set_key(key);
filter->set_iv(iv);
return filter;
}
QByteArray SshAbstractCryptoFacility::generateMac(const QByteArray &data,
quint32 dataSize) const
{
return m_sessionId.isEmpty()
? QByteArray()
: convertByteArray(m_hMac->process(reinterpret_cast<const byte *>(data.constData()),
dataSize));
}
QByteArray SshAbstractCryptoFacility::generateHash(const SshKeyExchange &kex,
char c, quint32 length)
{
const QByteArray &k = kex.k();
const QByteArray &h = kex.h();
QByteArray data(k);
data.append(h).append(c).append(m_sessionId);
SecureVector<byte> key
= kex.hash()->process(convertByteArray(data), data.size());
while (key.size() < length) {
SecureVector<byte> tmpKey;
tmpKey += SecureVector<byte>(convertByteArray(k), k.size());
tmpKey += SecureVector<byte>(convertByteArray(h), h.size());
tmpKey += key;
key += kex.hash()->process(tmpKey);
}
return QByteArray(reinterpret_cast<const char *>(key.begin()), length);
}
void SshAbstractCryptoFacility::checkInvariant() const
{
Q_ASSERT(m_sessionId.isEmpty() == !m_pipe);
}
const QByteArray SshEncryptionFacility::PrivKeyFileStartLineRsa("-----BEGIN RSA PRIVATE KEY-----");
const QByteArray SshEncryptionFacility::PrivKeyFileStartLineDsa("-----BEGIN DSA PRIVATE KEY-----");
const QByteArray SshEncryptionFacility::PrivKeyFileEndLineRsa("-----END RSA PRIVATE KEY-----");
const QByteArray SshEncryptionFacility::PrivKeyFileEndLineDsa("-----END DSA PRIVATE KEY-----");
const QByteArray SshEncryptionFacility::PrivKeyFileStartLineEcdsa("-----BEGIN EC PRIVATE KEY-----");
const QByteArray SshEncryptionFacility::PrivKeyFileEndLineEcdsa("-----END EC PRIVATE KEY-----");
QByteArray SshEncryptionFacility::cryptAlgoName(const SshKeyExchange &kex) const
{
return kex.encryptionAlgo();
}
QByteArray SshEncryptionFacility::hMacAlgoName(const SshKeyExchange &kex) const
{
return kex.hMacAlgoClientToServer();
}
Keyed_Filter *SshEncryptionFacility::makeCipherMode(BlockCipher *cipher, Mode mode,
const InitializationVector &iv, const SymmetricKey &key)
{
switch (mode) {
case CbcMode:
return new CBC_Encryption(cipher, new Null_Padding, key, iv);
case CtrMode:
return makeCtrCipherMode(cipher, iv, key);
}
return 0; // For dumb compilers.
}
void SshEncryptionFacility::encrypt(QByteArray &data) const
{
convert(data, 0, data.size());
}
void SshEncryptionFacility::createAuthenticationKey(const QByteArray &privKeyFileContents)
{
if (privKeyFileContents == m_cachedPrivKeyContents)
return;
m_authKeyAlgoName.clear();
qCDebug(sshLog, "%s: Key not cached, reading", Q_FUNC_INFO);
QList<BigInt> pubKeyParams;
QList<BigInt> allKeyParams;
QString error1;
QString error2;
if (!createAuthenticationKeyFromPKCS8(privKeyFileContents, pubKeyParams, allKeyParams, error1)
&& !createAuthenticationKeyFromOpenSSL(privKeyFileContents, pubKeyParams, allKeyParams,
error2)) {
qCDebug(sshLog, "%s: %s\n\t%s\n", Q_FUNC_INFO, qPrintable(error1), qPrintable(error2));
throw SshClientException(SshKeyFileError, SSH_TR("Decoding of private key file failed: "
"Format not understood."));
}
foreach (const BigInt &b, allKeyParams) {
if (b.is_zero()) {
throw SshClientException(SshKeyFileError,
SSH_TR("Decoding of private key file failed: Invalid zero parameter."));
}
}
m_authPubKeyBlob = AbstractSshPacket::encodeString(m_authKeyAlgoName);
auto * const ecdsaKey = dynamic_cast<ECDSA_PrivateKey *>(m_authKey.data());
if (ecdsaKey) {
m_authPubKeyBlob += AbstractSshPacket::encodeString(m_authKeyAlgoName.mid(11)); // Without "ecdsa-sha2-" prefix.
m_authPubKeyBlob += AbstractSshPacket::encodeString(
convertByteArray(EC2OSP(ecdsaKey->public_point(), PointGFp::UNCOMPRESSED)));
} else {
foreach (const BigInt &b, pubKeyParams)
m_authPubKeyBlob += AbstractSshPacket::encodeMpInt(b);
}
m_cachedPrivKeyContents = privKeyFileContents;
}
bool SshEncryptionFacility::createAuthenticationKeyFromPKCS8(const QByteArray &privKeyFileContents,
QList<BigInt> &pubKeyParams, QList<BigInt> &allKeyParams, QString &error)
{
try {
Pipe pipe;
pipe.process_msg(convertByteArray(privKeyFileContents), privKeyFileContents.size());
m_authKey.reset(PKCS8::load_key(pipe, m_rng, SshKeyPasswordRetriever()));
if (auto * const dsaKey = dynamic_cast<DSA_PrivateKey *>(m_authKey.data())) {
m_authKeyAlgoName = SshCapabilities::PubKeyDss;
pubKeyParams << dsaKey->group_p() << dsaKey->group_q()
<< dsaKey->group_g() << dsaKey->get_y();
allKeyParams << pubKeyParams << dsaKey->get_x();
} else if (auto * const rsaKey = dynamic_cast<RSA_PrivateKey *>(m_authKey.data())) {
m_authKeyAlgoName = SshCapabilities::PubKeyRsa;
pubKeyParams << rsaKey->get_e() << rsaKey->get_n();
allKeyParams << pubKeyParams << rsaKey->get_p() << rsaKey->get_q()
<< rsaKey->get_d();
} else if (auto * const ecdsaKey = dynamic_cast<ECDSA_PrivateKey *>(m_authKey.data())) {
const BigInt value = ecdsaKey->private_value();
m_authKeyAlgoName = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth(
static_cast<int>(value.bytes()));
pubKeyParams << ecdsaKey->public_point().get_affine_x()
<< ecdsaKey->public_point().get_affine_y();
allKeyParams << pubKeyParams << value;
} else {
qCWarning(sshLog, "%s: Unexpected code flow, expected success or exception.",
Q_FUNC_INFO);
return false;
}
} catch (const std::exception &ex) {
error = QLatin1String(ex.what());
return false;
}
return true;
}
bool SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray &privKeyFileContents,
QList<BigInt> &pubKeyParams, QList<BigInt> &allKeyParams, QString &error)
{
try {
bool syntaxOk = true;
QList<QByteArray> lines = privKeyFileContents.split('\n');
while (lines.last().isEmpty())
lines.removeLast();
if (lines.count() < 3) {
syntaxOk = false;
} else if (lines.first() == PrivKeyFileStartLineRsa) {
if (lines.last() != PrivKeyFileEndLineRsa)
syntaxOk = false;
else
m_authKeyAlgoName = SshCapabilities::PubKeyRsa;
} else if (lines.first() == PrivKeyFileStartLineDsa) {
if (lines.last() != PrivKeyFileEndLineDsa)
syntaxOk = false;
else
m_authKeyAlgoName = SshCapabilities::PubKeyDss;
} else if (lines.first() == PrivKeyFileStartLineEcdsa) {
if (lines.last() != PrivKeyFileEndLineEcdsa)
syntaxOk = false;
// m_authKeyAlgoName set below, as we don't know the size yet.
} else {
syntaxOk = false;
}
if (!syntaxOk) {
error = SSH_TR("Unexpected format.");
return false;
}
QByteArray privateKeyBlob;
for (int i = 1; i < lines.size() - 1; ++i)
privateKeyBlob += lines.at(i);
privateKeyBlob = QByteArray::fromBase64(privateKeyBlob);
BER_Decoder decoder(convertByteArray(privateKeyBlob), privateKeyBlob.size());
BER_Decoder sequence = decoder.start_cons(SEQUENCE);
size_t version;
sequence.decode (version);
const size_t expectedVersion = m_authKeyAlgoName.isEmpty() ? 1 : 0;
if (version != expectedVersion) {
error = SSH_TR("Key encoding has version %1, expected %2.")
.arg(version).arg(expectedVersion);
return false;
}
if (m_authKeyAlgoName == SshCapabilities::PubKeyDss) {
BigInt p, q, g, y, x;
sequence.decode (p).decode (q).decode (g).decode (y).decode (x);
DSA_PrivateKey * const dsaKey = new DSA_PrivateKey(m_rng, DL_Group(p, q, g), x);
m_authKey.reset(dsaKey);
pubKeyParams << p << q << g << y;
allKeyParams << pubKeyParams << x;
} else if (m_authKeyAlgoName == SshCapabilities::PubKeyRsa) {
BigInt p, q, e, d, n;
sequence.decode(n).decode(e).decode(d).decode(p).decode(q);
RSA_PrivateKey * const rsaKey = new RSA_PrivateKey(m_rng, p, q, e, d, n);
m_authKey.reset(rsaKey);
pubKeyParams << e << n;
allKeyParams << pubKeyParams << p << q << d;
} else {
BigInt privKey;
sequence.decode_octet_string_bigint(privKey);
m_authKeyAlgoName = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth(
static_cast<int>(privKey.bytes()));
const EC_Group group(SshCapabilities::oid(m_authKeyAlgoName));
auto * const key = new ECDSA_PrivateKey(m_rng, group, privKey);
m_authKey.reset(key);
pubKeyParams << key->public_point().get_affine_x()
<< key->public_point().get_affine_y();
allKeyParams << pubKeyParams << privKey;
}
sequence.discard_remaining();
sequence.verify_end();
} catch (const std::exception &ex) {
error = QLatin1String(ex.what());
return false;
}
return true;
}
QByteArray SshEncryptionFacility::authenticationAlgorithmName() const
{
Q_ASSERT(m_authKey);
return m_authKeyAlgoName;
}
QByteArray SshEncryptionFacility::authenticationKeySignature(const QByteArray &data) const
{
Q_ASSERT(m_authKey);
QScopedPointer<PK_Signer> signer(new PK_Signer(*m_authKey,
botanEmsaAlgoName(m_authKeyAlgoName)));
QByteArray dataToSign = AbstractSshPacket::encodeString(sessionId()) + data;
QByteArray signature
= convertByteArray(signer->sign_message(convertByteArray(dataToSign),
dataToSign.size(), m_rng));
if (m_authKeyAlgoName.startsWith(SshCapabilities::PubKeyEcdsaPrefix)) {
// The Botan output is not quite in the format that SSH defines.
const int halfSize = signature.count() / 2;
const BigInt r = BigInt::decode(convertByteArray(signature), halfSize);
const BigInt s = BigInt::decode(convertByteArray(signature.mid(halfSize)), halfSize);
signature = AbstractSshPacket::encodeMpInt(r) + AbstractSshPacket::encodeMpInt(s);
}
return AbstractSshPacket::encodeString(m_authKeyAlgoName)
+ AbstractSshPacket::encodeString(signature);
}
QByteArray SshEncryptionFacility::getRandomNumbers(int count) const
{
QByteArray data;
data.resize(count);
m_rng.randomize(convertByteArray(data), count);
return data;
}
SshEncryptionFacility::~SshEncryptionFacility() {}
QByteArray SshDecryptionFacility::cryptAlgoName(const SshKeyExchange &kex) const
{
return kex.decryptionAlgo();
}
QByteArray SshDecryptionFacility::hMacAlgoName(const SshKeyExchange &kex) const
{
return kex.hMacAlgoServerToClient();
}
Keyed_Filter *SshDecryptionFacility::makeCipherMode(BlockCipher *cipher, Mode mode, const InitializationVector &iv,
const SymmetricKey &key)
{
switch (mode) {
case CbcMode:
return new CBC_Decryption(cipher, new Null_Padding, key, iv);
case CtrMode:
return makeCtrCipherMode(cipher, iv, key);
}
return 0; // For dumb compilers.
}
void SshDecryptionFacility::decrypt(QByteArray &data, quint32 offset,
quint32 dataSize) const
{
convert(data, offset, dataSize);
qCDebug(sshLog, "Decrypted data:");
const char * const start = data.constData() + offset;
const char * const end = start + dataSize;
for (const char *c = start; c < end; ++c)
qCDebug(sshLog, ) << "'" << *c << "' (0x" << (static_cast<int>(*c) & 0xff) << ")";
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,138 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <botan/botan.h>
#include <QByteArray>
#include <QScopedPointer>
namespace QSsh {
namespace Internal {
class SshKeyExchange;
class SshAbstractCryptoFacility
{
public:
virtual ~SshAbstractCryptoFacility();
void clearKeys();
void recreateKeys(const SshKeyExchange &kex);
QByteArray generateMac(const QByteArray &data, quint32 dataSize) const;
quint32 cipherBlockSize() const { return m_cipherBlockSize; }
quint32 macLength() const { return m_macLength; }
protected:
enum Mode { CbcMode, CtrMode };
SshAbstractCryptoFacility();
void convert(QByteArray &data, quint32 offset, quint32 dataSize) const;
QByteArray sessionId() const { return m_sessionId; }
Botan::Keyed_Filter *makeCtrCipherMode(Botan::BlockCipher *cipher,
const Botan::InitializationVector &iv, const Botan::SymmetricKey &key);
private:
SshAbstractCryptoFacility(const SshAbstractCryptoFacility &);
SshAbstractCryptoFacility &operator=(const SshAbstractCryptoFacility &);
virtual QByteArray cryptAlgoName(const SshKeyExchange &kex) const = 0;
virtual QByteArray hMacAlgoName(const SshKeyExchange &kex) const = 0;
virtual Botan::Keyed_Filter *makeCipherMode(Botan::BlockCipher *cipher,
Mode mode, const Botan::InitializationVector &iv, const Botan::SymmetricKey &key) = 0;
virtual char ivChar() const = 0;
virtual char keyChar() const = 0;
virtual char macChar() const = 0;
QByteArray generateHash(const SshKeyExchange &kex, char c, quint32 length);
void checkInvariant() const;
static Mode getMode(const QByteArray &algoName);
QByteArray m_sessionId;
QScopedPointer<Botan::Pipe> m_pipe;
QScopedPointer<Botan::HMAC> m_hMac;
quint32 m_cipherBlockSize;
quint32 m_macLength;
};
class SshEncryptionFacility : public SshAbstractCryptoFacility
{
public:
void encrypt(QByteArray &data) const;
void createAuthenticationKey(const QByteArray &privKeyFileContents);
QByteArray authenticationAlgorithmName() const;
QByteArray authenticationPublicKey() const { return m_authPubKeyBlob; }
QByteArray authenticationKeySignature(const QByteArray &data) const;
QByteArray getRandomNumbers(int count) const;
~SshEncryptionFacility();
private:
virtual QByteArray cryptAlgoName(const SshKeyExchange &kex) const;
virtual QByteArray hMacAlgoName(const SshKeyExchange &kex) const;
virtual Botan::Keyed_Filter *makeCipherMode(Botan::BlockCipher *cipher,
Mode mode, const Botan::InitializationVector &iv, const Botan::SymmetricKey &key);
virtual char ivChar() const { return 'A'; }
virtual char keyChar() const { return 'C'; }
virtual char macChar() const { return 'E'; }
bool createAuthenticationKeyFromPKCS8(const QByteArray &privKeyFileContents,
QList<Botan::BigInt> &pubKeyParams, QList<Botan::BigInt> &allKeyParams, QString &error);
bool createAuthenticationKeyFromOpenSSL(const QByteArray &privKeyFileContents,
QList<Botan::BigInt> &pubKeyParams, QList<Botan::BigInt> &allKeyParams, QString &error);
static const QByteArray PrivKeyFileStartLineRsa;
static const QByteArray PrivKeyFileStartLineDsa;
static const QByteArray PrivKeyFileEndLineRsa;
static const QByteArray PrivKeyFileEndLineDsa;
static const QByteArray PrivKeyFileStartLineEcdsa;
static const QByteArray PrivKeyFileEndLineEcdsa;
QByteArray m_authKeyAlgoName;
QByteArray m_authPubKeyBlob;
QByteArray m_cachedPrivKeyContents;
QScopedPointer<Botan::Private_Key> m_authKey;
mutable Botan::AutoSeeded_RNG m_rng;
};
class SshDecryptionFacility : public SshAbstractCryptoFacility
{
public:
void decrypt(QByteArray &data, quint32 offset, quint32 dataSize) const;
private:
virtual QByteArray cryptAlgoName(const SshKeyExchange &kex) const;
virtual QByteArray hMacAlgoName(const SshKeyExchange &kex) const;
virtual Botan::Keyed_Filter *makeCipherMode(Botan::BlockCipher *cipher,
Mode mode, const Botan::InitializationVector &iv, const Botan::SymmetricKey &key);
virtual char ivChar() const { return 'B'; }
virtual char keyChar() const { return 'D'; }
virtual char macChar() const { return 'F'; }
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,122 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshdirecttcpiptunnel.h"
#include "sshdirecttcpiptunnel_p.h"
#include "sshincomingpacket_p.h"
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
#include <QTimer>
namespace QSsh {
namespace Internal {
SshDirectTcpIpTunnelPrivate::SshDirectTcpIpTunnelPrivate(quint32 channelId,
const QString &originatingHost, quint16 originatingPort, const QString &remoteHost,
quint16 remotePort, SshSendFacility &sendFacility)
: SshTcpIpTunnelPrivate(channelId, sendFacility),
m_originatingHost(originatingHost),
m_originatingPort(originatingPort),
m_remoteHost(remoteHost),
m_remotePort(remotePort)
{
}
void SshDirectTcpIpTunnelPrivate::handleOpenSuccessInternal()
{
emit initialized();
}
} // namespace Internal
using namespace Internal;
SshDirectTcpIpTunnel::SshDirectTcpIpTunnel(quint32 channelId, const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort,
SshSendFacility &sendFacility)
: d(new SshDirectTcpIpTunnelPrivate(channelId, originatingHost, originatingPort, remoteHost,
remotePort, sendFacility))
{
d->init(this);
connect(d, &SshDirectTcpIpTunnelPrivate::initialized,
this, &SshDirectTcpIpTunnel::initialized, Qt::QueuedConnection);
}
SshDirectTcpIpTunnel::~SshDirectTcpIpTunnel()
{
delete d;
}
bool SshDirectTcpIpTunnel::atEnd() const
{
return QIODevice::atEnd() && d->m_data.isEmpty();
}
qint64 SshDirectTcpIpTunnel::bytesAvailable() const
{
return QIODevice::bytesAvailable() + d->m_data.count();
}
bool SshDirectTcpIpTunnel::canReadLine() const
{
return QIODevice::canReadLine() || d->m_data.contains('\n');
}
void SshDirectTcpIpTunnel::close()
{
d->closeChannel();
QIODevice::close();
}
void SshDirectTcpIpTunnel::initialize()
{
QSSH_ASSERT_AND_RETURN(d->channelState() == AbstractSshChannel::Inactive);
try {
QIODevice::open(QIODevice::ReadWrite);
d->m_sendFacility.sendDirectTcpIpPacket(d->localChannelId(), d->initialWindowSize(),
d->maxPacketSize(), d->m_remoteHost.toUtf8(), d->m_remotePort,
d->m_originatingHost.toUtf8(), d->m_originatingPort);
d->setChannelState(AbstractSshChannel::SessionRequested);
d->m_timeoutTimer.start(d->ReplyTimeout);
} catch (const std::exception &e) { // Won't happen, but let's play it safe.
qCWarning(sshLog, "Botan error: %s", e.what());
d->closeChannel();
}
}
qint64 SshDirectTcpIpTunnel::readData(char *data, qint64 maxlen)
{
return d->readData(data, maxlen);
}
qint64 SshDirectTcpIpTunnel::writeData(const char *data, qint64 len)
{
return d->writeData(data, len);
}
} // namespace QSsh

View File

@@ -1,79 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssh_global.h"
#include <QIODevice>
#include <QSharedPointer>
namespace QSsh {
namespace Internal {
class SshChannelManager;
class SshDirectTcpIpTunnelPrivate;
class SshSendFacility;
class SshTcpIpTunnelPrivate;
} // namespace Internal
class QSSH_EXPORT SshDirectTcpIpTunnel : public QIODevice
{
Q_OBJECT
friend class Internal::SshChannelManager;
friend class Internal::SshTcpIpTunnelPrivate;
public:
typedef QSharedPointer<SshDirectTcpIpTunnel> Ptr;
~SshDirectTcpIpTunnel();
// QIODevice stuff
bool atEnd() const;
qint64 bytesAvailable() const;
bool canReadLine() const;
void close();
bool isSequential() const { return true; }
void initialize();
signals:
void initialized();
void error(const QString &reason);
private:
SshDirectTcpIpTunnel(quint32 channelId, const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort,
Internal::SshSendFacility &sendFacility);
// QIODevice stuff
qint64 readData(char *data, qint64 maxlen);
qint64 writeData(const char *data, qint64 len);
Internal::SshDirectTcpIpTunnelPrivate * const d;
};
} // namespace QSsh

View File

@@ -1,59 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sshtcpiptunnel_p.h"
namespace QSsh {
class SshDirectTcpIpTunnel;
namespace Internal {
class SshDirectTcpIpTunnelPrivate : public SshTcpIpTunnelPrivate
{
Q_OBJECT
friend class QSsh::SshDirectTcpIpTunnel;
public:
explicit SshDirectTcpIpTunnelPrivate(quint32 channelId, const QString &originatingHost,
quint16 originatingPort, const QString &remoteHost, quint16 remotePort,
SshSendFacility &sendFacility);
signals:
void initialized();
private:
void handleOpenSuccessInternal();
const QString m_originatingHost;
const quint16 m_originatingPort;
const QString m_remoteHost;
const quint16 m_remotePort;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,37 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#define SSHERRORS_P_H
namespace QSsh {
enum SshError {
SshNoError, SshSocketError, SshTimeoutError, SshProtocolError,
SshHostKeyError, SshKeyFileError, SshAuthenticationError,
SshClosedByServerError, SshInternalError
};
} // namespace QSsh

View File

@@ -1,82 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssherrors.h"
#include <QByteArray>
#include <QCoreApplication>
#include <QString>
namespace QSsh {
namespace Internal {
enum SshErrorCode {
SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
SSH_DISCONNECT_PROTOCOL_ERROR = 2,
SSH_DISCONNECT_KEY_EXCHANGE_FAILED = 3,
SSH_DISCONNECT_RESERVED = 4,
SSH_DISCONNECT_MAC_ERROR = 5,
SSH_DISCONNECT_COMPRESSION_ERROR = 6,
SSH_DISCONNECT_SERVICE_NOT_AVAILABLE = 7,
SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8,
SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9,
SSH_DISCONNECT_CONNECTION_LOST = 10,
SSH_DISCONNECT_BY_APPLICATION = 11,
SSH_DISCONNECT_TOO_MANY_CONNECTIONS = 12,
SSH_DISCONNECT_AUTH_CANCELLED_BY_USER = 13,
SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14,
SSH_DISCONNECT_ILLEGAL_USER_NAME = 15
};
#define SSH_TR(string) QCoreApplication::translate("SshConnection", string)
#define SSH_SERVER_EXCEPTION(error, errorString) \
SshServerException((error), (errorString), SSH_TR(errorString))
struct SshServerException
{
SshServerException(SshErrorCode error, const QByteArray &errorStringServer,
const QString &errorStringUser)
: error(error), errorStringServer(errorStringServer),
errorStringUser(errorStringUser) {}
const SshErrorCode error;
const QByteArray errorStringServer;
const QString errorStringUser;
};
struct SshClientException
{
SshClientException(SshError error, const QString &errorString)
: error(error), errorString(errorString) {}
const SshError error;
const QString errorString;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,100 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshforwardedtcpiptunnel.h"
#include "sshforwardedtcpiptunnel_p.h"
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
namespace QSsh {
namespace Internal {
SshForwardedTcpIpTunnelPrivate::SshForwardedTcpIpTunnelPrivate(quint32 channelId,
SshSendFacility &sendFacility) :
SshTcpIpTunnelPrivate(channelId, sendFacility)
{
setChannelState(SessionRequested);
}
void SshForwardedTcpIpTunnelPrivate::handleOpenSuccessInternal()
{
QSSH_ASSERT_AND_RETURN(channelState() == AbstractSshChannel::SessionEstablished);
try {
m_sendFacility.sendChannelOpenConfirmationPacket(remoteChannel(), localChannelId(),
initialWindowSize(), maxPacketSize());
} catch (const std::exception &e) { // Won't happen, but let's play it safe.
qCWarning(sshLog, "Botan error: %s", e.what());
closeChannel();
}
}
} // namespace Internal
using namespace Internal;
SshForwardedTcpIpTunnel::SshForwardedTcpIpTunnel(quint32 channelId, SshSendFacility &sendFacility) :
d(new SshForwardedTcpIpTunnelPrivate(channelId, sendFacility))
{
d->init(this);
}
SshForwardedTcpIpTunnel::~SshForwardedTcpIpTunnel()
{
delete d;
}
bool SshForwardedTcpIpTunnel::atEnd() const
{
return QIODevice::atEnd() && d->m_data.isEmpty();
}
qint64 SshForwardedTcpIpTunnel::bytesAvailable() const
{
return QIODevice::bytesAvailable() + d->m_data.count();
}
bool SshForwardedTcpIpTunnel::canReadLine() const
{
return QIODevice::canReadLine() || d->m_data.contains('\n');
}
void SshForwardedTcpIpTunnel::close()
{
d->closeChannel();
QIODevice::close();
}
qint64 SshForwardedTcpIpTunnel::readData(char *data, qint64 maxlen)
{
return d->readData(data, maxlen);
}
qint64 SshForwardedTcpIpTunnel::writeData(const char *data, qint64 len)
{
return d->writeData(data, len);
}
} // namespace QSsh

View File

@@ -1,70 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssh_global.h"
#include <QIODevice>
#include <QSharedPointer>
namespace QSsh {
namespace Internal {
class SshChannelManager;
class SshForwardedTcpIpTunnelPrivate;
class SshSendFacility;
class SshTcpIpTunnelPrivate;
} // namespace Internal
class QSSH_EXPORT SshForwardedTcpIpTunnel : public QIODevice
{
Q_OBJECT
friend class Internal::SshChannelManager;
friend class Internal::SshTcpIpTunnelPrivate;
public:
typedef QSharedPointer<SshForwardedTcpIpTunnel> Ptr;
~SshForwardedTcpIpTunnel() override;
// QIODevice stuff
bool atEnd() const override;
qint64 bytesAvailable() const override;
bool canReadLine() const override;
void close() override;
bool isSequential() const override { return true; }
signals:
void error(const QString &reason);
private:
SshForwardedTcpIpTunnel(quint32 channelId, Internal::SshSendFacility &sendFacility);
// QIODevice stuff
qint64 readData(char *data, qint64 maxlen) override;
qint64 writeData(const char *data, qint64 len) override;
Internal::SshForwardedTcpIpTunnelPrivate * const d;
};
} // namespace QSsh

View File

@@ -1,44 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sshforwardedtcpiptunnel.h"
#include "sshtcpiptunnel_p.h"
namespace QSsh {
namespace Internal {
class SshForwardedTcpIpTunnelPrivate : public SshTcpIpTunnelPrivate
{
Q_OBJECT
friend class QSsh::SshForwardedTcpIpTunnel;
public:
SshForwardedTcpIpTunnelPrivate(quint32 channelId, SshSendFacility &sendFacility);
void handleOpenSuccessInternal() override;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,118 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshhostkeydatabase.h"
#include "sshlogging_p.h"
#include <QByteArray>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QHash>
#include <QString>
namespace QSsh {
class SshHostKeyDatabase::SshHostKeyDatabasePrivate
{
public:
QHash<QString, QByteArray> hostKeys;
};
SshHostKeyDatabase::SshHostKeyDatabase() : d(new SshHostKeyDatabasePrivate)
{
}
SshHostKeyDatabase::~SshHostKeyDatabase()
{
delete d;
}
bool SshHostKeyDatabase::load(const QString &filePath, QString *error)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
if (error) {
*error = QCoreApplication::translate("QSsh::Ssh",
"Failed to open key file \"%1\" for reading: %2")
.arg(QDir::toNativeSeparators(filePath), file.errorString());
}
return false;
}
d->hostKeys.clear();
const QByteArray content = file.readAll().trimmed();
if (content.isEmpty())
return true;
foreach (const QByteArray &line, content.split('\n')) {
const QList<QByteArray> &lineData = line.trimmed().split(' ');
if (lineData.count() != 2) {
qCDebug(Internal::sshLog, "Unexpected line \"%s\" in file \"%s\".", line.constData(),
qPrintable(filePath));
continue;
}
d->hostKeys.insert(QString::fromUtf8(lineData.first()),
QByteArray::fromHex(lineData.last()));
}
return true;
}
bool SshHostKeyDatabase::store(const QString &filePath, QString *error) const
{
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly)) {
if (error) {
*error = QCoreApplication::translate("QSsh::Ssh",
"Failed to open key file \"%1\" for writing: %2")
.arg(QDir::toNativeSeparators(filePath), file.errorString());
}
return false;
}
file.resize(0);
for (auto it = d->hostKeys.constBegin(); it != d->hostKeys.constEnd(); ++it)
file.write(it.key().toUtf8() + ' ' + it.value().toHex() + '\n');
return true;
}
SshHostKeyDatabase::KeyLookupResult SshHostKeyDatabase::matchHostKey(const QString &hostName,
const QByteArray &key) const
{
auto it = d->hostKeys.constFind(hostName);
if (it == d->hostKeys.constEnd())
return KeyLookupNoMatch;
if (it.value() == key)
return KeyLookupMatch;
return KeyLookupMismatch;
}
void SshHostKeyDatabase::insertHostKey(const QString &hostName, const QByteArray &key)
{
d->hostKeys.insert(hostName, key);
}
} // namespace QSsh

View File

@@ -1,66 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssh_global.h"
#include <QSharedPointer>
QT_BEGIN_NAMESPACE
class QByteArray;
class QString;
QT_END_NAMESPACE
namespace QSsh {
class SshHostKeyDatabase;
typedef QSharedPointer<SshHostKeyDatabase> SshHostKeyDatabasePtr;
class QSSH_EXPORT SshHostKeyDatabase
{
friend class QSharedPointer<SshHostKeyDatabase>; // To give create() access to our constructor.
public:
enum KeyLookupResult {
KeyLookupMatch,
KeyLookupNoMatch,
KeyLookupMismatch
};
~SshHostKeyDatabase();
bool load(const QString &filePath, QString *error = 0);
bool store(const QString &filePath, QString *error = 0) const;
KeyLookupResult matchHostKey(const QString &hostName, const QByteArray &key) const;
void insertHostKey(const QString &hostName, const QByteArray &key);
private:
SshHostKeyDatabase();
class SshHostKeyDatabasePrivate;
SshHostKeyDatabasePrivate * const d;
};
} // namespace QSsh

View File

@@ -1,552 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshincomingpacket_p.h"
#include "ssh_global.h"
#include "sshbotanconversions_p.h"
#include "sshcapabilities_p.h"
#include "sshlogging_p.h"
namespace QSsh {
namespace Internal {
const QByteArray SshIncomingPacket::ExitStatusType("exit-status");
const QByteArray SshIncomingPacket::ExitSignalType("exit-signal");
const QByteArray SshIncomingPacket::ForwardedTcpIpType("forwarded-tcpip");
SshIncomingPacket::SshIncomingPacket() : m_serverSeqNr(0) { }
quint32 SshIncomingPacket::cipherBlockSize() const
{
return qMax(m_decrypter.cipherBlockSize(), 8U);
}
quint32 SshIncomingPacket::macLength() const
{
return m_decrypter.macLength();
}
void SshIncomingPacket::recreateKeys(const SshKeyExchange &keyExchange)
{
m_decrypter.recreateKeys(keyExchange);
}
void SshIncomingPacket::reset()
{
clear();
m_serverSeqNr = 0;
m_decrypter.clearKeys();
}
void SshIncomingPacket::consumeData(QByteArray &newData)
{
qCDebug(sshLog, "%s: current data size = %d, new data size = %d",
Q_FUNC_INFO, m_data.size(), newData.size());
if (isComplete() || newData.isEmpty())
return;
/*
* Until we have reached the minimum packet size, we cannot decrypt the
* length field.
*/
const quint32 minSize = minPacketSize();
if (currentDataSize() < minSize) {
const int bytesToTake
= qMin<quint32>(minSize - currentDataSize(), newData.size());
moveFirstBytes(m_data, newData, bytesToTake);
qCDebug(sshLog, "Took %d bytes from new data", bytesToTake);
if (currentDataSize() < minSize)
return;
}
if (4 + length() + macLength() < currentDataSize())
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, "Server sent invalid packet.");
const int bytesToTake
= qMin<quint32>(length() + 4 + macLength() - currentDataSize(),
newData.size());
moveFirstBytes(m_data, newData, bytesToTake);
qCDebug(sshLog, "Took %d bytes from new data", bytesToTake);
if (isComplete()) {
qCDebug(sshLog, "Message complete. Overall size: %u, payload size: %u",
m_data.size(), m_length - paddingLength() - 1);
decrypt();
++m_serverSeqNr;
}
}
void SshIncomingPacket::decrypt()
{
Q_ASSERT(isComplete());
const quint32 netDataLength = length() + 4;
m_decrypter.decrypt(m_data, cipherBlockSize(),
netDataLength - cipherBlockSize());
const QByteArray &mac = m_data.mid(netDataLength, macLength());
if (mac != generateMac(m_decrypter, m_serverSeqNr)) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_MAC_ERROR,
"Message authentication failed.");
}
}
void SshIncomingPacket::moveFirstBytes(QByteArray &target, QByteArray &source,
int n)
{
target.append(source.left(n));
source.remove(0, n);
}
SshKeyExchangeInit SshIncomingPacket::extractKeyExchangeInitData() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_KEXINIT);
SshKeyExchangeInit exchangeData;
try {
quint32 offset = TypeOffset + 1;
std::memcpy(exchangeData.cookie, &m_data.constData()[offset],
sizeof exchangeData.cookie);
offset += sizeof exchangeData.cookie;
exchangeData.keyAlgorithms
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.serverHostKeyAlgorithms
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.encryptionAlgorithmsClientToServer
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.encryptionAlgorithmsServerToClient
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.macAlgorithmsClientToServer
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.macAlgorithmsServerToClient
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.compressionAlgorithmsClientToServer
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.compressionAlgorithmsServerToClient
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.languagesClientToServer
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.languagesServerToClient
= SshPacketParser::asNameList(m_data, &offset);
exchangeData.firstKexPacketFollows
= SshPacketParser::asBool(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
"Key exchange failed: Server sent invalid SSH_MSG_KEXINIT packet.");
}
return exchangeData;
}
static void getHostKeySpecificReplyData(SshKeyExchangeReply &replyData,
const QByteArray &hostKeyAlgo, const QByteArray &input)
{
quint32 offset = 0;
if (hostKeyAlgo == SshCapabilities::PubKeyDss || hostKeyAlgo == SshCapabilities::PubKeyRsa) {
// DSS: p and q, RSA: e and n
replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset);
replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset);
// g and y
if (hostKeyAlgo == SshCapabilities::PubKeyDss) {
replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset);
replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset);
}
} else {
QSSH_ASSERT_AND_RETURN(hostKeyAlgo.startsWith(SshCapabilities::PubKeyEcdsaPrefix));
if (SshPacketParser::asString(input, &offset)
!= hostKeyAlgo.mid(11)) { // Without "ecdsa-sha2-" prefix.
throw SshPacketParseException();
}
replyData.q = SshPacketParser::asString(input, &offset);
}
}
static QByteArray &padToWidth(QByteArray &data, int targetWidth)
{
return data.prepend(QByteArray(targetWidth - data.count(), 0));
}
SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &kexAlgo,
const QByteArray &hostKeyAlgo) const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY);
try {
SshKeyExchangeReply replyData;
quint32 topLevelOffset = TypeOffset + 1;
replyData.k_s = SshPacketParser::asString(m_data, &topLevelOffset);
quint32 k_sOffset = 0;
if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != hostKeyAlgo)
throw SshPacketParseException();
getHostKeySpecificReplyData(replyData, hostKeyAlgo, replyData.k_s.mid(k_sOffset));
if (kexAlgo == SshCapabilities::DiffieHellmanGroup1Sha1) {
replyData.f = SshPacketParser::asBigInt(m_data, &topLevelOffset);
} else {
QSSH_ASSERT_AND_RETURN_VALUE(kexAlgo.startsWith(SshCapabilities::EcdhKexNamePrefix),
SshKeyExchangeReply());
replyData.q_s = SshPacketParser::asString(m_data, &topLevelOffset);
}
const QByteArray fullSignature = SshPacketParser::asString(m_data, &topLevelOffset);
quint32 sigOffset = 0;
if (SshPacketParser::asString(fullSignature, &sigOffset) != hostKeyAlgo)
throw SshPacketParseException();
replyData.signatureBlob = SshPacketParser::asString(fullSignature, &sigOffset);
if (hostKeyAlgo.startsWith(SshCapabilities::PubKeyEcdsaPrefix)) {
// Botan's PK_Verifier wants the signature in this format.
quint32 blobOffset = 0;
const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset);
const Botan::BigInt s = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset);
const int width = SshCapabilities::ecdsaIntegerWidthInBytes(hostKeyAlgo);
QByteArray encodedR = convertByteArray(Botan::BigInt::encode(r));
replyData.signatureBlob = padToWidth(encodedR, width);
QByteArray encodedS = convertByteArray(Botan::BigInt::encode(s));
replyData.signatureBlob += padToWidth(encodedS, width);
}
replyData.k_s.prepend(m_data.mid(TypeOffset + 1, 4));
return replyData;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
"Key exchange failed: "
"Server sent invalid key exchange reply packet.");
}
}
SshDisconnect SshIncomingPacket::extractDisconnect() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_DISCONNECT);
SshDisconnect msg;
try {
quint32 offset = TypeOffset + 1;
msg.reasonCode = SshPacketParser::asUint32(m_data, &offset);
msg.description = SshPacketParser::asUserString(m_data, &offset);
msg.language = SshPacketParser::asString(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_DISCONNECT.");
}
return msg;
}
SshUserAuthBanner SshIncomingPacket::extractUserAuthBanner() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_USERAUTH_BANNER);
try {
SshUserAuthBanner msg;
quint32 offset = TypeOffset + 1;
msg.message = SshPacketParser::asUserString(m_data, &offset);
msg.language = SshPacketParser::asString(m_data, &offset);
return msg;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_USERAUTH_BANNER.");
}
}
SshUserAuthInfoRequestPacket SshIncomingPacket::extractUserAuthInfoRequest() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_USERAUTH_INFO_REQUEST);
try {
SshUserAuthInfoRequestPacket msg;
quint32 offset = TypeOffset + 1;
msg.name = SshPacketParser::asUserString(m_data, &offset);
msg.instruction = SshPacketParser::asUserString(m_data, &offset);
msg.languageTag = SshPacketParser::asString(m_data, &offset);
const quint32 promptCount = SshPacketParser::asUint32(m_data, &offset);
msg.prompts.reserve(promptCount);
msg.echos.reserve(promptCount);
for (quint32 i = 0; i < promptCount; ++i) {
msg.prompts << SshPacketParser::asUserString(m_data, &offset);
msg.echos << SshPacketParser::asBool(m_data, &offset);
}
return msg;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_USERAUTH_INFO_REQUEST.");
}
}
SshDebug SshIncomingPacket::extractDebug() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_DEBUG);
try {
SshDebug msg;
quint32 offset = TypeOffset + 1;
msg.display = SshPacketParser::asBool(m_data, &offset);
msg.message = SshPacketParser::asUserString(m_data, &offset);
msg.language = SshPacketParser::asString(m_data, &offset);
return msg;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_DEBUG.");
}
}
SshRequestSuccess SshIncomingPacket::extractRequestSuccess() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_REQUEST_SUCCESS);
try {
SshRequestSuccess msg;
quint32 offset = TypeOffset + 1;
msg.bindPort = SshPacketParser::asUint32(m_data, &offset);
return msg;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_REQUEST_SUCCESS.");
}
}
SshUnimplemented SshIncomingPacket::extractUnimplemented() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_UNIMPLEMENTED);
try {
SshUnimplemented msg;
quint32 offset = TypeOffset + 1;
msg.invalidMsgSeqNr = SshPacketParser::asUint32(m_data, &offset);
return msg;
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_UNIMPLEMENTED.");
}
}
SshChannelOpen SshIncomingPacket::extractChannelOpen() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_OPEN);
SshChannelOpen open;
try {
quint32 offset = TypeOffset + 1;
QByteArray type = SshPacketParser::asString(m_data, &offset);
open.remoteChannel = SshPacketParser::asUint32(m_data, &offset);
open.remoteWindowSize = SshPacketParser::asUint32(m_data, &offset);
open.remoteMaxPacketSize = SshPacketParser::asUint32(m_data, &offset);
if (type == ForwardedTcpIpType) {
open.remoteAddress = SshPacketParser::asString(m_data, &offset);
open.remotePort = SshPacketParser::asUint32(m_data, &offset);
} else {
open.remotePort = 0;
}
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Server sent invalid SSH_MSG_CHANNEL_OPEN packet.");
}
return open;
}
SshChannelOpenFailure SshIncomingPacket::extractChannelOpenFailure() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_OPEN_FAILURE);
SshChannelOpenFailure openFailure;
try {
quint32 offset = TypeOffset + 1;
openFailure.localChannel = SshPacketParser::asUint32(m_data, &offset);
openFailure.reasonCode = SshPacketParser::asUint32(m_data, &offset);
openFailure.reasonString = QString::fromLocal8Bit(SshPacketParser::asString(m_data, &offset));
openFailure.language = SshPacketParser::asString(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Server sent invalid SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
}
return openFailure;
}
SshChannelOpenConfirmation SshIncomingPacket::extractChannelOpenConfirmation() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
SshChannelOpenConfirmation confirmation;
try {
quint32 offset = TypeOffset + 1;
confirmation.localChannel = SshPacketParser::asUint32(m_data, &offset);
confirmation.remoteChannel = SshPacketParser::asUint32(m_data, &offset);
confirmation.remoteWindowSize = SshPacketParser::asUint32(m_data, &offset);
confirmation.remoteMaxPacketSize = SshPacketParser::asUint32(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Server sent invalid SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet.");
}
return confirmation;
}
SshChannelWindowAdjust SshIncomingPacket::extractWindowAdjust() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_WINDOW_ADJUST);
SshChannelWindowAdjust adjust;
try {
quint32 offset = TypeOffset + 1;
adjust.localChannel = SshPacketParser::asUint32(m_data, &offset);
adjust.bytesToAdd = SshPacketParser::asUint32(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_CHANNEL_WINDOW_ADJUST packet.");
}
return adjust;
}
SshChannelData SshIncomingPacket::extractChannelData() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_DATA);
SshChannelData data;
try {
quint32 offset = TypeOffset + 1;
data.localChannel = SshPacketParser::asUint32(m_data, &offset);
data.data = SshPacketParser::asString(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_CHANNEL_DATA packet.");
}
return data;
}
SshChannelExtendedData SshIncomingPacket::extractChannelExtendedData() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_EXTENDED_DATA);
SshChannelExtendedData data;
try {
quint32 offset = TypeOffset + 1;
data.localChannel = SshPacketParser::asUint32(m_data, &offset);
data.type = SshPacketParser::asUint32(m_data, &offset);
data.data = SshPacketParser::asString(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_CHANNEL_EXTENDED_DATA packet.");
}
return data;
}
SshChannelExitStatus SshIncomingPacket::extractChannelExitStatus() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_REQUEST);
SshChannelExitStatus exitStatus;
try {
quint32 offset = TypeOffset + 1;
exitStatus.localChannel = SshPacketParser::asUint32(m_data, &offset);
const QByteArray &type = SshPacketParser::asString(m_data, &offset);
Q_ASSERT(type == ExitStatusType);
Q_UNUSED(type);
if (SshPacketParser::asBool(m_data, &offset))
throw SshPacketParseException();
exitStatus.exitStatus = SshPacketParser::asUint32(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid exit-status packet.");
}
return exitStatus;
}
SshChannelExitSignal SshIncomingPacket::extractChannelExitSignal() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_REQUEST);
SshChannelExitSignal exitSignal;
try {
quint32 offset = TypeOffset + 1;
exitSignal.localChannel = SshPacketParser::asUint32(m_data, &offset);
const QByteArray &type = SshPacketParser::asString(m_data, &offset);
Q_ASSERT(type == ExitSignalType);
Q_UNUSED(type);
if (SshPacketParser::asBool(m_data, &offset))
throw SshPacketParseException();
exitSignal.signal = SshPacketParser::asString(m_data, &offset);
exitSignal.coreDumped = SshPacketParser::asBool(m_data, &offset);
exitSignal.error = SshPacketParser::asUserString(m_data, &offset);
exitSignal.language = SshPacketParser::asString(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid exit-signal packet.");
}
return exitSignal;
}
quint32 SshIncomingPacket::extractRecipientChannel() const
{
Q_ASSERT(isComplete());
try {
quint32 offset = TypeOffset + 1;
return SshPacketParser::asUint32(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Server sent invalid packet.");
}
}
QByteArray SshIncomingPacket::extractChannelRequestType() const
{
Q_ASSERT(isComplete());
Q_ASSERT(type() == SSH_MSG_CHANNEL_REQUEST);
try {
quint32 offset = TypeOffset + 1;
SshPacketParser::asUint32(m_data, &offset);
return SshPacketParser::asString(m_data, &offset);
} catch (const SshPacketParseException &) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid SSH_MSG_CHANNEL_REQUEST packet.");
}
}
void SshIncomingPacket::calculateLength() const
{
Q_ASSERT(currentDataSize() >= minPacketSize());
qCDebug(sshLog, "Length field before decryption: %d-%d-%d-%d", m_data.at(0) & 0xff,
m_data.at(1) & 0xff, m_data.at(2) & 0xff, m_data.at(3) & 0xff);
m_decrypter.decrypt(m_data, 0, cipherBlockSize());
qCDebug(sshLog, "Length field after decryption: %d-%d-%d-%d", m_data.at(0) & 0xff, m_data.at(1) & 0xff, m_data.at(2) & 0xff, m_data.at(3) & 0xff);
qCDebug(sshLog, "message type = %d", m_data.at(TypeOffset));
m_length = SshPacketParser::asUint32(m_data, static_cast<quint32>(0));
qCDebug(sshLog, "decrypted length is %u", m_length);
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,213 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sshpacket_p.h"
#include "sshcryptofacility_p.h"
#include "sshpacketparser_p.h"
#include <QStringList>
namespace QSsh {
namespace Internal {
class SshKeyExchange;
struct SshKeyExchangeInit
{
char cookie[16];
SshNameList keyAlgorithms;
SshNameList serverHostKeyAlgorithms;
SshNameList encryptionAlgorithmsClientToServer;
SshNameList encryptionAlgorithmsServerToClient;
SshNameList macAlgorithmsClientToServer;
SshNameList macAlgorithmsServerToClient;
SshNameList compressionAlgorithmsClientToServer;
SshNameList compressionAlgorithmsServerToClient;
SshNameList languagesClientToServer;
SshNameList languagesServerToClient;
bool firstKexPacketFollows;
};
struct SshKeyExchangeReply
{
QByteArray k_s;
QList<Botan::BigInt> hostKeyParameters; // DSS: p, q, g, y. RSA: e, n.
QByteArray q; // For ECDSA host keys only.
Botan::BigInt f; // For DH only.
QByteArray q_s; // For ECDH only.
QByteArray signatureBlob;
};
struct SshDisconnect
{
quint32 reasonCode;
QString description;
QByteArray language;
};
struct SshUserAuthBanner
{
QString message;
QByteArray language;
};
struct SshUserAuthInfoRequestPacket
{
QString name;
QString instruction;
QByteArray languageTag;
QStringList prompts;
QList<bool> echos;
};
struct SshDebug
{
bool display;
QString message;
QByteArray language;
};
struct SshUnimplemented
{
quint32 invalidMsgSeqNr;
};
struct SshRequestSuccess
{
quint32 bindPort;
};
struct SshChannelOpen
{
quint32 remoteChannel;
quint32 remoteWindowSize;
quint32 remoteMaxPacketSize;
QByteArray remoteAddress;
quint32 remotePort;
};
struct SshChannelOpenFailure
{
quint32 localChannel;
quint32 reasonCode;
QString reasonString;
QByteArray language;
};
struct SshChannelOpenConfirmation
{
quint32 localChannel;
quint32 remoteChannel;
quint32 remoteWindowSize;
quint32 remoteMaxPacketSize;
};
struct SshChannelWindowAdjust
{
quint32 localChannel;
quint32 bytesToAdd;
};
struct SshChannelData
{
quint32 localChannel;
QByteArray data;
};
struct SshChannelExtendedData
{
quint32 localChannel;
quint32 type;
QByteArray data;
};
struct SshChannelExitStatus
{
quint32 localChannel;
quint32 exitStatus;
};
struct SshChannelExitSignal
{
quint32 localChannel;
QByteArray signal;
bool coreDumped;
QString error;
QByteArray language;
};
class SshIncomingPacket : public AbstractSshPacket
{
public:
SshIncomingPacket();
void consumeData(QByteArray &data);
void recreateKeys(const SshKeyExchange &keyExchange);
void reset();
SshKeyExchangeInit extractKeyExchangeInitData() const;
SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &kexAlgo,
const QByteArray &hostKeyAlgo) const;
SshDisconnect extractDisconnect() const;
SshUserAuthBanner extractUserAuthBanner() const;
SshUserAuthInfoRequestPacket extractUserAuthInfoRequest() const;
SshDebug extractDebug() const;
SshRequestSuccess extractRequestSuccess() const;
SshUnimplemented extractUnimplemented() const;
SshChannelOpen extractChannelOpen() const;
SshChannelOpenFailure extractChannelOpenFailure() const;
SshChannelOpenConfirmation extractChannelOpenConfirmation() const;
SshChannelWindowAdjust extractWindowAdjust() const;
SshChannelData extractChannelData() const;
SshChannelExtendedData extractChannelExtendedData() const;
SshChannelExitStatus extractChannelExitStatus() const;
SshChannelExitSignal extractChannelExitSignal() const;
quint32 extractRecipientChannel() const;
QByteArray extractChannelRequestType() const;
quint32 serverSeqNr() const { return m_serverSeqNr; }
static const QByteArray ExitStatusType;
static const QByteArray ExitSignalType;
static const QByteArray ForwardedTcpIpType;
private:
virtual quint32 cipherBlockSize() const;
virtual quint32 macLength() const;
virtual void calculateLength() const;
void decrypt();
void moveFirstBytes(QByteArray &target, QByteArray &source, int n);
quint32 m_serverSeqNr;
SshDecryptionFacility m_decrypter;
};
} // namespace Internal
} // namespace QSsh

View File

@@ -1,49 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshinit_p.h"
#include <botan/botan.h>
#include <QMutex>
#include <QMutexLocker>
namespace QSsh {
namespace Internal {
static bool initialized = false;
static QMutex initMutex;
void initSsh()
{
QMutexLocker locker(&initMutex);
if (!initialized) {
Botan::LibraryInitializer::initialize("thread_safe=true");
initialized = true;
}
}
} // namespace Internal
} // namespace QSsh

View File

@@ -1,32 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
namespace QSsh {
namespace Internal {
void initSsh();
} // namespace Internal
} // namespace QSsh

View File

@@ -1,174 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshkeycreationdialog.h"
#include "ui_sshkeycreationdialog.h"
#include "sshkeygenerator.h"
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QApplication>
#include <QMessageBox>
#include <QStandardPaths>
namespace QSsh {
SshKeyCreationDialog::SshKeyCreationDialog(QWidget *parent)
: QDialog(parent), m_keyGenerator(0), m_ui(new Ui::SshKeyCreationDialog)
{
m_ui->setupUi(this);
// Not using Utils::PathChooser::browseButtonLabel to avoid dependency
#ifdef Q_OS_MAC
m_ui->privateKeyFileButton->setText(tr("Choose..."));
#else
m_ui->privateKeyFileButton->setText(tr("Browse..."));
#endif
const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
+ QLatin1String("/.ssh/qtc_id");
setPrivateKeyFile(defaultPath);
connect(m_ui->rsa, &QRadioButton::toggled,
this, &SshKeyCreationDialog::keyTypeChanged);
connect(m_ui->dsa, &QRadioButton::toggled,
this, &SshKeyCreationDialog::keyTypeChanged);
connect(m_ui->privateKeyFileButton, &QPushButton::clicked,
this, &SshKeyCreationDialog::handleBrowseButtonClicked);
connect(m_ui->generateButton, &QPushButton::clicked,
this, &SshKeyCreationDialog::generateKeys);
keyTypeChanged();
}
SshKeyCreationDialog::~SshKeyCreationDialog()
{
delete m_keyGenerator;
delete m_ui;
}
void SshKeyCreationDialog::keyTypeChanged()
{
m_ui->comboBox->clear();
QStringList keySizes;
if (m_ui->rsa->isChecked())
keySizes << QLatin1String("1024") << QLatin1String("2048") << QLatin1String("4096");
else if (m_ui->ecdsa->isChecked())
keySizes << QLatin1String("256") << QLatin1String("384") << QLatin1String("521");
else if (m_ui->dsa->isChecked())
keySizes << QLatin1String("1024");
m_ui->comboBox->addItems(keySizes);
if (!keySizes.isEmpty())
m_ui->comboBox->setCurrentIndex(0);
m_ui->comboBox->setEnabled(!keySizes.isEmpty());
}
void SshKeyCreationDialog::generateKeys()
{
if (userForbidsOverwriting())
return;
const SshKeyGenerator::KeyType keyType = m_ui->rsa->isChecked()
? SshKeyGenerator::Rsa : m_ui->dsa->isChecked()
? SshKeyGenerator::Dsa : SshKeyGenerator::Ecdsa;
if (!m_keyGenerator)
m_keyGenerator = new SshKeyGenerator;
QApplication::setOverrideCursor(Qt::BusyCursor);
const bool success = m_keyGenerator->generateKeys(keyType, SshKeyGenerator::Mixed,
m_ui->comboBox->currentText().toUShort());
QApplication::restoreOverrideCursor();
if (success)
saveKeys();
else
QMessageBox::critical(this, tr("Key Generation Failed"), m_keyGenerator->error());
}
void SshKeyCreationDialog::handleBrowseButtonClicked()
{
const QString filePath = QFileDialog::getSaveFileName(this, tr("Choose Private Key File Name"));
if (!filePath.isEmpty())
setPrivateKeyFile(filePath);
}
void SshKeyCreationDialog::setPrivateKeyFile(const QString &filePath)
{
m_ui->privateKeyFileValueLabel->setText(filePath);
m_ui->generateButton->setEnabled(!privateKeyFilePath().isEmpty());
m_ui->publicKeyFileLabel->setText(filePath + QLatin1String(".pub"));
}
void SshKeyCreationDialog::saveKeys()
{
const QString parentDir = QFileInfo(privateKeyFilePath()).dir().path();
if (!QDir::root().mkpath(parentDir)) {
QMessageBox::critical(this, tr("Cannot Save Key File"),
tr("Failed to create directory: \"%1\".").arg(parentDir));
return;
}
QFile privateKeyFile(privateKeyFilePath());
if (!privateKeyFile.open(QIODevice::WriteOnly)
|| !privateKeyFile.write(m_keyGenerator->privateKey())) {
QMessageBox::critical(this, tr("Cannot Save Private Key File"),
tr("The private key file could not be saved: %1").arg(privateKeyFile.errorString()));
return;
}
QFile::setPermissions(privateKeyFilePath(), QFile::ReadOwner | QFile::WriteOwner);
QFile publicKeyFile(publicKeyFilePath());
if (!publicKeyFile.open(QIODevice::WriteOnly)
|| !publicKeyFile.write(m_keyGenerator->publicKey())) {
QMessageBox::critical(this, tr("Cannot Save Public Key File"),
tr("The public key file could not be saved: %1").arg(publicKeyFile.errorString()));
return;
}
accept();
}
bool SshKeyCreationDialog::userForbidsOverwriting()
{
if (!QFileInfo::exists(privateKeyFilePath()) && !QFileInfo::exists(publicKeyFilePath()))
return false;
const QMessageBox::StandardButton reply = QMessageBox::question(this, tr("File Exists"),
tr("There already is a file of that name. Do you want to overwrite it?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
return reply != QMessageBox::Yes;
}
QString SshKeyCreationDialog::privateKeyFilePath() const
{
return m_ui->privateKeyFileValueLabel->text();
}
QString SshKeyCreationDialog::publicKeyFilePath() const
{
return m_ui->publicKeyFileLabel->text();
}
} // namespace QSsh

View File

@@ -1,60 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "ssh_global.h"
#include <QDialog>
namespace QSsh {
class SshKeyGenerator;
namespace Ui { class SshKeyCreationDialog; }
class QSSH_EXPORT SshKeyCreationDialog : public QDialog
{
Q_OBJECT
public:
SshKeyCreationDialog(QWidget *parent = 0);
~SshKeyCreationDialog();
QString privateKeyFilePath() const;
QString publicKeyFilePath() const;
private:
void keyTypeChanged();
void generateKeys();
void handleBrowseButtonClicked();
void setPrivateKeyFile(const QString &filePath);
void saveKeys();
bool userForbidsOverwriting();
private:
SshKeyGenerator *m_keyGenerator;
Ui::SshKeyCreationDialog *m_ui;
};
} // namespace QSsh

View File

@@ -1,264 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QSsh::SshKeyCreationDialog</class>
<widget class="QDialog" name="QSsh::SshKeyCreationDialog">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>380</width>
<height>231</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>SSH Key Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Options</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="keyAlgo">
<property name="text">
<string>Key algorithm:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="rsa">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;RSA</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="dsa">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;DSA</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="ecdsa">
<property name="text">
<string>ECDSA</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="keySize">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Key &amp;size:</string>
</property>
<property name="buddy">
<cstring>comboBox</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QComboBox" name="comboBox">
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="privateKeyFileLabel">
<property name="text">
<string>Private key file:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="privateKeyFileValueLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="privateKeyFileButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Public key file:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="publicKeyFileLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="generateButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Generate And Save Key Pair</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>QSsh::SshKeyCreationDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>195</x>
<y>184</y>
</hint>
<hint type="destinationlabel">
<x>381</x>
<y>107</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,273 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sshkeyexchange_p.h"
#include "ssh_global.h"
#include "sshbotanconversions_p.h"
#include "sshcapabilities_p.h"
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
#include "sshexception_p.h"
#include "sshincomingpacket_p.h"
#include <botan/botan.h>
#include <string>
using namespace Botan;
namespace QSsh {
namespace Internal {
namespace {
// For debugging
void printNameList(const char *listName, const SshNameList &list)
{
qCDebug(sshLog, "%s:", listName);
foreach (const QByteArray &name, list.names)
qCDebug(sshLog, "%s", name.constData());
}
void printData(const char *name, const QByteArray &data)
{
qCDebug(sshLog, "The client thinks the %s has length %d and is: %s", name, data.count(),
data.toHex().constData());
}
} // anonymous namespace
SshKeyExchange::SshKeyExchange(const SshConnectionParameters &connParams,
SshSendFacility &sendFacility)
: m_connParams(connParams), m_sendFacility(sendFacility)
{
}
SshKeyExchange::~SshKeyExchange() {}
void SshKeyExchange::sendKexInitPacket(const QByteArray &serverId)
{
m_serverId = serverId;
m_clientKexInitPayload = m_sendFacility.sendKeyExchangeInitPacket();
}
bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit)
{
qCDebug(sshLog, "server requests key exchange");
serverKexInit.printRawBytes();
SshKeyExchangeInit kexInitParams
= serverKexInit.extractKeyExchangeInitData();
printNameList("Key Algorithms", kexInitParams.keyAlgorithms);
printNameList("Server Host Key Algorithms", kexInitParams.serverHostKeyAlgorithms);
printNameList("Encryption algorithms client to server", kexInitParams.encryptionAlgorithmsClientToServer);
printNameList("Encryption algorithms server to client", kexInitParams.encryptionAlgorithmsServerToClient);
printNameList("MAC algorithms client to server", kexInitParams.macAlgorithmsClientToServer);
printNameList("MAC algorithms server to client", kexInitParams.macAlgorithmsServerToClient);
printNameList("Compression algorithms client to server", kexInitParams.compressionAlgorithmsClientToServer);
printNameList("Compression algorithms client to server", kexInitParams.compressionAlgorithmsClientToServer);
printNameList("Languages client to server", kexInitParams.languagesClientToServer);
printNameList("Languages server to client", kexInitParams.languagesServerToClient);
qCDebug(sshLog, "First packet follows: %d", kexInitParams.firstKexPacketFollows);
m_kexAlgoName = SshCapabilities::findBestMatch(SshCapabilities::KeyExchangeMethods,
kexInitParams.keyAlgorithms.names);
m_serverHostKeyAlgo = SshCapabilities::findBestMatch(SshCapabilities::PublicKeyAlgorithms,
kexInitParams.serverHostKeyAlgorithms.names);
determineHashingAlgorithm(kexInitParams, true);
determineHashingAlgorithm(kexInitParams, false);
m_encryptionAlgo
= SshCapabilities::findBestMatch(SshCapabilities::EncryptionAlgorithms,
kexInitParams.encryptionAlgorithmsClientToServer.names);
m_decryptionAlgo
= SshCapabilities::findBestMatch(SshCapabilities::EncryptionAlgorithms,
kexInitParams.encryptionAlgorithmsServerToClient.names);
SshCapabilities::findBestMatch(SshCapabilities::CompressionAlgorithms,
kexInitParams.compressionAlgorithmsClientToServer.names);
SshCapabilities::findBestMatch(SshCapabilities::CompressionAlgorithms,
kexInitParams.compressionAlgorithmsServerToClient.names);
AutoSeeded_RNG rng;
if (m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix)) {
m_ecdhKey.reset(new ECDH_PrivateKey(rng, EC_Group(botanKeyExchangeAlgoName(m_kexAlgoName))));
m_sendFacility.sendKeyEcdhInitPacket(convertByteArray(m_ecdhKey->public_value()));
} else {
m_dhKey.reset(new DH_PrivateKey(rng, DL_Group(botanKeyExchangeAlgoName(m_kexAlgoName))));
m_sendFacility.sendKeyDhInitPacket(m_dhKey->get_y());
}
m_serverKexInitPayload = serverKexInit.payLoad();
return kexInitParams.firstKexPacketFollows;
}
void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
const QByteArray &clientId)
{
const SshKeyExchangeReply &reply
= dhReply.extractKeyExchangeReply(m_kexAlgoName, m_serverHostKeyAlgo);
if (m_dhKey && (reply.f <= 0 || reply.f >= m_dhKey->group_p())) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
"Server sent invalid f.");
}
QByteArray concatenatedData = AbstractSshPacket::encodeString(clientId);
concatenatedData += AbstractSshPacket::encodeString(m_serverId);
concatenatedData += AbstractSshPacket::encodeString(m_clientKexInitPayload);
concatenatedData += AbstractSshPacket::encodeString(m_serverKexInitPayload);
concatenatedData += reply.k_s;
printData("Client Id", AbstractSshPacket::encodeString(clientId));
printData("Server Id", AbstractSshPacket::encodeString(m_serverId));
printData("Client Payload", AbstractSshPacket::encodeString(m_clientKexInitPayload));
printData("Server payload", AbstractSshPacket::encodeString(m_serverKexInitPayload));
printData("K_S", reply.k_s);
SecureVector<byte> encodedK;
if (m_dhKey) {
concatenatedData += AbstractSshPacket::encodeMpInt(m_dhKey->get_y());
concatenatedData += AbstractSshPacket::encodeMpInt(reply.f);
DH_KA_Operation dhOp(*m_dhKey);
SecureVector<byte> encodedF = BigInt::encode(reply.f);
encodedK = dhOp.agree(encodedF, encodedF.size());
printData("y", AbstractSshPacket::encodeMpInt(m_dhKey->get_y()));
printData("f", AbstractSshPacket::encodeMpInt(reply.f));
m_dhKey.reset(nullptr);
} else {
Q_ASSERT(m_ecdhKey);
concatenatedData // Q_C.
+= AbstractSshPacket::encodeString(convertByteArray(m_ecdhKey->public_value()));
concatenatedData += AbstractSshPacket::encodeString(reply.q_s);
ECDH_KA_Operation ecdhOp(*m_ecdhKey);
encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count());
m_ecdhKey.reset(nullptr);
}
const BigInt k = BigInt::decode(encodedK);
m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently.
printData("K", m_k);
concatenatedData += m_k;
printData("Concatenated data", concatenatedData);
m_hash.reset(get_hash(botanHMacAlgoName(hashAlgoForKexAlgo())));
const SecureVector<byte> &hashResult = m_hash->process(convertByteArray(concatenatedData),
concatenatedData.size());
m_h = convertByteArray(hashResult);
printData("H", m_h);
QScopedPointer<Public_Key> sigKey;
if (m_serverHostKeyAlgo == SshCapabilities::PubKeyDss) {
const DL_Group group(reply.hostKeyParameters.at(0), reply.hostKeyParameters.at(1),
reply.hostKeyParameters.at(2));
DSA_PublicKey * const dsaKey
= new DSA_PublicKey(group, reply.hostKeyParameters.at(3));
sigKey.reset(dsaKey);
} else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyRsa) {
RSA_PublicKey * const rsaKey
= new RSA_PublicKey(reply.hostKeyParameters.at(1), reply.hostKeyParameters.at(0));
sigKey.reset(rsaKey);
} else {
QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo.startsWith(SshCapabilities::PubKeyEcdsaPrefix));
const EC_Group domain(SshCapabilities::oid(m_serverHostKeyAlgo));
const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(),
domain.get_curve());
ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(domain, point);
sigKey.reset(ecdsaKey);
}
const byte * const botanH = convertByteArray(m_h);
const Botan::byte * const botanSig = convertByteArray(reply.signatureBlob);
PK_Verifier verifier(*sigKey, botanEmsaAlgoName(m_serverHostKeyAlgo));
if (!verifier.verify_message(botanH, m_h.size(), botanSig, reply.signatureBlob.size())) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
"Invalid signature in key exchange reply packet.");
}
checkHostKey(reply.k_s);
m_sendFacility.sendNewKeysPacket();
}
QByteArray SshKeyExchange::hashAlgoForKexAlgo() const
{
if (m_kexAlgoName == SshCapabilities::EcdhNistp256)
return SshCapabilities::HMacSha256;
if (m_kexAlgoName == SshCapabilities::EcdhNistp384)
return SshCapabilities::HMacSha384;
if (m_kexAlgoName == SshCapabilities::EcdhNistp521)
return SshCapabilities::HMacSha512;
return SshCapabilities::HMacSha1;
}
void SshKeyExchange::determineHashingAlgorithm(const SshKeyExchangeInit &kexInit,
bool serverToClient)
{
QByteArray * const algo = serverToClient ? &m_s2cHMacAlgo : &m_c2sHMacAlgo;
const QList<QByteArray> &serverCapabilities = serverToClient
? kexInit.macAlgorithmsServerToClient.names
: kexInit.macAlgorithmsClientToServer.names;
*algo = SshCapabilities::findBestMatch(SshCapabilities::MacAlgorithms, serverCapabilities);
}
void SshKeyExchange::checkHostKey(const QByteArray &hostKey)
{
if (m_connParams.hostKeyCheckingMode == SshHostKeyCheckingNone) {
if (m_connParams.hostKeyDatabase)
m_connParams.hostKeyDatabase->insertHostKey(m_connParams.host, hostKey);
return;
}
if (!m_connParams.hostKeyDatabase) {
throw SshClientException(SshInternalError,
SSH_TR("Host key database must exist "
"if host key checking is enabled."));
}
switch (m_connParams.hostKeyDatabase->matchHostKey(m_connParams.host, hostKey)) {
case SshHostKeyDatabase::KeyLookupMatch:
return; // Nothing to do.
case SshHostKeyDatabase::KeyLookupMismatch:
if (m_connParams.hostKeyCheckingMode != SshHostKeyCheckingAllowMismatch)
throwHostKeyException();
break;
case SshHostKeyDatabase::KeyLookupNoMatch:
if (m_connParams.hostKeyCheckingMode == SshHostKeyCheckingStrict)
throwHostKeyException();
break;
}
m_connParams.hostKeyDatabase->insertHostKey(m_connParams.host, hostKey);
}
void SshKeyExchange::throwHostKeyException()
{
throw SshServerException(SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE, "Host key changed",
SSH_TR("Host key of machine \"%1\" has changed.")
.arg(m_connParams.host));
}
} // namespace Internal
} // namespace QSsh

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