Compare commits

...

187 Commits

Author SHA1 Message Date
Philipp Crocoll
a00267a0ac Manifest for 1.14-pre3 2025-08-19 18:04:45 +02:00
Philipp Crocoll
7fccb6cb16 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2025-08-19 18:04:01 +02:00
PhilippC
319f5d3113 Merge pull request #2983 from PhilippC/2893-bug-onedrive-sync-integration-no-longer-working-after-112-r5
attempt to fix app folder issue by creating it by an upload
2025-08-19 18:01:18 +02:00
Philipp Crocoll
b7276d1364 remove no-longer-sensible comment 2025-08-19 18:00:38 +02:00
Philipp Crocoll
58429ce0c4 attempt to fix app folder issue by creating it by an upload 2025-08-19 17:40:22 +02:00
Philipp Crocoll
72a72975e0 stability improvements 2025-08-19 12:25:38 +02:00
Philipp Crocoll
57be7af031 extend changelog for 1.14 2025-08-19 12:19:06 +02:00
Philipp Crocoll
5004a69bff modify release workflow to generate files as it was before on .net8 2025-08-19 11:19:52 +02:00
Philipp Crocoll
9628f2a1b8 manifest for 1.14-pre2 2025-08-12 17:36:03 +02:00
Philipp Crocoll
4cfdcb0f95 fix display issues with edge-to-edge when choosing file location; make file chooser look more modern 2025-08-12 17:23:13 +02:00
Philipp Crocoll
93d1eb9141 revert changes for https://github.com/PhilippC/keepass2android/issues/1617 because GnuTLS is currently not available for Android through FluentFTP 2025-08-12 14:43:37 +02:00
Philipp Crocoll
96f5953ed1 fix built-in keyboard padding on Android SDK 35 2025-08-12 14:04:29 +02:00
Philipp Crocoll
48b21b1006 manifest and changelog for 1.14-pre1 2025-07-29 17:33:10 +02:00
PhilippC
c7cdf5afcb Merge pull request #2948 from PhilippC/l10n_master3
New Crowdin updates
2025-07-29 17:32:45 +02:00
PhilippC
6d19a09c20 Merge pull request #2968 from PhilippC/feature/no-delete-history-element
Don't show delete-entry menu when viewing history elements
2025-07-29 17:32:35 +02:00
PhilippC
079756a2d7 New translations strings.xml (German) 2025-07-29 17:26:04 +02:00
Philipp Crocoll
9c43136e18 don't show some menu items when viewing history elements, closes #2967 2025-07-29 17:19:37 +02:00
PhilippC
38da94e6dd Merge pull request #2965 from PhilippC/feature/update-jsch
Update Jsch and switch to maven dependency. This adds more recent algorithms to the SFTP implementation and improves maintainability.
2025-07-29 17:13:47 +02:00
Philipp Crocoll
da245f3f88 add missing dependency 2025-07-29 16:11:55 +02:00
Philipp Crocoll
1e18763f8d Merge remote-tracking branch 'origin/master' 2025-07-29 13:50:38 +02:00
Philipp Crocoll
82c3b0546c remove jsch source code and replace with mwiede jsch reference. 2025-07-29 13:50:33 +02:00
PhilippC
f246726ab7 Merge pull request #2963 from PhilippC/feature/scrollable-credential-dialogs
make credential dialogs scrollable. Closes #2959
2025-07-29 13:49:49 +02:00
Philipp Crocoll
331daa7e12 Merge branch 'feature/scrollable-credential-dialogs' 2025-07-29 12:13:26 +02:00
Philipp Crocoll
9be215c295 Merge remote-tracking branch 'origin/master' into feature/scrollable-credential-dialogs 2025-07-29 12:06:22 +02:00
PhilippC
bb97a023de Merge pull request #2964 from PhilippC/v1.13
V1.13 fixes:
* fix QuickUnlock layout
* add an option to disable QuickUnlock blocking for cases where this is explicitly needed
2025-07-29 12:02:58 +02:00
Philipp Crocoll
edb4907bf5 add option to disable QuickUnlock blocking behavior, closes #2960 2025-07-29 10:53:02 +02:00
Philipp Crocoll
a718c7ed7e fix quickunlock layout also when showing the "blocked" message 2025-07-29 10:50:43 +02:00
Philipp Crocoll
4f11789f26 remove no longer used file 2025-07-29 10:22:37 +02:00
Philipp Crocoll
eb15861b13 fix QuickUnlock layout to close #2956 2025-07-29 10:22:18 +02:00
Philipp Crocoll
8c2c8049c8 make credential dialogs scrollable. Closes #2959 2025-07-29 09:49:10 +02:00
PhilippC
43c167073e New translations strings.xml (German) 2025-07-26 21:45:33 +02:00
PhilippC
1037e3306c New translations strings.xml (German) 2025-07-26 20:49:48 +02:00
PhilippC
08e818d4dc New translations strings.xml (Russian) 2025-07-23 17:19:06 +02:00
PhilippC
1946837277 New translations strings.xml (Turkish) 2025-07-22 22:10:08 +02:00
PhilippC
2f3761b0a7 Merge pull request #2949 from PhilippC/update/target-sdk-35
Update to .net 9 and Target SDK version 35
2025-07-22 16:01:07 +02:00
Philipp Crocoll
260bc8adb2 adjust layouts and colors for Edge-to-Edge with transparent status bar as is default in Android 35+ 2025-07-22 15:16:28 +02:00
Philipp Crocoll
87e979635b Merge remote-tracking branch 'origin/master' into update/target-sdk-35 2025-07-22 09:51:25 +02:00
PhilippC
0c9c163755 Merge pull request #2954 from PhilippC/ui-improvement/non-cancelable-dialogs
Make dialogs for SFTP, FTP, Mega, WebDav and Nextcloud not cancelable
2025-07-22 09:05:36 +02:00
Philipp Crocoll
74ceea562b Make dialogs for SFTP, FTP, Mega, WebDav and Nextcloud not "cancelable", i.e. they don't close when tapping outside. 2025-07-22 08:41:01 +02:00
PhilippC
4cd91ed228 New translations strings.xml (French) 2025-07-22 08:24:00 +02:00
PhilippC
de4a18dfa1 New translations strings.xml (Czech) 2025-07-17 12:35:51 +02:00
Philipp Crocoll
c6a5362ecb update to target sdk version 35 2025-07-15 17:16:14 +02:00
PhilippC
f2c1dc00a1 New translations strings.xml (Portuguese, Brazilian) 2025-07-15 14:49:52 +02:00
Philipp Crocoll
f655a89be0 don't run the release workflow when creating a tag 2025-07-15 14:26:12 +02:00
Philipp Crocoll
0d6f837578 manifest and changelog for 1.14-pre0 2025-07-15 14:24:10 +02:00
PhilippC
8c61b028b7 Merge pull request #2789 from PhilippC/feature/82-smb-support
Samba support
2025-07-15 14:17:54 +02:00
Philipp Crocoll
a3d5273285 Merge branch 'master' into feature/82-smb-support 2025-07-15 13:45:01 +02:00
Philipp Crocoll
93cf4f790c change TargetFramework to .net9 2025-07-15 13:41:58 +02:00
PhilippC
cd323c0a22 Merge pull request #2947 from PhilippC/feature/webdav-improvements
Webdav improvements:
 * Add support for chunked uploads (enabled by default)
 * Fix determination of resource type (file vs folder)
 * add support for transactional write
2025-07-15 13:38:08 +02:00
PhilippC
99ca8bf953 Merge pull request #2829 from PhilippC/1617-use-gnu-tls-stream
Use GnuTLS stream for FTPS
2025-07-15 13:23:05 +02:00
Philipp Crocoll
d40b3dc15c fix build issue with NoNet 2025-07-15 13:16:44 +02:00
Philipp Crocoll
057a7e2f7a another nonet fix 2025-07-15 13:12:18 +02:00
PhilippC
1b73c536d5 Merge pull request #2939 from PhilippC/l10n_master3
New Crowdin updates
2025-07-15 12:32:08 +02:00
Philipp Crocoll
2593a8548f Merge branch 'master' into 1617-use-gnu-tls-stream 2025-07-15 12:25:01 +02:00
Philipp Crocoll
13306a9076 fix another build issue in NoNet 2025-07-15 12:20:25 +02:00
Philipp Crocoll
cfb5098b38 add support for transactional upload 2025-07-15 12:18:45 +02:00
Philipp Crocoll
d04d455fbd add missing changelog for 1.13 2025-07-15 12:00:05 +02:00
Philipp Crocoll
b83c4b3772 improve Samba dialog. fix NoNet build 2025-07-15 11:51:15 +02:00
Philipp Crocoll
f03c11381e Merge branch 'master' into feature/82-smb-support 2025-07-15 11:28:49 +02:00
Philipp Crocoll
8a03ddb7f3 always upload files to Github release 2025-07-15 11:08:26 +02:00
Philipp Crocoll
913222d7cb allow chunked uploads, closes https://github.com/PhilippC/keepass2android/issues/2777 2025-07-15 11:07:40 +02:00
Philipp Crocoll
3e6d86c206 correctly check if an item is a folder or file. closes https://github.com/PhilippC/keepass2android/issues/2589 2025-07-15 09:10:41 +02:00
Philipp Crocoll
d6ce2a32e9 allow manually triggering a release workflow run 2025-07-15 08:30:17 +02:00
Philipp Crocoll
21f1c8404c update workflows to not create signed apks during build but only in release. Create releases as drafts. 2025-07-15 08:14:52 +02:00
PhilippC
16ff81cf81 New translations strings.xml (Czech) 2025-07-14 10:57:07 +02:00
PhilippC
0636f687ac New translations strings.xml (Greek) 2025-07-09 13:58:02 +02:00
PhilippC
60d8900473 New translations strings.xml (Greek) 2025-07-09 11:40:00 +02:00
PhilippC
4b2d2ef768 New translations strings.xml (Portuguese, Brazilian) 2025-07-09 02:47:52 +02:00
PhilippC
48899ba9a0 New translations strings.xml (Portuguese, Brazilian) 2025-07-09 01:34:39 +02:00
Philipp Crocoll
092b8689b8 fix build-artifact paths 2025-07-08 21:35:51 +02:00
Philipp Crocoll
3d3ba45cb1 extract keystore for subsequent build step 2025-07-08 18:23:02 +02:00
Philipp Crocoll
b380100307 Manifest and changelog for v1.13 2025-07-08 17:57:52 +02:00
Philipp Crocoll
4c5ddd59d8 build signed apk on every build of master branch 2025-07-08 17:57:37 +02:00
PhilippC
5ed183f318 Merge pull request #2929 from PhilippC/l10n_master3
New Crowdin updates
2025-07-08 17:56:50 +02:00
PhilippC
9c27fd3e78 Merge pull request #2938 from PhilippC/security/audit_suggestions
Security suggestions from Audit
2025-07-08 17:52:16 +02:00
Philipp Crocoll
62c361feb0 revert unintentional change 2025-07-08 17:03:32 +02:00
Philipp Crocoll
0ee2495528 disable password-based QuickUnlock when device is not protected by screen lock 2025-07-08 16:54:45 +02:00
Philipp Crocoll
7dc635a625 Update KeePass2 code for password quality estimation; add and use list of most popular passwords to account for NIST recommendation of using "blocklists" 2025-07-08 12:09:59 +02:00
Philipp Crocoll
e15112c3b4 disable cleartextTrafficPermitted. default to https for links. 2025-07-08 10:35:50 +02:00
PhilippC
1d85fffb18 New translations strings.xml (Chinese Simplified) 2025-07-07 18:44:26 +02:00
PhilippC
5e2f29e737 New translations strings.xml (Chinese Simplified) 2025-07-07 17:20:28 +02:00
Philipp Crocoll
89a09ea142 set version to 1.12-r9d 2025-07-05 14:17:07 +02:00
Philipp Crocoll
628c0d2c19 enable creation of a release 2025-07-05 14:16:17 +02:00
Philipp Crocoll
584feabe44 build process: add previously missing change; fix error in build.yml, more verbose output in release.yml 2025-07-05 13:34:01 +02:00
Philipp Crocoll
ae2cfde897 change makefile to no longer use msbuild but always dotnet 2025-07-05 13:10:21 +02:00
Philipp Crocoll
42c66670b8 release process: make find calls to run in bash 2025-07-05 12:12:49 +02:00
Philipp Crocoll
288539b902 make output more verbose 2025-07-05 11:09:55 +02:00
Philipp Crocoll
61fd32f121 avoid building the "full" apk when calling apk_split 2025-07-05 09:39:54 +02:00
Philipp Crocoll
43108ec4a6 remove ls step in release 2025-07-05 08:35:58 +02:00
Philipp Crocoll
51089c6b98 change build artifact release paths. make archive name depend on matrix variables. 2025-07-05 08:16:30 +02:00
Philipp Crocoll
cf18fcf91c remove distclean from build 2025-07-05 08:15:58 +02:00
Philipp Crocoll
da0513c768 don't create release but only list files to test the release workflow without polluting github releases 2025-07-05 07:49:39 +02:00
Philipp Crocoll
37f520cdbe manifest for r9c 2025-07-05 07:40:21 +02:00
Philipp Crocoll
c98572bee0 fix wildcard for selecting files to upload to release 2025-07-05 07:39:44 +02:00
Philipp Crocoll
b1774ffc4b increase version number ot r9b 2025-07-05 07:19:26 +02:00
Philipp Crocoll
57aaa0c4cd start release action by pushing version tags instead of when release is created on Github 2025-07-05 07:18:21 +02:00
Philipp Crocoll
b961ae1b33 make sure AndroidManifest.xml exists before running nuget 2025-07-05 07:12:17 +02:00
Philipp Crocoll
5e418e2b1b run workload update before any dotnet/nuget calls in github actions 2025-07-05 06:57:00 +02:00
Philipp Crocoll
6d22a213f3 add build target apk_split; build all combinations in a Github action when creating the release 2025-07-05 06:44:28 +02:00
Philipp Crocoll
a76addc43f manifest for 1.12-r9 2025-07-05 06:43:39 +02:00
Philipp Crocoll
1d96217713 remove GooglePlayServices Auth and Base from apk in NoNet build 2025-07-05 06:42:42 +02:00
Philipp Crocoll
d2b8fdcfff allow using Dropbox secrets from environment (better suited for Github action builds) 2025-07-05 06:34:23 +02:00
PhilippC
426fbc2510 New translations strings.xml (Polish) 2025-07-04 23:10:33 +02:00
PhilippC
e89a961c02 New translations strings.xml (Polish) 2025-07-04 22:15:11 +02:00
PhilippC
766c29b7a9 New translations strings.xml (Spanish) 2025-07-03 14:39:21 +02:00
Philipp Crocoll
507b671448 exclude Mega and OneDrive from NoNet build. Manifest for 1.12-r8c 2025-07-02 21:39:37 +02:00
Philipp Crocoll
3118ffaeb5 update version code and name => r8b (to distinguish from previously incorrect r8 build) 2025-07-02 21:04:22 +02:00
Philipp Crocoll
0abe29bd77 restore NoNet build, including removal of MLKit for that Flavor as it adds internet permission 2025-07-02 21:03:20 +02:00
Philipp Crocoll
f3a7831390 upload release artifacts before rebuilding 2025-06-30 22:29:31 +02:00
Philipp Crocoll
37cd58f7ba Merge branch 'v1.12' 2025-06-30 21:59:46 +02:00
Philipp Crocoll
7dd80a8ef7 remove "net" where no longer appropriate from workflow file 2025-06-30 16:16:55 +02:00
Philipp Crocoll
c78636264b align net and nonet manifests 2025-06-30 16:05:02 +02:00
Philipp Crocoll
035506a5a3 add nonet to release workflow 2025-06-30 16:04:38 +02:00
PhilippC
4cf46ef062 Merge pull request #2933 from PhilippC/v1.12
several updates for V1.12
2025-06-30 15:48:57 +02:00
Philipp Crocoll
c7b8063171 add previously forgotten changes 2025-06-30 14:36:59 +02:00
Philipp Crocoll
0a8b149c9a fix failing AutofillTest by adjusting to changed policy 2025-06-30 14:05:26 +02:00
Philipp Crocoll
9240a27791 run workload update before running tests, otherwise dotnet test can fail 2025-06-30 13:38:54 +02:00
PhilippC
e90d5b903c Merge pull request #2932 from PhilippC/2915-bug-exporting-the-key-file-broken-android-file-browser-doesnt-open
Fix crash when exporting key file
2025-06-30 12:43:08 +02:00
Philipp Crocoll
50b4a9f1b9 add missing Theme attributes 2025-06-30 12:42:05 +02:00
Philipp Crocoll
9783c3b5fe manifest for 1.12-r7 2025-06-24 17:12:22 +02:00
Philipp Crocoll
7a837e3237 show autofill more often without requiring manual requests, might mitigate issues in https://github.com/PhilippC/keepass2android/issues/2898 2025-06-24 17:10:50 +02:00
Philipp Crocoll
c8f6714373 refactoring: simplify autofill code 2025-06-24 17:10:08 +02:00
Philipp Crocoll
bc0313aa6a remove no-longer-needed step in release workflow 2025-06-24 15:41:46 +02:00
Philipp Crocoll
0f98668bcd improve app stability and refactor to get better logs 2025-06-24 15:41:11 +02:00
PhilippC
c4206e58bf New translations strings.xml (German) 2025-06-24 15:34:08 +02:00
PhilippC
630ededf3b New translations strings.xml (German) 2025-06-24 13:51:08 +02:00
Philipp Crocoll
8d1195ac96 manifest for v1.12-r6b. Same as v1.12-r6, but need a new version code for Google Play release based on github-action built apk 2025-06-18 03:00:52 +02:00
Philipp Crocoll
df731ac1b3 add checksum to releases; cleanup workflow 2025-06-18 02:40:03 +02:00
Philipp Crocoll
bd784fa13d fix file path for apk to upload 2025-06-18 02:29:47 +02:00
Philipp Crocoll
a6bc5e657c remove no longer needed installation of sdk 26 2025-06-18 02:09:36 +02:00
Philipp Crocoll
56c4cdb321 add Configuration=Release 2025-06-18 02:04:52 +02:00
Philipp Crocoll
42a4a83c7d add upload apk to release in workflow 2025-06-17 22:20:56 +02:00
Philipp Crocoll
fe3933e154 try escape keystore env for building apk 2025-06-17 22:02:21 +02:00
Philipp Crocoll
3efe130ee8 remove unescaped test 2025-06-17 21:59:46 +02:00
Philipp Crocoll
5808857749 fix quoting for shell 2025-06-17 21:12:51 +02:00
Philipp Crocoll
a7397c3316 explicitly set shell=bash 2025-06-17 21:08:13 +02:00
Philipp Crocoll
d12f936898 next attempt 2025-06-17 20:51:10 +02:00
Philipp Crocoll
67f7d74bb9 and more debugging 2025-06-17 20:44:34 +02:00
Philipp Crocoll
b0d0f06073 more debug 2025-06-17 20:37:24 +02:00
Philipp Crocoll
67ee571c27 fix debugging signing 2025-06-17 20:32:15 +02:00
Philipp Crocoll
a360695271 debug signing 2025-06-17 20:28:05 +02:00
Philipp Crocoll
149857a516 make keystore path absolute 2025-06-17 18:45:17 +02:00
Philipp Crocoll
fb8ffb802f try to fix release workflow 2025-06-17 17:50:10 +02:00
Philipp Crocoll
e957073457 add workflow file for generating the "net" release apk 2025-06-17 17:30:16 +02:00
Philipp Crocoll
da86b0f50b manifest for 1.12-r6 2025-06-17 16:55:47 +02:00
PhilippC
0aa78ffd66 Merge pull request #2862 from Gian-Fr/fix-makefile
Fixed MakeFile for Linux
2025-06-17 16:52:04 +02:00
PhilippC
ce0087af99 Merge pull request #2850 from PhilippC/l10n_master3
New Crowdin updates
2025-06-17 16:46:16 +02:00
PhilippC
576bfeecfe Merge pull request #2918 from PhilippC/2869-fix-bad-behavior-when-starting-passwordactivity-twice
Fix bad behavior when starting passwordactivity twice
2025-06-17 16:45:12 +02:00
Philipp Crocoll
c0e2f34b79 use correct message severity when synchronizing 2025-06-17 16:42:30 +02:00
Philipp Crocoll
84d0c32610 fix issue with loading Yubikey aux file. closes #2880 2025-06-17 16:27:43 +02:00
Philipp Crocoll
40184dbd55 catch exception while sending log data. might throw if too much data is sent. 2025-06-17 14:58:06 +02:00
Philipp Crocoll
2d17bdde19 add more logging while loading database to get more info regarding #2868 2025-06-17 14:58:01 +02:00
Philipp Crocoll
e2babde1fa do not reset activity state in OnNewIntent if the activity hasn't even been initialized. closes #2869, closes #2888 2025-06-17 14:04:15 +02:00
Philipp Crocoll
e1f26fb045 cleanup and improve formatting 2025-06-17 13:58:29 +02:00
Philipp Crocoll
adbbfa0ac1 add more logging to diagnose #2891 2025-06-17 08:27:13 +02:00
PhilippC
37a013135e New translations strings.xml (French) 2025-06-05 23:19:38 +02:00
PhilippC
acc6ea7f85 New translations strings.xml (French) 2025-06-05 22:10:08 +02:00
PhilippC
62f012713a New translations strings.xml (Turkish) 2025-06-03 19:34:43 +02:00
PhilippC
0d726c1789 New translations strings.xml (Turkish) 2025-06-03 17:37:29 +02:00
Philipp Crocoll
f162e868b9 link libargon2.so for x86 and x86_64 to fix #2881 2025-06-03 17:07:17 +02:00
PhilippC
0a1f95653f New translations strings.xml (Spanish) 2025-06-01 16:19:37 +02:00
PhilippC
27451825c6 New translations strings.xml (Italian) 2025-05-29 10:32:52 +02:00
PhilippC
bdd6f1033e New translations strings.xml (Romanian) 2025-05-26 14:25:46 +02:00
PhilippC
c0413f9b74 New translations strings.xml (Turkish) 2025-05-26 12:52:41 +02:00
PhilippC
59d6fc8fdb New translations strings.xml (German) 2025-05-16 08:18:05 +02:00
PhilippC
c500245647 New translations strings.xml (German) 2025-05-16 06:50:12 +02:00
PhilippC
026a263f10 New translations strings.xml (German) 2025-05-13 10:41:52 +02:00
PhilippC
839e6d3cb4 New translations strings.xml (French) 2025-05-12 04:51:42 +02:00
PhilippC
735f4caf89 New translations strings.xml (French) 2025-05-12 03:33:02 +02:00
PhilippC
11af71ef82 New translations strings.xml (Slovak) 2025-05-12 00:26:40 +02:00
PhilippC
e09577d17f New translations strings.xml (Slovak) 2025-05-11 22:34:40 +02:00
Gian-Fr
c1dbf171f5 Fixed MakeFile for Linux 2025-05-01 16:21:02 +02:00
PhilippC
4ca4ec10be New translations strings.xml (Czech) 2025-04-24 11:00:27 +02:00
PhilippC
77fded4964 New translations strings.xml (Chinese Simplified) 2025-04-24 11:00:26 +02:00
PhilippC
578491b1c7 New translations strings.xml (Slovenian) 2025-04-24 08:40:12 +02:00
PhilippC
eee3ffd861 New translations strings.xml (Slovenian) 2025-04-24 07:18:52 +02:00
PhilippC
89696d7f0d New translations strings.xml (Portuguese, Brazilian) 2025-04-23 00:14:27 +02:00
Philipp Crocoll
e5d28f0979 only try to activate the keyboard once in password activity and entry edit activity; explain why the prompt shows up in SwitchImeActivity. closes #1400 2025-04-22 17:48:56 +02:00
Philipp Crocoll
0e581a66c5 treat server certificate failures as error by default, closes #1078 2025-04-22 16:02:02 +02:00
PhilippC
a202c76bf0 New translations strings.xml (Chinese Simplified) 2025-04-22 08:10:50 +02:00
PhilippC
c9936ab76b New translations strings.xml (Italian) 2025-04-16 21:31:25 +02:00
PhilippC
7ac6f7ed51 New translations strings.xml (Italian) 2025-04-16 21:31:24 +02:00
PhilippC
ceb31c54b1 Merge pull request #2847 from PhilippC/2430-remove-plain-storage-uri-from-logs
remove potential plain-text credentials for file storage from logs
2025-04-15 14:27:02 +02:00
Philipp Crocoll
ba7b02cd1e remove testing credentials 2025-04-08 15:46:38 +02:00
Philipp Crocoll
aec9441de4 update FluentFTP 2025-04-08 15:26:04 +02:00
Philipp Crocoll
5edf42254d this is an experiment to use GnuTlsStream (the ftpcredentials.xml have some hardcoded credentials for a public FTP server for testing). Unfortunately, the app restarts when loading the native libraries for GnuTLS. 2025-04-01 15:10:04 +02:00
Philipp Crocoll
a51bfb102f implements Samba support to close #82 2025-03-05 08:14:02 +01:00
389 changed files with 16008 additions and 45995 deletions

View File

@@ -78,7 +78,7 @@ jobs:
# - name: Build keepass2android (net) # - name: Build keepass2android (net)
# run: | # run: |
# make msbuild Flavor=Net # make dotnetbuild Flavor=Net
# - name: Build APK (net) # - name: Build APK (net)
# run: | # run: |
@@ -96,7 +96,7 @@ jobs:
# - name: Build keepass2android (nonet) # - name: Build keepass2android (nonet)
# run: | # run: |
# make msbuild Flavor=NoNet # make dotnetbuild Flavor=NoNet
# - name: Build APK (nonet) # - name: Build APK (nonet)
# run: | # run: |
@@ -212,7 +212,7 @@ jobs:
# - name: Build keepass2android (net) # - name: Build keepass2android (net)
# run: | # run: |
# make msbuild Flavor=Net # make dotnetbuild Flavor=Net
# - name: Build APK (net) # - name: Build APK (net)
# run: | # run: |
@@ -230,7 +230,7 @@ jobs:
# - name: Build keepass2android (nonet) # - name: Build keepass2android (nonet)
# run: | # run: |
# make msbuild Flavor=NoNet # make dotnetbuild Flavor=NoNet
# - name: Build APK (nonet) # - name: Build APK (nonet)
# run: | # run: |
@@ -279,7 +279,7 @@ jobs:
with: with:
minimum-size: 8GB minimum-size: 8GB
- name: Add msbuild to PATH - name: Add dotnetbuild to PATH
uses: microsoft/setup-msbuild@v2 uses: microsoft/setup-msbuild@v2
# If we want to also have nmake, use this instead # If we want to also have nmake, use this instead
#uses: ilammy/msvc-dev-cmd@v1 #uses: ilammy/msvc-dev-cmd@v1
@@ -309,30 +309,49 @@ jobs:
run: | run: |
make java make java
- name: Update dotnet workloads
run: |
dotnet workload update
- name: Select the manifest
run: |
make manifestlink Flavor=Net
- name: Install NuGet dependencies (net) - name: Install NuGet dependencies (net)
run: make nuget Flavor=Net run: make nuget Flavor=Net
- name: Build keepass2android (net) - name: Build keepass2android (net)
run: | run: |
make msbuild Flavor=Net make dotnetbuild Flavor=Net
- name: Build APK (net) - name: Build APK (net)
if: github.ref == 'refs/heads/master'
env:
DropboxAppKey: ${{ secrets.DROPBOX_APP_KEY }}
DropboxAppSecret: ${{ secrets.DROPBOX_APP_SECRET }}
DropboxAppFolderAppKey: ${{ secrets.DROPBOX_APP_FOLDER_APP_KEY }}
DropboxAppFolderAppSecret: ${{ secrets.DROPBOX_APP_FOLDER_APP_SECRET }}
run: | run: |
make apk Flavor=Net make apk Configuration=Release Flavor=Net
- name: Archive production artifacts (net) - name: Archive production artifacts (net)
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: signed APK ('net' built on ${{ github.job }}) name: archive APK ('net' built on ${{ github.job }})
path: | path: |
src/keepass2android/bin/*/*-Signed.apk src/keepass2android-app/bin/Release/net9.0-android/publish/*.apk
- name: Select the manifest
run: |
make manifestlink Flavor=NoNet
- name: Install NuGet dependencies (nonet) - name: Install NuGet dependencies (nonet)
run: make nuget Flavor=NoNet run: make nuget Flavor=NoNet
- name: Build keepass2android (nonet) - name: Build keepass2android (nonet)
run: | run: |
make msbuild Flavor=NoNet make dotnetbuild Flavor=NoNet
- name: Test Autofill - name: Test Autofill
working-directory: ./src/Kp2aAutofillParser.Tests working-directory: ./src/Kp2aAutofillParser.Tests
run: dotnet test run: dotnet test
@@ -344,9 +363,7 @@ jobs:
- name: Archive production artifacts (nonet) - name: Archive production artifacts (nonet)
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: signed APK ('nonet' built on ${{ github.job }}) name: archive APK ('nonet' built on ${{ github.job }})
path: | path: |
src/keepass2android/bin/*/*-Signed.apk src/keepass2android-app/bin/Release/net9.0-android/publish/*.apk
- name: Perform "make distclean"
run: make distclean

162
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,162 @@
name: Create keepass2android release
env:
NAME: 'Release'
on:
# the workflow is always triggered manually. This allows to test the apks
# before publishing the release and not having a broken tag in the repo if that test fails.
workflow_dispatch:
jobs:
build-release:
runs-on: windows-2022
strategy:
matrix:
flavor: [Net, NoNet]
target: [apk, apk_split]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Extract key store
env:
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
KeyStore: "${{ github.workspace }}/kp2a.keystore"
shell: bash
run: |
echo $KeyStore
echo $KEYSTORE_BASE64 | base64 --decode > $KeyStore
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
restore-keys: |
${{ runner.os }}-nuget-
# Workaround an issue when building on windows-2022. Error was
# D8 : OpenJDK 64-Bit Server VM warning : INFO: os::commit_memory(0x00000000ae400000, 330301440, 0) failed; error='The paging file is too small for this operation to complete' (DOS error/errno=1455) [D:\a\keepass2android\keepass2android\src\keepass2android\keepass2android-app.csproj]
# C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.D8.targets(81,5): error MSB6006: "java.exe" exited with code 1. [D:\a\keepass2android\keepass2android\src\keepass2android\keepass2android-app.csproj]
- name: Configure Pagefile
uses: al-cheb/configure-pagefile-action@a3b6ebd6b634da88790d9c58d4b37a7f4a7b8708 # v1.4
with:
minimum-size: 8GB
- name: Add msbuild/dotnet to PATH
uses: microsoft/setup-msbuild@v2
# If we want to also have nmake, use this instead
#uses: ilammy/msvc-dev-cmd@v1
- name: Switch to JDK-17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Display java version
run: java -version
- name: Build native dependencies
shell: cmd
run: |
make native
- name: Build java dependencies
shell: cmd
run: |
make java
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Update dotnet workloads
run: |
dotnet workload update
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Select the manifest
run: |
make manifestlink Flavor=${{ matrix.flavor }}
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Install NuGet dependencies
run: make nuget Flavor=${{ matrix.flavor }}
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Build APK (net)
env:
KeyStore: "${{ github.workspace }}/kp2a.keystore"
MyAndroidSigningStorePass: ${{ secrets.KEY_STORE_PASSWORD }}
MyAndroidSigningKeyPass: ${{ secrets.KEY_PASSWORD }}
DropboxAppKey: ${{ secrets.DROPBOX_APP_KEY }}
DropboxAppSecret: ${{ secrets.DROPBOX_APP_SECRET }}
DropboxAppFolderAppKey: ${{ secrets.DROPBOX_APP_FOLDER_APP_KEY }}
DropboxAppFolderAppSecret: ${{ secrets.DROPBOX_APP_FOLDER_APP_SECRET }}
run: |
make ${{ matrix.target }} Configuration=Release Flavor=${{ matrix.flavor }}
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: keepass2android_${{ matrix.target }}_${{ matrix.flavor }}
# the first line is for "apk" target, the second line is for "apk_split" target
path: |
src/keepass2android-app/bin/Release/net9.0-android/publish/*.apk
src/keepass2android-app/bin/Release/net9.0-android/*/publish/*.apk
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Rename apks
# after updating to .net9, the naming scheme of the output apks has changed. rename them to the old scheme
# for consistancy with previous releases
run: |
for apk in src/keepass2android-app/bin/Release/net9.0-android/android-*/publish/*-Signed.apk; do
[ -e "$apk" ] || continue # if glob above doesn't return anything, the loop is still executed once
arch=$(basename "$(dirname "$(dirname "$apk")")") # e.g. "android-arm64"
base=$(basename "$apk" .apk) # e.g. "keepass2android.keepass2android_nonet-Signed"
mv "$apk" "$(dirname "$apk")/${base}-${arch#android-}.apk"
done
shell: bash
- name: List apks
run: find . -type f -name "*.apk"
shell: bash
- name: Upload APK to GitHub Release
uses: softprops/action-gh-release@v2
with:
draft: true
files: |
src/keepass2android-app/bin/Release/net9.0-android/publish/*.apk
src/keepass2android-app/bin/Release/net9.0-android/*/publish/*.apk

2
.gitignore vendored
View File

@@ -64,7 +64,7 @@ Thumbs.db
/src/java/android-filechooser/code/projectzip/project.zip /src/java/android-filechooser/code/projectzip/project.zip
/src/java/android-filechooser/code/unused.txt /src/java/android-filechooser/code/unused.txt
/src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs /src/Kp2aBusinessLogic/Io/DropboxFileStorage.g.cs
/src/java/workspace/DriveTest /src/java/workspace/DriveTest

View File

@@ -4,10 +4,10 @@
# This Makefile can be used on both unix-like (use make) & windows (with GNU make) # This Makefile can be used on both unix-like (use make) & windows (with GNU make)
# #
# append the Configuration variable to 'make' call with value to use in '/p:Configuration=' # append the Configuration variable to 'make' call with value to use in '/p:Configuration='
# of msbuild command. # of dotnetbuild command.
# #
# append the Flavor variable to 'make' call with value to use in '/p:Flavor=' # append the Flavor variable to 'make' call with value to use in '/p:Flavor='
# of msbuild command. # of dotnetbuild command.
# #
# Example: # Example:
# make Configuration=Release Flavor=NoNet # make Configuration=Release Flavor=NoNet
@@ -18,7 +18,7 @@
# - native: build the native libs # - native: build the native libs
# - java: build the java libs # - java: build the java libs
# - nuget: restore NuGet packages # - nuget: restore NuGet packages
# - msbuild: build the project # - dotnetbuild: build the project
# - apk: same as all # - apk: same as all
# - manifestlink: creates a symlink (to be used in building) to the AndroidManifest corresponding to the selected Flavor # - manifestlink: creates a symlink (to be used in building) to the AndroidManifest corresponding to the selected Flavor
# #
@@ -27,7 +27,7 @@
# - clean_native: clean native lib # - clean_native: clean native lib
# - clean_java: call clean target of java libs # - clean_java: call clean target of java libs
# - clean_nuget: cleanup the 'nuget restore' # - clean_nuget: cleanup the 'nuget restore'
# - clean_msbuild: call clean target of msbuild # - clean_dotnet: call clean target of dotnetbuild
# #
# #
# #
@@ -60,45 +60,23 @@ $(info MAKESHELL: $(MAKESHELL))
$(info SHELL: $(SHELL)) $(info SHELL: $(SHELL))
$(info ) $(info )
# On linux use xabuild, on Windows use MSBuild.exe, otherwise (macos?) use msbuild.
ifeq ($(detected_OS),Linux) ifeq ($(detected_OS),Linux)
MSBUILD_binary := xabuild DOTNET_binary := dotnet
MSBUILD := $(shell $(WHICH) $(MSBUILD_binary)) DOTNET := $(shell $(WHICH) $(DOTNET_binary))
else ifeq ($(detected_OS),Windows) else ifeq ($(detected_OS),Windows)
MSBUILD_binary := MSBuild.exe DOTNET_binary := dotnet
MSBUILD := $(shell $(WHICH) $(MSBUILD_binary) 2> nul) DOTNET := $(shell $(WHICH) $(DOTNET_binary) 2> nul)
ifeq ($(MSBUILD),)
# Additional heuristic to find MSBUILD_BINARY on Windows
VSWHERE := "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
VSWHERE_CHECK := $(shell @echo off & $(VSWHERE) 2> nul || echo VSWHERE_NOT_FOUND)
ifneq ($(VSWHERE_CHECK),VSWHERE_NOT_FOUND)
MSBUILD := $(shell @echo off & $(VSWHERE) -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe)
VS_INSTALL_PATH := $(shell @echo off & $(VSWHERE) -property installationPath)
endif
endif
else else
MSBUILD_binary := msbuild DOTNET_binary := dotnet
MSBUILD := $(shell $(WHICH) $(MSBUILD_binary)) DOTNET := $(shell $(WHICH) $(DOTNET_binary))
endif endif
ifeq ($(MSBUILD),) ifeq ($(DOTNET),)
$(info ) $(info )
$(info '$(MSBUILD_binary)' binary could not be found. Check it is in your PATH.) $(info '$(DOTNET_binary)' binary could not be found. Check it is in your PATH.)
ifeq ($(detected_OS),Windows)
ifneq ($(VSWHERE_CHECK),VSWHERE_NOT_FOUND)
$(info )
$(info You may retry after running in the command prompt:)
$(info )
$(info "$(VS_INSTALL_PATH)\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64)
$(info )
$(info If this doesn't work, install/find the location of vcvarsall.bat)
$(info or install and add msbuild.exe to your PATH)
$(info )
endif
endif
$(error ) $(error )
endif endif
$(info MSBUILD: $(MSBUILD)) $(info DOTNET: $(DOTNET))
$(info ) $(info )
ifeq ($(ANDROID_SDK_ROOT),) ifeq ($(ANDROID_SDK_ROOT),)
@@ -117,7 +95,7 @@ endif
$(info ANDROID_NDK_ROOT: $(ANDROID_NDK_ROOT)) $(info ANDROID_NDK_ROOT: $(ANDROID_NDK_ROOT))
ifneq ($(Configuration),) ifneq ($(Configuration),)
MSBUILD_PARAM = -p:Configuration="$(Configuration)" DOTNET_PARAM = -p:Configuration="$(Configuration)"
else else
$(warning Configuration environment variable not set.) $(warning Configuration environment variable not set.)
endif endif
@@ -127,7 +105,7 @@ CREATE_MANIFEST_LINK :=
MANIFEST_FILE := MANIFEST_FILE :=
ifneq ($(Flavor),) ifneq ($(Flavor),)
MSBUILD_PARAM += -p:Flavor="$(Flavor)" DOTNET_PARAM += -p:Flavor="$(Flavor)"
ifneq ($(Flavor),) ifneq ($(Flavor),)
ifeq ($(Flavor),Debug) ifeq ($(Flavor),Debug)
MANIFEST_FILE := AndroidManifest_debug.xml MANIFEST_FILE := AndroidManifest_debug.xml
@@ -152,7 +130,7 @@ else
endif endif
ifneq ($(KeyStore),) ifneq ($(KeyStore),)
MSBUILD_PARAM += -p:AndroidKeyStore=True -p:AndroidSigningKeyStore="$(KeyStore)" -p:AndroidSigningStorePass=env:MyAndroidSigningStorePass -p:AndroidSigningKeyPass=env:MyAndroidSigningKeyPass -p:AndroidSigningKeyAlias="kp2a" DOTNET_PARAM += -p:AndroidKeyStore=True -p:AndroidSigningKeyStore="$(KeyStore)" -p:AndroidSigningStorePass=env:MyAndroidSigningStorePass -p:AndroidSigningKeyPass=env:MyAndroidSigningKeyPass -p:AndroidSigningKeyAlias="kp2a"
endif endif
ifeq ($(detected_OS),Windows) ifeq ($(detected_OS),Windows)
@@ -176,7 +154,7 @@ endif
# Recursive wildcard: https://stackoverflow.com/a/18258352 # Recursive wildcard: https://stackoverflow.com/a/18258352
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
$(info MSBUILD_PARAM: $(MSBUILD_PARAM)) $(info DOTNET_PARAM: $(DOTNET_PARAM))
$(info nuget path: $(shell $(WHICH) nuget)) $(info nuget path: $(shell $(WHICH) nuget))
$(info ) $(info )
@@ -254,7 +232,7 @@ OUTPUT_PluginQR = src/java/Keepass2AndroidPluginSDK2/app/build/outputs/aar/Keepa
.PHONY: native $(NATIVE_COMPONENTS) clean_native $(NATIVE_CLEAN_TARGETS) \ .PHONY: native $(NATIVE_COMPONENTS) clean_native $(NATIVE_CLEAN_TARGETS) \
java $(JAVA_COMPONENTS) clean_java $(JAVA_CLEAN_TARGETS) \ java $(JAVA_COMPONENTS) clean_java $(JAVA_CLEAN_TARGETS) \
nuget clean_nuget \ nuget clean_nuget \
msbuild clean_msbuild \ dotnetbuild clean_dotnet \
apk all clean apk all clean
all: apk all: apk
@@ -303,7 +281,7 @@ ifeq ($(shell $(WHICH) nuget),)
endif endif
$(RMFILE) stamp.nuget_* $(RMFILE) stamp.nuget_*
nuget restore src/KeePass.sln nuget restore src/KeePass.sln
$(MSBUILD) src/KeePass.sln -t:restore $(MSBUILD_PARAM) -p:RestorePackagesConfig=true $(DOTNET) restore src/KeePass.sln $(DOTNET_PARAM) -p:RestorePackagesConfig=true
@echo "" > stamp.nuget_$(Flavor) @echo "" > stamp.nuget_$(Flavor)
manifestlink: manifestlink:
@@ -312,20 +290,21 @@ manifestlink:
$(CREATE_MANIFEST_LINK) $(CREATE_MANIFEST_LINK)
##### #####
src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs:
ifeq ($(detected_OS),Windows)
$(CP) src\Kp2aBusinessLogic\Io\DropboxFileStorageKeysDummy.cs src\Kp2aBusinessLogic\Io\DropboxFileStorageKeys.cs
else
$(CP) src/Kp2aBusinessLogic/Io/DropboxFileStorageKeysDummy.cs $@
endif
msbuild: manifestlink native java nuget src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs dotnetbuild: manifestlink native java nuget
$(MSBUILD) src/KeePass.sln -target:keepass2android-app -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -p:BuildProjectReferences=true $(MSBUILD_PARAM) -p:Platform="Any CPU" -m $(DOTNET) build src/KeePass.sln -target:keepass2android-app -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -p:BuildProjectReferences=true $(DOTNET_PARAM) -p:Platform="Any CPU" -m
apk: msbuild apk: manifestlink native java nuget
$(MSBUILD) src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(MSBUILD_PARAM) -p:Platform=AnyCPU -m $(DOTNET) publish src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(DOTNET_PARAM) -p:Platform=AnyCPU -m
build_all: msbuild apk_split: manifestlink native java nuget
$(DOTNET) publish src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(DOTNET_PARAM) -p:Platform=AnyCPU -m -p:RuntimeIdentifier=android-arm
$(DOTNET) publish src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(DOTNET_PARAM) -p:Platform=AnyCPU -m -p:RuntimeIdentifier=android-arm64
$(DOTNET) publish src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(DOTNET_PARAM) -p:Platform=AnyCPU -m -p:RuntimeIdentifier=android-x86
$(DOTNET) publish src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(DOTNET_PARAM) -p:Platform=AnyCPU -m -p:RuntimeIdentifier=android-x64
src/build-scripts/rename-output-apks.sh src/keepass2android-app/bin/Release/net8.0-android/
build_all: dotnetbuild
##### Cleanup targets ##### Cleanup targets
@@ -369,10 +348,10 @@ else
endif endif
$(RMFILE) stamp.nuget_* $(RMFILE) stamp.nuget_*
clean_msbuild: clean_dotnet:
$(MSBUILD) src/KeePass.sln -target:clean $(MSBUILD_PARAM) $(DOTNET) clean src/KeePass.sln $(DOTNET_PARAM)
clean: clean_native clean_java clean_nuget clean_msbuild clean: clean_native clean_java clean_nuget clean_dotnet
distclean: clean distclean: clean
ifneq ("$(wildcard ./allow_git_clean)","") ifneq ("$(wildcard ./allow_git_clean)","")

View File

@@ -11,10 +11,10 @@ Regular stable releases of Keepass2Android are available on [Google Play](https:
Beta-releases can be obtained by opting in to the [Beta testing channel](https://play.google.com/apps/testing/keepass2android.keepass2android) or [Beta testing channel for Keepass2Android Offline](https://play.google.com/apps/testing/keepass2android.keepass2android_nonet). Beta-releases can be obtained by opting in to the [Beta testing channel](https://play.google.com/apps/testing/keepass2android.keepass2android) or [Beta testing channel for Keepass2Android Offline](https://play.google.com/apps/testing/keepass2android.keepass2android_nonet).
# How can I contribute? # How can I contribute?
* Help to translate Keepass2Android into your language or improve translations at [our Crowdin page](http://crowdin.net/project/keepass2android) * Help to translate Keepass2Android into your language or improve translations at [our Crowdin page](https://crowdin.net/project/keepass2android)
* Add features by [creating a plugin](How-to-create-a-plug-in_.md) or creating a pull request. You might want to contact me before you start working so I can coordinate efforts. * Add features by [creating a plugin](How-to-create-a-plug-in_.md) or creating a pull request. You might want to contact me before you start working so I can coordinate efforts.
* [Become a GitHub sponsor to boost 🚀 development](https://github.com/sponsors/PhilippC) * [Become a GitHub sponsor to boost 🚀 development](https://github.com/sponsors/PhilippC)
* [Make a donation](http://philipp.crocoll.net/donate.php) * [Make a donation](https://philipp.crocoll.net/donate.php)
# How do I learn more? # How do I learn more?
Please see the [wiki](https://github.com/PhilippC/keepass2android/wiki/Documentation) for further information. Please see the [wiki](https://github.com/PhilippC/keepass2android/wiki/Documentation) for further information.

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -34,5 +34,6 @@
<AndroidLibrary Bind="False" Update="okhttp-digest-3.1.0.jar" /> <AndroidLibrary Bind="False" Update="okhttp-digest-3.1.0.jar" />
<AndroidLibrary Bind="False" Update="okio-3.6.0.jar" /> <AndroidLibrary Bind="False" Update="okio-3.6.0.jar" />
<AndroidLibrary Bind="False" Update="okio-jvm-3.6.0.jar" /> <AndroidLibrary Bind="False" Update="okio-jvm-3.6.0.jar" />
<AndroidLibrary Bind="False" Update="jsch-2.27.2.jar" />
</ItemGroup> </ItemGroup>
</Project> </Project>

Binary file not shown.

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2025 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -40,8 +40,8 @@ namespace KeePassLib.Cryptography
Null = 0, Null = 0,
/// <summary> /// <summary>
/// A variant of the ARCFour algorithm (RC4 incompatible). /// A variant of the ArcFour algorithm (RC4 incompatible).
/// </summary> /// Insecure; for backward compatibility only.
/// </summary> /// </summary>
ArcFourVariant = 1, ArcFourVariant = 1,
@@ -66,68 +66,72 @@ namespace KeePassLib.Cryptography
/// </summary> /// </summary>
public sealed class CryptoRandomStream : IDisposable public sealed class CryptoRandomStream : IDisposable
{ {
private readonly CrsAlgorithm m_crsAlgorithm; private readonly CrsAlgorithm m_alg;
private bool m_bDisposed = false;
private byte[] m_pbState = null; private readonly byte[] m_pbKey = null;
private readonly byte[] m_pbIV = null;
private readonly ChaCha20Cipher m_chacha20 = null;
private readonly Salsa20Cipher m_salsa20 = null;
private readonly byte[] m_pbState = null;
private byte m_i = 0; private byte m_i = 0;
private byte m_j = 0; private byte m_j = 0;
private Salsa20Cipher m_salsa20 = null;
private ChaCha20Cipher m_chacha20 = null;
/// <summary> /// <summary>
/// Construct a new cryptographically secure random stream object. /// Construct a new cryptographically secure random stream object.
/// </summary> /// </summary>
/// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="a">Algorithm to use.</param>
/// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// <param name="pbKey">Initialization key. Must not be <c>null</c>
/// must contain at least 1 byte.</param> /// and must contain at least 1 byte.</param>
public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey) public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey)
{ {
if(pbKey == null) { Debug.Assert(false); throw new ArgumentNullException("pbKey"); } if (pbKey == null) { Debug.Assert(false); throw new ArgumentNullException("pbKey"); }
/// <exception cref="System.ArgumentNullException">Thrown if the
int cbKey = pbKey.Length; int cbKey = pbKey.Length;
if(cbKey <= 0) if (cbKey <= 0)
{ {
Debug.Assert(false); // Need at least one byte Debug.Assert(false); // Need at least one byte
throw new ArgumentOutOfRangeException("pbKey"); throw new ArgumentOutOfRangeException("pbKey");
} }
/// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
m_crsAlgorithm = a; m_alg = a;
/// <exception cref="System.ArgumentException">Thrown if the
if(a == CrsAlgorithm.ChaCha20) if (a == CrsAlgorithm.ChaCha20)
{ {
byte[] pbKey32 = new byte[32]; m_pbKey = new byte[32];
byte[] pbIV12 = new byte[12]; m_pbIV = new byte[12];
/// <paramref name="pbKey" /> parameter contains no bytes or the
using(SHA512Managed h = new SHA512Managed()) using (SHA512Managed h = new SHA512Managed())
{ {
byte[] pbHash = h.ComputeHash(pbKey); byte[] pbHash = h.ComputeHash(pbKey);
Array.Copy(pbHash, pbKey32, 32); Array.Copy(pbHash, m_pbKey, 32);
Array.Copy(pbHash, 32, pbIV12, 0, 12); Array.Copy(pbHash, 32, m_pbIV, 0, 12);
MemUtil.ZeroByteArray(pbHash); MemUtil.ZeroByteArray(pbHash);
} }
/// algorithm is unknown.</exception>
m_chacha20 = new ChaCha20Cipher(pbKey32, pbIV12, true); m_chacha20 = new ChaCha20Cipher(m_pbKey, m_pbIV, true);
} }
else if(a == CrsAlgorithm.Salsa20) else if (a == CrsAlgorithm.Salsa20)
{ {
byte[] pbKey32 = CryptoUtil.HashSha256(pbKey); m_pbKey = CryptoUtil.HashSha256(pbKey);
byte[] pbIV8 = new byte[8] { 0xE8, 0x30, 0x09, 0x4B, m_pbIV = new byte[8] { 0xE8, 0x30, 0x09, 0x4B,
0x97, 0x20, 0x5D, 0x2A }; // Unique constant 0x97, 0x20, 0x5D, 0x2A }; // Unique constant
m_salsa20 = new Salsa20Cipher(pbKey32, pbIV8); m_salsa20 = new Salsa20Cipher(m_pbKey, m_pbIV);
} }
else if(a == CrsAlgorithm.ArcFourVariant) else if (a == CrsAlgorithm.ArcFourVariant)
{ {
// Fill the state linearly // Fill the state linearly
m_pbState = new byte[256]; m_pbState = new byte[256];
for(int w = 0; w < 256; ++w) m_pbState[w] = (byte)w; for (int w = 0; w < 256; ++w) m_pbState[w] = (byte)w;
unchecked unchecked
{ {
byte j = 0, t; byte j = 0, t;
int inxKey = 0; int inxKey = 0;
for(int w = 0; w < 256; ++w) // Key setup for (int w = 0; w < 256; ++w) // Key setup
{ {
j += (byte)(m_pbState[w] + pbKey[inxKey]); j += (byte)(m_pbState[w] + pbKey[inxKey]);
@@ -136,7 +140,7 @@ namespace KeePassLib.Cryptography
m_pbState[j] = t; m_pbState[j] = t;
++inxKey; ++inxKey;
if(inxKey >= cbKey) inxKey = 0; if (inxKey >= cbKey) inxKey = 0;
} }
} }
@@ -157,19 +161,24 @@ namespace KeePassLib.Cryptography
private void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if(disposing) if (disposing)
{ {
if(m_crsAlgorithm == CrsAlgorithm.ChaCha20) if (m_alg == CrsAlgorithm.ChaCha20)
m_chacha20.Dispose(); m_chacha20.Dispose();
else if(m_crsAlgorithm == CrsAlgorithm.Salsa20) else if (m_alg == CrsAlgorithm.Salsa20)
m_salsa20.Dispose(); m_salsa20.Dispose();
else if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant) else if (m_alg == CrsAlgorithm.ArcFourVariant)
{ {
MemUtil.ZeroByteArray(m_pbState); MemUtil.ZeroByteArray(m_pbState);
m_i = 0; m_i = 0;
m_j = 0; m_j = 0;
} }
else { Debug.Assert(false); } else { Debug.Assert(false); }
if (m_pbKey != null) MemUtil.ZeroByteArray(m_pbKey);
if (m_pbIV != null) MemUtil.ZeroByteArray(m_pbIV);
m_bDisposed = true;
} }
} }
@@ -180,23 +189,24 @@ namespace KeePassLib.Cryptography
/// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns> /// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns>
public byte[] GetRandomBytes(uint uRequestedCount) public byte[] GetRandomBytes(uint uRequestedCount)
{ {
if(uRequestedCount == 0) return MemUtil.EmptyByteArray; if (m_bDisposed) throw new ObjectDisposedException(null);
if(uRequestedCount > (uint)int.MaxValue) if (uRequestedCount == 0) return MemUtil.EmptyByteArray;
if (uRequestedCount > (uint)int.MaxValue)
throw new ArgumentOutOfRangeException("uRequestedCount"); throw new ArgumentOutOfRangeException("uRequestedCount");
int cb = (int)uRequestedCount; int cb = (int)uRequestedCount;
byte[] pbRet = new byte[cb]; byte[] pbRet = new byte[cb];
if(m_crsAlgorithm == CrsAlgorithm.ChaCha20) if (m_alg == CrsAlgorithm.ChaCha20)
m_chacha20.Encrypt(pbRet, 0, cb); m_chacha20.Encrypt(pbRet, 0, cb);
else if(m_crsAlgorithm == CrsAlgorithm.Salsa20) else if (m_alg == CrsAlgorithm.Salsa20)
m_salsa20.Encrypt(pbRet, 0, cb); m_salsa20.Encrypt(pbRet, 0, cb);
else if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant) else if (m_alg == CrsAlgorithm.ArcFourVariant)
{ {
unchecked unchecked
{ {
for(int w = 0; w < cb; ++w) for (int w = 0; w < cb; ++w)
{ {
++m_i; ++m_i;
m_j += m_pbState[m_i]; m_j += m_pbState[m_i];
@@ -221,6 +231,25 @@ namespace KeePassLib.Cryptography
return MemUtil.BytesToUInt64(pb); return MemUtil.BytesToUInt64(pb);
} }
internal ulong GetRandomUInt64(ulong uMaxExcl)
{
if (uMaxExcl == 0) { Debug.Assert(false); throw new ArgumentOutOfRangeException("uMaxExcl"); }
ulong uGen, uRem;
do
{
uGen = GetRandomUInt64();
uRem = uGen % uMaxExcl;
}
while ((uGen - uRem) > (ulong.MaxValue - (uMaxExcl - 1UL)));
// This ensures that the last number of the block (i.e.
// (uGen - uRem) + (uMaxExcl - 1)) is generatable;
// for signed longs, overflow to negative number:
// while((uGen - uRem) + (uMaxExcl - 1) < 0);
return uRem;
}
#if CRSBENCHMARK #if CRSBENCHMARK
public static string Benchmark() public static string Benchmark()
{ {
@@ -237,21 +266,20 @@ namespace KeePassLib.Cryptography
return str; return str;
} }
private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize) private static int BenchTime(CrsAlgorithm a, int nRounds, int cbData)
{ {
byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 }; byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 };
int nStart = Environment.TickCount; int tStart = Environment.TickCount;
for(int i = 0; i < nRounds; ++i) for(int i = 0; i < nRounds; ++i)
{ {
using(CryptoRandomStream c = new CryptoRandomStream(cra, pbKey)) using(CryptoRandomStream crs = new CryptoRandomStream(a, pbKey))
{ {
c.GetRandomBytes((uint)nDataSize); crs.GetRandomBytes((uint)cbData);
} }
} }
int nEnd = Environment.TickCount;
return (nEnd - nStart); return (Environment.TickCount - tStart);
} }
#endif #endif
} }

View File

@@ -1,65 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using KeePassLib.Security;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.PasswordGenerator
{
internal static class CharSetBasedGenerator
{
internal static PwgError Generate(out ProtectedString psOut,
PwProfile pwProfile, CryptoRandomStream crsRandomSource)
{
psOut = ProtectedString.Empty;
if(pwProfile.Length == 0) return PwgError.Success;
PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString());
char[] vGenerated = new char[pwProfile.Length];
PwGenerator.PrepareCharSet(pcs, pwProfile);
for(int nIndex = 0; nIndex < (int)pwProfile.Length; ++nIndex)
{
char ch = PwGenerator.GenerateCharacter(pwProfile, pcs,
crsRandomSource);
if(ch == char.MinValue)
{
MemUtil.ZeroArray<char>(vGenerated);
return PwgError.TooFewCharacters;
}
vGenerated[nIndex] = ch;
}
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vGenerated);
psOut = new ProtectedString(true, pbUtf8);
MemUtil.ZeroByteArray(pbUtf8);
MemUtil.ZeroArray<char>(vGenerated);
return PwgError.Success;
}
}
}

View File

@@ -1,173 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using KeePassLib.Security;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.PasswordGenerator
{
internal static class PatternBasedGenerator
{
internal static PwgError Generate(out ProtectedString psOut,
PwProfile pwProfile, CryptoRandomStream crsRandomSource)
{
psOut = ProtectedString.Empty;
LinkedList<char> vGenerated = new LinkedList<char>();
PwCharSet pcsCurrent = new PwCharSet();
PwCharSet pcsCustom = new PwCharSet();
PwCharSet pcsUsed = new PwCharSet();
bool bInCharSetDef = false;
string strPattern = ExpandPattern(pwProfile.Pattern);
if(strPattern.Length == 0) return PwgError.Success;
CharStream csStream = new CharStream(strPattern);
char ch = csStream.ReadChar();
while(ch != char.MinValue)
{
pcsCurrent.Clear();
bool bGenerateChar = false;
if(ch == '\\')
{
ch = csStream.ReadChar();
if(ch == char.MinValue) // Backslash at the end
{
vGenerated.AddLast('\\');
break;
}
if(bInCharSetDef) pcsCustom.Add(ch);
else
{
vGenerated.AddLast(ch);
pcsUsed.Add(ch);
}
}
else if(ch == '[')
{
pcsCustom.Clear();
bInCharSetDef = true;
}
else if(ch == ']')
{
pcsCurrent.Add(pcsCustom.ToString());
bInCharSetDef = false;
bGenerateChar = true;
}
else if(bInCharSetDef)
{
if(pcsCustom.AddCharSet(ch) == false)
pcsCustom.Add(ch);
}
else if(pcsCurrent.AddCharSet(ch) == false)
{
vGenerated.AddLast(ch);
pcsUsed.Add(ch);
}
else bGenerateChar = true;
if(bGenerateChar)
{
PwGenerator.PrepareCharSet(pcsCurrent, pwProfile);
if(pwProfile.NoRepeatingCharacters)
pcsCurrent.Remove(pcsUsed.ToString());
char chGen = PwGenerator.GenerateCharacter(pwProfile,
pcsCurrent, crsRandomSource);
if(chGen == char.MinValue) return PwgError.TooFewCharacters;
vGenerated.AddLast(chGen);
pcsUsed.Add(chGen);
}
ch = csStream.ReadChar();
}
if(vGenerated.Count == 0) return PwgError.Success;
char[] vArray = new char[vGenerated.Count];
vGenerated.CopyTo(vArray, 0);
if(pwProfile.PatternPermutePassword)
PwGenerator.ShufflePassword(vArray, crsRandomSource);
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vArray);
psOut = new ProtectedString(true, pbUtf8);
MemUtil.ZeroByteArray(pbUtf8);
MemUtil.ZeroArray<char>(vArray);
vGenerated.Clear();
return PwgError.Success;
}
private static string ExpandPattern(string strPattern)
{
Debug.Assert(strPattern != null); if(strPattern == null) return string.Empty;
string str = strPattern;
while(true)
{
int nOpen = FindFirstUnescapedChar(str, '{');
int nClose = FindFirstUnescapedChar(str, '}');
if((nOpen >= 0) && (nOpen < nClose))
{
string strCount = str.Substring(nOpen + 1, nClose - nOpen - 1);
str = str.Remove(nOpen, nClose - nOpen + 1);
uint uRepeat;
if(StrUtil.TryParseUInt(strCount, out uRepeat) && (nOpen >= 1))
{
if(uRepeat == 0)
str = str.Remove(nOpen - 1, 1);
else
str = str.Insert(nOpen, new string(str[nOpen - 1], (int)uRepeat - 1));
}
}
else break;
}
return str;
}
private static int FindFirstUnescapedChar(string str, char ch)
{
for(int i = 0; i < str.Length; ++i)
{
char chCur = str[i];
if(chCur == '\\') ++i; // Next is escaped, skip it
else if(chCur == ch) return i;
}
return -1;
}
}
}

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2025 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -19,122 +19,81 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.PasswordGenerator namespace KeePassLib.Cryptography.PasswordGenerator
{ {
public sealed class PwCharSet public sealed class PwCharSet : IEquatable<PwCharSet>
{ {
public const string UpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static readonly string UpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public const string LowerCase = "abcdefghijklmnopqrstuvwxyz"; public static readonly string LowerCase = "abcdefghijklmnopqrstuvwxyz";
public const string Digits = "0123456789"; public static readonly string Digits = "0123456789";
public const string UpperConsonants = "BCDFGHJKLMNPQRSTVWXYZ"; public static readonly string UpperConsonants = "BCDFGHJKLMNPQRSTVWXYZ";
public const string LowerConsonants = "bcdfghjklmnpqrstvwxyz"; public static readonly string LowerConsonants = "bcdfghjklmnpqrstvwxyz";
public const string UpperVowels = "AEIOU"; public static readonly string UpperVowels = "AEIOU";
public const string LowerVowels = "aeiou"; public static readonly string LowerVowels = "aeiou";
public const string Punctuation = @",.;:"; public static readonly string Punctuation = ",.;:";
public const string Brackets = @"[]{}()<>"; public static readonly string Brackets = @"[]{}()<>";
public const string PrintableAsciiSpecial = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; public static readonly string Special = "!\"#$%&'*+,./:;=?@\\^`|~";
public static readonly string PrintableAsciiSpecial = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
public const string UpperHex = "0123456789ABCDEF"; public static readonly string UpperHex = "0123456789ABCDEF";
public const string LowerHex = "0123456789abcdef"; public static readonly string LowerHex = "0123456789abcdef";
public const string Invalid = "\t\r\n"; public static readonly string LookAlike = "O0Il1|";
public const string LookAlike = @"O0l1I|";
internal const string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits;
private const int CharTabSize = (0x10000 / 8);
private List<char> m_vChars = new List<char>();
private byte[] m_vTab = new byte[CharTabSize];
private static string m_strHighAnsi = null;
public static string HighAnsiChars
{
get
{
if(m_strHighAnsi == null) { new PwCharSet(); } // Create string
Debug.Assert(m_strHighAnsi != null);
return m_strHighAnsi;
}
}
private static string m_strSpecial = null;
public static string SpecialChars
{
get
{
if(m_strSpecial == null) { new PwCharSet(); } // Create string
Debug.Assert(m_strSpecial != null);
return m_strSpecial;
}
}
/// <summary> /// <summary>
/// Create a new, empty character set collection object. /// Latin-1 Supplement except U+00A0 (NBSP) and U+00AD (SHY).
/// </summary>
public static readonly string Latin1S =
"\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7" +
"\u00A8\u00A9\u00AA\u00AB\u00AC\u00AE\u00AF" +
"\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6\u00B7" +
"\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF" +
"\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7" +
"\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF" +
"\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7" +
"\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF" +
"\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7" +
"\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF" +
"\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7" +
"\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF";
// internal static readonly string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits;
[Obsolete]
public static string SpecialChars { get { return PwCharSet.Special; } }
[Obsolete]
public static string HighAnsiChars { get { return PwCharSet.Latin1S; } }
private readonly List<char> m_lChars = new List<char>();
private readonly byte[] m_vTab = new byte[0x10000 / 8];
/// <summary>
/// Create a new, empty character set.
/// </summary> /// </summary>
public PwCharSet() public PwCharSet()
{ {
Initialize(true); Debug.Assert(PwCharSet.Latin1S.Length == (16 * 6 - 2));
} }
public PwCharSet(string strCharSet) public PwCharSet(string strCharSet)
{ {
Initialize(true);
Add(strCharSet); Add(strCharSet);
} }
private PwCharSet(bool bFullInitialize)
{
Initialize(bFullInitialize);
}
private void Initialize(bool bFullInitialize)
{
Clear();
if(!bFullInitialize) return;
if(m_strHighAnsi == null)
{
StringBuilder sbHighAnsi = new StringBuilder();
// [U+0080, U+009F] are C1 control characters,
// U+00A0 is non-breaking space
for(char ch = '\u00A1'; ch <= '\u00AC'; ++ch)
sbHighAnsi.Append(ch);
// U+00AD is soft hyphen (format character)
for(char ch = '\u00AE'; ch < '\u00FF'; ++ch)
sbHighAnsi.Append(ch);
sbHighAnsi.Append('\u00FF');
m_strHighAnsi = sbHighAnsi.ToString();
}
if(m_strSpecial == null)
{
PwCharSet pcs = new PwCharSet(false);
pcs.AddRange('!', '/');
pcs.AddRange(':', '@');
pcs.AddRange('[', '`');
pcs.Add(@"|~");
pcs.Remove(@"-_ ");
pcs.Remove(PwCharSet.Brackets);
m_strSpecial = pcs.ToString();
}
}
/// <summary> /// <summary>
/// Number of characters in this set. /// Number of characters in this set.
/// </summary> /// </summary>
public uint Size public uint Size
{ {
get { return (uint)m_vChars.Count; } get { return (uint)m_lChars.Count; }
} }
/// <summary> /// <summary>
@@ -147,19 +106,39 @@ namespace KeePassLib.Cryptography.PasswordGenerator
{ {
get get
{ {
if(uPos >= (uint)m_vChars.Count) if (uPos >= (uint)m_lChars.Count)
throw new ArgumentOutOfRangeException("uPos"); throw new ArgumentOutOfRangeException("uPos");
return m_vChars[(int)uPos]; return m_lChars[(int)uPos];
} }
} }
public bool Equals(PwCharSet other)
{
if (object.ReferenceEquals(other, this)) return true;
if (object.ReferenceEquals(other, null)) return false;
if (m_lChars.Count != other.m_lChars.Count) return false;
return MemUtil.ArraysEqual(m_vTab, other.m_vTab);
}
public override bool Equals(object obj)
{
return Equals(obj as PwCharSet);
}
public override int GetHashCode()
{
return (int)MemUtil.Hash32(m_vTab, 0, m_vTab.Length);
}
/// <summary> /// <summary>
/// Remove all characters from this set. /// Remove all characters from this set.
/// </summary> /// </summary>
public void Clear() public void Clear()
{ {
m_vChars.Clear(); m_lChars.Clear();
Array.Clear(m_vTab, 0, m_vTab.Length); Array.Clear(m_vTab, 0, m_vTab.Length);
} }
@@ -171,11 +150,11 @@ namespace KeePassLib.Cryptography.PasswordGenerator
public bool Contains(string strCharacters) public bool Contains(string strCharacters)
{ {
Debug.Assert(strCharacters != null); Debug.Assert(strCharacters != null);
if(strCharacters == null) throw new ArgumentNullException("strCharacters"); if (strCharacters == null) throw new ArgumentNullException("strCharacters");
foreach(char ch in strCharacters) foreach (char ch in strCharacters)
{ {
if(!Contains(ch)) return false; if (!Contains(ch)) return false;
} }
return true; return true;
@@ -187,11 +166,11 @@ namespace KeePassLib.Cryptography.PasswordGenerator
/// <param name="ch">Character to add.</param> /// <param name="ch">Character to add.</param>
public void Add(char ch) public void Add(char ch)
{ {
if(ch == char.MinValue) { Debug.Assert(false); return; } if (ch == char.MinValue) { Debug.Assert(false); return; }
if(!Contains(ch)) if (!Contains(ch))
{ {
m_vChars.Add(ch); m_lChars.Add(ch);
m_vTab[ch / 8] |= (byte)(1 << (ch % 8)); m_vTab[ch / 8] |= (byte)(1 << (ch % 8));
} }
} }
@@ -203,11 +182,9 @@ namespace KeePassLib.Cryptography.PasswordGenerator
public void Add(string strCharSet) public void Add(string strCharSet)
{ {
Debug.Assert(strCharSet != null); Debug.Assert(strCharSet != null);
if(strCharSet == null) throw new ArgumentNullException("strCharSet"); if (strCharSet == null) throw new ArgumentNullException("strCharSet");
m_vChars.Capacity = m_vChars.Count + strCharSet.Length; foreach (char ch in strCharSet)
foreach(char ch in strCharSet)
Add(ch); Add(ch);
} }
@@ -226,9 +203,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
public void AddRange(char chMin, char chMax) public void AddRange(char chMin, char chMax)
{ {
m_vChars.Capacity = m_vChars.Count + (chMax - chMin) + 1; for (char ch = chMin; ch < chMax; ++ch)
for(char ch = chMin; ch < chMax; ++ch)
Add(ch); Add(ch);
Add(chMax); Add(chMax);
@@ -238,14 +213,16 @@ namespace KeePassLib.Cryptography.PasswordGenerator
{ {
bool bResult = true; bool bResult = true;
switch(chCharSetIdentifier) switch (chCharSetIdentifier)
{ {
case 'a': Add(PwCharSet.LowerCase, PwCharSet.Digits); break; case 'a': Add(PwCharSet.LowerCase, PwCharSet.Digits); break;
case 'A': Add(PwCharSet.LowerCase, PwCharSet.UpperCase, case 'A':
Add(PwCharSet.LowerCase, PwCharSet.UpperCase,
PwCharSet.Digits); break; PwCharSet.Digits); break;
case 'U': Add(PwCharSet.UpperCase, PwCharSet.Digits); break; case 'U': Add(PwCharSet.UpperCase, PwCharSet.Digits); break;
case 'c': Add(PwCharSet.LowerConsonants); break; case 'c': Add(PwCharSet.LowerConsonants); break;
case 'C': Add(PwCharSet.LowerConsonants, case 'C':
Add(PwCharSet.LowerConsonants,
PwCharSet.UpperConsonants); break; PwCharSet.UpperConsonants); break;
case 'z': Add(PwCharSet.UpperConsonants); break; case 'z': Add(PwCharSet.UpperConsonants); break;
case 'd': Add(PwCharSet.Digits); break; // Digit case 'd': Add(PwCharSet.Digits); break; // Digit
@@ -257,12 +234,13 @@ namespace KeePassLib.Cryptography.PasswordGenerator
case 'p': Add(PwCharSet.Punctuation); break; case 'p': Add(PwCharSet.Punctuation); break;
case 'b': Add(PwCharSet.Brackets); break; case 'b': Add(PwCharSet.Brackets); break;
case 's': Add(PwCharSet.PrintableAsciiSpecial); break; case 's': Add(PwCharSet.PrintableAsciiSpecial); break;
case 'S': Add(PwCharSet.UpperCase, PwCharSet.LowerCase); case 'S':
Add(PwCharSet.UpperCase, PwCharSet.LowerCase);
Add(PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial); break; Add(PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial); break;
case 'v': Add(PwCharSet.LowerVowels); break; case 'v': Add(PwCharSet.LowerVowels); break;
case 'V': Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break; case 'V': Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break;
case 'Z': Add(PwCharSet.UpperVowels); break; case 'Z': Add(PwCharSet.UpperVowels); break;
case 'x': Add(m_strHighAnsi); break; case 'x': Add(PwCharSet.Latin1S); break;
default: bResult = false; break; default: bResult = false; break;
} }
@@ -272,18 +250,18 @@ namespace KeePassLib.Cryptography.PasswordGenerator
public bool Remove(char ch) public bool Remove(char ch)
{ {
m_vTab[ch / 8] &= (byte)(~(1 << (ch % 8))); m_vTab[ch / 8] &= (byte)(~(1 << (ch % 8)));
return m_vChars.Remove(ch); return m_lChars.Remove(ch);
} }
public bool Remove(string strCharacters) public bool Remove(string strCharacters)
{ {
Debug.Assert(strCharacters != null); Debug.Assert(strCharacters != null);
if(strCharacters == null) throw new ArgumentNullException("strCharacters"); if (strCharacters == null) throw new ArgumentNullException("strCharacters");
bool bResult = true; bool bResult = true;
foreach(char ch in strCharacters) foreach (char ch in strCharacters)
{ {
if(!Remove(ch)) bResult = false; if (!Remove(ch)) bResult = false;
} }
return bResult; return bResult;
@@ -292,9 +270,9 @@ namespace KeePassLib.Cryptography.PasswordGenerator
public bool RemoveIfAllExist(string strCharacters) public bool RemoveIfAllExist(string strCharacters)
{ {
Debug.Assert(strCharacters != null); Debug.Assert(strCharacters != null);
if(strCharacters == null) throw new ArgumentNullException("strCharacters"); if (strCharacters == null) throw new ArgumentNullException("strCharacters");
if(!Contains(strCharacters)) if (!Contains(strCharacters))
return false; return false;
return Remove(strCharacters); return Remove(strCharacters);
@@ -306,8 +284,8 @@ namespace KeePassLib.Cryptography.PasswordGenerator
/// <returns>String containing all character set characters.</returns> /// <returns>String containing all character set characters.</returns>
public override string ToString() public override string ToString()
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder(m_lChars.Count);
foreach(char ch in m_vChars) foreach (char ch in m_lChars)
sb.Append(ch); sb.Append(ch);
return sb.ToString(); return sb.ToString();
@@ -320,32 +298,32 @@ namespace KeePassLib.Cryptography.PasswordGenerator
sb.Append(RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_');
sb.Append(RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_');
sb.Append(RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_');
sb.Append(RemoveIfAllExist(m_strSpecial) ? 'S' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Special) ? 'S' : '_');
sb.Append(RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_');
sb.Append(RemoveIfAllExist(@"-") ? 'm' : '_'); sb.Append(RemoveIfAllExist("-") ? 'm' : '_');
sb.Append(RemoveIfAllExist(@"_") ? 'u' : '_'); sb.Append(RemoveIfAllExist("_") ? 'u' : '_');
sb.Append(RemoveIfAllExist(@" ") ? 's' : '_'); sb.Append(RemoveIfAllExist(" ") ? 's' : '_');
sb.Append(RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_');
sb.Append(RemoveIfAllExist(m_strHighAnsi) ? 'H' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Latin1S) ? 'H' : '_');
return sb.ToString(); return sb.ToString();
} }
public void UnpackCharRanges(string strRanges) public void UnpackCharRanges(string strRanges)
{ {
if(strRanges == null) { Debug.Assert(false); return; } if (strRanges == null) { Debug.Assert(false); return; }
if(strRanges.Length < 10) { Debug.Assert(false); return; } if (strRanges.Length < 10) { Debug.Assert(false); return; }
if(strRanges[0] != '_') Add(PwCharSet.UpperCase); if (strRanges[0] != '_') Add(PwCharSet.UpperCase);
if(strRanges[1] != '_') Add(PwCharSet.LowerCase); if (strRanges[1] != '_') Add(PwCharSet.LowerCase);
if(strRanges[2] != '_') Add(PwCharSet.Digits); if (strRanges[2] != '_') Add(PwCharSet.Digits);
if(strRanges[3] != '_') Add(m_strSpecial); if (strRanges[3] != '_') Add(PwCharSet.Special);
if(strRanges[4] != '_') Add(PwCharSet.Punctuation); if (strRanges[4] != '_') Add(PwCharSet.Punctuation);
if(strRanges[5] != '_') Add('-'); if (strRanges[5] != '_') Add('-');
if(strRanges[6] != '_') Add('_'); if (strRanges[6] != '_') Add('_');
if(strRanges[7] != '_') Add(' '); if (strRanges[7] != '_') Add(' ');
if(strRanges[8] != '_') Add(PwCharSet.Brackets); if (strRanges[8] != '_') Add(PwCharSet.Brackets);
if(strRanges[9] != '_') Add(m_strHighAnsi); if (strRanges[9] != '_') Add(PwCharSet.Latin1S);
} }
} }
} }

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2016 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2025 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -20,9 +20,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Security.Cryptography;
using System.Text; using System.Text;
#if !KeePassUAP
using System.Security.Cryptography;
#endif
using KeePassLib.Resources;
using KeePassLib.Security; using KeePassLib.Security;
using KeePassLib.Utility; using KeePassLib.Utility;
@@ -33,95 +37,78 @@ namespace KeePassLib.Cryptography.PasswordGenerator
Success = 0, Success = 0,
Unknown = 1, Unknown = 1,
TooFewCharacters = 2, TooFewCharacters = 2,
UnknownAlgorithm = 3 UnknownAlgorithm = 3,
InvalidCharSet = 4,
InvalidPattern = 5
} }
/// <summary> /// <summary>
/// Utility functions for generating random passwords. /// Password generator.
/// </summary> /// </summary>
public static class PwGenerator public static class PwGenerator
{ {
public static PwgError Generate(out ProtectedString psOut,
PwProfile pwProfile, byte[] pbUserEntropy, private static CryptoRandomStream CreateRandomStream(byte[] pbAdditionalEntropy,
CustomPwGeneratorPool pwAlgorithmPool) out byte[] pbKey)
{ {
Debug.Assert(pwProfile != null); pbKey = CryptoRandom.Instance.GetRandomBytes(128);
if (pwProfile == null) throw new ArgumentNullException("pwProfile");
CryptoRandomStream crs = CreateCryptoStream(pbUserEntropy);
PwgError e = PwgError.Unknown;
if (pwProfile.GeneratorType == PasswordGeneratorType.CharSet)
e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs);
else if (pwProfile.GeneratorType == PasswordGeneratorType.Pattern)
e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs);
else if (pwProfile.GeneratorType == PasswordGeneratorType.Custom)
e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool);
else { Debug.Assert(false); psOut = ProtectedString.Empty; }
return e;
}
private static CryptoRandomStream CreateCryptoStream(byte[] pbAdditionalEntropy)
{
byte[] pbKey = CryptoRandom.Instance.GetRandomBytes(128);
// Mix in additional entropy // Mix in additional entropy
Debug.Assert(pbKey.Length >= 64); Debug.Assert(pbKey.Length >= 64);
if ((pbAdditionalEntropy != null) && (pbAdditionalEntropy.Length > 0)) if ((pbAdditionalEntropy != null) && (pbAdditionalEntropy.Length != 0))
{ {
using (SHA512Managed h = new SHA512Managed()) using (SHA512Managed h = new SHA512Managed())
{ {
byte[] pbHash = h.ComputeHash(pbAdditionalEntropy); byte[] pbHash = h.ComputeHash(pbAdditionalEntropy);
MemUtil.XorArray(pbHash, 0, pbKey, 0, pbHash.Length); MemUtil.XorArray(pbHash, 0, pbKey, 0, pbHash.Length);
MemUtil.ZeroByteArray(pbHash);
} }
} }
return new CryptoRandomStream(CrsAlgorithm.ChaCha20, pbKey); return new CryptoRandomStream(CrsAlgorithm.ChaCha20, pbKey);
} }
internal static char GenerateCharacter(PwProfile pwProfile, internal static char GenerateCharacter(PwCharSet pwCharSet,
PwCharSet pwCharSet, CryptoRandomStream crsRandomSource) CryptoRandomStream crsRandomSource)
{ {
if (pwCharSet.Size == 0) return char.MinValue; uint cc = pwCharSet.Size;
if (cc == 0) return char.MinValue;
ulong uIndex = crsRandomSource.GetRandomUInt64(); uint i = (uint)crsRandomSource.GetRandomUInt64(cc);
uIndex %= (ulong)pwCharSet.Size; return pwCharSet[i];
char ch = pwCharSet[(uint)uIndex];
if (pwProfile.NoRepeatingCharacters)
pwCharSet.Remove(ch);
return ch;
} }
internal static void PrepareCharSet(PwCharSet pwCharSet, PwProfile pwProfile) internal static bool PrepareCharSet(PwCharSet pwCharSet, PwProfile pwProfile)
{ {
pwCharSet.Remove(PwCharSet.Invalid); uint cc = pwCharSet.Size;
for (uint i = 0; i < cc; ++i)
{
char ch = pwCharSet[i];
if ((ch == char.MinValue) || (ch == '\t') || (ch == '\r') ||
(ch == '\n') || char.IsSurrogate(ch))
return false;
}
if (pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike); if (pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike);
if (pwProfile.ExcludeCharacters.Length > 0) if (!string.IsNullOrEmpty(pwProfile.ExcludeCharacters))
pwCharSet.Remove(pwProfile.ExcludeCharacters); pwCharSet.Remove(pwProfile.ExcludeCharacters);
return true;
} }
internal static void ShufflePassword(char[] pPassword, internal static void Shuffle(char[] v, CryptoRandomStream crsRandomSource)
CryptoRandomStream crsRandomSource)
{ {
Debug.Assert(pPassword != null); if (pPassword == null) return; if (v == null) { Debug.Assert(false); return; }
Debug.Assert(crsRandomSource != null); if (crsRandomSource == null) return; if (crsRandomSource == null) { Debug.Assert(false); return; }
if (pPassword.Length <= 1) return; // Nothing to shuffle for (int i = v.Length - 1; i >= 1; --i)
for (int nSelect = 0; nSelect < pPassword.Length; ++nSelect)
{ {
ulong uRandomIndex = crsRandomSource.GetRandomUInt64(); int j = (int)crsRandomSource.GetRandomUInt64((ulong)(i + 1));
uRandomIndex %= (ulong)(pPassword.Length - nSelect);
char chTemp = pPassword[nSelect]; char t = v[i];
pPassword[nSelect] = pPassword[nSelect + (int)uRandomIndex]; v[i] = v[j];
pPassword[nSelect + (int)uRandomIndex] = chTemp; v[j] = t;
} }
} }
@@ -135,7 +122,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
if (pwAlgorithmPool == null) return PwgError.UnknownAlgorithm; if (pwAlgorithmPool == null) return PwgError.UnknownAlgorithm;
string strID = pwProfile.CustomAlgorithmUuid; string strID = pwProfile.CustomAlgorithmUuid;
if (string.IsNullOrEmpty(strID)) { Debug.Assert(false); return PwgError.UnknownAlgorithm; } if (string.IsNullOrEmpty(strID)) return PwgError.UnknownAlgorithm;
byte[] pbUuid = Convert.FromBase64String(strID); byte[] pbUuid = Convert.FromBase64String(strID);
PwUuid uuid = new PwUuid(pbUuid); PwUuid uuid = new PwUuid(pbUuid);
@@ -148,5 +135,57 @@ namespace KeePassLib.Cryptography.PasswordGenerator
psOut = pwd; psOut = pwd;
return PwgError.Success; return PwgError.Success;
} }
internal static string ErrorToString(PwgError e, bool bHeader)
{
if (e == PwgError.Success) { Debug.Assert(false); return string.Empty; }
if ((e == PwgError.Unknown) && bHeader) return KLRes.PwGenFailed;
string str = KLRes.UnknownError;
switch (e)
{
// case PwgError.Success:
// break;
case PwgError.Unknown:
break;
case PwgError.TooFewCharacters:
str = KLRes.CharSetTooFewChars;
break;
case PwgError.UnknownAlgorithm:
str = KLRes.AlgorithmUnknown;
break;
case PwgError.InvalidCharSet:
str = KLRes.CharSetInvalid;
break;
case PwgError.InvalidPattern:
str = KLRes.PatternInvalid;
break;
default:
Debug.Assert(false);
break;
}
if (bHeader)
str = KLRes.PwGenFailed + MessageService.NewParagraph + str;
return str;
}
internal static string ErrorToString(Exception ex, bool bHeader)
{
string str = ((ex == null) ? KLRes.UnknownError :
StrUtil.FormatException(ex));
if (bHeader)
str = KLRes.PwGenFailed + MessageService.NewParagraph + str;
return str;
}
} }
} }

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2025 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -19,8 +19,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
using KeePassLib.Utility; using KeePassLib.Utility;
@@ -28,17 +28,19 @@ namespace KeePassLib.Cryptography
{ {
public static class PopularPasswords public static class PopularPasswords
{ {
private static Dictionary<int, Dictionary<string, bool>> m_dicts = private static readonly Dictionary<int, Dictionary<char[], bool>> g_dicts =
new Dictionary<int, Dictionary<string, bool>>(); new Dictionary<int, Dictionary<char[], bool>>();
internal static int MaxLength internal static int MaxLength
{ {
get get
{ {
Debug.Assert(g_dicts.Count > 0); // Should be initialized
int iMaxLen = 0; int iMaxLen = 0;
foreach(int iLen in m_dicts.Keys) foreach (int iLen in g_dicts.Keys)
{ {
if(iLen > iMaxLen) iMaxLen = iLen; if (iLen > iMaxLen) iMaxLen = iLen;
} }
return iMaxLen; return iMaxLen;
@@ -47,8 +49,8 @@ namespace KeePassLib.Cryptography
internal static bool ContainsLength(int nLength) internal static bool ContainsLength(int nLength)
{ {
Dictionary<string, bool> dDummy; Dictionary<char[], bool> dDummy;
return m_dicts.TryGetValue(nLength, out dDummy); return g_dicts.TryGetValue(nLength, out dDummy);
} }
public static bool IsPopularPassword(char[] vPassword) public static bool IsPopularPassword(char[] vPassword)
@@ -59,74 +61,73 @@ namespace KeePassLib.Cryptography
public static bool IsPopularPassword(char[] vPassword, out ulong uDictSize) public static bool IsPopularPassword(char[] vPassword, out ulong uDictSize)
{ {
if(vPassword == null) throw new ArgumentNullException("vPassword"); if (vPassword == null) throw new ArgumentNullException("vPassword");
if(vPassword.Length == 0) { uDictSize = 0; return false; } if (vPassword.Length == 0) { uDictSize = 0; return false; }
string str = new string(vPassword); #if DEBUG
Array.ForEach(vPassword, ch => Debug.Assert(ch == char.ToLower(ch)));
#endif
try { return IsPopularPasswordPriv(str, out uDictSize); } try { return IsPopularPasswordPriv(vPassword, out uDictSize); }
catch(Exception) { Debug.Assert(false); } catch (Exception) { Debug.Assert(false); }
uDictSize = 0; uDictSize = 0;
return false; return false;
} }
private static bool IsPopularPasswordPriv(string str, out ulong uDictSize) private static bool IsPopularPasswordPriv(char[] vPassword, out ulong uDictSize)
{ {
Debug.Assert(m_dicts.Count > 0); // Should be initialized with data Debug.Assert(g_dicts.Count > 0); // Should be initialized with data
Dictionary<string, bool> d; Dictionary<char[], bool> d;
if(!m_dicts.TryGetValue(str.Length, out d)) if (!g_dicts.TryGetValue(vPassword.Length, out d))
{ {
uDictSize = 0; uDictSize = 0;
return false; return false;
} }
uDictSize = (ulong)d.Count; uDictSize = (ulong)d.Count;
return d.ContainsKey(str); return d.ContainsKey(vPassword);
} }
public static void Add(byte[] pbData, bool bGZipped) public static void Add(byte[] pbData, bool bGZipped)
{ {
try try
{ {
if(bGZipped) if (bGZipped)
pbData = MemUtil.Decompress(pbData); pbData = MemUtil.Decompress(pbData);
string strData = StrUtil.Utf8.GetString(pbData, 0, pbData.Length); string strData = StrUtil.Utf8.GetString(pbData, 0, pbData.Length);
if(string.IsNullOrEmpty(strData)) { Debug.Assert(false); return; } if (string.IsNullOrEmpty(strData)) { Debug.Assert(false); return; }
if(!char.IsWhiteSpace(strData[strData.Length - 1]))
strData += "\n";
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for(int i = 0; i < strData.Length; ++i) for (int i = 0; i <= strData.Length; ++i)
{ {
char ch = strData[i]; char ch = ((i == strData.Length) ? ' ' : strData[i]);
if(char.IsWhiteSpace(ch)) if (char.IsWhiteSpace(ch))
{ {
int cc = sb.Length; int cc = sb.Length;
if(cc > 0) if (cc > 0)
{ {
string strWord = sb.ToString(); char[] vWord = new char[cc];
Debug.Assert(strWord.Length == cc); sb.CopyTo(0, vWord, 0, cc);
Dictionary<string, bool> d; Dictionary<char[], bool> d;
if(!m_dicts.TryGetValue(cc, out d)) if (!g_dicts.TryGetValue(cc, out d))
{ {
d = new Dictionary<string, bool>(); d = new Dictionary<char[], bool>(MemUtil.ArrayHelperExOfChar);
m_dicts[cc] = d; g_dicts[cc] = d;
} }
d[strWord] = true; d[vWord] = true;
sb.Remove(0, cc); sb.Remove(0, cc);
} }
} }
else sb.Append(char.ToLower(ch)); else sb.Append(char.ToLower(ch));
} }
} }
catch(Exception) { Debug.Assert(false); } catch (Exception) { Debug.Assert(false); }
} }
} }
} }

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2025 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -19,8 +19,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Cryptography.PasswordGenerator;
using KeePassLib.Utility; using KeePassLib.Utility;
@@ -35,19 +35,19 @@ namespace KeePassLib.Cryptography
{ {
private static class PatternID private static class PatternID
{ {
public const char LowerAlpha = 'L'; internal const char LowerAlpha = 'L';
public const char UpperAlpha = 'U'; internal const char UpperAlpha = 'U';
public const char Digit = 'D'; internal const char Digit = 'D';
public const char Special = 'S'; internal const char Special = 'S';
public const char High = 'H'; internal const char Latin1S = 'H';
public const char Other = 'X'; internal const char Other = 'X';
public const char Dictionary = 'W'; internal const char Dictionary = 'W';
public const char Repetition = 'R'; internal const char Repetition = 'R';
public const char Number = 'N'; internal const char Number = 'N';
public const char DiffSeq = 'C'; internal const char DiffSeq = 'C';
public const string All = "LUDSHXWRNC"; internal const string All = "LUDSHXWRNC";
} }
// private static class CharDistrib // private static class CharDistrib
@@ -84,8 +84,8 @@ namespace KeePassLib.Cryptography
public QeCharType(char chTypeID, string strAlphabet, bool bIsConsecutive) public QeCharType(char chTypeID, string strAlphabet, bool bIsConsecutive)
{ {
if(strAlphabet == null) throw new ArgumentNullException(); if (strAlphabet == null) throw new ArgumentNullException();
if(strAlphabet.Length == 0) throw new ArgumentException(); if (strAlphabet.Length == 0) throw new ArgumentException();
m_chTypeID = chTypeID; m_chTypeID = chTypeID;
m_strAlph = strAlphabet; m_strAlph = strAlphabet;
@@ -101,7 +101,7 @@ namespace KeePassLib.Cryptography
public QeCharType(char chTypeID, int nChars) // Catch-none set public QeCharType(char chTypeID, int nChars) // Catch-none set
{ {
if(nChars <= 0) throw new ArgumentOutOfRangeException(); if (nChars <= 0) throw new ArgumentOutOfRangeException();
m_chTypeID = chTypeID; m_chTypeID = chTypeID;
m_strAlph = string.Empty; m_strAlph = string.Empty;
@@ -114,7 +114,7 @@ namespace KeePassLib.Cryptography
public bool Contains(char ch) public bool Contains(char ch)
{ {
if(m_chLast != char.MinValue) if (m_chLast != char.MinValue)
return ((ch >= m_chFirst) && (ch <= m_chLast)); return ((ch >= m_chFirst) && (ch <= m_chLast));
Debug.Assert(m_strAlph.Length > 0); // Don't call for catch-none set Debug.Assert(m_strAlph.Length > 0); // Don't call for catch-none set
@@ -125,7 +125,7 @@ namespace KeePassLib.Cryptography
private sealed class EntropyEncoder private sealed class EntropyEncoder
{ {
private readonly string m_strAlph; private readonly string m_strAlph;
private Dictionary<char, ulong> m_dHisto = new Dictionary<char, ulong>(); private readonly Dictionary<char, ulong> m_dHisto = new Dictionary<char, ulong>();
private readonly ulong m_uBaseWeight; private readonly ulong m_uBaseWeight;
private readonly ulong m_uCharWeight; private readonly ulong m_uCharWeight;
private readonly ulong m_uOccExclThreshold; private readonly ulong m_uOccExclThreshold;
@@ -133,8 +133,8 @@ namespace KeePassLib.Cryptography
public EntropyEncoder(string strAlphabet, ulong uBaseWeight, public EntropyEncoder(string strAlphabet, ulong uBaseWeight,
ulong uCharWeight, ulong uOccExclThreshold) ulong uCharWeight, ulong uOccExclThreshold)
{ {
if(strAlphabet == null) throw new ArgumentNullException(); if (strAlphabet == null) throw new ArgumentNullException();
if(strAlphabet.Length == 0) throw new ArgumentException(); if (strAlphabet.Length == 0) throw new ArgumentException();
m_strAlph = strAlphabet; m_strAlph = strAlphabet;
m_uBaseWeight = uBaseWeight; m_uBaseWeight = uBaseWeight;
@@ -143,7 +143,7 @@ namespace KeePassLib.Cryptography
#if DEBUG #if DEBUG
Dictionary<char, bool> d = new Dictionary<char, bool>(); Dictionary<char, bool> d = new Dictionary<char, bool>();
foreach(char ch in m_strAlph) { d[ch] = true; } foreach (char ch in m_strAlph) { d[ch] = true; }
Debug.Assert(d.Count == m_strAlph.Length); // No duplicates Debug.Assert(d.Count == m_strAlph.Length); // No duplicates
#endif #endif
} }
@@ -166,18 +166,18 @@ namespace KeePassLib.Cryptography
public double GetOutputSize() public double GetOutputSize()
{ {
ulong uTotalWeight = m_uBaseWeight * (ulong)m_strAlph.Length; ulong uTotalWeight = m_uBaseWeight * (ulong)m_strAlph.Length;
foreach(ulong u in m_dHisto.Values) foreach (ulong u in m_dHisto.Values)
{ {
Debug.Assert(u >= 1); Debug.Assert(u >= 1);
if(u > m_uOccExclThreshold) if (u > m_uOccExclThreshold)
uTotalWeight += (u - m_uOccExclThreshold) * m_uCharWeight; uTotalWeight += (u - m_uOccExclThreshold) * m_uCharWeight;
} }
double dSize = 0.0, dTotalWeight = (double)uTotalWeight; double dSize = 0.0, dTotalWeight = (double)uTotalWeight;
foreach(ulong u in m_dHisto.Values) foreach (ulong u in m_dHisto.Values)
{ {
ulong uWeight = m_uBaseWeight; ulong uWeight = m_uBaseWeight;
if(u > m_uOccExclThreshold) if (u > m_uOccExclThreshold)
uWeight += (u - m_uOccExclThreshold) * m_uCharWeight; uWeight += (u - m_uOccExclThreshold) * m_uCharWeight;
dSize -= (double)u * Log2((double)uWeight / dTotalWeight); dSize -= (double)u * Log2((double)uWeight / dTotalWeight);
@@ -189,7 +189,7 @@ namespace KeePassLib.Cryptography
private sealed class MultiEntropyEncoder private sealed class MultiEntropyEncoder
{ {
private Dictionary<char, EntropyEncoder> m_dEncs = private readonly Dictionary<char, EntropyEncoder> m_dEncs =
new Dictionary<char, EntropyEncoder>(); new Dictionary<char, EntropyEncoder>();
public MultiEntropyEncoder() public MultiEntropyEncoder()
@@ -198,7 +198,7 @@ namespace KeePassLib.Cryptography
public void AddEncoder(char chTypeID, EntropyEncoder ec) public void AddEncoder(char chTypeID, EntropyEncoder ec)
{ {
if(ec == null) { Debug.Assert(false); return; } if (ec == null) { Debug.Assert(false); return; }
Debug.Assert(!m_dEncs.ContainsKey(chTypeID)); Debug.Assert(!m_dEncs.ContainsKey(chTypeID));
m_dEncs[chTypeID] = ec; m_dEncs[chTypeID] = ec;
@@ -206,13 +206,13 @@ namespace KeePassLib.Cryptography
public void Reset() public void Reset()
{ {
foreach(EntropyEncoder ec in m_dEncs.Values) { ec.Reset(); } foreach (EntropyEncoder ec in m_dEncs.Values) { ec.Reset(); }
} }
public bool Write(char chTypeID, char chData) public bool Write(char chTypeID, char chData)
{ {
EntropyEncoder ec; EntropyEncoder ec;
if(!m_dEncs.TryGetValue(chTypeID, out ec)) if (!m_dEncs.TryGetValue(chTypeID, out ec))
return false; return false;
ec.Write(chData); ec.Write(chData);
@@ -223,7 +223,7 @@ namespace KeePassLib.Cryptography
{ {
double d = 0.0; double d = 0.0;
foreach(EntropyEncoder ec in m_dEncs.Values) foreach (EntropyEncoder ec in m_dEncs.Values)
{ {
d += ec.GetOutputSize(); d += ec.GetOutputSize();
} }
@@ -281,36 +281,31 @@ namespace KeePassLib.Cryptography
} }
} }
private static object m_objSyncInit = new object(); private static readonly object m_objSyncInit = new object();
private static List<QeCharType> m_lCharTypes = null; private static List<QeCharType> m_lCharTypes = null;
private static void EnsureInitialized() private static void EnsureInitialized()
{ {
lock(m_objSyncInit) lock (m_objSyncInit)
{ {
if(m_lCharTypes == null) if (m_lCharTypes == null)
{ {
string strSpecial = PwCharSet.PrintableAsciiSpecial; string strSpecial = PwCharSet.PrintableAsciiSpecial;
if(strSpecial.IndexOf(' ') >= 0) { Debug.Assert(false); } if (strSpecial.IndexOf(' ') >= 0) { Debug.Assert(false); }
else strSpecial = strSpecial + " "; else strSpecial += " ";
int nSp = strSpecial.Length; int nSp = strSpecial.Length;
int nHi = PwCharSet.HighAnsiChars.Length; int nL1S = PwCharSet.Latin1S.Length;
m_lCharTypes = new List<QeCharType>(); m_lCharTypes = new List<QeCharType>()
{
m_lCharTypes.Add(new QeCharType(PatternID.LowerAlpha, new QeCharType(PatternID.LowerAlpha, PwCharSet.LowerCase, true),
PwCharSet.LowerCase, true)); new QeCharType(PatternID.UpperAlpha, PwCharSet.UpperCase, true),
m_lCharTypes.Add(new QeCharType(PatternID.UpperAlpha, new QeCharType(PatternID.Digit, PwCharSet.Digits, true),
PwCharSet.UpperCase, true)); new QeCharType(PatternID.Special, strSpecial, false),
m_lCharTypes.Add(new QeCharType(PatternID.Digit, new QeCharType(PatternID.Latin1S, PwCharSet.Latin1S, false),
PwCharSet.Digits, true)); new QeCharType(PatternID.Other, 0x10000 - (2 * 26) - 10 - nSp - nL1S)
m_lCharTypes.Add(new QeCharType(PatternID.Special, };
strSpecial, false));
m_lCharTypes.Add(new QeCharType(PatternID.High,
PwCharSet.HighAnsiChars, false));
m_lCharTypes.Add(new QeCharType(PatternID.Other,
0x10000 - (2 * 26) - 10 - nSp - nHi));
} }
} }
} }
@@ -318,37 +313,37 @@ namespace KeePassLib.Cryptography
/// <summary> /// <summary>
/// Estimate the quality of a password. /// Estimate the quality of a password.
/// </summary> /// </summary>
/// <param name="vPasswordChars">Password to check.</param> /// <param name="vPassword">Password to check.</param>
/// <returns>Estimated bit-strength of the password.</returns> /// <returns>Estimated bit-strength of the password.</returns>
public static uint EstimatePasswordBits(char[] vPasswordChars) public static uint EstimatePasswordBits(char[] vPassword)
{ {
if(vPasswordChars == null) { Debug.Assert(false); return 0; } if (vPassword == null) { Debug.Assert(false); return 0; }
if(vPasswordChars.Length == 0) return 0; if (vPassword.Length == 0) return 0;
EnsureInitialized(); EnsureInitialized();
int n = vPasswordChars.Length; int n = vPassword.Length;
List<QePatternInstance>[] vPatterns = new List<QePatternInstance>[n]; List<QePatternInstance>[] vPatterns = new List<QePatternInstance>[n];
for(int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
{ {
vPatterns[i] = new List<QePatternInstance>(); vPatterns[i] = new List<QePatternInstance>();
QePatternInstance piChar = new QePatternInstance(i, 1, QePatternInstance piChar = new QePatternInstance(i, 1,
GetCharType(vPasswordChars[i])); GetCharType(vPassword[i]));
vPatterns[i].Add(piChar); vPatterns[i].Add(piChar);
} }
FindRepetitions(vPasswordChars, vPatterns); FindRepetitions(vPassword, vPatterns);
FindNumbers(vPasswordChars, vPatterns); FindNumbers(vPassword, vPatterns);
FindDiffSeqs(vPasswordChars, vPatterns); FindDiffSeqs(vPassword, vPatterns);
FindPopularPasswords(vPasswordChars, vPatterns); FindPopularPasswords(vPassword, vPatterns);
// Encoders must not be static, because the entropy estimation // Encoders must not be static, because the entropy estimation
// may run concurrently in multiple threads and the encoders are // may run concurrently in multiple threads and the encoders are
// not read-only // not read-only
EntropyEncoder ecPattern = new EntropyEncoder(PatternID.All, 0, 1, 0); EntropyEncoder ecPattern = new EntropyEncoder(PatternID.All, 0, 1, 0);
MultiEntropyEncoder mcData = new MultiEntropyEncoder(); MultiEntropyEncoder mcData = new MultiEntropyEncoder();
for(int i = 0; i < (m_lCharTypes.Count - 1); ++i) for (int i = 0; i < (m_lCharTypes.Count - 1); ++i)
{ {
// Let m be the alphabet size. In order to ensure that two same // Let m be the alphabet size. In order to ensure that two same
// characters cost at least as much as a single character, for // characters cost at least as much as a single character, for
@@ -371,25 +366,25 @@ namespace KeePassLib.Cryptography
Stack<QePathState> sRec = new Stack<QePathState>(); Stack<QePathState> sRec = new Stack<QePathState>();
sRec.Push(new QePathState(0, new List<QePatternInstance>())); sRec.Push(new QePathState(0, new List<QePatternInstance>()));
while(sRec.Count > 0) while (sRec.Count > 0)
{ {
int tDiff = Environment.TickCount - tStart; int tDiff = Environment.TickCount - tStart;
if(tDiff > 500) break; if (tDiff > 500) break;
QePathState s = sRec.Pop(); QePathState s = sRec.Pop();
if(s.Position >= n) if (s.Position >= n)
{ {
Debug.Assert(s.Position == n); Debug.Assert(s.Position == n);
double dblCost = ComputePathCost(s.Path, vPasswordChars, double dblCost = ComputePathCost(s.Path, vPassword,
ecPattern, mcData); ecPattern, mcData);
if(dblCost < dblMinCost) dblMinCost = dblCost; if (dblCost < dblMinCost) dblMinCost = dblCost;
} }
else else
{ {
List<QePatternInstance> lSubs = vPatterns[s.Position]; List<QePatternInstance> lSubs = vPatterns[s.Position];
for(int i = lSubs.Count - 1; i >= 0; --i) for (int i = lSubs.Count - 1; i >= 0; --i)
{ {
QePatternInstance pi = lSubs[i]; QePatternInstance pi = lSubs[i];
Debug.Assert(pi.Position == s.Position); Debug.Assert(pi.Position == s.Position);
@@ -418,13 +413,14 @@ namespace KeePassLib.Cryptography
/// <returns>Estimated bit-strength of the password.</returns> /// <returns>Estimated bit-strength of the password.</returns>
public static uint EstimatePasswordBits(byte[] pbUnprotectedUtf8) public static uint EstimatePasswordBits(byte[] pbUnprotectedUtf8)
{ {
if(pbUnprotectedUtf8 == null) { Debug.Assert(false); return 0; } if (pbUnprotectedUtf8 == null) { Debug.Assert(false); return 0; }
char[] vChars = StrUtil.Utf8.GetChars(pbUnprotectedUtf8); char[] v = StrUtil.Utf8.GetChars(pbUnprotectedUtf8);
uint uResult = EstimatePasswordBits(vChars); uint r;
MemUtil.ZeroArray<char>(vChars); try { r = EstimatePasswordBits(v); }
finally { MemUtil.ZeroArray<char>(v); }
return uResult; return r;
} }
private static QeCharType GetCharType(char ch) private static QeCharType GetCharType(char ch)
@@ -432,9 +428,9 @@ namespace KeePassLib.Cryptography
int nTypes = m_lCharTypes.Count; int nTypes = m_lCharTypes.Count;
Debug.Assert((nTypes > 0) && (m_lCharTypes[nTypes - 1].CharCount > 256)); Debug.Assert((nTypes > 0) && (m_lCharTypes[nTypes - 1].CharCount > 256));
for(int i = 0; i < (nTypes - 1); ++i) for (int i = 0; i < (nTypes - 1); ++i)
{ {
if(m_lCharTypes[i].Contains(ch)) if (m_lCharTypes[i].Contains(ch))
return m_lCharTypes[i]; return m_lCharTypes[i];
} }
@@ -445,19 +441,19 @@ namespace KeePassLib.Cryptography
char[] vPassword, EntropyEncoder ecPattern, MultiEntropyEncoder mcData) char[] vPassword, EntropyEncoder ecPattern, MultiEntropyEncoder mcData)
{ {
ecPattern.Reset(); ecPattern.Reset();
for(int i = 0; i < l.Count; ++i) for (int i = 0; i < l.Count; ++i)
ecPattern.Write(l[i].PatternID); ecPattern.Write(l[i].PatternID);
double dblPatternCost = ecPattern.GetOutputSize(); double dblPatternCost = ecPattern.GetOutputSize();
mcData.Reset(); mcData.Reset();
double dblDataCost = 0.0; double dblDataCost = 0.0;
foreach(QePatternInstance pi in l) foreach (QePatternInstance pi in l)
{ {
QeCharType tChar = pi.SingleCharType; QeCharType tChar = pi.SingleCharType;
if(tChar != null) if (tChar != null)
{ {
char ch = vPassword[pi.Position]; char ch = vPassword[pi.Position];
if(!mcData.Write(tChar.TypeID, ch)) if (!mcData.Write(tChar.TypeID, ch))
dblDataCost += pi.Cost; dblDataCost += pi.Cost;
} }
else dblDataCost += pi.Cost; else dblDataCost += pi.Cost;
@@ -474,7 +470,7 @@ namespace KeePassLib.Cryptography
char[] vLower = new char[n]; char[] vLower = new char[n];
char[] vLeet = new char[n]; char[] vLeet = new char[n];
for(int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
{ {
char ch = vPassword[i]; char ch = vPassword[i];
@@ -482,27 +478,27 @@ namespace KeePassLib.Cryptography
vLeet[i] = char.ToLower(DecodeLeetChar(ch)); vLeet[i] = char.ToLower(DecodeLeetChar(ch));
} }
char chErased = default(char); char chErased = default(char); // The value that Array.Clear uses
Debug.Assert(chErased == char.MinValue); Debug.Assert(chErased == char.MinValue);
int nMaxLen = Math.Min(n, PopularPasswords.MaxLength); int nMaxLen = Math.Min(n, PopularPasswords.MaxLength);
for(int nSubLen = nMaxLen; nSubLen >= 3; --nSubLen) for (int nSubLen = nMaxLen; nSubLen >= 3; --nSubLen)
{ {
if(!PopularPasswords.ContainsLength(nSubLen)) continue; if (!PopularPasswords.ContainsLength(nSubLen)) continue;
char[] vSub = new char[nSubLen]; char[] vSub = new char[nSubLen];
for(int i = 0; i <= (n - nSubLen); ++i) for (int i = 0; i <= (n - nSubLen); ++i)
{ {
if(Array.IndexOf<char>(vLower, chErased, i, nSubLen) >= 0) if (Array.IndexOf<char>(vLower, chErased, i, nSubLen) >= 0)
continue; continue;
Array.Copy(vLower, i, vSub, 0, nSubLen); Array.Copy(vLower, i, vSub, 0, nSubLen);
if(!EvalAddPopularPasswordPattern(vPatterns, vPassword, if (!EvalAddPopularPasswordPattern(vPatterns, vPassword,
i, vSub, 0.0)) i, vSub, 0.0))
{ {
Array.Copy(vLeet, i, vSub, 0, nSubLen); Array.Copy(vLeet, i, vSub, 0, nSubLen);
if(EvalAddPopularPasswordPattern(vPatterns, vPassword, if (EvalAddPopularPasswordPattern(vPatterns, vPassword,
i, vSub, 1.5)) i, vSub, 1.5))
{ {
Array.Clear(vLower, i, nSubLen); // Not vLeet Array.Clear(vLower, i, nSubLen); // Not vLeet
@@ -515,14 +511,19 @@ namespace KeePassLib.Cryptography
Debug.Assert(vLower[i] == chErased); Debug.Assert(vLower[i] == chErased);
} }
} }
MemUtil.ZeroArray<char>(vSub);
} }
MemUtil.ZeroArray<char>(vLower);
MemUtil.ZeroArray<char>(vLeet);
} }
private static bool EvalAddPopularPasswordPattern(List<QePatternInstance>[] vPatterns, private static bool EvalAddPopularPasswordPattern(List<QePatternInstance>[] vPatterns,
char[] vPassword, int i, char[] vSub, double dblCostPerMod) char[] vPassword, int i, char[] vSub, double dblCostPerMod)
{ {
ulong uDictSize; ulong uDictSize;
if(!PopularPasswords.IsPopularPassword(vSub, out uDictSize)) if (!PopularPasswords.IsPopularPassword(vSub, out uDictSize))
return false; return false;
int n = vSub.Length; int n = vSub.Length;
@@ -532,9 +533,9 @@ namespace KeePassLib.Cryptography
// dblCost += log2(n binom d) // dblCost += log2(n binom d)
int k = Math.Min(d, n - d); int k = Math.Min(d, n - d);
for(int j = n; j > (n - k); --j) for (int j = n; j > (n - k); --j)
dblCost += Log2(j); dblCost += Log2(j);
for(int j = k; j >= 2; --j) for (int j = k; j >= 2; --j)
dblCost -= Log2(j); dblCost -= Log2(j);
dblCost += dblCostPerMod * (double)d; dblCost += dblCostPerMod * (double)d;
@@ -546,19 +547,19 @@ namespace KeePassLib.Cryptography
private static char DecodeLeetChar(char chLeet) private static char DecodeLeetChar(char chLeet)
{ {
if((chLeet >= '\u00C0') && (chLeet <= '\u00C6')) return 'a'; if ((chLeet >= '\u00C0') && (chLeet <= '\u00C6')) return 'a';
if((chLeet >= '\u00C8') && (chLeet <= '\u00CB')) return 'e'; if ((chLeet >= '\u00C8') && (chLeet <= '\u00CB')) return 'e';
if((chLeet >= '\u00CC') && (chLeet <= '\u00CF')) return 'i'; if ((chLeet >= '\u00CC') && (chLeet <= '\u00CF')) return 'i';
if((chLeet >= '\u00D2') && (chLeet <= '\u00D6')) return 'o'; if ((chLeet >= '\u00D2') && (chLeet <= '\u00D6')) return 'o';
if((chLeet >= '\u00D9') && (chLeet <= '\u00DC')) return 'u'; if ((chLeet >= '\u00D9') && (chLeet <= '\u00DC')) return 'u';
if((chLeet >= '\u00E0') && (chLeet <= '\u00E6')) return 'a'; if ((chLeet >= '\u00E0') && (chLeet <= '\u00E6')) return 'a';
if((chLeet >= '\u00E8') && (chLeet <= '\u00EB')) return 'e'; if ((chLeet >= '\u00E8') && (chLeet <= '\u00EB')) return 'e';
if((chLeet >= '\u00EC') && (chLeet <= '\u00EF')) return 'i'; if ((chLeet >= '\u00EC') && (chLeet <= '\u00EF')) return 'i';
if((chLeet >= '\u00F2') && (chLeet <= '\u00F6')) return 'o'; if ((chLeet >= '\u00F2') && (chLeet <= '\u00F6')) return 'o';
if((chLeet >= '\u00F9') && (chLeet <= '\u00FC')) return 'u'; if ((chLeet >= '\u00F9') && (chLeet <= '\u00FC')) return 'u';
char ch; char ch;
switch(chLeet) switch (chLeet)
{ {
case '4': case '4':
case '@': case '@':
@@ -621,9 +622,9 @@ namespace KeePassLib.Cryptography
char[] v2, int iOffset2, int nLength) char[] v2, int iOffset2, int nLength)
{ {
int nDist = 0; int nDist = 0;
for(int i = 0; i < nLength; ++i) for (int i = 0; i < nLength; ++i)
{ {
if(v1[iOffset1 + i] != v2[iOffset2 + i]) ++nDist; if (v1[iOffset1 + i] != v2[iOffset2 + i]) ++nDist;
} }
return nDist; return nDist;
@@ -637,15 +638,15 @@ namespace KeePassLib.Cryptography
Array.Copy(vPassword, v, n); Array.Copy(vPassword, v, n);
char chErased = char.MaxValue; char chErased = char.MaxValue;
for(int m = (n / 2); m >= 3; --m) for (int m = (n / 2); m >= 3; --m)
{ {
for(int x1 = 0; x1 <= (n - (2 * m)); ++x1) for (int x1 = 0; x1 <= (n - (2 * m)); ++x1)
{ {
bool bFoundRep = false; bool bFoundRep = false;
for(int x2 = (x1 + m); x2 <= (n - m); ++x2) for (int x2 = (x1 + m); x2 <= (n - m); ++x2)
{ {
if(PartsEqual(v, x1, x2, m)) if (PartsEqual(v, x1, x2, m))
{ {
double dblCost = Log2(x1 + 1) + Log2(m); double dblCost = Log2(x1 + 1) + Log2(m);
vPatterns[x2].Add(new QePatternInstance(x2, m, vPatterns[x2].Add(new QePatternInstance(x2, m,
@@ -656,16 +657,18 @@ namespace KeePassLib.Cryptography
} }
} }
if(bFoundRep) ErasePart(v, x1, m, ref chErased); if (bFoundRep) ErasePart(v, x1, m, ref chErased);
} }
} }
MemUtil.ZeroArray<char>(v);
} }
private static bool PartsEqual(char[] v, int x1, int x2, int nLength) private static bool PartsEqual(char[] v, int x1, int x2, int nLength)
{ {
for(int i = 0; i < nLength; ++i) for (int i = 0; i < nLength; ++i)
{ {
if(v[x1 + i] != v[x2 + i]) return false; if (v[x1 + i] != v[x2 + i]) return false;
} }
return true; return true;
@@ -673,7 +676,7 @@ namespace KeePassLib.Cryptography
private static void ErasePart(char[] v, int i, int n, ref char chErased) private static void ErasePart(char[] v, int i, int n, ref char chErased)
{ {
for(int j = 0; j < n; ++j) for (int j = 0; j < n; ++j)
{ {
v[i + j] = chErased; v[i + j] = chErased;
--chErased; --chErased;
@@ -685,33 +688,35 @@ namespace KeePassLib.Cryptography
{ {
int n = vPassword.Length; int n = vPassword.Length;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; ++i)
for (int i = 0; i < n; ++i)
{ {
char ch = vPassword[i]; char ch = vPassword[i];
if((ch >= '0') && (ch <= '9')) sb.Append(ch); if ((ch >= '0') && (ch <= '9')) sb.Append(ch);
else else
{ {
AddNumberPattern(vPatterns, sb.ToString(), i - sb.Length); AddNumberPattern(vPatterns, sb, i - sb.Length);
sb.Remove(0, sb.Length); sb.Remove(0, sb.Length);
} }
} }
AddNumberPattern(vPatterns, sb.ToString(), n - sb.Length); AddNumberPattern(vPatterns, sb, n - sb.Length);
} }
private static void AddNumberPattern(List<QePatternInstance>[] vPatterns, private static void AddNumberPattern(List<QePatternInstance>[] vPatterns,
string strNumber, int i) StringBuilder sb, int i)
{ {
if(strNumber.Length <= 2) return; if (sb.Length <= 2) return;
string strNumber = sb.ToString();
int nZeros = 0; int nZeros = 0;
for(int j = 0; j < strNumber.Length; ++j) for (int j = 0; j < strNumber.Length; ++j)
{ {
if(strNumber[j] != '0') break; if (strNumber[j] != '0') break;
++nZeros; ++nZeros;
} }
double dblCost = Log2(nZeros + 1); double dblCost = Log2(nZeros + 1);
if(nZeros < strNumber.Length) if (nZeros < strNumber.Length)
{ {
string strNonZero = strNumber.Substring(nZeros); string strNonZero = strNumber.Substring(nZeros);
@@ -720,7 +725,7 @@ namespace KeePassLib.Cryptography
catch(Exception) { Debug.Assert(false); return; } catch(Exception) { Debug.Assert(false); return; }
#else #else
double d; double d;
if(double.TryParse(strNonZero, out d)) if (double.TryParse(strNonZero, out d))
dblCost += Log2(d); dblCost += Log2(d);
else { Debug.Assert(false); return; } else { Debug.Assert(false); return; }
#endif #endif
@@ -733,17 +738,18 @@ namespace KeePassLib.Cryptography
private static void FindDiffSeqs(char[] vPassword, private static void FindDiffSeqs(char[] vPassword,
List<QePatternInstance>[] vPatterns) List<QePatternInstance>[] vPatterns)
{ {
int d = int.MinValue, p = 0; int n = vPassword.Length;
string str = new string(vPassword) + new string(char.MaxValue, 1); int d = int.MaxValue, p = 0;
for(int i = 1; i < str.Length; ++i) for (int i = 1; i <= n; ++i)
{ {
int dCur = (int)str[i] - (int)str[i - 1]; int dCur = ((i == n) ? int.MinValue :
if(dCur != d) ((int)vPassword[i] - (int)vPassword[i - 1]));
if (dCur != d)
{ {
if((i - p) >= 3) // At least 3 chars involved if ((i - p) >= 3) // At least 3 chars involved
{ {
QeCharType ct = GetCharType(str[p]); QeCharType ct = GetCharType(vPassword[p]);
double dblCost = ct.CharSize + Log2(i - p - 1); double dblCost = ct.CharSize + Log2(i - p - 1);
vPatterns[p].Add(new QePatternInstance(p, vPatterns[p].Add(new QePatternInstance(p,

View File

@@ -46,4 +46,12 @@ namespace KeePassLib.Delegates
public delegate void VoidDelegate(); public delegate void VoidDelegate();
public delegate string StrPwEntryDelegate(string str, PwEntry pe); public delegate string StrPwEntryDelegate(string str, PwEntry pe);
public delegate TResult GFunc<TResult>();
public delegate TResult GFunc<T, TResult>(T o);
public delegate TResult GFunc<T1, T2, TResult>(T1 o1, T2 o2);
public delegate TResult GFunc<T1, T2, T3, TResult>(T1 o1, T2 o2, T3 o3);
public delegate TResult GFunc<T1, T2, T3, T4, TResult>(T1 o1, T2 o2, T3 o3, T4 o4);
public delegate TResult GFunc<T1, T2, T3, T4, T5, TResult>(T1 o1, T2 o2, T3 o3, T4 o4, T5 o5);
public delegate TResult GFunc<T1, T2, T3, T4, T5, T6, TResult>(T1 o1, T2 o2, T3 o3, T4 o4, T5 o5, T6 o6);
} }

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -116,12 +116,23 @@ namespace keepass2android
Intent sendIntent = new Intent(); Intent sendIntent = new Intent();
sendIntent.SetAction(Intent.ActionSend); sendIntent.SetAction(Intent.ActionSend);
sendIntent.PutExtra(Intent.ExtraText, File.ReadAllText(LogFilename)); string logText = File.ReadAllText(LogFilename);
sendIntent.PutExtra(Intent.ExtraText, logText);
sendIntent.PutExtra(Intent.ExtraEmail, "crocoapps@gmail.com"); sendIntent.PutExtra(Intent.ExtraEmail, "crocoapps@gmail.com");
sendIntent.PutExtra(Intent.ExtraSubject, "Keepass2Android log"); sendIntent.PutExtra(Intent.ExtraSubject, "Keepass2Android log");
sendIntent.SetType("text/plain"); sendIntent.SetType("text/plain");
try
{
ctx.StartActivity(Intent.CreateChooser(sendIntent, "Send log to...")); ctx.StartActivity(Intent.CreateChooser(sendIntent, "Send log to..."));
} }
catch (Exception e)
{
Toast.MakeText(ctx, $"Error sending log of length {logText.Length} bytes: " + e.Message, ToastLength.Long)?.Show();
}
}
public static void LogTask(object task, string activityName) public static void LogTask(object task, string activityName)
{ {

View File

@@ -83,6 +83,7 @@ namespace KeePassLib.Serialization
if (m_bUsedOnce) if (m_bUsedOnce)
throw new InvalidOperationException("Do not reuse KdbxFile objects!"); throw new InvalidOperationException("Do not reuse KdbxFile objects!");
m_bUsedOnce = true; m_bUsedOnce = true;
Kp2aLog.Log("Starting to load KDBX file...");
#if KDBX_BENCHMARK #if KDBX_BENCHMARK
Stopwatch swTime = Stopwatch.StartNew(); Stopwatch swTime = Stopwatch.StartNew();
@@ -257,6 +258,7 @@ namespace KeePassLib.Serialization
MessageService.ShowInfo("Loading KDBX took " + MessageService.ShowInfo("Loading KDBX took " +
swTime.ElapsedMilliseconds.ToString() + " ms."); swTime.ElapsedMilliseconds.ToString() + " ms.");
#endif #endif
Kp2aLog.Log("Finished loading KDBX file.");
} }
private void CommonCleanUpRead(List<Stream> lStreams, HashingStreamEx sHashing) private void CommonCleanUpRead(List<Stream> lStreams, HashingStreamEx sHashing)

File diff suppressed because it is too large Load Diff

View File

@@ -95,7 +95,7 @@ namespace Kp2aAutofillParserTest
StructureParserBase<TestInputField> parser = StructureParserBase<TestInputField> parser =
new StructureParserBase<TestInputField>(new TestLogger(), new TestDalSourceTrustAll()); new StructureParserBase<TestInputField>(new TestLogger(), new TestDalSourceTrustAll());
var result = parser.ParseForFill(false, autofillView); var result = parser.ParseForFill(autofillView);
if (expectedPackageName != null) if (expectedPackageName != null)
Assert.Equal(expectedPackageName, result.PackageName); Assert.Equal(expectedPackageName, result.PackageName);
if (expectedWebDomain != null) if (expectedWebDomain != null)

View File

@@ -58,7 +58,8 @@
"IsFocused": false, "IsFocused": false,
"InputType": 97, "InputType": 97,
"HtmlInfoTag": null, "HtmlInfoTag": null,
"HtmlInfoTypeAttribute": null "HtmlInfoTypeAttribute": null,
"ExpectedAssignedHints": [ "username" ]
}, },
{ {
"IdEntry": "password_text_input_layout", "IdEntry": "password_text_input_layout",
@@ -81,6 +82,7 @@
"InputType": 129, "InputType": 129,
"HtmlInfoTag": null, "HtmlInfoTag": null,
"HtmlInfoTypeAttribute": null, "HtmlInfoTypeAttribute": null,
"ExpectedAssignedHints": [ "password" ]
}, },
{ {

View File

@@ -476,8 +476,16 @@ namespace Kp2aAutofillParser
foreach (var field in autofillFields.HintMap.Values.Distinct()) foreach (var field in autofillFields.HintMap.Values.Distinct())
{ {
if (field == null || field.AutofillHints == null)
{
continue;
}
foreach (var hint in field.AutofillHints) foreach (var hint in field.AutofillHints)
{ {
if (hint == null)
{
continue;
}
if (GetPartitionIndex(hint) == partitionIndex) if (GetPartitionIndex(hint) == partitionIndex)
{ {
filteredCollection.Add(field); filteredCollection.Add(field);
@@ -793,14 +801,14 @@ namespace Kp2aAutofillParser
} }
} }
public AutofillTargetId ParseForFill(bool isManual, AutofillView<FieldT> autofillView) public AutofillTargetId ParseForFill(AutofillView<FieldT> autofillView)
{ {
return Parse(true, isManual, autofillView); return Parse(true, autofillView);
} }
public AutofillTargetId ParseForSave(AutofillView<FieldT> autofillView) public AutofillTargetId ParseForSave(AutofillView<FieldT> autofillView)
{ {
return Parse(false, true, autofillView); return Parse(false, autofillView);
} }
/// <summary> /// <summary>
@@ -808,8 +816,7 @@ namespace Kp2aAutofillParser
/// </summary> /// </summary>
/// <returns>The parse.</returns> /// <returns>The parse.</returns>
/// <param name="forFill">If set to <c>true</c> for fill.</param> /// <param name="forFill">If set to <c>true</c> for fill.</param>
/// <param name="isManualRequest"></param> protected virtual AutofillTargetId Parse(bool forFill, AutofillView<FieldT> autofillView)
protected virtual AutofillTargetId Parse(bool forFill, bool isManualRequest, AutofillView<FieldT> autofillView)
{ {
AutofillTargetId result = new AutofillTargetId() AutofillTargetId result = new AutofillTargetId()
{ {
@@ -876,8 +883,9 @@ namespace Kp2aAutofillParser
} }
//for "heuristic determination" we demand that one of the filled fields is focused: //for "heuristic determination" we demand that there is a password field or one of the username fields is focused:
if (passwordFields.Concat(usernameFields).Any(f => f.IsFocused)) //Note that "IsFocused" might be false even when tapping the field. It might require long-press to autofill.
if (passwordFields.Any() || usernameFields.Any(f => f.IsFocused))
{ {
foreach (var uf in usernameFields) foreach (var uf in usernameFields)
AddFieldToHintMap(uf, new string[] { AutofillHintsHelper.AutofillHintUsername }); AddFieldToHintMap(uf, new string[] { AutofillHintsHelper.AutofillHintUsername });

View File

@@ -140,6 +140,10 @@ namespace keepass2android
#endif #endif
int WebDavChunkedUploadSize
{
get;
}
} }
} }

View File

@@ -15,6 +15,8 @@ namespace keepass2android.Io
{ {
get { return false; } get { return false; }
} }
static public bool IsConfigured => !string.IsNullOrEmpty(AppKey) && !string.IsNullOrEmpty(AppSecret);
} }
public partial class DropboxAppFolderFileStorage: JavaFileStorage public partial class DropboxAppFolderFileStorage: JavaFileStorage
@@ -29,6 +31,7 @@ namespace keepass2android.Io
get { return false; } get { return false; }
} }
static public bool IsConfigured => !string.IsNullOrEmpty(AppKey) && !string.IsNullOrEmpty(AppSecret);
} }
} }

View File

@@ -1,13 +0,0 @@
namespace keepass2android.Io
{
public partial class DropboxFileStorage
{
private const string AppKey = "dummy";
private const string AppSecret = "dummy";
}
public partial class DropboxAppFolderFileStorage
{
private const string AppKey = "dummy";
private const string AppSecret = "dummy";
}
}

View File

@@ -0,0 +1,27 @@
<Project>
<Target Name="GenerateDropboxSecrets" BeforeTargets="BeforeCompile"
Inputs="@(DropboxSecretLines)"
Outputs="DropboxFileStorage.g.cs">
<WriteLinesToFile
File="Io/DropboxFileStorage.g.cs"
Lines="@(DropboxSecretLines->'%(Text)')"
Overwrite="true"
/>
</Target>
<ItemGroup>
<DropboxSecretLines Include="GeneratedDropboxSecrets">
<Text>namespace keepass2android.Io {
public partial class DropboxFileStorage {
private const string AppKey = "$(DropboxAppKey)";
private const string AppSecret = "$(DropboxAppSecret)";
}
public partial class DropboxAppFolderFileStorage {
private const string AppKey = "$(DropboxAppFolderAppKey)";
private const string AppSecret = "$(DropboxAppFolderAppSecret)";
}
}</Text>
</DropboxSecretLines>
</ItemGroup>
</Project>

View File

@@ -123,7 +123,7 @@ namespace keepass2android.Io
} }
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction) public virtual IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
{ {
return new JavaFileStorageWriteTransaction(IocToPath(ioc), useFileTransaction, this); return new JavaFileStorageWriteTransaction(IocToPath(ioc), useFileTransaction, this);
} }

View File

@@ -1125,9 +1125,57 @@ namespace keepass2android.Io
} }
} }
public static async Task<DriveItem> GetOrCreateAppRootAsync(GraphServiceClient client, string dummyFileName = "welcome_at_kp2a.txt")
{
private async Task<List<FileDescription>> ListShares(OneDrive2ItemLocation<OneDrive2PrefixContainerType> parentPath, GraphServiceClient client) try
{
return await client.RequestAdapter.SendAsync(
new Microsoft.Graph.Drives.Item.Items.Item.DriveItemItemRequestBuilder(
new Dictionary<string, object> {
{ "drive%2Did", "me" },
{ "driveItem%2Did", "special/approot" }
},
client.RequestAdapter
).ToGetRequestInformation(),
static (p) => DriveItem.CreateFromDiscriminatorValue(p)
);
}
catch (Microsoft.Kiota.Abstractions.ApiException ex) when (ex.ResponseStatusCode == 404)
{
// App folder doesnt exist yet → create it by uploading a dummy file
using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes("init"));
var uploadRequest = new RequestInformation
{
HttpMethod = Method.PUT,
UrlTemplate = "{+baseurl}/me/drive/special/approot:/{filename}:/content",
PathParameters = new Dictionary<string, object>
{
{ "baseurl", client.RequestAdapter.BaseUrl },
{ "filename", dummyFileName }
},
Content = stream
};
var uploadedItem = await client.RequestAdapter.SendAsync<DriveItem>(
uploadRequest,
DriveItem.CreateFromDiscriminatorValue
);
var parentId = uploadedItem.ParentReference.Id;
var parentItemRequest = new DriveItemRequestBuilder(
$"{client.RequestAdapter.BaseUrl}/me/drive/items/{parentId}",
client.RequestAdapter
);
return await parentItemRequest.GetAsync();
}
}
protected virtual async Task<List<FileDescription>> ListShares(OneDrive2ItemLocation<OneDrive2PrefixContainerType> parentPath, GraphServiceClient client)
{ {
List<FileDescription> result = []; List<FileDescription> result = [];
@@ -1346,6 +1394,8 @@ namespace keepass2android.Io
} }
} }
protected override async Task<string?> GetSpecialFolder( protected override async Task<string?> GetSpecialFolder(
OneDrive2ItemLocation<OneDrive2AppFolderPrefixContainer> itemLocation, GraphServiceClient client) OneDrive2ItemLocation<OneDrive2AppFolderPrefixContainer> itemLocation, GraphServiceClient client)
{ {
@@ -1378,8 +1428,55 @@ namespace keepass2android.Io
{ {
return drive.Name ?? MyOneDriveDisplayName; return drive.Name ?? MyOneDriveDisplayName;
} }
public static async Task GetOrCreateAppRootAsync(GraphServiceClient client, string dummyFileName = "welcome_at_kp2a_app_folder.txt")
{
try
{
await client.RequestAdapter.SendAsync(
new Microsoft.Graph.Drives.Item.Items.Item.DriveItemItemRequestBuilder(
new Dictionary<string, object> {
{ "drive%2Did", "me" },
{ "driveItem%2Did", "special/approot" }
},
client.RequestAdapter
).ToGetRequestInformation(),
static (p) => DriveItem.CreateFromDiscriminatorValue(p)
);
//if this is successful, approot seems to exist
}
catch (Microsoft.Kiota.Abstractions.ApiException ex) when (ex.ResponseStatusCode == 404)
{
// App folder doesnt exist yet → create it by uploading a dummy file
using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes("init"));
var uploadRequest = new RequestInformation
{
HttpMethod = Method.PUT,
UrlTemplate = "{+baseurl}/me/drive/special/approot:/{filename}:/content",
PathParameters = new Dictionary<string, object>
{
{ "baseurl", client.RequestAdapter.BaseUrl },
{ "filename", dummyFileName }
},
Content = stream
};
await client.RequestAdapter.SendAsync<DriveItem>(
uploadRequest,
DriveItem.CreateFromDiscriminatorValue
);
}
}
protected override async Task<List<FileDescription>> ListShares(OneDrive2ItemLocation<OneDrive2AppFolderPrefixContainer> parentPath, GraphServiceClient client)
{
await GetOrCreateAppRootAsync(client);
return await base.ListShares(parentPath, client);
}
public override bool CanListShares { get { return false; } } public override bool CanListShares { get { return false; } }
protected override string MyOneDriveDisplayName => "Keepass2Android App Folder"; protected override string MyOneDriveDisplayName => "Keepass2Android App Folder";
} }

View File

@@ -0,0 +1,617 @@
#if !NoNet
using System.Net;
using Android.Content;
using keepass2android;
using keepass2android.Io;
using KeePassLib.Serialization;
using SMBLibrary.Client;
using SMBLibrary;
using FileAttributes = SMBLibrary.FileAttributes;
using KeePassLib.Utility;
using Java.Nio.FileNio;
namespace Kp2aBusinessLogic.Io
{
public class SmbFileStorage : IFileStorage
{
public IEnumerable<string> SupportedProtocols
{
get { yield return "smb"; }
}
public bool UserShouldBackup
{
get { return false; }
}
public void Delete(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
{
return false;
}
public string GetCurrentFileVersionFast(IOConnectionInfo ioc)
{
return null;
}
public struct SmbConnectionInfo
{
public string Host;
public string Username;
public string Password;
public string? Domain;
public string? Share;
public string? LocalPath;
public static SmbConnectionInfo FromUrlAndCredentials(string url, string username, string password, string? domain)
{
string userDomain = username;
if (domain != null)
{
userDomain = domain + "\\" + username;
}
if (url.StartsWith("smb://"))
{
url = url.Substring(6);
}
if (url.StartsWith("\\\\"))
{
url = url.Substring(2);
}
url = url.Replace("\\", "/");
string fullPath = "smb://" + WebUtility.UrlEncode(userDomain) + ":" + WebUtility.UrlEncode(password) + "@" + url;
return new SmbConnectionInfo(new IOConnectionInfo() { Path = fullPath} );
}
public SmbConnectionInfo(IOConnectionInfo ioc)
{
string fullpath = ioc.Path;
if (!fullpath.StartsWith("smb://"))
{
throw new Exception("Invalid smb path!");
}
fullpath = fullpath.Substring(6);
string[] authAndPath = fullpath.Split('@');
if (authAndPath.Length != 2)
{
throw new Exception("Invalid smb path!");
}
string[] userAndPwd = authAndPath[0].Split(':');
if (userAndPwd.Length != 2)
{
throw new Exception("Invalid smb path!");
}
string[] pathParts = authAndPath[1].Split('/');
if (pathParts.Length < 1)
{
throw new Exception("Invalid smb path!");
}
Host = pathParts[0];
if (pathParts.Length > 1)
{
Share = pathParts[1];
}
LocalPath = String.Join("/", pathParts.Skip(2));
if (LocalPath.EndsWith("/"))
{
LocalPath = LocalPath.Substring(0, LocalPath.Length - 1);
}
Username = WebUtility.UrlDecode(userAndPwd[0]);
if (Username.Contains("\\"))
{
string[] domainAndUser = Username.Split('\\');
Domain = domainAndUser[0];
Username = domainAndUser[1];
}
else Domain = null;
Password = WebUtility.UrlDecode(userAndPwd[1]);
}
public string ToPath()
{
string domainUser = Username;
if (Domain != null)
{
domainUser = Domain + "\\" + Username;
}
return "smb://" + WebUtility.UrlEncode(domainUser) + ":" + WebUtility.UrlEncode(Password) + "@" + Host +
"/" + Share + "/" + LocalPath;
}
public string GetPathWithoutCredentials()
{
return "smb://" + Host + "/" + Share + "/" + LocalPath;
}
public string GetLocalSmbPath()
{
return LocalPath?.Replace("/", "\\") ?? "";
}
public SmbConnectionInfo GetParent()
{
SmbConnectionInfo parent = new SmbConnectionInfo
{
Host = Host,
Username = Username,
Password = Password,
Domain = Domain,
Share = Share
};
string[] pathParts = LocalPath?.Split('/') ?? [];
if (pathParts.Length > 0)
{
parent.LocalPath = string.Join("/", pathParts.Take(pathParts.Length - 1));
}
else
{
parent.LocalPath = "";
parent.Share = "";
}
return parent;
}
public string Stem()
{
return LocalPath?.Split('/').Last() ?? "";
}
public SmbConnectionInfo GetChild(string childName)
{
SmbConnectionInfo child = new SmbConnectionInfo();
child.Host = Host;
child.Username = Username;
child.Password = Password;
child.Domain = Domain;
if (string.IsNullOrEmpty(Share))
{
child.Share = childName;
}
else
{
child.Share = Share;
var pathPartsList = LocalPath?.Split('/').Where(p => !string.IsNullOrEmpty(p)).ToList() ?? [];
pathPartsList.Add(childName);
child.LocalPath = string.Join("/", pathPartsList);
}
return child;
}
public string ToDisplayString()
{
return "smb://" + Host + "/" + Share + "/" + LocalPath;
}
}
class SmbConnection: IDisposable
{
public SmbConnection(SmbConnectionInfo info)
{
_isLoggedIn = false;
var isConnected = Client.Connect(info.Host, SMBTransportType.DirectTCPTransport);
if (!isConnected)
{
throw new Exception($"Failed to connect to SMB server {info.Host}");
}
var status = Client.Login(info.Domain ?? string.Empty, info.Username, info.Password);
if (status != NTStatus.STATUS_SUCCESS)
{
throw new Exception($"Failed to login to SMB as {info.Username}");
}
_isLoggedIn = true;
if (!string.IsNullOrEmpty(info.Share))
{
FileStore = Client.TreeConnect(info.Share, out status);
}
}
public readonly SMB2Client Client = new SMB2Client();
public readonly ISMBFileStore? FileStore;
private readonly bool _isLoggedIn;
public void Dispose()
{
FileStore?.Disconnect();
if (_isLoggedIn)
Client.Logoff();
if (!Client.IsConnected) return;
Client.Disconnect();
}
}
public Stream OpenFileForRead(IOConnectionInfo ioc)
{
SmbConnectionInfo info = new SmbConnectionInfo(ioc);
using SmbConnection conn = new SmbConnection(info);
if (conn.FileStore == null)
{
throw new Exception($"Failed to read to {info.GetPathWithoutCredentials()}");
}
NTStatus status = conn.FileStore.CreateFile(out var fileHandle, out _, info.GetLocalSmbPath(),
AccessMask.GENERIC_READ | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.Read,
CreateDisposition.FILE_OPEN,
CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);
if (status != NTStatus.STATUS_SUCCESS)
{
throw new Exception($"Failed to open file {info.LocalPath}");
}
var stream = new MemoryStream();
long bytesRead = 0;
while (true)
{
status = conn.FileStore.ReadFile(out var data, fileHandle, bytesRead, (int)conn.Client.MaxReadSize);
if (status != NTStatus.STATUS_SUCCESS && status != NTStatus.STATUS_END_OF_FILE)
{
throw new Exception("Failed to read from file");
}
if (status == NTStatus.STATUS_END_OF_FILE || data.Length == 0)
{
break;
}
bytesRead += data.Length;
stream.Write(data, 0, data.Length);
}
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
class SmbFileStorageWriteTransaction : IWriteTransaction
{
private bool UseFileTransaction { get; }
private readonly string _path;
private readonly string _uploadPath;
private readonly SmbFileStorage _fileStorage;
private MemoryStream? _memoryStream;
public SmbFileStorageWriteTransaction(string path, SmbFileStorage fileStorage, bool useFileTransaction)
{
UseFileTransaction = useFileTransaction;
_path = path;
if (useFileTransaction)
{
_uploadPath = _path + Guid.NewGuid().ToString().Substring(0, 8) + ".tmp";
}
else
{
_uploadPath = _path;
}
_fileStorage = fileStorage;
_memoryStream = null;
}
public void Dispose()
{
_memoryStream?.Dispose();
}
public Stream OpenFile()
{
_memoryStream = new MemoryStream();
return _memoryStream;
}
public void CommitWrite()
{
_fileStorage.UploadData(new MemoryStream(_memoryStream!.ToArray()), new SmbConnectionInfo(new IOConnectionInfo() { Path = _uploadPath}));
if (UseFileTransaction)
{
SmbConnectionInfo uploadPath = new SmbConnectionInfo(new IOConnectionInfo() { Path = _uploadPath });
SmbConnectionInfo finalPath = new SmbConnectionInfo(new IOConnectionInfo() { Path = _path });
_fileStorage.RenameFile(uploadPath, finalPath);
}
}
}
private void RenameFile(SmbConnectionInfo fromPath, SmbConnectionInfo toPath)
{
using var connection = new SmbConnection(fromPath);
// Open existing file
var status = connection.FileStore!.CreateFile(out var handle, out _, fromPath.GetLocalSmbPath(), AccessMask.MAXIMUM_ALLOWED, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_NON_DIRECTORY_FILE, null);
if (status != NTStatus.STATUS_SUCCESS)
throw new Exception($"Failed to open {fromPath.LocalPath} for renaming!");
FileRenameInformationType2 renameInfo = new FileRenameInformationType2
{
FileName = toPath.GetLocalSmbPath(),
ReplaceIfExists = true
};
connection.FileStore.SetFileInformation(handle, renameInfo);
connection.FileStore.CloseFile(handle);
}
private void UploadData(Stream data, SmbConnectionInfo uploadPath)
{
using var connection = new SmbConnection(uploadPath);
var status = connection.FileStore!.CreateFile(out var fileHandle, out _, uploadPath.GetLocalSmbPath(), AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.None, CreateDisposition.FILE_CREATE, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);
if (status == NTStatus.STATUS_OBJECT_NAME_COLLISION)
status = connection.FileStore!.CreateFile(out fileHandle, out _, uploadPath.GetLocalSmbPath(), AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.None, CreateDisposition.FILE_OVERWRITE, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);
if (status != NTStatus.STATUS_SUCCESS)
{
throw new Exception($"Failed to open {uploadPath.LocalPath} for writing!");
}
long writeOffset = 0;
while (data.Position < data.Length)
{
byte[] buffer = new byte[(int)connection.Client.MaxWriteSize];
int bytesRead = data.Read(buffer, 0, buffer.Length);
if (bytesRead < (int)connection.Client.MaxWriteSize)
{
Array.Resize(ref buffer, bytesRead);
}
status = connection.FileStore.WriteFile(out _, fileHandle, writeOffset, buffer);
if (status != NTStatus.STATUS_SUCCESS)
{
throw new Exception("Failed to write to file");
}
writeOffset += bytesRead;
}
}
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
{
return new SmbFileStorageWriteTransaction(ioc.Path, this, useFileTransaction);
}
public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
{
return UrlUtil.StripExtension(
UrlUtil.GetFileName(ioc.Path));
}
public string GetFileExtension(IOConnectionInfo ioc)
{
return UrlUtil.GetExtension(ioc.Path);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return false;
}
public void CreateDirectory(IOConnectionInfo ioc, string newDirName)
{
throw new NotImplementedException();
}
private static IEnumerable<FileDescription> ListShares(SmbConnection conn, SmbConnectionInfo parent)
{
foreach (string share in conn.Client.ListShares(out _))
{
yield return new FileDescription()
{
CanRead = true,
CanWrite = true,
DisplayName = share,
IsDirectory = true,
Path = parent.GetChild(share).ToPath()
};
}
}
public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc)
{
List<FileDescription> result = [];
SmbConnectionInfo info = new SmbConnectionInfo(ioc);
using SmbConnection conn = new SmbConnection(info);
if (string.IsNullOrEmpty(info.Share))
{
var shares = ListShares(conn, info).ToList();
return shares;
}
NTStatus status = conn.FileStore!.CreateFile(out var directoryHandle, out _, info.GetLocalSmbPath(), AccessMask.GENERIC_READ, FileAttributes.Directory, ShareAccess.Read | ShareAccess.Write, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null);
if (status == NTStatus.STATUS_SUCCESS)
{
conn.FileStore.QueryDirectory(out List<QueryDirectoryFileInformation> fileList, directoryHandle, "*", FileInformationClass.FileDirectoryInformation);
foreach (var fi in fileList)
{
var fileDirectoryInformation = fi as FileDirectoryInformation;
if (fileDirectoryInformation == null)
continue;
if (fileDirectoryInformation.FileName is "." or "..")
continue;
var fileDescription = FileDescriptionConvert(ioc, fileDirectoryInformation);
result.Add(fileDescription);
}
conn.FileStore.CloseFile(directoryHandle);
}
return result;
}
private FileDescription FileDescriptionConvert(IOConnectionInfo parentIoc,
FileDirectoryInformation fileDirectoryInformation)
{
FileDescription fileDescription = new FileDescription
{
CanRead = true,
CanWrite = true,
IsDirectory = (fileDirectoryInformation.FileAttributes & FileAttributes.Directory) != 0,
DisplayName = fileDirectoryInformation.FileName
};
fileDescription.Path = CreateFilePath(parentIoc.Path, fileDescription.DisplayName);
fileDescription.LastModified = fileDirectoryInformation.LastWriteTime;
fileDescription.SizeInBytes = fileDirectoryInformation.EndOfFile;
return fileDescription;
}
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
SmbConnectionInfo info = new SmbConnectionInfo(ioc);
if (string.IsNullOrEmpty(info.Share))
{
return new FileDescription
{
CanRead = true, CanWrite = true,
DisplayName = info.Host,
IsDirectory = true,
Path = info.ToPath()
};
}
using SmbConnection conn = new SmbConnection(info);
NTStatus status = conn.FileStore!.CreateFile(out var directoryHandle, out _, info.GetParent().GetLocalSmbPath(), AccessMask.GENERIC_READ, FileAttributes.Directory, ShareAccess.Read | ShareAccess.Write, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null);
if (status != NTStatus.STATUS_SUCCESS) throw new Exception($"Failed to query details for {info.LocalPath}");
conn.FileStore.QueryDirectory(out List<QueryDirectoryFileInformation> fileList, directoryHandle, info.Stem(), FileInformationClass.FileDirectoryInformation);
foreach (var fi in fileList)
{
var fileDirectoryInformation = fi as FileDirectoryInformation;
if (fileDirectoryInformation == null)
continue;
if (fileDirectoryInformation.FileName is "." or "..")
continue;
return FileDescriptionConvert(ioc, fileDirectoryInformation);
}
conn.FileStore.CloseFile(directoryHandle);
throw new Exception($"Failed to query details for {info.LocalPath}");
}
public bool RequiresSetup(IOConnectionInfo ioConnection)
{
return false;
}
public string IocToPath(IOConnectionInfo ioc)
{
return ioc.Path;
}
public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId)
{
activity.PerformManualFileSelect(isForSave, requestCode, protocolId);
}
public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode,
bool alwaysReturnSuccess)
{
Intent intent = new Intent();
activity.IocToIntent(intent, ioc);
activity.OnImmediateResult(requestCode, (int)FileStorageResults.FileUsagePrepared, intent);
}
public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc)
{
}
public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
{
}
public void OnResume(IFileStorageSetupActivity activity)
{
}
public void OnStart(IFileStorageSetupActivity activity)
{
}
public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
{
}
public string GetDisplayName(IOConnectionInfo ioc)
{
return new SmbConnectionInfo(ioc).ToDisplayString();
}
public string CreateFilePath(string parent, string newFilename)
{
return new SmbConnectionInfo(new IOConnectionInfo() { Path = parent}).GetChild(newFilename).ToPath();
}
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
{
SmbConnectionInfo connectionInfo = new SmbConnectionInfo(ioc);
return new IOConnectionInfo() { Path = connectionInfo.GetParent().ToPath() };
}
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
{
return new IOConnectionInfo() { Path = CreateFilePath(folderPath.Path, filename)};
}
public bool IsPermanentLocation(IOConnectionInfo ioc)
{
return true;
}
public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null)
{
return false;
}
}
}
#endif

View File

@@ -6,10 +6,12 @@ using System.Text;
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.OS; using Android.OS;
using Android.Preferences;
using Android.Runtime; using Android.Runtime;
using Android.Views; using Android.Views;
using Android.Widget; using Android.Widget;
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE #if !NoNet && !EXCLUDE_JAVAFILESTORAGE
using Keepass2android.Javafilestorage; using Keepass2android.Javafilestorage;
#endif #endif
using KeePassLib.Serialization; using KeePassLib.Serialization;
@@ -19,8 +21,14 @@ namespace keepass2android.Io
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE #if !NoNet && !EXCLUDE_JAVAFILESTORAGE
public class WebDavFileStorage: JavaFileStorage public class WebDavFileStorage: JavaFileStorage
{ {
public WebDavFileStorage(IKp2aApp app) : base(new Keepass2android.Javafilestorage.WebDavStorage(app.CertificateErrorHandler), app) private readonly IKp2aApp _app;
private readonly WebDavStorage baseWebdavStorage;
public WebDavFileStorage(IKp2aApp app, int chunkSize) : base(new Keepass2android.Javafilestorage.WebDavStorage(app.CertificateErrorHandler, chunkSize), app)
{ {
_app = app;
baseWebdavStorage = (WebDavStorage)Jfs;
} }
public override IEnumerable<string> SupportedProtocols public override IEnumerable<string> SupportedProtocols
@@ -75,6 +83,15 @@ namespace keepass2android.Io
} }
return base.IocToPath(ioc); return base.IocToPath(ioc);
} }
public override IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
{
baseWebdavStorage.SetUploadChunkSize(_app.WebDavChunkedUploadSize);
return base.OpenWriteTransaction(ioc, useFileTransaction);
} }
}
#endif #endif
} }

View File

@@ -1,33 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<DefineConstants Condition="'$(Flavor)'=='NoNet'">NO_QR_SCANNER;EXCLUDE_JAVAFILESTORAGE;NoNet</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Resources\" /> <Folder Include="Resources\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentFTP" Version="51.1.0" /> <PackageReference Include="FluentFTP" Version="52.1.0" Condition="'$(Flavor)'!='NoNet'" />
<PackageReference Include="MegaApiClient" Version="1.10.4" /> <PackageReference Include="MegaApiClient" Version="1.10.4" Condition="'$(Flavor)'!='NoNet'" />
<PackageReference Include="Microsoft.Graph" Version="5.68.0" /> <PackageReference Include="Microsoft.Graph" Version="5.68.0" Condition="'$(Flavor)'!='NoNet'" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.67.1" /> <PackageReference Include="Microsoft.Identity.Client" Version="4.67.1" Condition="'$(Flavor)'!='NoNet'" />
<PackageReference Include="SMBLibrary" Version="1.5.4" Condition="'$(Flavor)'!='NoNet'" />
<PackageReference Include="Xamarin.AndroidX.Browser" Version="1.8.0" /> <PackageReference Include="Xamarin.AndroidX.Browser" Version="1.8.0" />
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.13.1.5" /> <PackageReference Include="Xamarin.AndroidX.Core" Version="1.13.1.5" />
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.11.0.3" /> <PackageReference Include="Xamarin.Google.Android.Material" Version="1.11.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\AndroidFileChooserBinding\AndroidFileChooserBinding.csproj" /> <ProjectReference Include="..\AndroidFileChooserBinding\AndroidFileChooserBinding.csproj" />
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj" /> <ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj" Condition="'$(Flavor)'!='NoNet'" />
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj" /> <ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj" />
<ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj" /> <ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj" />
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj" /> <ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Remove="Io/DropboxFileStorageKeysDummy.cs" />
<Compile Remove="Io/DropboxFileStorageKeysDummy.cs" /> </ItemGroup>
<Content Remove="Io/DropboxFileStorageKeysDummy.cs" /> <ItemGroup Condition="'$(Flavor)'=='NoNet'">
<None Remove="Io/OneDrive2FileStorage.cs" />
<Compile Remove="Io/OneDrive2FileStorage.cs" />
<Content Remove="Io/OneDrive2FileStorage.cs" />
<None Remove="Io/MegaFileStorage.cs" />
<Compile Remove="Io/MegaFileStorage.cs" />
<Content Remove="Io/MegaFileStorage.cs" />
</ItemGroup> </ItemGroup>
<Import Project="Io/GenerateSecrets.targets" />
<ItemGroup>
<Compile Include="Io/DropboxFileStorage.g.cs" />
</ItemGroup>
</Project> </Project>

View File

@@ -11,6 +11,9 @@ namespace KeePass.Util
{ {
public static string GetErrorMessage(Exception e) public static string GetErrorMessage(Exception e)
{
try
{ {
string errorMessage = e.Message; string errorMessage = e.Message;
if (e is Java.Lang.Exception javaException) if (e is Java.Lang.Exception javaException)
@@ -20,6 +23,11 @@ namespace KeePass.Util
return errorMessage; return errorMessage;
} }
catch
{
return "";
}
}
} }
} }

View File

@@ -90,8 +90,11 @@ namespace keepass2android
PwDatabase pwDatabase = new PwDatabase(); PwDatabase pwDatabase = new PwDatabase();
IFileStorage fileStorage = _app.GetFileStorage(iocInfo); IFileStorage fileStorage = _app.GetFileStorage(iocInfo);
Kp2aLog.Log("LoadData: Retrieving stream");
Stream s = databaseData ?? fileStorage.OpenFileForRead(iocInfo); Stream s = databaseData ?? fileStorage.OpenFileForRead(iocInfo);
Kp2aLog.Log("LoadData: GetCurrentFileVersion");
var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo);
Kp2aLog.Log("LoadData: PopulateDatabaseFromStream");
PopulateDatabaseFromStream(pwDatabase, s, iocInfo, compositeKey, status, databaseFormat); PopulateDatabaseFromStream(pwDatabase, s, iocInfo, compositeKey, status, databaseFormat);
LastFileVersion = fileVersion; LastFileVersion = fileVersion;

View File

@@ -138,6 +138,7 @@ namespace keepass2android
Database TryLoad(MemoryStream databaseStream) Database TryLoad(MemoryStream databaseStream)
{ {
Kp2aLog.Log("LoadDb: Copying database in memory");
//create a copy of the stream so we can try again if we get an exception which indicates we should change parameters //create a copy of the stream so we can try again if we get an exception which indicates we should change parameters
//This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors. //This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors.
//Alternatives would involve increased traffic (if file is on remote) and slower loading times, so this seems to be the best choice. //Alternatives would involve increased traffic (if file is on remote) and slower loading times, so this seems to be the best choice.
@@ -146,6 +147,7 @@ namespace keepass2android
workingCopy.Seek(0, SeekOrigin.Begin); workingCopy.Seek(0, SeekOrigin.Begin);
//reset stream if we need to reuse it later: //reset stream if we need to reuse it later:
databaseStream.Seek(0, SeekOrigin.Begin); databaseStream.Seek(0, SeekOrigin.Begin);
Kp2aLog.Log("LoadDb: Ready to start loading");
//now let's go: //now let's go:
try try
{ {

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework> <TargetFramework>net9.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>

View File

@@ -20,7 +20,6 @@ git clone --recurse-submodules https://github.com/PhilippC/keepass2android.git
cd keepass2android/src/build-scripts cd keepass2android/src/build-scripts
./build-java.sh && ./build-native.sh ./build-java.sh && ./build-native.sh
cd .. cd ..
cp Kp2aBusinessLogic/Io/DropboxFileStorageKeysDummy.cs Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs
cd keepass2android-app cd keepass2android-app
ln -s Manifests/AndroidManifest_debug.xml AndroidManifest.xml ln -s Manifests/AndroidManifest_debug.xml AndroidManifest.xml
dotnet workload restore dotnet workload restore

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
BASE_DIR="${1}"
for arch_dir in "$BASE_DIR"/android-*/; do
arch=$(basename "$arch_dir")
arch=${arch#android-}
APK_DIR="${arch_dir}publish"
if [[ -d "$APK_DIR" ]]; then
apk_path=$(find "$APK_DIR" -maxdepth 1 -type f -name "*.apk" | head -n1)
if [[ -n "$apk_path" ]]; then
base=$(basename "$apk_path" .apk)
new_path="$APK_DIR/${base}-${arch}.apk"
mv "$apk_path" "$new_path"
echo "Renamed $apk_path to $new_path"
else
echo "No APK found in $APK_DIR"
fi
else
echo "Directory $APK_DIR does not exist"
fi
done

View File

@@ -6,8 +6,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 35
compileSdk 34 compileSdk 35
} }
buildTypes { buildTypes {
release { release {
@@ -51,4 +51,6 @@ dependencies {
implementation 'com.pcloud.sdk:android:1.9.1' implementation 'com.pcloud.sdk:android:1.9.1'
implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.github.mwiede:jsch:2.27.2'
} }

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2011 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface AgentConnector {
String getName();
boolean isAvailable();
void query(Buffer buffer) throws AgentProxyException;
}

View File

@@ -1,80 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2011 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class AgentIdentity implements Identity {
private AgentProxy agent;
private byte[] blob;
private String comment;
private String algname;
AgentIdentity(AgentProxy agent, byte[] blob, String comment) {
this.agent = agent;
this.blob = blob;
this.comment = comment;
algname = Util.byte2str((new Buffer(blob)).getString());
}
@Override
public boolean setPassphrase(byte[] passphrase) throws JSchException{
return true;
}
@Override
public byte[] getPublicKeyBlob() { return blob; }
@Override
public byte[] getSignature(byte[] data){
return agent.sign(blob, data, null);
}
@Override
public byte[] getSignature(byte[] data, String alg){
return agent.sign(blob, data, alg);
}
@Override
@Deprecated
public boolean decrypt() {
throw new RuntimeException("not implemented");
}
@Override
public String getAlgName() { return algname; }
@Override
public String getName() { return comment; }
@Override
public boolean isEncrypted() { return false; }
@Override
public void clear() { }
}

View File

@@ -1,75 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2011 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.util.Vector;
public class AgentIdentityRepository implements IdentityRepository {
private AgentProxy agent;
public AgentIdentityRepository(AgentConnector connector) {
this.agent = new AgentProxy(connector);
}
@Override
public Vector<Identity> getIdentities() {
return agent.getIdentities();
}
@Override
public boolean add(byte[] identity) {
return agent.addIdentity(identity);
}
@Override
public boolean remove(byte[] blob) {
return agent.removeIdentity(blob);
}
@Override
public void removeAll() {
agent.removeAllIdentities();
}
@Override
public String getName() {
return agent.getConnector().getName();
}
@Override
public int getStatus() {
if(agent.getConnector().isAvailable()){
return RUNNING;
}
else {
return NOTRUNNING;
}
}
}

View File

@@ -1,256 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2012 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.util.Vector;
class AgentProxy {
private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
private static final byte SSH_AGENTC_RSA_CHALLENGE = 3;
private static final byte SSH_AGENT_RSA_RESPONSE = 4;
private static final byte SSH_AGENT_FAILURE = 5;
private static final byte SSH_AGENT_SUCCESS = 6;
private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11;
private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12;
private static final byte SSH2_AGENTC_SIGN_REQUEST = 13;
private static final byte SSH2_AGENT_SIGN_RESPONSE = 14;
private static final byte SSH2_AGENTC_ADD_IDENTITY = 17;
private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18;
private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20;
private static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21;
private static final byte SSH_AGENTC_LOCK = 22;
private static final byte SSH_AGENTC_UNLOCK = 23;
private static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24;
private static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25;
private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26;
private static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1;
private static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2;
private static final byte SSH2_AGENT_FAILURE = 30;
private static final byte SSH_COM_AGENT2_FAILURE = 102;
//private static final byte SSH_AGENT_OLD_SIGNATURE = 0x1;
private static final int SSH_AGENT_RSA_SHA2_256 = 0x2;
private static final int SSH_AGENT_RSA_SHA2_512 = 0x4;
private static final int MAX_AGENT_IDENTITIES = 2048;
private final byte[] buf = new byte[1024];
private final Buffer buffer = new Buffer(buf);
private AgentConnector connector;
AgentProxy(AgentConnector connector){
this.connector = connector;
}
synchronized Vector<Identity> getIdentities() {
Vector<Identity> identities = new Vector<>();
int required_size = 1 + 4;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES);
try {
connector.query(buffer);
}
catch(AgentProxyException e){
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
return identities;
}
int rcode = buffer.getByte();
//System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER);
if(rcode != SSH2_AGENT_IDENTITIES_ANSWER) {
return identities;
}
int count = buffer.getInt();
//System.out.println(count);
if(count <= 0 || count > MAX_AGENT_IDENTITIES) {
return identities;
}
for(int i=0; i<count; i++){
byte[] blob = buffer.getString();
String comment = Util.byte2str(buffer.getString());
identities.add(new AgentIdentity(this, blob, comment));
}
return identities;
}
synchronized byte[] sign(byte[] blob, byte[] data, String alg) {
int flags = 0x0;
if(alg != null) {
if(alg.equals("rsa-sha2-256")) {
flags = SSH_AGENT_RSA_SHA2_256;
}
else if(alg.equals("rsa-sha2-512")) {
flags = SSH_AGENT_RSA_SHA2_512;
}
}
int required_size = 1 + 4*4 + blob.length + data.length;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_SIGN_REQUEST);
buffer.putString(blob);
buffer.putString(data);
buffer.putInt(flags);
try {
connector.query(buffer);
}
catch(AgentProxyException e){
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
int rcode = buffer.getByte();
//System.out.println(rcode == SSH2_AGENT_SIGN_RESPONSE);
if(rcode != SSH2_AGENT_SIGN_RESPONSE) {
return null;
}
return buffer.getString();
}
synchronized boolean removeIdentity(byte[] blob) {
int required_size = 1 + 4*2 + blob.length;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REMOVE_IDENTITY);
buffer.putString(blob);
try {
connector.query(buffer);
}
catch(AgentProxyException e){
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
int rcode = buffer.getByte();
//System.out.println(rcode == SSH_AGENT_SUCCESS);
return rcode == SSH_AGENT_SUCCESS;
}
synchronized void removeAllIdentities() {
int required_size = 1 + 4;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
try {
connector.query(buffer);
}
catch(AgentProxyException e){
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
//int rcode = buffer.getByte();
//System.out.println(rcode == SSH_AGENT_SUCCESS);
}
synchronized boolean addIdentity(byte[] identity) {
int required_size = 1 + 4 + identity.length;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_ADD_IDENTITY);
buffer.putByte(identity);
try {
connector.query(buffer);
}
catch(AgentProxyException e){
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
int rcode = buffer.getByte();
//System.out.println(rcode == SSH_AGENT_SUCCESS);
return rcode == SSH_AGENT_SUCCESS;
}
synchronized boolean isRunning(){
int required_size = 1 + 4;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES);
try {
connector.query(buffer);
}
catch(AgentProxyException e){
return false;
}
int rcode = buffer.getByte();
//System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER);
return rcode == SSH2_AGENT_IDENTITIES_ANSWER;
}
synchronized AgentConnector getConnector() {
return connector;
}
}

View File

@@ -1,40 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2011 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class AgentProxyException extends Exception {
private static final long serialVersionUID=-1L;
public AgentProxyException(String message){
super(message);
}
public AgentProxyException(String message, Throwable e){
super(message, e);
}
}

View File

@@ -1,297 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class Buffer{
final byte[] tmp=new byte[4];
byte[] buffer;
int index;
int s;
public Buffer(int size){
buffer=new byte[size];
index=0;
s=0;
}
public Buffer(byte[] buffer){
this.buffer=buffer;
index=0;
s=0;
}
public Buffer(){ this(1024*10*2); }
public void putByte(byte foo){
buffer[index++]=foo;
}
public void putByte(byte[] foo) {
putByte(foo, 0, foo.length);
}
public void putByte(byte[] foo, int begin, int length) {
System.arraycopy(foo, begin, buffer, index, length);
index+=length;
}
public void putString(byte[] foo){
putString(foo, 0, foo.length);
}
public void putString(byte[] foo, int begin, int length) {
putInt(length);
putByte(foo, begin, length);
}
public void putInt(int val) {
tmp[0]=(byte)(val >>> 24);
tmp[1]=(byte)(val >>> 16);
tmp[2]=(byte)(val >>> 8);
tmp[3]=(byte)(val);
System.arraycopy(tmp, 0, buffer, index, 4);
index+=4;
}
public void putLong(long val) {
tmp[0]=(byte)(val >>> 56);
tmp[1]=(byte)(val >>> 48);
tmp[2]=(byte)(val >>> 40);
tmp[3]=(byte)(val >>> 32);
System.arraycopy(tmp, 0, buffer, index, 4);
tmp[0]=(byte)(val >>> 24);
tmp[1]=(byte)(val >>> 16);
tmp[2]=(byte)(val >>> 8);
tmp[3]=(byte)(val);
System.arraycopy(tmp, 0, buffer, index+4, 4);
index+=8;
}
void skip(int n) {
index+=n;
}
void putPad(int n) {
while(n>0){
buffer[index++]=(byte)0;
n--;
}
}
public void putMPInt(byte[] foo){
int i=foo.length;
if((foo[0]&0x80)!=0){
i++;
putInt(i);
putByte((byte)0);
}
else{
putInt(i);
}
putByte(foo);
}
public int getLength(){
return index-s;
}
public int getOffSet(){
return s;
}
public void setOffSet(int s){
this.s=s;
}
public long getLong(){
long foo = getInt()&0xffffffffL;
foo = ((foo<<32)) | (getInt()&0xffffffffL);
return foo;
}
public int getInt(){
int foo = getShort();
foo = ((foo<<16)&0xffff0000) | (getShort()&0xffff);
return foo;
}
public long getUInt(){
long foo = 0L;
long bar = 0L;
foo = getByte();
foo = ((foo<<8)&0xff00)|(getByte()&0xff);
bar = getByte();
bar = ((bar<<8)&0xff00)|(getByte()&0xff);
foo = ((foo<<16)&0xffff0000) | (bar&0xffff);
return foo;
}
int getShort() {
int foo = getByte();
foo = ((foo<<8)&0xff00)|(getByte()&0xff);
return foo;
}
public int getByte() {
return (buffer[s++]&0xff);
}
public void getByte(byte[] foo) {
getByte(foo, 0, foo.length);
}
void getByte(byte[] foo, int start, int len) {
System.arraycopy(buffer, s, foo, start, len);
s+=len;
}
public int getByte(int len) {
int foo=s;
s+=len;
return foo;
}
public byte[] getMPInt() {
int i=getInt(); // uint32
if(i<0 || // bigger than 0x7fffffff
i>8*1024){
// TODO: an exception should be thrown.
i = 8*1024; // the session will be broken, but working around OOME.
}
byte[] foo=new byte[i];
getByte(foo, 0, i);
return foo;
}
public byte[] getMPIntBits() {
int bits=getInt();
int bytes=(bits+7)/8;
byte[] foo=new byte[bytes];
getByte(foo, 0, bytes);
if((foo[0]&0x80)!=0){
byte[] bar=new byte[foo.length+1];
bar[0]=0; // ??
System.arraycopy(foo, 0, bar, 1, foo.length);
foo=bar;
}
return foo;
}
public byte[] getString() {
int i = getInt(); // uint32
if(i<0 || // bigger than 0x7fffffff
i>256*1024){
// TODO: an exception should be thrown.
i = 256*1024; // the session will be broken, but working around OOME.
}
byte[] foo=new byte[i];
getByte(foo, 0, i);
return foo;
}
byte[] getString(int[]start, int[]len) {
int i=getInt();
start[0]=getByte(i);
len[0]=i;
return buffer;
}
public void reset(){
index=0;
s=0;
}
public void shift(){
if(s==0)return;
System.arraycopy(buffer, s, buffer, 0, index-s);
index=index-s;
s=0;
}
void rewind(){
s=0;
}
byte getCommand(){
return buffer[5];
}
void checkFreeSize(int n){
int size = index+n+Session.buffer_margin;
if(buffer.length<size){
int i = buffer.length*2;
if(i<size) i = size;
byte[] tmp = new byte[i];
System.arraycopy(buffer, 0, tmp, 0, index);
buffer = tmp;
}
}
byte[][] getBytes(int n, String msg) throws JSchException {
byte[][] tmp = new byte[n][];
for(int i = 0; i < n; i++){
int j = getInt();
if(getLength() < j){
throw new JSchException(msg);
}
tmp[i] = new byte[j];
getByte(tmp[i]);
}
return tmp;
}
/*
static Buffer fromBytes(byte[]... args){
int length = args.length*4;
for(int i = 0; i < args.length; i++){
length += args[i].length;
}
Buffer buf = new Buffer(length);
for(int i = 0; i < args.length; i++){
buf.putString(args[i]);
}
return buf;
}
*/
static Buffer fromBytes(byte[][] args){
int length = args.length*4;
for(int i = 0; i < args.length; i++){
length += args[i].length;
}
Buffer buf = new Buffer(length);
for(int i = 0; i < args.length; i++){
buf.putString(args[i]);
}
return buf;
}
/*
static String[] chars={
"0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f"
};
static void dump_buffer(){
int foo;
for(int i=0; i<tmp_buffer_index; i++){
foo=tmp_buffer[i]&0xff;
System.err.print(chars[(foo>>>4)&0xf]);
System.err.print(chars[foo&0xf]);
if(i%16==15){
System.err.println("");
continue;
}
if(i>0 && i%2==1){
System.err.print(" ");
}
}
System.err.println("");
}
static void dump(byte[] b){
dump(b, 0, b.length);
}
static void dump(byte[] b, int s, int l){
for(int i=s; i<s+l; i++){
System.err.print(Integer.toHexString(b[i]&0xff)+":");
}
System.err.println("");
}
*/
}

View File

@@ -1,782 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.*;
import java.util.Vector;
public abstract class Channel{
static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION= 91;
static final int SSH_MSG_CHANNEL_OPEN_FAILURE= 92;
static final int SSH_MSG_CHANNEL_WINDOW_ADJUST= 93;
static final int SSH_OPEN_ADMINISTRATIVELY_PROHIBITED= 1;
static final int SSH_OPEN_CONNECT_FAILED= 2;
static final int SSH_OPEN_UNKNOWN_CHANNEL_TYPE= 3;
static final int SSH_OPEN_RESOURCE_SHORTAGE= 4;
static int index=0;
private static Vector<Channel> pool=new Vector<>();
static Channel getChannel(String type, Session session){
Channel ret = null;
if(type.equals("session")){
ret = new ChannelSession();
}
if(type.equals("shell")){
ret = new ChannelShell();
}
if(type.equals("exec")){
ret = new ChannelExec();
}
if(type.equals("x11")){
ret = new ChannelX11();
}
if(type.equals("auth-agent@openssh.com")){
ret = new ChannelAgentForwarding();
}
if(type.equals("direct-tcpip")){
ret = new ChannelDirectTCPIP();
}
if(type.equals("forwarded-tcpip")){
ret = new ChannelForwardedTCPIP();
}
if(type.equals("sftp")){
ret = new ChannelSftp();
}
if(type.equals("subsystem")){
ret = new ChannelSubsystem();
}
if(type.equals("direct-streamlocal@openssh.com")){
ret = new ChannelDirectStreamLocal();
}
if (ret == null) {
return null;
}
ret.setSession(session);
return ret;
}
static Channel getChannel(int id, Session session){
synchronized(pool){
for(int i=0; i<pool.size(); i++){
Channel c=pool.elementAt(i);
if(c.id==id && c.session==session) return c;
}
}
return null;
}
static void del(Channel c){
synchronized(pool){
pool.removeElement(c);
}
}
int id;
volatile int recipient=-1;
protected byte[] type=Util.str2byte("foo");
volatile int lwsize_max=0x100000;
volatile int lwsize=lwsize_max; // local initial window size
volatile int lmpsize=0x4000; // local maximum packet size
volatile long rwsize=0; // remote initial window size
volatile int rmpsize=0; // remote maximum packet size
IO io=null;
Thread thread=null;
volatile boolean eof_local=false;
volatile boolean eof_remote=false;
volatile boolean close=false;
volatile boolean connected=false;
volatile boolean open_confirmation=false;
volatile int exitstatus=-1;
volatile int reply=0;
volatile int connectTimeout=0;
protected Session session;
int notifyme=0;
Channel(){
synchronized(pool){
id=index++;
pool.addElement(this);
}
}
synchronized void setRecipient(int foo){
this.recipient=foo;
if(notifyme>0)
notifyAll();
}
int getRecipient(){
return recipient;
}
void init() throws JSchException {
}
public void connect() throws JSchException{
connect(0);
}
public void connect(int connectTimeout) throws JSchException{
this.connectTimeout=connectTimeout;
try{
sendChannelOpen();
start();
}
catch(Exception e){
connected=false;
disconnect();
if(e instanceof JSchException)
throw (JSchException)e;
throw new JSchException(e.toString(), e);
}
}
public void setXForwarding(boolean foo){
}
public void start() throws JSchException{}
public boolean isEOF() {return eof_remote;}
void getData(Buffer buf){
setRecipient(buf.getInt());
setRemoteWindowSize(buf.getUInt());
setRemotePacketSize(buf.getInt());
}
public void setInputStream(InputStream in){
io.setInputStream(in, false);
}
public void setInputStream(InputStream in, boolean dontclose){
io.setInputStream(in, dontclose);
}
public void setOutputStream(OutputStream out){
io.setOutputStream(out, false);
}
public void setOutputStream(OutputStream out, boolean dontclose){
io.setOutputStream(out, dontclose);
}
public void setExtOutputStream(OutputStream out){
io.setExtOutputStream(out, false);
}
public void setExtOutputStream(OutputStream out, boolean dontclose){
io.setExtOutputStream(out, dontclose);
}
public InputStream getInputStream() throws IOException {
int max_input_buffer_size = 32*1024;
try {
max_input_buffer_size =
Integer.parseInt(getSession().getConfig("max_input_buffer_size"));
}
catch(Exception e){}
PipedInputStream in =
new MyPipedInputStream(
32*1024, // this value should be customizable.
max_input_buffer_size
);
boolean resizable = 32*1024<max_input_buffer_size;
io.setOutputStream(new PassiveOutputStream(in, resizable), false);
return in;
}
public InputStream getExtInputStream() throws IOException {
int max_input_buffer_size = 32*1024;
try {
max_input_buffer_size =
Integer.parseInt(getSession().getConfig("max_input_buffer_size"));
}
catch(Exception e){}
PipedInputStream in =
new MyPipedInputStream(
32*1024, // this value should be customizable.
max_input_buffer_size
);
boolean resizable = 32*1024<max_input_buffer_size;
io.setExtOutputStream(new PassiveOutputStream(in, resizable), false);
return in;
}
public OutputStream getOutputStream() throws IOException {
final Channel channel=this;
OutputStream out=new OutputStream(){
private int dataLen=0;
private Buffer buffer=null;
private Packet packet=null;
private boolean closed=false;
private synchronized void init() throws IOException{
buffer=new Buffer(rmpsize);
packet=new Packet(buffer);
byte[] _buf=buffer.buffer;
if(_buf.length-(14+0)-Session.buffer_margin<=0){
buffer=null;
packet=null;
throw new IOException("failed to initialize the channel.");
}
}
byte[] b=new byte[1];
@Override
public void write(int w) throws IOException{
b[0]=(byte)w;
write(b, 0, 1);
}
@Override
public void write(byte[] buf, int s, int l) throws IOException{
if(packet==null){
init();
}
if(closed){
throw new IOException("Already closed");
}
byte[] _buf=buffer.buffer;
int _bufl=_buf.length;
while(l>0){
int _l=l;
if(l>_bufl-(14+dataLen)-Session.buffer_margin){
_l=_bufl-(14+dataLen)-Session.buffer_margin;
}
if(_l<=0){
flush();
continue;
}
System.arraycopy(buf, s, _buf, 14+dataLen, _l);
dataLen+=_l;
s+=_l;
l-=_l;
}
}
@Override
public void flush() throws IOException{
if(closed){
throw new IOException("Already closed");
}
if(dataLen==0)
return;
packet.reset();
buffer.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buffer.putInt(recipient);
buffer.putInt(dataLen);
buffer.skip(dataLen);
try{
int foo=dataLen;
dataLen=0;
synchronized(channel){
if(!channel.close)
getSession().write(packet, channel, foo);
}
}
catch(Exception e){
close();
throw new IOException(e.toString(), e);
}
}
@Override
public void close() throws IOException{
if(packet==null){
try{
init();
}
catch(IOException e){
// close should be finished silently.
return;
}
}
if(closed){
return;
}
if(dataLen>0){
flush();
}
channel.eof();
closed=true;
}
};
return out;
}
static class MyPipedInputStream extends PipedInputStream{
private int BUFFER_SIZE = 1024;
private int max_buffer_size = BUFFER_SIZE;
MyPipedInputStream() throws IOException{ super(); }
MyPipedInputStream(int size) throws IOException{
super();
buffer=new byte[size];
BUFFER_SIZE = size;
max_buffer_size = size;
}
MyPipedInputStream(int size, int max_buffer_size) throws IOException{
this(size);
this.max_buffer_size = max_buffer_size;
}
MyPipedInputStream(PipedOutputStream out) throws IOException{ super(out); }
MyPipedInputStream(PipedOutputStream out, int size) throws IOException{
super(out);
buffer=new byte[size];
BUFFER_SIZE=size;
}
/*
* TODO: We should have our own Piped[I/O]Stream implementation.
* Before accepting data, JDK's PipedInputStream will check the existence of
* reader thread, and if it is not alive, the stream will be closed.
* That behavior may cause the problem if multiple threads make access to it.
*/
public synchronized void updateReadSide() throws IOException {
if(available() != 0){ // not empty
return;
}
in = 0;
out = 0;
buffer[in++] = 0;
read();
}
private int freeSpace(){
int size = 0;
if(out < in) {
size = buffer.length-in;
}
else if(in < out){
if(in == -1) size = buffer.length;
else size = out - in;
}
return size;
}
synchronized void checkSpace(int len) throws IOException {
int size = freeSpace();
if(size<len){
int datasize=buffer.length-size;
int foo = buffer.length;
while((foo - datasize) < len){
foo*=2;
}
if(foo > max_buffer_size){
foo = max_buffer_size;
}
if((foo - datasize) < len) return;
byte[] tmp = new byte[foo];
if(out < in) {
System.arraycopy(buffer, 0, tmp, 0, buffer.length);
}
else if(in < out){
if(in == -1) {
}
else {
System.arraycopy(buffer, 0, tmp, 0, in);
System.arraycopy(buffer, out,
tmp, tmp.length-(buffer.length-out),
(buffer.length-out));
out = tmp.length-(buffer.length-out);
}
}
else if(in == out){
System.arraycopy(buffer, 0, tmp, 0, buffer.length);
in=buffer.length;
}
buffer=tmp;
}
else if(buffer.length == size && size > BUFFER_SIZE) {
int i = size/2;
if(i<BUFFER_SIZE) i = BUFFER_SIZE;
byte[] tmp = new byte[i];
buffer=tmp;
}
}
}
void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; }
void setLocalWindowSize(int foo){ this.lwsize=foo; }
void setLocalPacketSize(int foo){ this.lmpsize=foo; }
synchronized void setRemoteWindowSize(long foo){ this.rwsize=foo; }
synchronized void addRemoteWindowSize(long foo){
this.rwsize+=foo;
if(notifyme>0)
notifyAll();
}
void setRemotePacketSize(int foo){ this.rmpsize=foo; }
abstract void run();
void write(byte[] foo) throws IOException {
write(foo, 0, foo.length);
}
void write(byte[] foo, int s, int l) throws IOException {
try{
io.put(foo, s, l);
}catch(NullPointerException e){}
}
void write_ext(byte[] foo, int s, int l) throws IOException {
try{
io.put_ext(foo, s, l);
}catch(NullPointerException e){}
}
void eof_remote(){
eof_remote=true;
try{
io.out_close();
}
catch(NullPointerException e){}
}
void eof(){
if(eof_local)return;
eof_local=true;
int i = getRecipient();
if(i == -1) return;
try{
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
buf.putInt(i);
synchronized(this){
if(!close)
getSession().write(packet);
}
}
catch(Exception e){
//System.err.println("Channel.eof");
//e.printStackTrace();
}
/*
if(!isConnected()){ disconnect(); }
*/
}
/*
http://www1.ietf.org/internet-drafts/draft-ietf-secsh-connect-24.txt
5.3 Closing a Channel
When a party will no longer send more data to a channel, it SHOULD
send SSH_MSG_CHANNEL_EOF.
byte SSH_MSG_CHANNEL_EOF
uint32 recipient_channel
No explicit response is sent to this message. However, the
application may send EOF to whatever is at the other end of the
channel. Note that the channel remains open after this message, and
more data may still be sent in the other direction. This message
does not consume window space and can be sent even if no window space
is available.
When either party wishes to terminate the channel, it sends
SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
message for the channel. The channel is considered closed for a
party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
the party may then reuse the channel number. A party MAY send
SSH_MSG_CHANNEL_CLOSE without having sent or received
SSH_MSG_CHANNEL_EOF.
byte SSH_MSG_CHANNEL_CLOSE
uint32 recipient_channel
This message does not consume window space and can be sent even if no
window space is available.
It is recommended that any data sent before this message is delivered
to the actual destination, if possible.
*/
void close(){
if(close)return;
close=true;
eof_local=eof_remote=true;
int i = getRecipient();
if(i == -1) return;
try{
Buffer buf=new Buffer(100);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
buf.putInt(i);
synchronized(this){
getSession().write(packet);
}
}
catch(Exception e){
//e.printStackTrace();
}
}
public boolean isClosed(){
return close;
}
static void disconnect(Session session){
Channel[] channels=null;
int count=0;
synchronized(pool){
channels=new Channel[pool.size()];
for(int i=0; i<pool.size(); i++){
try{
Channel c=pool.elementAt(i);
if(c.session==session){
channels[count++]=c;
}
}
catch(Exception e){
}
}
}
for(int i=0; i<count; i++){
channels[i].disconnect();
}
}
public void disconnect(){
//System.err.println(this+":disconnect "+io+" "+connected);
//Thread.dumpStack();
try{
synchronized(this){
if(!connected){
return;
}
connected=false;
}
close();
eof_remote=eof_local=true;
thread=null;
try{
if(io!=null){
io.close();
}
}
catch(Exception e){
//e.printStackTrace();
}
// io=null;
}
finally{
Channel.del(this);
}
}
public boolean isConnected(){
Session _session=this.session;
if(_session!=null){
return _session.isConnected() && connected;
}
return false;
}
public void sendSignal(String signal) throws Exception {
RequestSignal request=new RequestSignal();
request.setSignal(signal);
request.request(getSession(), this);
}
// public String toString(){
// return "Channel: type="+new String(type)+",id="+id+",recipient="+recipient+",window_size="+window_size+",packet_size="+packet_size;
// }
/*
class OutputThread extends Thread{
Channel c;
OutputThread(Channel c){ this.c=c;}
public void run(){c.output_thread();}
}
*/
static class PassiveInputStream extends MyPipedInputStream{
PipedOutputStream os;
PassiveInputStream(PipedOutputStream out, int size) throws IOException{
super(out, size);
this.os=out;
}
PassiveInputStream(PipedOutputStream out) throws IOException{
super(out);
this.os=out;
}
@Override
public void close() throws IOException{
if(this.os!=null){
this.os.close();
}
this.os=null;
}
}
static class PassiveOutputStream extends PipedOutputStream{
private MyPipedInputStream _sink=null;
PassiveOutputStream(PipedInputStream in,
boolean resizable_buffer) throws IOException{
super(in);
if(resizable_buffer && (in instanceof MyPipedInputStream)) {
this._sink=(MyPipedInputStream)in;
}
}
@Override
public void write(int b) throws IOException {
if(_sink != null) {
_sink.checkSpace(1);
}
super.write(b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
if(_sink != null) {
_sink.checkSpace(len);
}
super.write(b, off, len);
}
}
void setExitStatus(int status){ exitstatus=status; }
public int getExitStatus(){ return exitstatus; }
void setSession(Session session){
this.session=session;
}
public Session getSession() throws JSchException{
Session _session=session;
if(_session==null){
throw new JSchException("session is not available");
}
return _session;
}
public int getId(){ return id; }
protected void sendOpenConfirmation() throws Exception{
Buffer buf=new Buffer(200);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
buf.putInt(getRecipient());
buf.putInt(id);
buf.putInt(lwsize);
buf.putInt(lmpsize);
getSession().write(packet);
}
protected void sendOpenFailure(int reasoncode){
try{
Buffer buf=new Buffer(200);
Packet packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
buf.putInt(getRecipient());
buf.putInt(reasoncode);
buf.putString(Util.str2byte("open failed"));
buf.putString(Util.empty);
getSession().write(packet);
}
catch(Exception e){
}
}
protected Packet genChannelOpenPacket(){
Buffer buf=new Buffer(200);
Packet packet=new Packet(buf);
// byte SSH_MSG_CHANNEL_OPEN(90)
// string channel type //
// uint32 sender channel // 0
// uint32 initial window size // 0x100000(65536)
// uint32 maxmum packet size // 0x4000(16384)
packet.reset();
buf.putByte((byte)90);
buf.putString(this.type);
buf.putInt(this.id);
buf.putInt(this.lwsize);
buf.putInt(this.lmpsize);
return packet;
}
protected void sendChannelOpen() throws Exception {
Session _session=getSession();
if(!_session.isConnected()){
throw new JSchException("session is down");
}
Packet packet = genChannelOpenPacket();
_session.write(packet);
int retry=2000;
long start=System.currentTimeMillis();
long timeout=connectTimeout;
if(timeout!=0L) retry = 1;
synchronized(this){
while(this.getRecipient()==-1 &&
_session.isConnected() &&
retry>0){
if(timeout>0L){
if((System.currentTimeMillis()-start)>timeout){
retry=0;
continue;
}
}
try{
long t = timeout==0L ? 10L : timeout;
this.notifyme=1;
wait(t);
}
catch(InterruptedException e){
}
finally{
this.notifyme=0;
}
retry--;
}
}
if(!_session.isConnected()){
throw new JSchException("session is down");
}
if(this.getRecipient()==-1){ // timeout
throw new JSchException("channel is not opened.");
}
if(this.open_confirmation==false){ // SSH_MSG_CHANNEL_OPEN_FAILURE
throw new JSchException("channel is not opened.");
}
connected=true;
}
}

View File

@@ -1,287 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2006-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.net.*;
import java.util.Vector;
class ChannelAgentForwarding extends Channel{
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
static private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
static private final byte SSH_AGENTC_RSA_CHALLENGE = 3;
static private final byte SSH_AGENT_RSA_RESPONSE = 4;
static private final byte SSH_AGENT_FAILURE = 5;
static private final byte SSH_AGENT_SUCCESS = 6;
static private final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
static private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
static private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
static private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11;
static private final byte SSH2_AGENT_IDENTITIES_ANSWER=12;
static private final byte SSH2_AGENTC_SIGN_REQUEST=13;
static private final byte SSH2_AGENT_SIGN_RESPONSE=14;
static private final byte SSH2_AGENTC_ADD_IDENTITY=17;
static private final byte SSH2_AGENTC_REMOVE_IDENTITY=18;
static private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
static private final byte SSH2_AGENT_FAILURE=30;
//static private final int SSH_AGENT_OLD_SIGNATURE=0x1;
static private final int SSH_AGENT_RSA_SHA2_256=0x2;
static private final int SSH_AGENT_RSA_SHA2_512=0x4;
private Buffer rbuf=null;
private Buffer wbuf=null;
private Packet packet=null;
private Buffer mbuf=null;
ChannelAgentForwarding(){
super();
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
type=Util.str2byte("auth-agent@openssh.com");
rbuf=new Buffer();
rbuf.reset();
//wbuf=new Buffer(rmpsize);
//packet=new Packet(wbuf);
mbuf=new Buffer();
connected=true;
}
@Override
void run(){
try{
sendOpenConfirmation();
}
catch(Exception e){
close=true;
disconnect();
}
}
@Override
void write(byte[] foo, int s, int l) throws IOException {
if(packet==null){
wbuf=new Buffer(rmpsize);
packet=new Packet(wbuf);
}
rbuf.shift();
if(rbuf.buffer.length<rbuf.index+l){
byte[] newbuf=new byte[rbuf.s+l];
System.arraycopy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.length);
rbuf.buffer=newbuf;
}
rbuf.putByte(foo, s, l);
int mlen=rbuf.getInt();
if(mlen>rbuf.getLength()){
rbuf.s-=4;
return;
}
int typ=rbuf.getByte();
Session _session=null;
try{
_session=getSession();
}
catch(JSchException e){
throw new IOException(e.toString(), e);
}
IdentityRepository irepo = _session.getIdentityRepository();
UserInfo userinfo=_session.getUserInfo();
mbuf.reset();
if(typ==SSH2_AGENTC_REQUEST_IDENTITIES){
mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
Vector<Identity> identities = irepo.getIdentities();
synchronized(identities){
int count=0;
for(int i=0; i<identities.size(); i++){
Identity identity=identities.elementAt(i);
if(identity.getPublicKeyBlob()!=null)
count++;
}
mbuf.putInt(count);
for(int i=0; i<identities.size(); i++){
Identity identity=identities.elementAt(i);
byte[] pubkeyblob=identity.getPublicKeyBlob();
if(pubkeyblob==null)
continue;
mbuf.putString(pubkeyblob);
mbuf.putString(Util.empty);
}
}
}
else if(typ==SSH_AGENTC_REQUEST_RSA_IDENTITIES) {
mbuf.putByte(SSH_AGENT_RSA_IDENTITIES_ANSWER);
mbuf.putInt(0);
}
else if(typ==SSH2_AGENTC_SIGN_REQUEST){
byte[] blob=rbuf.getString();
byte[] data=rbuf.getString();
int flags=rbuf.getInt();
// if((flags & SSH_AGENT_OLD_SIGNATURE)!=0){ // old OpenSSH 2.0, 2.1
// datafellows = SSH_BUG_SIGBLOB;
// }
Vector<Identity> identities = irepo.getIdentities();
Identity identity = null;
synchronized(identities){
for(int i=0; i<identities.size(); i++){
Identity _identity=identities.elementAt(i);
if(_identity.getPublicKeyBlob()==null)
continue;
if(!Util.array_equals(blob, _identity.getPublicKeyBlob())){
continue;
}
if(_identity.isEncrypted()){
if(userinfo==null)
continue;
while(_identity.isEncrypted()){
if(!userinfo.promptPassphrase("Passphrase for "+_identity.getName())){
break;
}
String _passphrase=userinfo.getPassphrase();
if(_passphrase==null){
break;
}
byte[] passphrase=Util.str2byte(_passphrase);
try{
if(_identity.setPassphrase(passphrase)){
break;
}
}
catch(JSchException e){
break;
}
}
}
if(!_identity.isEncrypted()){
identity=_identity;
break;
}
}
}
byte[] signature=null;
if(identity!=null){
Buffer kbuf=new Buffer(blob);
String keytype=Util.byte2str(kbuf.getString());
if(keytype.equals("ssh-rsa")){
if((flags & SSH_AGENT_RSA_SHA2_256)!=0){
signature=identity.getSignature(data, "rsa-sha2-256");
}
else if((flags & SSH_AGENT_RSA_SHA2_512)!=0){
signature=identity.getSignature(data, "rsa-sha2-512");
}
else{
signature=identity.getSignature(data, "ssh-rsa");
}
}
else{
signature=identity.getSignature(data);
}
}
if(signature==null){
mbuf.putByte(SSH2_AGENT_FAILURE);
}
else{
mbuf.putByte(SSH2_AGENT_SIGN_RESPONSE);
mbuf.putString(signature);
}
}
else if(typ==SSH2_AGENTC_REMOVE_IDENTITY){
byte[] blob=rbuf.getString();
irepo.remove(blob);
mbuf.putByte(SSH_AGENT_SUCCESS);
}
else if(typ==SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES){
mbuf.putByte(SSH_AGENT_SUCCESS);
}
else if(typ==SSH2_AGENTC_REMOVE_ALL_IDENTITIES){
irepo.removeAll();
mbuf.putByte(SSH_AGENT_SUCCESS);
}
else if(typ==SSH2_AGENTC_ADD_IDENTITY){
int fooo = rbuf.getLength();
byte[] tmp = new byte[fooo];
rbuf.getByte(tmp);
boolean result = irepo.add(tmp);
mbuf.putByte(result ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
}
else {
rbuf.skip(rbuf.getLength()-1);
mbuf.putByte(SSH_AGENT_FAILURE);
}
byte[] response = new byte[mbuf.getLength()];
mbuf.getByte(response);
send(response);
}
private void send(byte[] message){
packet.reset();
wbuf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
wbuf.putInt(recipient);
wbuf.putInt(4+message.length);
wbuf.putString(message);
try{
getSession().write(packet, this, 4+message.length);
}
catch(Exception e){
}
}
@Override
void eof_remote(){
super.eof_remote();
eof();
}
}

View File

@@ -1,71 +0,0 @@
package com.jcraft.jsch;
import static com.jcraft.jsch.Session.SSH_MSG_CHANNEL_OPEN;
/**
* Extension of {@link ChannelDirectTCPIP} to support socket forwarding.
* <p>
* https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL
*/
public class ChannelDirectStreamLocal extends ChannelDirectTCPIP {
static private final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
static private final byte[] _type = Util.str2byte("direct-streamlocal@openssh.com");
private String socketPath;
ChannelDirectStreamLocal() {
super();
type = _type;
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
}
@Override
protected Packet genChannelOpenPacket() {
if (socketPath == null) {
session.getLogger().log(Logger.FATAL, "socketPath must be set");
throw new RuntimeException("socketPath must be set");
}
/*
Similar to direct-tcpip, direct-streamlocal is sent by the client
to request that the server make a connection to a Unix domain socket.
byte SSH_MSG_CHANNEL_OPEN
string "direct-streamlocal@openssh.com"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
string socket path
string reserved
uint32 reserved
*/
Buffer buf = new Buffer(50 +
socketPath.length() +
Session.buffer_margin);
Packet packet = new Packet(buf);
packet.reset();
buf.putByte((byte) SSH_MSG_CHANNEL_OPEN);
buf.putString(this.type);
buf.putInt(id);
buf.putInt(lwsize);
buf.putInt(lmpsize);
buf.putString(Util.str2byte(socketPath));
buf.putString(Util.str2byte(originator_IP_address));
buf.putInt(originator_port);
return packet;
}
public String getSocketPath() {
return socketPath;
}
public void setSocketPath(String socketPath) {
this.socketPath = socketPath;
}
}

View File

@@ -1,176 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.*;
public class ChannelDirectTCPIP extends Channel{
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final byte[] _type = Util.str2byte("direct-tcpip");
String host;
int port;
String originator_IP_address="127.0.0.1";
int originator_port=0;
ChannelDirectTCPIP(){
super();
type = _type;
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
}
@Override
void init (){
io=new IO();
}
@Override
public void connect(int connectTimeout) throws JSchException{
this.connectTimeout=connectTimeout;
try{
Session _session=getSession();
if(!_session.isConnected()){
throw new JSchException("session is down");
}
if(io.in!=null){
thread=new Thread(this::run);
thread.setName("DirectTCPIP thread "+_session.getHost());
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
else {
sendChannelOpen();
}
}
catch(Exception e){
io.close();
io=null;
Channel.del(this);
if (e instanceof JSchException) {
throw (JSchException) e;
}
}
}
@Override
void run(){
try{
sendChannelOpen();
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
Session _session=getSession();
int i=0;
while(isConnected() &&
thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
);
if(i<=0){
eof();
break;
}
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
synchronized(this){
if(close)
break;
_session.write(packet, this, i);
}
}
}
catch(Exception e){
// Whenever an exception is thrown by sendChannelOpen(),
// 'connected' is false.
if(!connected){
connected=true;
}
disconnect();
return;
}
eof();
disconnect();
}
@Override
public void setInputStream(InputStream in){
io.setInputStream(in);
}
@Override
public void setOutputStream(OutputStream out){
io.setOutputStream(out);
}
public void setHost(String host){this.host=host;}
public void setPort(int port){this.port=port;}
public void setOrgIPAddress(String foo){this.originator_IP_address=foo;}
public void setOrgPort(int foo){this.originator_port=foo;}
@Override
protected Packet genChannelOpenPacket(){
Buffer buf = new Buffer(50 + // 6 + 4*8 + 12
host.length() + originator_IP_address.length() +
Session.buffer_margin);
Packet packet = new Packet(buf);
// byte SSH_MSG_CHANNEL_OPEN(90)
// string channel type //
// uint32 sender channel // 0
// uint32 initial window size // 0x100000(65536)
// uint32 maxmum packet size // 0x4000(16384)
packet.reset();
buf.putByte((byte)90);
buf.putString(this.type);
buf.putInt(id);
buf.putInt(lwsize);
buf.putInt(lmpsize);
buf.putString(Util.str2byte(host));
buf.putInt(port);
buf.putString(Util.str2byte(originator_IP_address));
buf.putInt(originator_port);
return packet;
}
}

View File

@@ -1,84 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.*;
import java.util.*;
public class ChannelExec extends ChannelSession{
byte[] command=new byte[0];
@Override
public void start() throws JSchException{
Session _session=getSession();
try{
sendRequests();
Request request=new RequestExec(command);
request.request(_session, this);
}
catch(Exception e){
if(e instanceof JSchException) throw (JSchException)e;
throw new JSchException("ChannelExec", e);
}
if(io.in!=null){
thread=new Thread(this::run);
thread.setName("Exec thread "+_session.getHost());
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
public void setCommand(String command){
this.command=Util.str2byte(command);
}
public void setCommand(byte[] command){
this.command=command;
}
@Override
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
public void setErrStream(OutputStream out){
setExtOutputStream(out);
}
public void setErrStream(OutputStream out, boolean dontclose){
setExtOutputStream(out, dontclose);
}
public InputStream getErrStream() throws IOException {
return getExtInputStream();
}
}

View File

@@ -1,335 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.net.*;
import java.io.*;
import java.util.Vector;
public class ChannelForwardedTCPIP extends Channel{
private static Vector<Config> pool = new Vector<>();
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
//static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final int TIMEOUT=10*1000;
private Socket socket=null;
private ForwardedTCPIPDaemon daemon=null;
private Config config = null;
ChannelForwardedTCPIP(){
super();
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
io=new IO();
connected=true;
}
@Override
public void run(){
try{
if(config instanceof ConfigDaemon){
ConfigDaemon _config = (ConfigDaemon)config;
Class<? extends ForwardedTCPIPDaemon> c=Class.forName(_config.target).asSubclass(ForwardedTCPIPDaemon.class);
daemon=c.getDeclaredConstructor().newInstance();
PipedOutputStream out=new PipedOutputStream();
io.setInputStream(new PassiveInputStream(out
, 32*1024
), false);
daemon.setChannel(this, getInputStream(), out);
daemon.setArg(_config.arg);
new Thread(daemon).start();
}
else{
ConfigLHost _config = (ConfigLHost)config;
socket=(_config.factory==null) ?
Util.createSocket(_config.target, _config.lport, TIMEOUT) :
_config.factory.createSocket(_config.target, _config.lport);
socket.setTcpNoDelay(true);
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
}
sendOpenConfirmation();
}
catch(Exception e){
sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
close=true;
disconnect();
return;
}
thread=Thread.currentThread();
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
int i=0;
try{
Session _session = getSession();
while(thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
);
if(i<=0){
eof();
break;
}
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
synchronized(this){
if(close)
break;
_session.write(packet, this, i);
}
}
}
catch(Exception e){
//System.err.println(e);
}
//thread=null;
//eof();
disconnect();
}
@Override
void getData(Buffer buf){
setRecipient(buf.getInt());
setRemoteWindowSize(buf.getUInt());
setRemotePacketSize(buf.getInt());
byte[] addr=buf.getString();
int port=buf.getInt();
byte[] orgaddr=buf.getString();
int orgport=buf.getInt();
/*
System.err.println("addr: "+Util.byte2str(addr));
System.err.println("port: "+port);
System.err.println("orgaddr: "+Util.byte2str(orgaddr));
System.err.println("orgport: "+orgport);
*/
Session _session=null;
try{
_session=getSession();
}
catch(JSchException e){
// session has been already down.
}
this.config = getPort(_session, Util.byte2str(addr), port);
if(this.config == null)
this.config = getPort(_session, null, port);
if(this.config == null){
if(_session.getLogger().isEnabled(Logger.ERROR)){
_session.getLogger().log(Logger.ERROR,
"ChannelForwardedTCPIP: "+Util.byte2str(addr)+":"+port+" is not registered.");
}
}
}
private static Config getPort(Session session, String address_to_bind, int rport){
synchronized(pool){
for(int i=0; i<pool.size(); i++){
Config bar = pool.elementAt(i);
if(bar.session != session) continue;
if(bar.rport != rport) {
if(bar.rport != 0 || bar.allocated_rport != rport)
continue;
}
if(address_to_bind != null &&
!bar.address_to_bind.equals(address_to_bind)) continue;
return bar;
}
return null;
}
}
static String[] getPortForwarding(Session session){
Vector<String> foo = new Vector<>();
synchronized(pool){
for(int i=0; i<pool.size(); i++){
Config config = pool.elementAt(i);
if(config.session==session){
if(config instanceof ConfigDaemon)
foo.addElement(config.allocated_rport+":"+config.target+":");
else
foo.addElement(config.allocated_rport+":"+config.target+":"+((ConfigLHost)config).lport);
}
}
}
String[] bar=new String[foo.size()];
for(int i=0; i<foo.size(); i++){
bar[i]=foo.elementAt(i);
}
return bar;
}
static String normalize(String address){
if(address==null){ return "localhost"; }
else if(address.length()==0 || address.equals("*")){ return ""; }
else{ return address; }
}
static void addPort(Session session, String _address_to_bind,
int port, int allocated_port, String target, int lport, SocketFactory factory) throws JSchException{
String address_to_bind=normalize(_address_to_bind);
synchronized(pool){
if(getPort(session, address_to_bind, port)!=null){
throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
}
ConfigLHost config = new ConfigLHost();
config.session = session;
config.rport = port;
config.allocated_rport = allocated_port;
config.target = target;
config.lport =lport;
config.address_to_bind = address_to_bind;
config.factory = factory;
pool.addElement(config);
}
}
static void addPort(Session session, String _address_to_bind,
int port, int allocated_port, String daemon, Object[] arg) throws JSchException{
String address_to_bind=normalize(_address_to_bind);
synchronized(pool){
if(getPort(session, address_to_bind, port)!=null){
throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
}
ConfigDaemon config = new ConfigDaemon();
config.session = session;
config.rport = port;
config.allocated_rport = port;
config.target = daemon;
config.arg = arg;
config.address_to_bind = address_to_bind;
pool.addElement(config);
}
}
static void delPort(ChannelForwardedTCPIP c){
Session _session=null;
try{
_session=c.getSession();
}
catch(JSchException e){
// session has been already down.
}
if(_session!=null && c.config!=null)
delPort(_session, c.config.rport);
}
static void delPort(Session session, int rport){
delPort(session, null, rport);
}
static void delPort(Session session, String address_to_bind, int rport){
synchronized(pool){
Config foo = getPort(session, normalize(address_to_bind), rport);
if(foo == null)
foo = getPort(session, null, rport);
if(foo==null) return;
pool.removeElement(foo);
if(address_to_bind==null){
address_to_bind=foo.address_to_bind;
}
if(address_to_bind==null){
address_to_bind="0.0.0.0";
}
}
Buffer buf=new Buffer(200); // ??
Packet packet=new Packet(buf);
try{
// byte SSH_MSG_GLOBAL_REQUEST 80
// string "cancel-tcpip-forward"
// boolean want_reply
// string address_to_bind (e.g. "127.0.0.1")
// uint32 port number to bind
packet.reset();
buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
buf.putString(Util.str2byte("cancel-tcpip-forward"));
buf.putByte((byte)0);
buf.putString(Util.str2byte(address_to_bind));
buf.putInt(rport);
session.write(packet);
}
catch(Exception e){
// throw new JSchException(e.toString(), e);
}
}
static void delPort(Session session){
int[] rport=null;
int count=0;
synchronized(pool){
rport=new int[pool.size()];
for(int i=0; i<pool.size(); i++){
Config config = pool.elementAt(i);
if(config.session == session) {
rport[count++]=config.rport; // ((Integer)bar[1]).intValue();
}
}
}
for(int i=0; i<count; i++){
delPort(session, rport[i]);
}
}
public int getRemotePort(){return (config!=null ? config.rport: 0);}
private void setSocketFactory(SocketFactory factory){
if(config!=null && (config instanceof ConfigLHost) )
((ConfigLHost)config).factory = factory;
}
static abstract class Config {
Session session;
int rport;
int allocated_rport;
String address_to_bind;
String target;
}
static class ConfigDaemon extends Config {
Object[] arg;
}
static class ConfigLHost extends Config {
int lport;
SocketFactory factory;
}
}

View File

@@ -1,279 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.util.*;
class ChannelSession extends Channel{
private static byte[] _session=Util.str2byte("session");
protected boolean agent_forwarding=false;
protected boolean xforwading=false;
protected Hashtable<byte[], byte[]> env=null;
protected boolean pty=false;
protected String ttype="vt100";
protected int tcol=80;
protected int trow=24;
protected int twp=640;
protected int thp=480;
protected byte[] terminal_mode=null;
ChannelSession(){
super();
type=_session;
io=new IO();
}
/**
* Enable the agent forwarding.
*
* @param enable
*/
public void setAgentForwarding(boolean enable){
agent_forwarding=enable;
}
/**
* Enable the X11 forwarding.
* Refer to RFC4254 6.3.1. Requesting X11 Forwarding.
*
* @param enable
*/
@Override
public void setXForwarding(boolean enable){
xforwading=enable;
}
/**
* @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead.
* @see #setEnv(String, String)
* @see #setEnv(byte[], byte[])
*/
@Deprecated
public void setEnv(Hashtable<byte[], byte[]> env){
synchronized(this){
this.env=env;
}
}
/**
* Set the environment variable.
* If <code>name</code> and <code>value</code> are needed to be passed
* to the remote in your favorite encoding,
* use {@link #setEnv(byte[], byte[])}.
* Refer to RFC4254 6.4 Environment Variable Passing.
*
* @param name A name for environment variable.
* @param value A value for environment variable.
*/
public void setEnv(String name, String value){
setEnv(Util.str2byte(name), Util.str2byte(value));
}
/**
* Set the environment variable.
* Refer to RFC4254 6.4 Environment Variable Passing.
*
* @param name A name of environment variable.
* @param value A value of environment variable.
* @see #setEnv(String, String)
*/
public void setEnv(byte[] name, byte[] value){
synchronized(this){
getEnv().put(name, value);
}
}
private Hashtable<byte[], byte[]> getEnv(){
if(env==null)
env=new Hashtable<>();
return env;
}
/**
* Allocate a Pseudo-Terminal.
* Refer to RFC4254 6.2. Requesting a Pseudo-Terminal.
*
* @param enable
*/
public void setPty(boolean enable){
pty=enable;
}
/**
* Set the terminal mode.
*
* @param terminal_mode
*/
public void setTerminalMode(byte[] terminal_mode){
this.terminal_mode=terminal_mode;
}
/**
* Change the window dimension interactively.
* Refer to RFC4254 6.7. Window Dimension Change Message.
*
* @param col terminal width, columns
* @param row terminal height, rows
* @param wp terminal width, pixels
* @param hp terminal height, pixels
*/
public void setPtySize(int col, int row, int wp, int hp){
setPtyType(this.ttype, col, row, wp, hp);
if(!pty || !isConnected()){
return;
}
try{
RequestWindowChange request=new RequestWindowChange();
request.setSize(col, row, wp, hp);
request.request(getSession(), this);
}
catch(Exception e){
//System.err.println("ChannelSessio.setPtySize: "+e);
}
}
/**
* Set the terminal type.
* This method is not effective after Channel#connect().
*
* @param ttype terminal type(for example, "vt100")
* @see #setPtyType(String, int, int, int, int)
*/
public void setPtyType(String ttype){
setPtyType(ttype, 80, 24, 640, 480);
}
/**
* Set the terminal type.
* This method is not effective after Channel#connect().
*
* @param ttype terminal type(for example, "vt100")
* @param col terminal width, columns
* @param row terminal height, rows
* @param wp terminal width, pixels
* @param hp terminal height, pixels
*/
public void setPtyType(String ttype, int col, int row, int wp, int hp){
this.ttype=ttype;
this.tcol=col;
this.trow=row;
this.twp=wp;
this.thp=hp;
}
protected void sendRequests() throws Exception{
Session _session=getSession();
Request request;
if(agent_forwarding){
request=new RequestAgentForwarding();
request.request(_session, this);
}
if(xforwading){
request=new RequestX11();
request.request(_session, this);
}
if(pty){
request=new RequestPtyReq();
((RequestPtyReq)request).setTType(ttype);
((RequestPtyReq)request).setTSize(tcol, trow, twp, thp);
if(terminal_mode!=null){
((RequestPtyReq)request).setTerminalMode(terminal_mode);
}
request.request(_session, this);
}
if(env!=null){
for(Enumeration<byte[]> _env=env.keys(); _env.hasMoreElements();){
byte[] name=_env.nextElement();
byte[] value=env.get(name);
request=new RequestEnv();
((RequestEnv)request).setEnv(toByteArray(name),
toByteArray(value));
request.request(_session, this);
}
}
}
private byte[] toByteArray(Object o){
if(o instanceof String){
return Util.str2byte((String)o);
}
return (byte[])o;
}
@Override
void run(){
//System.err.println(this+":run >");
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
int i=-1;
try{
while(isConnected() &&
thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14
-Session.buffer_margin
);
if(i==0)continue;
if(i==-1){
eof();
break;
}
if(close)break;
//System.out.println("write: "+i);
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
getSession().write(packet, this, i);
}
}
catch(Exception e){
//System.err.println("# ChannelExec.run");
//e.printStackTrace();
}
Thread _thread=thread;
if(_thread!=null){
synchronized(_thread){ _thread.notifyAll(); }
}
thread=null;
//System.err.println(this+":run <");
}
}

View File

@@ -1,70 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.util.*;
public class ChannelShell extends ChannelSession{
ChannelShell(){
super();
pty=true;
}
@Override
public void start() throws JSchException{
Session _session=getSession();
try{
sendRequests();
Request request=new RequestShell();
request.request(_session, this);
}
catch(Exception e){
if(e instanceof JSchException) throw (JSchException)e;
throw new JSchException("ChannelShell", e);
}
if(io.in!=null){
thread=new Thread(this::run);
thread.setName("Shell for "+_session.host);
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
@Override
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
}

View File

@@ -1,81 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2005-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.*;
public class ChannelSubsystem extends ChannelSession{
boolean want_reply=true;
String subsystem="";
public void setWantReply(boolean foo){ want_reply=foo; }
public void setSubsystem(String foo){ subsystem=foo; }
@Override
public void start() throws JSchException{
Session _session=getSession();
try{
Request request;
if(xforwading){
request=new RequestX11();
request.request(_session, this);
}
if(pty){
request=new RequestPtyReq();
request.request(_session, this);
}
request=new RequestSubsystem();
((RequestSubsystem)request).request(_session, this, subsystem, want_reply);
}
catch(Exception e){
if(e instanceof JSchException){ throw (JSchException)e; }
throw new JSchException("ChannelSubsystem", e);
}
if(io.in!=null){
thread=new Thread(this::run);
thread.setName("Subsystem for "+_session.host);
if(_session.daemon_thread){
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
@Override
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
public void setErrStream(OutputStream out){
setExtOutputStream(out);
}
public InputStream getErrStream() throws IOException {
return getExtInputStream();
}
}

View File

@@ -1,277 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.net.*;
import java.util.Hashtable;
class ChannelX11 extends Channel{
static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
static private final int TIMEOUT=10*1000;
private static String host="127.0.0.1";
private static int port=6000;
private boolean init=true;
static byte[] cookie=null;
private static byte[] cookie_hex=null;
private static Hashtable<Session, byte[]> faked_cookie_pool=new Hashtable<>();
private static Hashtable<Session, byte[]> faked_cookie_hex_pool=new Hashtable<>();
private static byte[] table={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x61,0x62,0x63,0x64,0x65,0x66};
private Socket socket = null;
static int revtable(byte foo){
for(int i=0; i<table.length; i++){
if(table[i]==foo)return i;
}
return 0;
}
static void setCookie(String foo){
cookie_hex=Util.str2byte(foo);
cookie=new byte[16];
for(int i=0; i<16; i++){
cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) |
((revtable(cookie_hex[i*2+1]))&0xf));
}
}
static void setHost(String foo){ host=foo; }
static void setPort(int foo){ port=foo; }
static byte[] getFakedCookie(Session session){
synchronized(faked_cookie_hex_pool){
byte[] foo=faked_cookie_hex_pool.get(session);
if(foo==null){
Random random=Session.random;
foo=new byte[16];
synchronized(random){
random.fill(foo, 0, 16);
}
/*
System.err.print("faked_cookie: ");
for(int i=0; i<foo.length; i++){
System.err.print(Integer.toHexString(foo[i]&0xff)+":");
}
System.err.println("");
*/
faked_cookie_pool.put(session, foo);
byte[] bar=new byte[32];
for(int i=0; i<16; i++){
bar[2*i]=table[(foo[i]>>>4)&0xf];
bar[2*i+1]=table[(foo[i])&0xf];
}
faked_cookie_hex_pool.put(session, bar);
foo=bar;
}
return foo;
}
}
static void removeFakedCookie(Session session){
synchronized(faked_cookie_hex_pool){
faked_cookie_hex_pool.remove(session);
faked_cookie_pool.remove(session);
}
}
ChannelX11(){
super();
setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
type=Util.str2byte("x11");
connected=true;
/*
try{
socket=Util.createSocket(host, port, TIMEOUT);
socket.setTcpNoDelay(true);
io=new IO();
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
}
catch(Exception e){
//System.err.println(e);
}
*/
}
@Override
void run(){
try{
socket=Util.createSocket(host, port, TIMEOUT);
socket.setTcpNoDelay(true);
io=new IO();
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
sendOpenConfirmation();
}
catch(Exception e){
sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
close=true;
disconnect();
return;
}
thread=Thread.currentThread();
Buffer buf=new Buffer(rmpsize);
Packet packet=new Packet(buf);
int i=0;
try{
while(thread!=null &&
io!=null &&
io.in!=null){
i=io.in.read(buf.buffer,
14,
buf.buffer.length-14-Session.buffer_margin);
if(i<=0){
eof();
break;
}
if(close)break;
packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
getSession().write(packet, this, i);
}
}
catch(Exception e){
//System.err.println(e);
}
disconnect();
}
private byte[] cache=new byte[0];
private byte[] addCache(byte[] foo, int s, int l){
byte[] bar=new byte[cache.length+l];
System.arraycopy(foo, s, bar, cache.length, l);
if(cache.length>0)
System.arraycopy(cache, 0, bar, 0, cache.length);
cache=bar;
return cache;
}
@Override
void write(byte[] foo, int s, int l) throws IOException {
//if(eof_local)return;
if(init){
Session _session=null;
try{
_session=getSession();
}
catch(JSchException e){
throw new IOException(e.toString(), e);
}
foo=addCache(foo, s, l);
s=0;
l=foo.length;
if(l<9)
return;
int plen=(foo[s+6]&0xff)*256+(foo[s+7]&0xff);
int dlen=(foo[s+8]&0xff)*256+(foo[s+9]&0xff);
if((foo[s]&0xff)==0x42){
}
else if((foo[s]&0xff)==0x6c){
plen=((plen>>>8)&0xff)|((plen<<8)&0xff00);
dlen=((dlen>>>8)&0xff)|((dlen<<8)&0xff00);
}
else{
// ??
}
if(l<12+plen+((-plen)&3)+dlen)
return;
byte[] bar=new byte[dlen];
System.arraycopy(foo, s+12+plen+((-plen)&3), bar, 0, dlen);
byte[] faked_cookie=null;
synchronized(faked_cookie_pool){
faked_cookie=faked_cookie_pool.get(_session);
}
/*
System.err.print("faked_cookie: ");
for(int i=0; i<faked_cookie.length; i++){
System.err.print(Integer.toHexString(faked_cookie[i]&0xff)+":");
}
System.err.println("");
System.err.print("bar: ");
for(int i=0; i<bar.length; i++){
System.err.print(Integer.toHexString(bar[i]&0xff)+":");
}
System.err.println("");
*/
if(equals(bar, faked_cookie)){
if(cookie!=null)
System.arraycopy(cookie, 0, foo, s+12+plen+((-plen)&3), dlen);
}
else{
//System.err.println("wrong cookie");
thread=null;
eof();
io.close();
disconnect();
}
init=false;
io.put(foo, s, l);
cache=null;
return;
}
io.put(foo, s, l);
}
private static boolean equals(byte[] foo, byte[] bar){
if(foo.length!=bar.length)return false;
for(int i=0; i<foo.length; i++){
if(foo[i]!=bar[i])return false;
}
return true;
}
}

View File

@@ -1,46 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface Cipher{
static int ENCRYPT_MODE=0;
static int DECRYPT_MODE=1;
int getIVSize();
int getBlockSize();
default int getTagSize() {return 0;}
void init(int mode, byte[] key, byte[] iv) throws Exception;
default void update(int foo) throws Exception {}
void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception;
default void updateAAD(byte[] foo, int s1, int len) throws Exception {}
default void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception {}
boolean isCBC();
default boolean isAEAD() {return false;}
default boolean isChaCha20() {return false;}
}

View File

@@ -1,47 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class CipherNone implements Cipher{
private static final int ivsize=8;
private static final int bsize=16;
@Override
public int getIVSize(){return ivsize;}
@Override
public int getBlockSize(){return bsize;}
@Override
public void init(int mode, byte[] key, byte[] iv) throws Exception{
}
@Override
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
}
@Override
public boolean isCBC(){return false; }
}

View File

@@ -1,45 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface Compression{
static public final int INFLATER=0;
static public final int DEFLATER=1;
default void init(int type, int level, Session session) {
init(type, level);
}
default void end() {}
void init(int type, int level);
byte[] compress(byte[] buf, int start, int[] len);
byte[] uncompress(byte[] buf, int start, int[] len);
}

View File

@@ -1,61 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2013-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface ConfigRepository {
public Config getConfig(String host);
public interface Config {
public String getHostname();
public String getUser();
public int getPort();
public String getValue(String key);
public String[] getValues(String key);
}
static final Config defaultConfig = new Config() {
@Override
public String getHostname() {return null;}
@Override
public String getUser() {return null;}
@Override
public int getPort() {return -1;}
@Override
public String getValue(String key) {return null;}
@Override
public String[] getValues(String key) {return null;}
};
static final ConfigRepository nullConfig = new ConfigRepository(){
@Override
public Config getConfig(String host) { return defaultConfig; }
};
}

View File

@@ -1,43 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface DH{
void init() throws Exception;
void setP(byte[] p);
void setG(byte[] g);
byte[] getE() throws Exception;
void setF(byte[] f);
byte[] getK() throws Exception;
// checkRange() will check if e and f are in [1,p-1]
// as defined at https://tools.ietf.org/html/rfc4253#section-8
void checkRange() throws Exception;
}

View File

@@ -1,38 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DH25519 extends DHXEC {
public DH25519(){
sha_name="sha-256";
curve_name="X25519";
key_len=32;
}
}

View File

@@ -1,38 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DH448 extends DHXEC {
public DH448(){
sha_name="sha-512";
curve_name="X448";
key_len=56;
}
}

View File

@@ -1,37 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHEC256 extends DHECN {
public DHEC256(){
sha_name="sha-256";
key_size=256;
}
}

View File

@@ -1,37 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHEC384 extends DHECN {
public DHEC384(){
sha_name="sha-384";
key_size=384;
}
}

View File

@@ -1,37 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHEC521 extends DHECN {
public DHEC521(){
sha_name="sha-512";
key_size=521;
}
}

View File

@@ -1,187 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHECN extends KeyExchange{
private static final int SSH_MSG_KEX_ECDH_INIT = 30;
private static final int SSH_MSG_KEX_ECDH_REPLY= 31;
private int state;
byte[] Q_C;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
private ECDH ecdh;
protected String sha_name;
protected int key_size;
@Override
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class<? extends HASH> c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
sha=c.getDeclaredConstructor().newInstance();
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT);
try{
Class<? extends ECDH> c=Class.forName(session.getConfig("ecdh-sha2-nistp")).asSubclass(ECDH.class);
ecdh=c.getDeclaredConstructor().newInstance();
ecdh.init(key_size);
Q_C = ecdh.getQ();
buf.putString(Q_C);
}
catch(Exception e){
throw new JSchException(e.toString(), e);
}
if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if(session.getLogger().isEnabled(Logger.INFO)){
session.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_ECDH_INIT sent");
session.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_ECDH_REPLY");
}
state=SSH_MSG_KEX_ECDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_ECDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_ECDH_REPLY
// string K_S, server's public host key
// string Q_S, server's ephemeral public key octet string
// string the signature on the exchange hash
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_ECDH_REPLY){
System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j);
return false;
}
K_S=_buf.getString();
byte[] Q_S=_buf.getString();
byte[][] r_s = KeyPairECDSA.fromPoint(Q_S);
// RFC 5656,
// 4. ECDH Key Exchange
// All elliptic curve public keys MUST be validated after they are
// received. An example of a validation algorithm can be found in
// Section 3.2.2 of [SEC1]. If a key fails validation,
// the key exchange MUST fail.
if(!ecdh.validate(r_s[0], r_s[1])){
return false;
}
K = ecdh.getSecret(r_s[0], r_s[1]);
K=normalize(K);
byte[] sig_of_H=_buf.getString();
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, client's identification string (CR and LF excluded)
// string V_S, server's identification string (CR and LF excluded)
// string I_C, payload of the client's SSH_MSG_KEXINIT
// string I_S, payload of the server's SSH_MSG_KEXINIT
// string K_S, server's public host key
// string Q_C, client's ephemeral public key octet string
// string Q_S, server's ephemeral public key octet string
// mpint K, shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putString(Q_C); buf.putString(Q_S);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result = verify(alg, K_S, i, sig_of_H);
state=STATE_END;
return result;
}
return false;
}
@Override
public int getState(){return state; }
}

View File

@@ -1,61 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG1 extends DHGN{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
@Override
byte[] G(){ return g; }
@Override
byte[] P(){ return p; }
@Override
String sha_name(){ return "sha-1"; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG14 extends DHG14N{
@Override
String sha_name(){ return "sha-1"; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG14224 extends DHG14N{
@Override
String sha_name(){ return "sha-224"; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG14256 extends DHG14N{
@Override
String sha_name(){ return "sha-256"; }
}

View File

@@ -1,75 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHG14N extends DHGN{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
@Override
byte[] G(){ return g; }
@Override
byte[] P(){ return p; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG15 extends DHG15N{
@Override
String sha_name(){ return "sha-512"; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG15256 extends DHG15N{
@Override
String sha_name(){ return "sha-256"; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG15384 extends DHG15N{
@Override
String sha_name(){ return "sha-384"; }
}

View File

@@ -1,91 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHG15N extends DHGN{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x3A,(byte)0xD2,(byte)0xCA,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
@Override
byte[] G(){ return g; }
@Override
byte[] P(){ return p; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG16 extends DHG16N{
@Override
String sha_name(){ return "sha-512"; }
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG16384 extends DHG16N{
@Override
String sha_name(){ return "sha-384"; }
}

View File

@@ -1,107 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHG16N extends DHGN{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01,
(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7,
(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26,
(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C,
(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA,
(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8,
(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9,
(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6,
(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D,
(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2,
(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED,
(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF,
(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C,
(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9,
(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1,
(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F,
(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x06,(byte)0x31,(byte)0x99,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
@Override
byte[] G(){ return g; }
@Override
byte[] P(){ return p; }
}

View File

@@ -1,141 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG17 extends DHGN{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01,
(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7,
(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26,
(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C,
(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA,
(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8,
(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9,
(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6,
(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D,
(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2,
(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED,
(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF,
(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C,
(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9,
(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1,
(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F,
(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92,
(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26,
(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE,
(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD,
(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E,
(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE,
(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31,
(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18,
(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED,
(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B,
(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B,
(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42,
(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF,
(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC,
(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03,
(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6,
(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82,
(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E,
(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3,
(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE,
(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5,
(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA,
(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8,
(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0,
(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28,
(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76,
(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0,
(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C,
(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32,
(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68,
(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE,
(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6,
(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xCC,(byte)0x40,(byte)0x24,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
};
@Override
byte[] G(){ return g; }
@Override
byte[] P(){ return p; }
@Override
String sha_name(){ return "sha-512"; }
}

View File

@@ -1,173 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHG18 extends DHGN{
static final byte[] g={ 2 };
static final byte[] p={
(byte)0x00,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01,
(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7,
(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26,
(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C,
(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA,
(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8,
(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9,
(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6,
(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D,
(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2,
(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED,
(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF,
(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C,
(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9,
(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1,
(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F,
(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92,
(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26,
(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE,
(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD,
(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E,
(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE,
(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31,
(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18,
(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED,
(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B,
(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B,
(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42,
(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF,
(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC,
(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03,
(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6,
(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82,
(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E,
(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3,
(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE,
(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5,
(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA,
(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8,
(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0,
(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28,
(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76,
(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0,
(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C,
(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32,
(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68,
(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE,
(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6,
(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xBE,(byte)0x11,(byte)0x59,
(byte)0x74,(byte)0xA3,(byte)0x92,(byte)0x6F,(byte)0x12,(byte)0xFE,(byte)0xE5,(byte)0xE4,
(byte)0x38,(byte)0x77,(byte)0x7C,(byte)0xB6,(byte)0xA9,(byte)0x32,(byte)0xDF,(byte)0x8C,
(byte)0xD8,(byte)0xBE,(byte)0xC4,(byte)0xD0,(byte)0x73,(byte)0xB9,(byte)0x31,(byte)0xBA,
(byte)0x3B,(byte)0xC8,(byte)0x32,(byte)0xB6,(byte)0x8D,(byte)0x9D,(byte)0xD3,(byte)0x00,
(byte)0x74,(byte)0x1F,(byte)0xA7,(byte)0xBF,(byte)0x8A,(byte)0xFC,(byte)0x47,(byte)0xED,
(byte)0x25,(byte)0x76,(byte)0xF6,(byte)0x93,(byte)0x6B,(byte)0xA4,(byte)0x24,(byte)0x66,
(byte)0x3A,(byte)0xAB,(byte)0x63,(byte)0x9C,(byte)0x5A,(byte)0xE4,(byte)0xF5,(byte)0x68,
(byte)0x34,(byte)0x23,(byte)0xB4,(byte)0x74,(byte)0x2B,(byte)0xF1,(byte)0xC9,(byte)0x78,
(byte)0x23,(byte)0x8F,(byte)0x16,(byte)0xCB,(byte)0xE3,(byte)0x9D,(byte)0x65,(byte)0x2D,
(byte)0xE3,(byte)0xFD,(byte)0xB8,(byte)0xBE,(byte)0xFC,(byte)0x84,(byte)0x8A,(byte)0xD9,
(byte)0x22,(byte)0x22,(byte)0x2E,(byte)0x04,(byte)0xA4,(byte)0x03,(byte)0x7C,(byte)0x07,
(byte)0x13,(byte)0xEB,(byte)0x57,(byte)0xA8,(byte)0x1A,(byte)0x23,(byte)0xF0,(byte)0xC7,
(byte)0x34,(byte)0x73,(byte)0xFC,(byte)0x64,(byte)0x6C,(byte)0xEA,(byte)0x30,(byte)0x6B,
(byte)0x4B,(byte)0xCB,(byte)0xC8,(byte)0x86,(byte)0x2F,(byte)0x83,(byte)0x85,(byte)0xDD,
(byte)0xFA,(byte)0x9D,(byte)0x4B,(byte)0x7F,(byte)0xA2,(byte)0xC0,(byte)0x87,(byte)0xE8,
(byte)0x79,(byte)0x68,(byte)0x33,(byte)0x03,(byte)0xED,(byte)0x5B,(byte)0xDD,(byte)0x3A,
(byte)0x06,(byte)0x2B,(byte)0x3C,(byte)0xF5,(byte)0xB3,(byte)0xA2,(byte)0x78,(byte)0xA6,
(byte)0x6D,(byte)0x2A,(byte)0x13,(byte)0xF8,(byte)0x3F,(byte)0x44,(byte)0xF8,(byte)0x2D,
(byte)0xDF,(byte)0x31,(byte)0x0E,(byte)0xE0,(byte)0x74,(byte)0xAB,(byte)0x6A,(byte)0x36,
(byte)0x45,(byte)0x97,(byte)0xE8,(byte)0x99,(byte)0xA0,(byte)0x25,(byte)0x5D,(byte)0xC1,
(byte)0x64,(byte)0xF3,(byte)0x1C,(byte)0xC5,(byte)0x08,(byte)0x46,(byte)0x85,(byte)0x1D,
(byte)0xF9,(byte)0xAB,(byte)0x48,(byte)0x19,(byte)0x5D,(byte)0xED,(byte)0x7E,(byte)0xA1,
(byte)0xB1,(byte)0xD5,(byte)0x10,(byte)0xBD,(byte)0x7E,(byte)0xE7,(byte)0x4D,(byte)0x73,
(byte)0xFA,(byte)0xF3,(byte)0x6B,(byte)0xC3,(byte)0x1E,(byte)0xCF,(byte)0xA2,(byte)0x68,
(byte)0x35,(byte)0x90,(byte)0x46,(byte)0xF4,(byte)0xEB,(byte)0x87,(byte)0x9F,(byte)0x92,
(byte)0x40,(byte)0x09,(byte)0x43,(byte)0x8B,(byte)0x48,(byte)0x1C,(byte)0x6C,(byte)0xD7,
(byte)0x88,(byte)0x9A,(byte)0x00,(byte)0x2E,(byte)0xD5,(byte)0xEE,(byte)0x38,(byte)0x2B,
(byte)0xC9,(byte)0x19,(byte)0x0D,(byte)0xA6,(byte)0xFC,(byte)0x02,(byte)0x6E,(byte)0x47,
(byte)0x95,(byte)0x58,(byte)0xE4,(byte)0x47,(byte)0x56,(byte)0x77,(byte)0xE9,(byte)0xAA,
(byte)0x9E,(byte)0x30,(byte)0x50,(byte)0xE2,(byte)0x76,(byte)0x56,(byte)0x94,(byte)0xDF,
(byte)0xC8,(byte)0x1F,(byte)0x56,(byte)0xE8,(byte)0x80,(byte)0xB9,(byte)0x6E,(byte)0x71,
(byte)0x60,(byte)0xC9,(byte)0x80,(byte)0xDD,(byte)0x98,(byte)0xED,(byte)0xD3,(byte)0xDF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
@Override
byte[] G(){ return g; }
@Override
byte[] P(){ return p; }
@Override
String sha_name(){ return "sha-512"; }
}

View File

@@ -1,237 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHGEX extends KeyExchange{
private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31;
private static final int SSH_MSG_KEX_DH_GEX_INIT= 32;
private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33;
private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34;
int min;
int preferred;
int max;
private int state;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
private Buffer buf;
private Packet packet;
private byte[] p;
private byte[] g;
private byte[] e;
protected String hash;
@Override
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class<? extends HASH> c=Class.forName(session.getConfig(hash)).asSubclass(HASH.class);
sha=c.getDeclaredConstructor().newInstance();
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class<? extends DH> c=Class.forName(session.getConfig("dh")).asSubclass(DH.class);
min=Integer.parseInt(session.getConfig("dhgex_min"));
max=Integer.parseInt(session.getConfig("dhgex_max"));
preferred=Integer.parseInt(session.getConfig("dhgex_preferred"));
if(checkInvalidSize(min) || checkInvalidSize(max) || checkInvalidSize(preferred) || preferred < min || max < preferred){
throw new JSchException("Invalid DHGEX sizes: min=" + min + " max=" + max + " preferred=" + preferred);
}
dh=c.getDeclaredConstructor().newInstance();
dh.init();
}
catch(Exception e){
throw e;
}
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
buf.putInt(min);
buf.putInt(preferred);
buf.putInt(max);
session.write(packet);
if(session.getLogger().isEnabled(Logger.INFO)){
session.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
session.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_GROUP");
}
state=SSH_MSG_KEX_DH_GEX_GROUP;
}
@Override
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_DH_GEX_GROUP:
// byte SSH_MSG_KEX_DH_GEX_GROUP(31)
// mpint p, safe prime
// mpint g, generator for subgroup in GF (p)
_buf.getInt();
_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
return false;
}
p=_buf.getMPInt();
g=_buf.getMPInt();
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEX_DH_GEX_INIT(32)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
buf.putMPInt(e);
session.write(packet);
if(session.getLogger().isEnabled(Logger.INFO)){
session.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_INIT sent");
session.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_REPLY");
}
state=SSH_MSG_KEX_DH_GEX_REPLY;
return true;
//break;
case SSH_MSG_KEX_DH_GEX_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_DH_GEX_REPLY(33)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
return false;
}
K_S=_buf.getString();
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
dh.setF(f);
dh.checkRange();
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// uint32 min, minimal size in bits of an acceptable group
// uint32 n, preferred size in bits of the group the server should send
// uint32 max, maximal size in bits of an acceptable group
// mpint p, safe prime
// mpint g, generator for subgroup
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
// System.err.print("H -> "); dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result = verify(alg, K_S, i, sig_of_H);
state=STATE_END;
return result;
}
return false;
}
@Override
public int getState(){return state; }
static boolean checkInvalidSize(int size) {
return (size < 1024 || size > 8192 || size % 1024 != 0);
}
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHGEX1 extends DHGEX {
DHGEX1(){
hash="sha-1";
}
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHGEX224 extends DHGEX {
DHGEX224(){
hash="sha-224";
}
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHGEX256 extends DHGEX {
DHGEX256(){
hash="sha-256";
}
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHGEX384 extends DHGEX {
DHGEX384(){
hash="sha-384";
}
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
class DHGEX512 extends DHGEX {
DHGEX512(){
hash="sha-512";
}
}

View File

@@ -1,184 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHGN extends KeyExchange{
private static final int SSH_MSG_KEXDH_INIT= 30;
private static final int SSH_MSG_KEXDH_REPLY= 31;
private int state;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
abstract byte[] G();
abstract byte[] P();
abstract String sha_name();
@Override
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class<? extends HASH> c=Class.forName(session.getConfig(sha_name())).asSubclass(HASH.class);
sha=c.getDeclaredConstructor().newInstance();
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class<? extends DH> c=Class.forName(session.getConfig("dh")).asSubclass(DH.class);
dh=c.getDeclaredConstructor().newInstance();
dh.init();
}
catch(Exception e){
//System.err.println(e);
throw e;
}
dh.setP(P());
dh.setG(G());
// The client responds with:
// byte SSH_MSG_KEXDH_INIT(30)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEXDH_INIT);
buf.putMPInt(e);
if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if(session.getLogger().isEnabled(Logger.INFO)){
session.getLogger().log(Logger.INFO,
"SSH_MSG_KEXDH_INIT sent");
session.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEXDH_REPLY");
}
state=SSH_MSG_KEXDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEXDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEXDH_REPLY(31)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=31){
System.err.println("type: must be 31 "+j);
return false;
}
K_S=_buf.getString();
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
dh.setF(f);
dh.checkRange();
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
//System.err.print("H -> "); //dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result = verify(alg, K_S, i, sig_of_H);
state=STATE_END;
return result;
}
return false;
}
@Override
public int getState(){return state; }
}

View File

@@ -1,200 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
abstract class DHXEC extends KeyExchange{
private static final int SSH_MSG_KEX_ECDH_INIT = 30;
private static final int SSH_MSG_KEX_ECDH_REPLY= 31;
private int state;
byte[] Q_C;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
private XDH xdh;
protected String sha_name;
protected String curve_name;
protected int key_len;
@Override
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class<? extends HASH> c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
sha=c.getDeclaredConstructor().newInstance();
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT);
try{
Class<? extends XDH> c=Class.forName(session.getConfig("xdh")).asSubclass(XDH.class);
xdh=c.getDeclaredConstructor().newInstance();
xdh.init(curve_name, key_len);
Q_C = xdh.getQ();
buf.putString(Q_C);
}
catch(Exception | NoClassDefFoundError e){
throw new JSchException(e.toString(), e);
}
if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if(session.getLogger().isEnabled(Logger.INFO)){
session.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_ECDH_INIT sent");
session.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_ECDH_REPLY");
}
state=SSH_MSG_KEX_ECDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_ECDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_ECDH_REPLY
// string K_S, server's public host key
// string Q_S, server's ephemeral public key octet string
// string the signature on the exchange hash
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_ECDH_REPLY){
System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j);
return false;
}
K_S=_buf.getString();
byte[] Q_S=_buf.getString();
// RFC 5656,
// 4. ECDH Key Exchange
// All elliptic curve public keys MUST be validated after they are
// received. An example of a validation algorithm can be found in
// Section 3.2.2 of [SEC1]. If a key fails validation,
// the key exchange MUST fail.
if(!xdh.validate(Q_S)){
return false;
}
K = xdh.getSecret(Q_S);
K=normalize(K);
byte[] sig_of_H=_buf.getString();
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, client's identification string (CR and LF excluded)
// string V_S, server's identification string (CR and LF excluded)
// string I_C, payload of the client's SSH_MSG_KEXINIT
// string I_S, payload of the server's SSH_MSG_KEXINIT
// string K_S, server's public host key
// string Q_C, client's ephemeral public key octet string
// string Q_S, server's ephemeral public key octet string
// mpint K, shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
// RFC 8731,
// 3.1. Shared Secret Encoding
// The shared secret, K, is defined in [RFC4253] and [RFC5656] as an
// integer encoded as a multiple precision integer (mpint).
// Curve25519/448 outputs a binary string X, which is the 32- or 56-byte
// point obtained by scalar multiplication of the other side's public
// key and the local private key scalar. The 32 or 56 bytes of X are
// converted into K by interpreting the octets as an unsigned fixed-
// length integer encoded in network byte order.
//
// The mpint K is then encoded using the process described in Section 5
// of [RFC4251], and the resulting bytes are fed as described in
// [RFC4253] to the key exchange method's hash function to generate
// encryption keys.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putString(Q_C); buf.putString(Q_S);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result = verify(alg, K_S, i, sig_of_H);
state=STATE_END;
return result;
}
return false;
}
@Override
public int getState(){return state; }
}

View File

@@ -1,37 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface ECDH {
void init(int size) throws Exception;
byte[] getSecret(byte[] r, byte[] s) throws Exception;
byte[] getQ() throws Exception;
boolean validate(byte[] r, byte[] s) throws Exception;
}

View File

@@ -1,36 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.io.*;
public interface ForwardedTCPIPDaemon extends Runnable{
void setChannel(ChannelForwardedTCPIP channel, InputStream in, OutputStream out);
void setArg(Object[] arg);
}

View File

@@ -1,38 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2004-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface GSSContext{
public void create(String user, String host) throws JSchException;
public boolean isEstablished();
public byte[] init(byte[] token, int s, int l) throws JSchException;
public byte[] getMIC(byte[] message, int s, int l);
public void dispose();
}

View File

@@ -1,38 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface HASH{
void init() throws Exception;
int getBlockSize();
void update(byte[] foo, int start, int len) throws Exception;
byte[] digest() throws Exception;
default String name() {return "";}
}

View File

@@ -1,150 +0,0 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2002-2018 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class HostKey{
private static final byte[][] names = {
Util.str2byte("ssh-dss"),
Util.str2byte("ssh-rsa"),
Util.str2byte("ecdsa-sha2-nistp256"),
Util.str2byte("ecdsa-sha2-nistp384"),
Util.str2byte("ecdsa-sha2-nistp521"),
Util.str2byte("ssh-ed25519"),
Util.str2byte("ssh-ed448")
};
public static final int UNKNOWN=-1;
public static final int GUESS=0;
public static final int SSHDSS=1;
public static final int SSHRSA=2;
public static final int ECDSA256=3;
public static final int ECDSA384=4;
public static final int ECDSA521=5;
public static final int ED25519=6;
public static final int ED448=7;
protected String marker;
protected String host;
protected int type;
protected byte[] key;
protected String comment;
public HostKey(String host, byte[] key) throws JSchException {
this(host, GUESS, key);
}
public HostKey(String host, int type, byte[] key) throws JSchException {
this(host, type, key, null);
}
public HostKey(String host, int type, byte[] key, String comment) throws JSchException {
this("", host, type, key, comment);
}
public HostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException {
this.marker=marker;
this.host=host;
if(type==GUESS){
if(key[8]=='d'){ this.type=SSHDSS; }
else if(key[8]=='r'){ this.type=SSHRSA; }
else if(key[8]=='e' && key[10]=='2'){ this.type=ED25519; }
else if(key[8]=='e' && key[10]=='4'){ this.type=ED448; }
else if(key[8]=='a' && key[20]=='2'){ this.type=ECDSA256; }
else if(key[8]=='a' && key[20]=='3'){ this.type=ECDSA384; }
else if(key[8]=='a' && key[20]=='5'){ this.type=ECDSA521; }
else { throw new JSchException("invalid key type");}
}
else{
this.type=type;
}
this.key=key;
this.comment=comment;
}
public String getHost(){ return host; }
public String getType(){
if(type==SSHDSS ||
type==SSHRSA ||
type==ED25519 ||
type==ED448 ||
type==ECDSA256 ||
type==ECDSA384 ||
type==ECDSA521){
return Util.byte2str(names[type-1]);
}
return "UNKNOWN";
}
protected static int name2type(String name){
for(int i = 0; i < names.length; i++){
if(Util.byte2str(names[i]).equals(name)){
return i + 1;
}
}
return UNKNOWN;
}
public String getKey(){
return Util.byte2str(Util.toBase64(key, 0, key.length, true));
}
public String getFingerPrint(JSch jsch){
HASH hash=null;
try{
String _c=JSch.getConfig("FingerprintHash").toLowerCase();
Class<? extends HASH> c=Class.forName(JSch.getConfig(_c)).asSubclass(HASH.class);
hash=c.getDeclaredConstructor().newInstance();
}
catch(Exception e){ System.err.println("getFingerPrint: "+e); }
return Util.getFingerPrint(hash, key, false, true);
}
public String getComment(){ return comment; }
public String getMarker(){ return marker; }
boolean isMatched(String _host){
return isIncluded(_host);
}
private boolean isIncluded(String _host){
int i=0;
String hosts=this.host;
int hostslen=hosts.length();
int hostlen=_host.length();
int j;
while(i<hostslen){
j=hosts.indexOf(',', i);
if(j==-1){
if(hostlen!=hostslen-i) return false;
return hosts.regionMatches(true, i, _host, 0, hostlen);
}
if(hostlen==(j-i)){
if(hosts.regionMatches(true, i, _host, 0, hostlen)) return true;
}
i=j+1;
}
return false;
}
}

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