Compare commits

...

675 Commits

Author SHA1 Message Date
Jeroen van Erp
8f3d751431 Some cleanup of integration container and add integration test 2021-04-20 11:29:52 +02:00
Jeroen van Erp
9051c8c7e9 Merge branch 'master' into issue-670 2021-04-20 09:28:08 +02:00
Estraysian
e283880e49 Minor improvement for SCP preserve flag: (#680)
- Added an override for copy method, allowing the user to specify whether preserve flag is used in the SCP command.
- Propagated the preserveTime boolean to process method to skip preserveTimeIfPossible when it's not desired
2021-04-13 11:32:30 +02:00
Jeroen van Erp
cf7309c866 Add extra logging to troubleshoot issue #670 2021-03-30 12:00:34 +02:00
Jeroen van Erp
45b2f32b14 Fixed examples for 0.31.0 2021-03-29 11:39:49 +02:00
Jeroen van Erp
1d8eaa7ce2 Release version: 0.31.0 2021-02-08 22:21:35 +01:00
Jeroen van Erp
6eea9a993c VSCode files 2021-02-08 22:21:23 +01:00
Jeroen van Erp
67d2cf72d6 Prepare release notes for 0.31.0 2021-02-08 22:17:42 +01:00
Jeroen van Erp
b8d58389cf Merge branch 'informaticum-master' 2021-01-13 14:30:45 +01:00
Jeroen van Erp
c5f48f9888 Merge branch 'master' of github.com:informaticum/sshj into informaticum-master 2021-01-13 14:30:29 +01:00
Jeroen van Erp
c05c3307b3 Update dependencies
- BouncyCastle 1.68
- asn-one 0.5.0
- slf4j-api 1.7.30
2021-01-13 10:41:01 +01:00
Vladimir Lagunov
9bc9262842 Support ED25519 and ECDSA keys in the PuTTY format (#660)
* Support ED25519 PuTTY keys.

Fix #659

* PuTTYKeyFile: Use net.schmizz.sshj.common.Buffer instead of own KeyReader.

A tiny refactoring made in order to allow usage of other utility methods which require Buffer.

* Support ECDSA PuTTY keys.

* Some code cleanup

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2021-01-08 22:44:19 +01:00
Fabian Bonk
6d7dd741de Bump bouncycastle version (#655) 2020-12-21 13:41:11 +01:00
stefan
7f8328f23f Backdate license to prevent build's "License violations" (#653) 2020-12-12 20:10:32 +01:00
stefan
be18cc6e6a Add license prelude (#653) 2020-12-12 20:03:42 +01:00
stefan
ee68e0a8e6 Adopt project's import order (#653)
- copied by import order of 'SocketStreamCopyMonitorTest'
2020-12-12 20:03:12 +01:00
stefan
9266b6c04a Testing #toString of Parameters (#653) 2020-12-12 20:00:43 +01:00
stefan
9e9797c326 Adding #toString to Parameters (#653) 2020-12-12 19:58:31 +01:00
stefan
ee7a65531f Testing #equals of Parameters (#653) 2020-12-12 19:58:19 +01:00
stefan
8337cce382 Adding #equals to Parameters (#653) 2020-12-12 19:58:05 +01:00
stefan
bc5a119169 Testing #hashCode of Parameters (#653) 2020-12-12 19:57:51 +01:00
stefan
cda04809e1 Adding #hashCode to Parameters (#653) 2020-12-12 19:56:56 +01:00
Henning Poettker
07d624b1df reduced log level for lenient handling of missing CR at end of identification (#647) 2020-11-24 15:03:11 +01:00
Jeroen van Erp
60aa230929 Update release notes for upcoming 0.31.0 2020-11-17 14:47:18 +01:00
Fabian Henneke
2edaf07e71 Improve Android compatibility (#636)
* Loop through security providers to check for BC

Instead of only counting BouncyCastle as being registered if it
is set as the explicit security provider used by SSHJ, count it as
registered if it is available as a provider.

This commit improves Android compatibility, which requires not
specifying an explicit provider.

* Generify BC-specific curve specifiers

The ECNamendCurveGenParameterSpec is a BC-specific workaround for
missing curve tables in Java 1.4 and earlier. For the sake of Android
compatibility, where Conscrypt can't deal with this custom spec class,
replace it with the standard ECGenParameterSpec and update the curve
names to the standard identifiers.
2020-10-20 09:57:51 +02:00
Fabian Henneke
d124607225 Fix PR links in README (#632) 2020-09-10 09:26:08 +02:00
Jeroen van Erp
8c899eb867 Fix warnings 2020-09-09 11:02:28 +02:00
Jeroen van Erp
939a170ee8 Update README 2020-09-09 10:37:56 +02:00
Raymond Lai
143069e3e0 Implement AES-GCM cipher support (#630)
* Implement AES-GCM cipher support

Fixes #217.

A port of AES-GCM cipher support from Apache MINA-SSHD, based on https://github.com/apache/mina-sshd/pull/132.

Included tests for decoding SSH packets sent from Apache MINA-SSHD and OpenSSH (Version 7.9p1 as used by Debian 10).

Manual tests also done on OpenSSH server 7.9p1 running Debian 10 with its available ciphers, including 3des-cbc, aes128-cbc, aes192-cbc, aes256-cbc, aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com and aes256-gcm@openssh.com.

* Changes per PR feedback

- Fixed variable/statement whitespaces and add back missing braces per coding standard requirement
- Moved Buffer.putLong() and Buffer.getLong() into GcmCipher.CounterGCMParameterSpec since it's the only user
- Moved BaseCipher.authSize into GcmCipher since it is the only cipher that would return a non-zero. BaseCipher will keep return 0 instead
- Made BaseCipher.cipher protected instead of making it publicly accessible
- Combined the three decoding modes in Decoder.decode() into one single method, to reduce code duplication
- Added integration test for the ciphers, along with the newly implemented AES-GCM ciphers
2020-09-09 09:51:17 +02:00
Jeroen van Erp
4458332cbf Update release notes for 0.30.0 2020-08-25 15:56:15 +02:00
Pavel Dionisev
a0d7b7fd41 Avoid key lleakage. (#627)
In some cases, current code will leak parts or even the whole ssh key if it's slightly malformed.
One example of that malformation will be a key, where all newlines are replaced by other character, thus turning a multiline key to a single big string.
Then that whole line will be leaked to exception message.
2020-08-25 15:23:46 +02:00
Jeroen van Erp
b6213401db Release version: 0.30.0 2020-08-17 15:43:12 +02:00
Jeroen van Erp
19ec6d9d8d Made java 11 default java version 2020-08-17 15:42:58 +02:00
Jeroen van Erp
0ba491c01a Add testcase for reading signed certificate (Fixes #613) 2020-08-17 10:59:03 +02:00
Jeroen van Erp
73d7560e6e Add Reader constructor to OpenSSHKnownHosts (Fixes #626) 2020-08-17 10:23:37 +02:00
Vladimir Lagunov
0e0d730bbf Fix RSA certificate key determination. (#602)
* Fix RSA certificate key determination.

Fixes #599.

* Correct serialization of RSA certificates with unlimited dates.

* The test for connecting with RSA certificate.

* Remove redundant change in TransportImpl.java

* Add forgotten test keys.

* Make net.schmizz.sshj.common.KeyType.CertUtils.epochFromDate readable.

Co-authored-by: Vladimir Lagunov <vladimir.lagunov@jetbrains.com>
Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-07-31 09:43:11 +02:00
Fabian Henneke
6becee176a Fix matching of pubkeys to key algorithms (#607)
* Fix matching of pubkeys to key algorithms

Allow all configured key algorithms for pubkey authentication, even if
these algorithms are not supported as host key algorithms by the
server.

Preference is given to the modern rsa-sha2-* signature algorithms if
the server indicates support for them as host keys signature
algorithms.

* Replace Boolean with primitive boolean

* Add integration tests for ecdsa-sha2-nistp384/521

* Remove redundant import

* Clean up Transport interface

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-07-28 12:30:29 +02:00
Fabian Henneke
4b1619d54f Fix transport encoding of nistp521 signatures (#623)
SignatureECDSA.encode() does not correctly handle signatures longer
than 128 bytes, which affects signatures using the nistp521 curve.

This commits fixes the issue by replacing the ad-hoc ASN.1 DER
parsing with a use of ASN1InputStream.
2020-07-28 11:56:17 +02:00
Fabian Henneke
64f448d438 Send ext-info-c with kex algorithms (#622)
Some SSH servers will not honor the negotiated rsa-sha2-256 algorithms
if the client does not indicate support for SSH_MSG_EXT_INFO messages.
Since we only need to accept these messages, but are free to ignore
their contents, adding support amounts to sending "ext-info-c" with our
kex algorithm proposal.
2020-07-20 15:54:28 +02:00
Moritz Weichert
a5efdf1f0d Bump bonucycastle version (#619)
Co-authored-by: Moritz Weichert <moritz.weichert@check24.de>
2020-07-10 19:02:32 +02:00
Moritz Weichert
588853554a Fix localport for openssh >= 8.0 (#618)
Co-authored-by: Moritz Weichert <moritz.weichert@check24.de>
2020-07-09 11:29:47 +02:00
Fabian Henneke
7bde5c15c1 Clear passphrase bytes after use (#609)
Mimics the behavior of `decrypt()` in `PKCS5KeyFile.java`.
2020-07-01 21:34:31 +02:00
Fabian Henneke
3c85b86915 Always use JCERandom as the default RNG (#606)
The current implementation relies on `VMPCRandomGenerator` for random number generation if BouncyCastle is registered, otherwise it falls back to `SecureRandom`. Nowadays, `SecureRandom` should always be the best available option, whereas `VMPCRandomGenerator` [has known weaknesses](https://books.google.de/books?id=niO6BQAAQBAJ&pg=PA140&lpg=PA140&dq=vmpc+prng&source=bl&ots=QAdZJOT607&sig=ACfU3U0Edqlpm08iRZJLxeWGQNwNQz7WsQ&hl=en&sa=X&ved=2ahUKEwjd2Zyr9pfqAhXWMMAKHT70AioQ6AEwDnoECAoQAQ#v=onepage&q=vmpc%20prng&f=false).
2020-06-23 14:51:55 +02:00
Simon Legner
2ca0fa4732 Use daemon thread to avoid blocking JVM shutdown (#605) 2020-06-23 12:48:11 +02:00
dajoropo
769c896e53 Added method to created Stateful clients ( #268). (#603)
Co-authored-by: Daniel Rodriguez <daniel.rodriguez@elca.ch>
2020-06-22 12:05:11 +02:00
Fabian Henneke
eb19325bc6 Don't specify JcaPEM providers as null (#596)
* Don't specify JcaPEMKeyConverter provider as null

If no provider is set in the `SecurityUtils`, no named provider should be set for the `JcaPEMKeyConverter` as this would cause a `missing provider` exception.

* Don't specify JcePEMDecryptorProviderBuilder provider as null

If no provider is set in the `SecurityUtils`, no named provider should be set for the `JcePEMDecryptorProviderBuilder` as this would cause a missing provider exception. This currently breaks `PKCS8KeyFile` if `SecurityUtils.setSecurityProvider(null)` and `SecurityUtils.setRegisterBouncyCastle(false)` is used.
2020-06-08 09:47:30 +02:00
David Kocher
2d8af5a687 Allow to query for server extensions available. (#591)
Co-authored-by: Jöran Malek <joeran3@gmail.com>
2020-06-05 11:40:58 +02:00
David Kocher
c4fef33d8f Remove length restriction in key reader. (#595) 2020-06-05 11:35:27 +02:00
Jeroen van Erp
ff85e832af Update README.adoc 2020-06-05 11:14:39 +02:00
David Kocher
0dcb4b9a7a Review interface to return collection for allowed authentication methods that allows to query for elements. (#593) 2020-06-05 11:11:50 +02:00
Jeroen van Erp
2baf51bf64 Replace BC ASN.1 dependency with asn-one library 2020-06-02 23:40:08 +02:00
Jeroen van Erp
3194fd9bd0 Refactored KeyAlgorithms slightly 2020-06-02 23:22:55 +02:00
Jeroen van Erp
ab3f0143bd Update release notes 2020-06-02 16:39:56 +02:00
Jeroen van Erp
9671352bda Introduce KeyAlgorithm to separate KeyType from Algorithm (Fixes #588) (#589) 2020-06-02 16:39:22 +02:00
Jeroen van Erp
91105e6a07 Fix integration build 2020-06-02 14:07:31 +02:00
Fabian Henneke
4e802cec86 Make KeyType compatible with Android Keystore (#586)
* Make KeyType compatible with Android Keystore

Android Keystore private keys do not implement PrivateKey since the
raw key material is not available to applications.

With this commit, sshj's KeyType correctly detects the algorithm
associated with Android Keystore keys, which makes them usable for SSH
authentication.

* Extract RSA, DSA, ECDSA and EC into constants

* Fix license lint issue

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-05-28 16:09:43 +02:00
Fabian Henneke
dfdc464e08 Add pwdf retry logic to OpenSSHKeyV1KeyFile (#587)
* Add pwdf retry logic to OpenSSHKeyV1KeyFile

While PKCS8KeyFile uses PasswordFinder's shouldRetry to determine
whether it should call reqPassword again if decryption of they key file
fails, OpenSSHKeyV1KeyFile simply gives up and throws an exception.

With this commit, retry logic similar to that of PKCS8KeyFile is added
to OpenSSHKeyV1KeyFile. The PasswordFinder's reqPassword is called
again if the validation of the "checkint" fails, which indicates an
incorrect passphrase.

* Use new exception to signal incorrect passphrase

* Throw common exception on key decryption failure

* Add test coverage for retry logic

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-05-28 09:25:52 +02:00
Jeroen van Erp
fa7c40cc66 Use java12 for building due to gradle --release flag 2020-05-27 16:41:48 +02:00
Vladimir Lagunov
b1be9258b4 Fix NPE in OpenSSHKnownHosts (#579)
Co-authored-by: Vladimir Lagunov <vladimir.lagunov@jetbrains.com>
2020-05-26 14:56:29 +02:00
Jeroen van Erp
11543b2c00 Release version: 0.29.0 2020-05-12 11:30:41 +02:00
Jeroen van Erp
3526694558 Fix build for Java9 and up, verifying Java7 compat 2020-05-12 11:29:30 +02:00
Jeroen van Erp
d618156ede Fix bintray plugin version 2020-05-11 23:17:02 +02:00
Jeroen van Erp
98063680bc Release version: 0.28.0 2020-05-01 11:30:34 +02:00
Jeroen van Erp
17754a65fe Update build.gradle for newer gradle versions 2020-04-16 09:38:04 +02:00
Jeroen van Erp
2bb52fcf7d Add checks for Channel.isOpen to ChannelOutputStream (Fixes #440) 2020-04-14 22:23:35 +02:00
Jeroen van Erp
1a70023e2d Fix task exclusion for java9 2020-04-14 21:48:04 +02:00
Jeroen van Erp
5e25c017bf Remove animalSniffer from Java9 build 2020-04-14 20:42:25 +02:00
Jeroen van Erp
27a5039831 Fixes for GH Actions 2020-04-14 20:39:46 +02:00
Jeroen van Erp
c2d25a9d62 Upgrade release plugin 2020-04-14 20:00:41 +02:00
Jeroen van Erp
2a22809de2 Update gradle.yml 2020-04-14 19:55:24 +02:00
Vladimir Dimitrov
9d1f6d9d83 Making OpenSSHKnownHosts.EntryFactory public 2020-04-14 19:45:11 +02:00
Jeroen van Erp
4542d94440 Add GitHub actions workflow 2020-04-14 16:47:04 +02:00
Jeroen van Erp
46a0cbac9e Upgrade BouncyCastle (Fixes #572) 2020-04-14 16:00:29 +02:00
Jeroen van Erp
f470ddf219 Fix race condition on SERVICE_ACCEPT (Fixes #559) (#560) 2020-02-25 13:33:38 +01:00
Meteorite
d09276fe01 extract makeInetSocketAddress (by hostname) in SocketClient (#509)
to allow overriding with InetSocketAddress.createUnresolved for use with proxy

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-02-20 09:04:38 +01:00
Josh Soref
241c355e20 Spelling (#547)
* spelling: accommodate

* spelling: algorithms

* spelling: containing

* spelling: creating

* spelling: developed

* spelling: environment

* spelling: exception

* spelling: heartbeat

* spelling: hellman

* spelling: identifier

* spelling: initiated

* spelling: interface

* spelling: negotiated

* spelling: occurred

* spelling: possibility

* spelling: requesting

* spelling: strong

* spelling: successfully

* spelling: suspended

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-02-19 11:06:27 +01:00
Jeroen van Erp
56ef6c1223 Fix divide by zero in trace logging (Fixes #550) (#561) 2020-02-19 10:27:00 +01:00
Jason
989fb8cde6 Added comment field in HostEntry for end-of-line comments in known_hosts file (#517)
* Added comment field in HostEntry for end-of-line comments in known_hosts file.

* Also modified the getLine() method to return the comment, if it exists.

* Fixed implementation

* Add CODEOWNERS file

Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
2020-02-14 11:40:15 +01:00
Michiel ten Hagen
d10a33ec59 Use nano time instead of current time millis. (#552)
* Use nano time instead of current time millis.

* Add license header
2020-01-22 09:40:53 +01:00
Vladimir Lagunov
327a4c4c5b Forgive redundant spaces in OpenSSHv2 public keys and known_hosts (#524)
* Forgive redundant spaces in OpenSSHv2 public keys and known_hosts

Sometimes users copy-pastes private and public keys in text editors. It leads to redundant spaces
and newlines. OpenSSH can easily read such keys, so users expect from SSHJ the same.

* Fixed bugs in OpenSSH key file and known_hosts parsers

* OpenSSHKnownHosts should not throw errors while parsing corrupted records
2019-09-18 15:14:45 +02:00
Vladimir Lagunov
d5c045defd Fix non-ASCII passwords 2019-09-18 14:36:20 +02:00
Tobias Gruetzmacher
02b70ef427 Minor updates (#520)
* Update Gradle Wrapper to Gradle 4.10.3

* Update test dependencies
2019-08-04 08:57:44 +02:00
Adam Iwaniuk
fdf08ef3c9 Add support for tunneling via channels (#511) 2019-06-03 16:33:39 +02:00
Adam Iwaniuk
633b42fec8 Added support for RSA certificates as host key (#514)
* Added support for RSA certificates as host key

* removed not needed check

* added rsa cert signature verification test
2019-05-27 10:46:01 +02:00
Adam Iwaniuk
3c594d9a1c fix exception when parsing max possible date (#513)
* fix exception when parsing max possible date

* added test with rsa cert with large date
2019-05-27 10:12:45 +02:00
Jeroen van Erp
c2b9c0266d Refactored out duplicate code. 2019-05-08 14:07:46 +02:00
Jeroen van Erp
0e784dd171 Merge branch 'master' into jumping 2019-03-01 21:45:09 +01:00
Jeroen van Erp
f322a4b060 Updated ed25519-java to 0.3.0 2019-03-01 21:44:18 +01:00
Michał Wyrzykowski
0cd19284ee Fix local port forwarding disconnecting issue (#491)
* `SocketStreamCopyMonitor` closes channel after setting the one event. It doesn't wait for the second stream to finish the job.

* #317 Fix `SocketStreamCopyMonitor` to wait for all events before closing the channel.
2019-02-20 15:18:58 +01:00
Jeroen van Erp
a5017d55c8 Cleanup some code 2019-01-24 15:09:00 +01:00
Jeroen van Erp
2f7b181306 Release version: 0.27.0 2019-01-24 13:21:11 +01:00
Jeroen van Erp
20223d3614 Added release notes 2019-01-24 13:19:02 +01:00
Jeroen van Erp
cac340dd43 Add support for other keytypes to openssh-key-v1 keyfiles (#485)
* Added support for RSA to openssh-key-v1 keyfile

* Fixed exception

* Added ECDSA support to openssh-key-v1

* Added integration tests for different keytypes
2019-01-17 13:01:49 +01:00
Jeroen van Erp
00cd335f47 Moved tests to spock 2018-11-27 11:27:45 +01:00
Andremoniy
e14fb2f695 Expose the numeric code of the Response.StatusCode #473 (#474)
* Expose the numeric code of the Response.StatusCode #473

* Expose the numeric code of the Response.StatusCode #473
2018-11-27 10:22:00 +01:00
Pepijn Van Eeckhoudt
b0dee02bf9 Handle server initiated global requests (#472)
* Handle server initiated global requests

* Code layout
2018-11-26 15:16:43 +01:00
Jeroen van Erp
17c09eb471 Fixed integration test 2018-11-16 12:29:45 +01:00
Jeroen van Erp
0301d4537f Enable 'curve25519-sha256@libssh.org' in DefaultConfig (Fixes #464) 2018-11-16 11:48:15 +01:00
Jeroen van Erp
f71d34e106 Ignore bin/ directory 2018-11-16 11:13:09 +01:00
Jeroen van Erp
254f739ac1 Upgraded sshd to 2.1.0 2018-11-16 11:12:58 +01:00
Jeroen van Erp
aa201fa08c Add AES256-CBC to OpenSSHKeyV1KeyFile (Fixes #467) 2018-11-16 10:39:20 +01:00
Jeroen van Erp
8721269d0f Added EdDSA as first signature factory (Fixed #470) 2018-11-16 10:07:32 +01:00
Ben Manes
971ccf6273 Add lock timeout for remote action (fixes #466) (#468)
When the remove window size is expanded, a condition is waited on until
the remote server acknowledges and completes the action. If the server
does not respond, e.g. due to a connectivity issue, then this blocks the
client indefinitely. Instead the client waits up to the connection's
timeout (500 min default) and fails. This allows users to set a reasonable
timeout, fail their operations, and retry accordingly.
2018-11-16 09:33:48 +01:00
Andremoniy
813469646e Improving logging for KeyExchanger (#458) 2018-10-23 10:47:34 +02:00
OlivierSalasc
17c368f9c2 add Buffer capacity check for type UInt64 (#454) 2018-09-27 14:49:25 +02:00
Jeroen van Erp
4de9f8ab9f Add support for Encrypt-then-MAC MAC Algorithms (#450) 2018-08-28 13:22:31 +02:00
Jeroen van Erp
deff097170 Fix SFTPClient.mkdirs to not inadvertently prefix with '/' (#415) 2018-08-02 13:11:09 +02:00
Jeroen van Erp
7556a7f6f6 Updated license header 2018-07-25 12:59:25 +02:00
Jeroen van Erp
c5792fe4a8 Added Kex integration test 2018-07-25 10:34:52 +02:00
Jeroen van Erp
02cfeb9a6a Release version: 0.26.0 2018-07-24 14:27:54 +02:00
Jeroen van Erp
5e771382fe Updated license header 2018-07-24 14:24:28 +02:00
Jeroen van Erp
59e68f1ed7 Updated release plugin 2018-07-24 14:20:10 +02:00
Jeroen van Erp
7d07c1bb46 Refactored Macs and added hmac-ripemd1600@openssh.com 2018-07-24 14:18:02 +02:00
Jeroen van Erp
5bebe044aa Code cleanup, add { to single-line if 2018-07-12 14:55:03 +02:00
Jeroen van Erp
d2a16385da Upgraded BouncyCastle to 1.60 (Fixes #436) 2018-07-10 16:33:33 +02:00
Jeroen van Erp
adc0451b3f Cleanup OpenSSHKeyFile and add Disconnection test 2018-07-10 16:29:09 +02:00
Jeroen van Erp
df5e73f1e8 Close before interrupt LocalPortForwarder (Fixes #426) 2018-07-10 16:28:28 +02:00
Jeroen van Erp
eeeba57c73 Code formatting improvements. 2018-07-10 16:15:37 +02:00
Jeroen van Erp
db48ff85c0 Add support for encrypted ed25519 openssh-key-v1 files (Fixes #427) (#429) 2018-06-19 11:53:32 +02:00
Jeroen van Erp
49a450fb53 Fixed some codacy issues 2018-06-18 14:27:45 +02:00
Tom Caflisch
80d93ae8e7 Remove unnecessary nested try/finally (#417)
* Remove unnecessary nested try/finally

* This handles the case of your concern.

An even better solution would be to have SSHClient and Session implement Auto-Closable so then you don't have to worry about doing anything in the finally block!
2018-06-11 09:54:26 +02:00
Jeroen van Erp
42c52e4fe6 Fixed logging of Encoder to log correct sequence number 2018-04-30 09:30:28 +02:00
Jeroen van Erp
329966ecc4 Using UTF-8 encoding for PrivateKeyFileResource (Fixes #413) 2018-04-30 09:30:00 +02:00
Jeroen van Erp
10918f3201 Using forked gradle process for upload 2018-04-04 13:15:54 +02:00
Jeroen van Erp
b5f0d4c9fb Release version: 0.25.0 2018-04-04 13:05:02 +02:00
Jeroen van Erp
c10cb7f138 Fix release plugin? 2018-04-04 13:03:56 +02:00
Jeroen van Erp
81e26f4a7f Release version: 0.24.0 2018-04-04 12:00:30 +02:00
Jeroen van Erp
aa53effce8 Merge branch 'issue-358' 2018-03-22 22:50:51 +01:00
Jeroen van Erp
76e6e572b4 Merge branch 'master' into issue-358 2018-03-22 22:50:37 +01:00
Jeroen van Erp
2003a9f8c9 Add support for verifying multiple host entries (Fixes #405) 2018-03-21 23:54:25 +01:00
Jeroen van Erp
84a7677a62 Add support for hmac-ripemd-160 2018-03-05 13:00:41 +01:00
Jeroen van Erp
3bcd3530cf Renamed test to spec 2018-03-05 13:00:41 +01:00
Jeroen van Erp
a63f9ee8fd New version Base64 class 2018-03-05 13:00:41 +01:00
Jeroen van Erp
4be5a98ea3 Merge pull request #400 from maxd/public_constructor_of_host_entry
HostEntry constructor must be public
2018-02-20 23:16:41 +01:00
Maxim Dobryakov
26df2f3c23 HostEntry constructor must be public
Reasons:

1) SimpleEntry (was replaced to HostEntry) class had public constructor
2) HostEntry class can be used outside of sshj library to add entries to .known_hosts file (i.e. for implementation of interactive HostKeyVerifier)
2018-02-20 22:59:36 +03:00
Michael Prankl
39b72eed62 Android Compability, again ;-) (#392)
* Rework SecurityUtils and PKCS8KeyFile for usage with SpongyCastle.

* Specifying providerName for registration is unneccessary.

* Update AndroidConfig, fix imports.

* Workaround for Android 5.0 bug when SpongyCastle is the default JCE provider.

On Android 5.0 reading the version from the jar does throw a SecurityException due to a bug in Android (see https://issuetracker.google.com/issues/36993752). Including that Exception in the catch provides a workaround for that issue.
2018-01-30 16:22:05 +01:00
Jeroen van Erp
d55eb6d02e Fix build for windows 2018-01-24 21:34:29 +01:00
Jeroen van Erp
265e9d2916 Add extra logging in OpenSSHKnownHosts and extra test 2018-01-24 15:53:12 +01:00
Jeroen van Erp
0b6552654b Fix 'key spec not recognized' exception with ECDSA keys 2018-01-23 19:58:04 +01:00
Jeroen van Erp
dabe43dfdc Fixed headers 2017-12-28 13:18:30 +01:00
Jeroen van Erp
0f67fa2541 Added integration test for append scenario (Fixes #390) 2017-12-28 13:00:49 +01:00
Michael Prankl
54018a4a81 Update AndroidConfig (#389)
* Add EdDSA signature for AndroidConfig.

* Initialize KeyExchange- and FileKeyProviderFactories with registered "bouncyCastle" (in fact, SpongyCastle is registered).

See #308 for discussion.
2017-12-28 11:55:36 +01:00
Jeroen van Erp
ca81c2eea4 Added integration test to travis 2017-12-28 10:13:56 +01:00
Jeroen van Erp
048f84b42a Removed docker from travis yml as it is included in gradle build now 2017-12-28 10:10:46 +01:00
Jeroen van Erp
8ca6451d5d Fixed length bug in putString (Fixes #187) 2017-12-27 23:02:41 +01:00
Jeroen van Erp
5e1be8b1b0 Separated out integration tests 2017-12-27 23:01:59 +01:00
Jeroen van Erp
bc4da2ea8e Upgraded gradle to cope with java9 2017-12-27 15:02:42 +01:00
Jeroen van Erp
09fb2b9dc2 Merge pull request #385 from Igerly/ssh-with-docker-tests
Integration test(s) with OpenSSH server in Docker
2017-12-04 00:23:44 +01:00
Iger
4045d5a7ef - One more time 2017-12-03 23:10:56 +02:00
Iger
d0daa2c12f - desperation 2017-12-03 23:00:40 +02:00
Iger
64a2a4f779 - orly? 2017-12-03 22:55:18 +02:00
Iger
7cb1f8b11c - switch username back 2017-12-03 22:49:29 +02:00
Iger
73bc785ab4 - eh? 2017-12-03 22:40:41 +02:00
Iger
9d697ede12 - minor improvements 2017-12-03 22:28:02 +02:00
Iger
2b62492caf - grr, ip 2017-12-03 22:11:29 +02:00
Iger
a0f1aa7e2c - Fixed server keys
- Use sshj branding
2017-12-03 22:08:06 +02:00
Iger
0e981f7656 - try common format 2017-12-03 20:25:26 +02:00
Iger
a014567c9e - still -d 2017-12-03 20:05:26 +02:00
Iger
8454cf1a0c - double before_install 2017-12-03 19:44:05 +02:00
Iger
663f118d0f - yaml-yaml 2017-12-03 19:36:20 +02:00
Iger
47d73a9381 - account for different working dir 2017-12-03 19:31:31 +02:00
Iger
c4552d5f3d - fix ip for online testing 2017-12-03 19:18:21 +02:00
Iger
7a884d0938 - Experimenting with travis 2017-12-03 19:10:08 +02:00
Jeroen van Erp
661f63eab7 Updated builds to include CodeCov 2017-11-30 11:33:13 +01:00
Jeroen van Erp
a71a7d7d33 Fix escaping in WildcardHostMatcher (#382)
* Escape '[' and ']' in WildcardHostMatcher

* Anchoring regex to match entire string (Fixes #381)
2017-11-13 15:49:48 +01:00
Jeroen van Erp
d2e0f50d0c Updated build plugins 2017-11-09 15:22:34 +01:00
Jeroen van Erp
b41f0acd19 Using new release plugin 2017-10-16 12:38:55 +02:00
Jeroen van Erp
a1f501a027 Updated README for v0.23.0 release 2017-10-13 16:19:27 +02:00
Jeroen van Erp
fef9cfaf79 Merge pull request #369 from charlesrgould/migrate-block-ciphers
Migrate remaining block ciphers
2017-10-11 23:50:02 +02:00
Charles Gould
c67ae242f2 Migrate remaining block ciphers 2017-10-11 17:34:18 -04:00
charlesrgould
823f1e5759 Log security provider registration failures (#374) 2017-10-11 23:21:49 +02:00
paladox
f046a41750 Update net.i2p.crypto:eddsa to 0.2.0 (#372)
* Update net.i2p.crypto:eddsa to 0.2.0

* Update net.i2p.crypto.eddsa to 0.2.0

* Update net.i2p.crypto.eddsa to 0.2.0

* Update net.i2p.crypto.eddsa to 0.2.0
2017-10-11 21:47:51 +02:00
charlesrgould
c161fe26f6 Extracted ASN.1/DER encoding to method (#368) 2017-10-04 11:06:37 +02:00
Jeroen van Erp
ec46a7a489 Fix decoding signature bytes (Fixes #355, #354) (#361)
* Fix for signature verify in DSA

* Cleaned up signature verification

* Fixed import

* Ignored erroneous pmd warnings

* Updated JavaDoc
2017-09-29 13:23:21 +02:00
Jeroen van Erp
762d088388 Added support for new-style fingerprints (#365)
* Added support for new-style fingerprints

* Fixed codacy warnings
2017-09-28 14:01:04 +02:00
Jeroen van Erp
99c85672b8 Added 'out/' to gitignore 2017-09-19 17:23:26 -04:00
Jeroen van Erp
28d57840ab Organised imports 2017-09-19 17:22:55 -04:00
Charles Gould
2984291d84 Removed deprecated method 2017-09-07 23:18:46 +02:00
Charles Gould
bdbd9d7eb5 Disambiguated signature initialization 2017-09-07 23:18:46 +02:00
Jeroen van Erp
9ac55de26c Fixed Java9 build? 2017-09-07 21:54:42 +02:00
Jeroen van Erp
a9928c2882 fixed build 2017-09-05 15:58:10 +02:00
Jeroen van Erp
c6c9a3f6a8 Correctly determine KeyType for ECDSA public key (Fixes #356) 2017-09-05 15:23:47 +02:00
Jeroen van Erp
0918bc626f Improved test stability 2017-08-24 13:59:58 +02:00
Jeroen van Erp
aa7748395d Removed build of broken openJDK7 in favour of using animal-sniffer to detect java 1.6 compatibility 2017-08-24 13:18:27 +02:00
Jeroen van Erp
cf077e2a4f Removed use of DataTypeConverter as that is no longer in default JDK9 2017-08-24 11:20:35 +02:00
Jeroen van Erp
c58c7c7c60 Added gradle caching to travis config 2017-08-24 09:32:24 +02:00
Jeroen van Erp
0b548d9d13 Removed oraclejdk7 as that is no longer supported on trusty, added openjdk 2017-08-24 09:30:03 +02:00
Jeroen van Erp
eb1629f250 Updated README release notes 2017-08-24 09:11:58 +02:00
Jeroen van Erp
8856aaea61 Fixed codacy 2017-08-22 19:32:45 +02:00
Jeroen van Erp
1f6615b57a Check whether filename is a child of the current file (Fixes #341) 2017-08-22 19:32:45 +02:00
Olli Helenius
a96fbfcf2f Merge branch 'master' into jumping 2017-07-29 10:16:36 +03:00
Matt Dailey
e5084ed8db Removed Builder, and fixed call to checkFormatString 2017-07-10 09:30:10 +02:00
Matt Dailey
3729119e23 Added assertions to testPromptFormat 2017-07-10 09:30:10 +02:00
Matt Dailey
aed3decf1d Upgraded Mockito, and added message and retries to ConsolePasswordFinder
* Upgraded Mockito to 2.8.47 (latest)
* Added extension to allow mocking final classes
* ConsolePasswordFinder allows custom message and number of retries
* Added builder for ConsolePasswordFinder
* Added more unit tests
2017-07-10 09:30:10 +02:00
Matt Dailey
303c03061c Add ConsolePasswordFinder to read from Console
* There was no example `PasswordFinder` to prompt
a user for their password
2017-07-10 09:30:10 +02:00
Olli Helenius
15e6924fc4 Fix indentation 2017-07-06 22:44:31 +03:00
Olli Helenius
9e8bef24c5 Add support for tunneling TCP/IP connections. 2017-07-06 22:32:56 +03:00
Iger
5e3a08a637 - boggle 2017-07-04 10:02:00 +02:00
Iger
d0800058e8 - Test ECDSA signature verifications 2017-07-04 10:02:00 +02:00
Iger
ad9c2d5411 - Test ECDSA fingerprints 2017-07-04 10:02:00 +02:00
Iger
ed65176b68 - Incorrect key format during write 2017-07-04 10:02:00 +02:00
Iger
28f3280a84 - license header 2017-07-04 10:02:00 +02:00
Iger
d69f722908 - Some more indentation fixes 2017-07-04 10:02:00 +02:00
Iger
1d7cb8c2c6 - Some more indentation fixes 2017-07-04 10:02:00 +02:00
Iger
6ad6242ed1 - Ident in spaces 2017-07-04 10:02:00 +02:00
Iger
3310530d42 - cleanup 2017-07-04 10:02:00 +02:00
Iger
3685f9dc36 - Formal generation of ASN.1 encoding for the ecdsa signature
- Support ecdsa-sha2-nistp521
2017-07-04 10:02:00 +02:00
Iger
f8cad120a6 - Pretty honed up implementation of -384 2017-07-04 10:02:00 +02:00
Iger
56dd4e4af4 - A separate enum members take with lots of code duplication 2017-07-04 10:02:00 +02:00
Jeroen van Erp
9f8cf1f298 Upgrade to gradle 4.0 2017-06-26 10:01:19 +02:00
Jeroen van Erp
a51270791d Remove deprecated ZLib usage 2017-06-26 09:56:37 +02:00
Jeroen van Erp
d43fc4551e Minor reformatting 2017-06-26 09:51:40 +02:00
Jan Peter Stotz
93bf6c0089 Fixed small exception logging problem 2017-06-09 11:58:24 +02:00
Jeroen van Erp
7b535a8db3 Added support for wildcard host entries in known_hosts (Fixes #331) 2017-05-22 14:43:30 +02:00
Jeroen van Erp
9d4f8fc46a Updated release notes 2017-04-25 15:32:44 +02:00
David Kocher
2b21ec6032 Fix regression from 40f956b. Invalid length parameter. (#322)
Also Fixes #306
2017-04-25 15:30:20 +02:00
Jeroen van Erp
8e15a8bd7d Updated README with release notes 2017-04-14 09:54:00 +02:00
Jeroen van Erp
531eb97767 Added log message for early identification termination 2017-04-14 09:14:52 +02:00
chqr
e36fd0fb3d Add support for authentication with DSA & RSA user certificates (#153) (#319)
* Add support for authentication with DSA & RSA user certificates (#153)

Updates:

- KeyType.java - add support for two certificate key types
    ssh-rsa-cert-v01@openssh.com
    ssh-dsa-cert-v01@openssh.com

- Buffer.java - allow uint64s that overflow Long.MAX_VALUE, otherwise
  we break on certificates with serial numbers greater Long.MAX_VALUE

- OpenSSHKeyFile, KeyProviderUtil - prefer public key files that end
  "-cert.pub" if they exist

Added new class Certificate, which represents certificate key

Reference:

https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD

* Use BigInteger for certificate serial numbers, address Codacy issues

* Address code review concerns
2017-04-14 08:49:16 +02:00
Jeroen van Erp
382321deca Updated README 2017-04-10 10:13:47 +02:00
Jeroen van Erp
7b75fb3d53 Upgraded Gradle to 3.4.1 2017-04-10 10:13:35 +02:00
Jeroen van Erp
4d84d3f67c Upgraded BouncyCastle (Fixes #312) 2017-04-10 10:08:09 +02:00
Jeroen van Erp
8eb7d1a2ad Update README to point to right repository (Fixes #309) 2017-03-23 14:05:32 +01:00
ISQ-GTT
a03fa9ac63 Added charset support, centralized UTF-8 usage (#305)
* Added charset support, centralized UTF-8 usage

* Code style, buffer methods with charsets

* assure remote charset isn't null
2017-03-09 13:58:51 +01:00
Jeroen van Erp
bcb15e6ccd Changed deprecated build notation 2017-03-01 21:53:42 +01:00
Jeroen van Erp
d85b22fe8d Upgrade to Gradle 3.4 2017-03-01 21:51:29 +01:00
Jeroen van Erp
f4b71941a3 Updated release notes for 0.20.0 2017-02-10 10:38:43 +01:00
Jeroen van Erp
636f896850 Cleaned up some code 2017-02-10 09:43:12 +01:00
Jeroen van Erp
56c0baf814 Merge pull request #301 from adagios/master
adds current version to exported classes
2017-02-06 10:16:45 +01:00
João Nelas
edfb069f2a adds current version to exported classes 2017-02-03 17:33:07 +00:00
Jeroen van Erp
65b3003e72 Merge pull request #295 from adagios/master
converts bouncycastle OSGi dep from Import-Bundle to Import-Package
2017-01-24 09:20:15 +01:00
Jeroen van Erp
fbee0b3956 Update build.gradle 2017-01-23 22:56:23 +01:00
Jeroen van Erp
fd60139b98 Merge branch 'master' into master 2017-01-23 22:54:15 +01:00
Jeroen van Erp
0b397bc3d7 Added TODO 2017-01-23 15:33:47 +01:00
Jeroen van Erp
40f956b4b6 More code cleanup 2017-01-23 15:33:22 +01:00
Jeroen van Erp
ef3f7a2eaf Fixed more warnings 2017-01-23 14:40:33 +01:00
Jeroen van Erp
8134113510 Cleaned up more PMD/Codacy warnings 2017-01-23 10:46:01 +01:00
Jeroen van Erp
c883c87963 Fixed a few warnings 2017-01-23 09:55:04 +01:00
Jeroen van Erp
920537dac9 More cleaning up 2017-01-20 16:41:16 +01:00
Jeroen van Erp
356ec9ed08 Upgraded to mina sshd 1.2.0 2017-01-20 16:30:01 +01:00
Jeroen van Erp
aa47b0c5f7 Cleaning up unused code 2017-01-20 16:29:37 +01:00
Jeroen van Erp
d3ed3cfe0f Merge pull request #296 from hierynomus/new-dhgroups
Added new DH groups
2017-01-20 16:17:06 +01:00
Jeroen van Erp
786734ce26 Suppressing Method naming conventions for Factory classes 2017-01-20 15:43:36 +01:00
Jeroen van Erp
9cb5bf4e10 Organized imports 2017-01-20 15:26:21 +01:00
Jeroen van Erp
0e3f7c2bbf Added new DH groups 2017-01-20 15:05:18 +01:00
João Nelas
66d4b34eba re-adding Export-Package of com.hierynomus.sshj.* 2017-01-12 14:37:02 +00:00
João Nelas
aafb9942a3 converts bouncycastle OSGi dep from Import-Bundle to Import-Package
Import-Bundle is generally discouraged by OSGi best practices.

See http://stackoverflow.com/questions/1865819/when-should-i-use-import-package-and-when-should-i-use-require-bundle for more info.
2017-01-12 14:26:59 +00:00
Jeroen van Erp
d1dff550ce Updated OSGi bundling (Fixes #255 again) 2017-01-11 23:14:43 +01:00
Jeroen van Erp
ac2720becd Added bettercodehub config 2017-01-10 17:45:37 +01:00
Jeroen van Erp
48dd1fdc41 Merge pull request #294 from joval/master
Reference the EdDSANamedCurveTable constant instead of its value...
2017-01-09 11:21:13 +01:00
Jeroen van Erp
9826a71d2b Merge pull request #293 from adagios/osgi-fix
excludes net.i2p.crypto.eddsa.math from OSGI Import-Package
2017-01-09 11:20:48 +01:00
David A. Solin
936eb26e9e Reference the EdDSANamedCurveTable constant instead of its value, for forward-compatibility with the ed25519-java project on Github.
See: abdee146c3
2017-01-06 12:58:04 -06:00
João Nelas
9438157b93 excludes net.i2p.crypto.eddsa.math from OSGI Import-Package 2017-01-06 15:12:44 +00:00
Jeroen van Erp
7d326e5ae4 Updated example build 2016-12-30 09:26:43 +01:00
Jeroen van Erp
f038b5ce2b Updated Release notes 2016-12-30 09:26:00 +01:00
Jeroen van Erp
20879a4aa5 LocalPortForwarder interrupts its thread on close() 2016-12-29 16:06:57 +01:00
Jeroen van Erp
516abb0282 Disable version inference when no git history present (Fixes #256) 2016-12-28 10:09:48 +01:00
Jeroen van Erp
0ad51709c2 Use the configured Random factory in DH KEX (Fixes #292) 2016-12-28 10:00:24 +01:00
Jeroen van Erp
c9c68f019e StreamCipher can use the constructor without random. 2016-12-28 09:52:58 +01:00
Jeroen van Erp
fc75f9796c Added logging to trace time creation of Randoms 2016-12-28 09:52:20 +01:00
Jeroen van Erp
61af500c3e Added 'classes' directory to ignore 2016-12-28 09:51:03 +01:00
Jeroen van Erp
56553ea086 Prepared release notes 2016-12-23 11:58:49 +01:00
Jeroen van Erp
86e6631b1e Enabled PKCS5 in DefaultConfig 2016-12-23 11:54:43 +01:00
Jeroen van Erp
b6f437a932 Merge pull request #291 from joval/master
Two minor changes
2016-12-21 21:51:23 +01:00
David Solin
9e3b9f7c24 Obtain the sshj.properties resource from the ClassLoader that loaded the DefaultConfig class, not from the context classloader. 2016-12-21 10:04:56 -06:00
David Solin
766ab916ee Use cause message when initializing an SSHRuntimeException from a Throwable. 2016-12-21 07:48:02 -06:00
Jeroen van Erp
cdca43a848 Merge pull request #284 from gatesking/patch-1
Catch interrupt signal in keepalive thread
2016-11-30 09:42:29 +01:00
gatesking
3ce7c2ebfb Catch interrupt signal in keepalive thread
Interrupt signal may be catched when keepalive thread is sleeping. As a result, it will still go into conn.getTransport().die(e).
2016-11-30 09:30:57 +08:00
Jeroen van Erp
ca4e0bf2d7 Update README.adoc 2016-11-25 13:27:20 +01:00
Jeroen van Erp
2ca2bbd633 Prepared for next release 2016-11-25 13:14:48 +01:00
Jeroen van Erp
256e65dea4 Build jar with correct version string automatically (Fixes #280) 2016-11-23 13:30:37 +01:00
Jeroen van Erp
1feb7fe9a6 Update README.adoc 2016-10-31 09:57:12 +01:00
Jeroen van Erp
d95b4db930 Merge pull request #279 from hierynomus/issue-276
Support for OpenSSH new key file format (fixes #276)
2016-10-31 09:55:47 +01:00
Jeroen van Erp
677f482a69 Fixed text 2016-10-28 16:31:23 +02:00
Jeroen van Erp
179b30ef4e Fixed some codacy warnings 2016-10-28 14:50:37 +02:00
Jeroen van Erp
f59bbccc5f Fixed ed-25519 and openssh-key-v1 formats 2016-10-28 14:45:16 +02:00
Jeroen van Erp
bf34072c3a Reading first part of the new openssh key format 2016-10-24 09:49:45 +02:00
Jeroen van Erp
771751ca4c Fixed license header 2016-10-19 14:48:06 +01:00
Jeroen van Erp
968d4284a0 Extracted common key file methods into an abstract base class 2016-10-19 12:08:51 +01:00
Jeroen van Erp
63927a3e2b Setting version to 0.18.0 2016-09-30 11:43:02 +02:00
Jeroen van Erp
ac262f8086 Updated README for 0.17.3 2016-09-30 11:26:01 +02:00
Jeroen van Erp
6e56cd9d0a Changed release process to bintray 2016-09-30 11:03:22 +02:00
Jeroen van Erp
2f6025d9ba Merge branch 'CherifGh-gcif-patch-android-compat' 2016-09-30 10:38:22 +02:00
Jeroen van Erp
275e98e55b Refactored SecurityUtils a bit 2016-09-30 10:37:55 +02:00
Ghozzi Cherif
655d070571 Update AndroidConfig.java 2016-09-25 15:28:59 +02:00
Jeroen van Erp
c9775ca2c7 Fixed formatting warnings of Codacy 2016-09-13 15:34:08 +02:00
Jeroen van Erp
a2fb4fbd98 Merge pull request #271 from joval/master
Gracefully load OpenSSH known_hosts without requiring BouncyCastle
2016-09-13 15:21:09 +02:00
David Solin
6185ac4db8 Improvements per JVE. 2016-09-13 08:04:15 -05:00
David Solin
e420593fa9 Okay, more spaces Codacy, you win! 2016-09-09 16:03:45 -05:00
David Solin
68b924863e Fail gracefully when reading an OpenSSH Known Hosts file that uses key types requiring BouncyCastle, but we're not including BouncyCastle. 2016-09-09 14:39:21 -05:00
Jeroen van Erp
613ace1864 Upgrade to gradle 3.0 2016-09-05 11:32:59 +02:00
Jeroen van Erp
78e0ecd264 Merge pull request #270 from hierynomus/java6
Java6 re-enabled
2016-09-05 11:29:02 +02:00
Jeroen van Erp
64085e62f4 Removed openJDK6 as release plugin is incompatible 2016-09-05 09:54:15 +02:00
Jeroen van Erp
8c7d2fa8d0 Java6 re-enabled 2016-09-02 16:54:21 +02:00
Jeroen van Erp
766d292bad Merge pull request #269 from joval/master
Compatibility features
2016-09-02 16:46:56 +02:00
David Solin
a40957fffc Merge remote-tracking branch 'upstream/master' 2016-09-02 09:24:18 -05:00
David Solin
8ffd852e67 SPACES NOT TABS (like in Silicon Valley). 2016-09-02 09:16:26 -05:00
Jeroen van Erp
b90be512e7 REformatted 2016-09-02 16:08:26 +02:00
Jeroen van Erp
c0d49cf6b3 Removed dependency on VRallev ECC25519 library 2016-09-02 16:05:18 +02:00
David Solin
1b5b2b25b7 Merge branch 'master' into post-logging-factory 2016-09-02 06:45:58 -05:00
Jeroen van Erp
1dad19ca6e Merge pull request #267 from joval/logging-factory
Logging factory
2016-09-02 10:55:43 +02:00
David Solin
90fa26925d Merge branch 'logging-factory' into post-logging-factory 2016-08-29 15:19:57 -05:00
David Solin
9425300262 Better argument order for IdentificationStringParser constructor. 2016-08-29 15:19:06 -05:00
David A. Solin
f2bfe9bfcf Make Java-6 compatible. 2016-08-26 13:26:01 -05:00
David Solin
71498ad961 Added some features required to integrate sshj with Joval's remote jSAF provider.
1) Added boolean Channel.isEOF() method, for checking whether the server has sent EOF.
2) Added SFTP response constants to the Response enumeration
3) Spelling correction for the SYMLINK FileMode enum constant
2016-08-26 13:02:16 -05:00
David Solin
7b8b1cfdf5 Merge branch 'master' into logging-factory 2016-08-24 08:37:24 -05:00
David Solin
3f29879eca Test fixes 2016-08-24 08:35:08 -05:00
David Solin
79c1ae2bb0 Re-add public constructor used by Groovy 2016-08-24 08:08:33 -05:00
David Solin
819d411cf1 Merge branch 'master' of github.com:joval/sshj into logging-factory 2016-08-24 07:57:22 -05:00
David Solin
6579f6f710 Removed unnecessary DefaultLoggerFactory inner class from DefaultConfig
Fixed license header in LoggerFactory.java (via gradle licenseForamat)
2016-08-24 07:34:01 -05:00
David Solin
cf5830eda5 Indentation fixes. 2016-08-24 06:23:45 -05:00
Jeroen van Erp
36ad389ccf Merge pull request #266 from joval/master
Decryption fix and junit test updates for PKCS5
2016-08-24 13:04:36 +02:00
David Solin
f63a88ec9f Removed unnecessary import statements. 2016-08-23 19:24:11 -05:00
David Solin
7379a89268 Inadvertently added this class to a PR where it's not in-scope. 2016-08-23 19:18:51 -05:00
David Solin
219901211e Changes for injecting a LoggingFactory. 2016-08-23 19:13:43 -05:00
David Solin
8c1329036a Updated test case for PKCS5 over-"simplification", to prevent regression. 2016-08-23 19:08:03 -05:00
David Solin
733c19350c Un-break PKCS5 (I inadvertently over-simplified setting the salt length). 2016-08-23 17:40:00 -05:00
Jeroen van Erp
e5ec84c06a Merge pull request #265 from joval/master
Minor modifications to PKCS5KeyFile
2016-08-19 23:35:03 +02:00
David Solin
ed0156c985 Forgot to move 2 fields to the top of the file. 2016-08-19 15:54:48 -05:00
David Solin
6321685881 Moved constant declarations per codacy. 2016-08-19 15:51:07 -05:00
David Solin
f6b4d47945 Another missing import. This should be it. 2016-08-19 15:09:50 -05:00
David Solin
d198ef121c Missing import in test. 2016-08-19 15:04:55 -05:00
David Solin
7786468875 Simplification? 2016-08-19 15:00:12 -05:00
David Solin
0847e8460a Merge remote-tracking branch 'upstream/master' 2016-08-19 12:24:14 -05:00
David Solin
62b8726807 Fixed bug wherein PKCS5KeyFile messed up the data if a bad passphrase was used, which prevented decryption with a subsequent correct passphrase.
Also, made it possible for subclasses of PKCS5KeyFile to access the decrypted ASN.1 data directly (useful if you want to decrypt then store a PKCS5 key for later use elsewhere).
And I think I made the code a little prettier.
2016-08-19 12:18:49 -05:00
Jeroen van Erp
a6af27ae91 Added Codacy badge 2016-08-19 13:02:55 +02:00
Jeroen van Erp
628cbf5eba Organized imports 2016-08-19 12:57:37 +02:00
Jeroen van Erp
e134e00574 Merge pull request #263 from joval/master
Modifications for working with SSH gateways
2016-08-17 08:41:33 +02:00
David Solin
1caa7ac722 For null hostnames, use the loopback InetAddress (for backward-compatibility). 2016-08-16 10:26:57 -05:00
David Solin
4183776adb Updates per Jeroen van Erp. 2016-08-16 09:17:30 -05:00
David Solin
791f112752 Merge remote-tracking branch 'upstream/master' 2016-08-15 09:27:10 -05:00
Jeroen van Erp
233f3765c9 Added PKCS5 key file support (#262) 2016-08-15 15:49:47 +02:00
Jeroen van Erp
5f292d398f Fixed toString of FileAttributes (Fixes #258) 2016-08-15 09:56:13 +02:00
David Solin
ba347f927d Close any LocalPortForwarders with the SSHClient that produced them (assuming they're still open). 2016-08-15 00:17:48 -05:00
David Solin
6f9ecf69e4 Reordered connect methods so that the similar ones are grouped together.
Also, eliminated all use of InetAddress.getByName, because we'll want to be able to connect even when the target host is only visible to DNS from the Proxy, or the SocketFactory.
2016-08-14 14:06:40 -05:00
David Solin
e78ae4dbeb 4th time's the charm? 2016-08-13 15:11:20 -05:00
David Solin
618f2fd111 String.format error was causing tests to unexpectedly fail. 2016-08-13 14:45:00 -05:00
David Solin
8503046302 Made the pkcs8-blanks file an actual pkcs8 file (so it doesn't fail the test). 2016-08-13 14:21:59 -05:00
David Solin
c6cde27e4b Oops, I shouldn't have encrypted the pkcs8 key file. 2016-08-13 11:00:00 -05:00
David Solin
113aa0aebd Updated KeyProviderUtil, KeyFormat, KeyProviderUtilTest and test resources to properly differentiate between PKCS5 and PKCS8 file formats. 2016-08-13 10:24:05 -05:00
David Solin
e7c50165c7 Removed GNUmake-related files from source control
Removed 3rd-party JARs from source control
Re-introduced original BouncyCastle-dependent PKCS5KeyFile class
Re-named non-BouncyCastle-dependent PKCS8KeyFile class to PKCS5KeyFile, since it really only supports PKCS5 formats anyway
2016-08-13 10:03:52 -05:00
David Solin
09616c4834 Tweaks 2016-08-12 20:03:08 -05:00
David Solin
df710d8dc9 Added getFingerprint method to SSH Known Host entry API.
Removed BouncyCastle dependency for public key authentication.
2016-08-12 19:58:09 -05:00
David Solin
df82774ea3 Added resources and GNUmake files.
Updated StreamCopier class to make it compatible with older SLF4J versions.
2016-08-10 21:45:30 -05:00
Jeroen van Erp
caa6cca665 Updated README for 0.17.2 and upcoming 0.17.3 release 2016-07-19 11:36:03 +02:00
Jeroen van Erp
9a5ccefb5d Removed dependency on net.i2p.crypto.eddsa.math classes (Fixes #255) 2016-07-19 11:22:13 +02:00
Jeroen van Erp
90f8c592b0 Prepped for v0.17.2 release 2016-07-07 11:03:05 +02:00
Jeroen van Erp
f491e8d101 Fixed bug that crept in 0edc4a5 2016-07-07 11:01:43 +02:00
Jeroen van Erp
77c10334f1 Updated for 0.17.1 release 2016-07-06 16:23:12 +02:00
Jeroen van Erp
0edc4a5787 Reimplemented parsing the identification (Fixes #176)
This ensures that any header lines sent before the identification
string do not break the identification parsing if they are longer
than the identification string should be.
2016-07-06 16:20:39 +02:00
Jeroen van Erp
b43cff07bf Updated README 2016-07-05 13:14:30 +02:00
Jeroen van Erp
1ab72b7eaf Ensure that same name subdirs aren't omitted when doing SFTP (#253)
* Updated version string in config

* Fixed #252 with backwards compatible behaviour

* Fixed logic and expanded test
2016-07-05 12:21:51 +02:00
Juraj Oprsal
3229584a95 made classes non-final to allow mocking (#250) 2016-05-20 14:59:31 +02:00
Jeroen van Erp
364a82154d Add correct source manifest headers for OSGI (#244) (Fixes #242)
* Improved OSGI sources manifest

* Added correct manifest entries for OSGI source bundle (Fixes #242)

* Removed empty sourceset
2016-04-15 11:01:50 +02:00
Jeroen van Erp
11fbf2964b Merge pull request #243 from valery1707/badges
Add some useful badges with automatic version detection: Maven and Javadoc
2016-04-14 20:39:39 +02:00
Valeriy.Vyrva
a248d50301 Add some useful badges with automatic version detection: Maven and Javadoc 2016-04-14 16:42:36 +06:00
Jeroen van Erp
fddc943565 updated release notes 2016-04-11 16:17:14 +02:00
Jeroen van Erp
ae834134d0 Release task depends on build and uploadArchives 2016-04-11 16:14:58 +02:00
Jeroen van Erp
bc41908694 Added gradle release and license plugins, and updated all license headers 2016-04-11 15:48:43 +02:00
Jeroen van Erp
bf1a855647 Updated README with release notes. 2016-04-11 15:08:24 +02:00
Jeroen van Erp
cd3b0a5bd6 Some cleanup 2016-04-11 15:05:54 +02:00
Jeroen van Erp
b01eccda4a Fixed bug in Forward lookup in which we did not deal with the special cases (Fixes #239) 2016-04-11 15:05:27 +02:00
Jeroen van Erp
4c9ebc306d Added OSGI manifest to -sources.jar (Fixes #242) 2016-04-11 10:56:18 +02:00
Jeroen van Erp
c3f75cda19 Fixed javadoc warning 2016-03-21 10:17:12 +01:00
Jeroen van Erp
1f0e2b1e69 Attempt to fix race condition if a packet is received from the server immediately after successful auth (Fixes #237) 2016-03-21 10:17:01 +01:00
Jeroen van Erp
8e55e50fd9 Fixed some Java7 warnings 2016-03-21 10:15:47 +01:00
Jeroen van Erp
eb8b7b51ca Added callback to request updated password for a user in case of USERAUTH_PASSWD_CHANGEREQ (Fixes #193) 2016-03-18 15:24:58 +01:00
Jeroen van Erp
a2cccd5cef Added javadoc to indicate that close() should always be called on a Command, before inspecting the result(s) (Fixes #114) 2016-03-18 13:31:25 +01:00
Jeroen van Erp
50403483da Implemented switch for waiting on server ident before sending client ident. (Fixes #118) 2016-03-18 13:24:33 +01:00
Jeroen van Erp
3c230a0fc4 Fixed potential race condition identified in #203 2016-03-18 13:11:59 +01:00
Jeroen van Erp
4f152749ce JavaDoc fixes 2016-03-18 13:11:03 +01:00
Jeroen van Erp
e0df6a5fb5 Organised some imports 2016-03-18 13:09:28 +01:00
Jeroen van Erp
f36c011844 Dropped Java6 support (Fixes #234) 2016-03-18 13:09:28 +01:00
Jeroen van Erp
94113eb6f5 Upgraded gradle to 2.12 2016-03-18 13:09:28 +01:00
Jeroen van Erp
0532f27a78 Merge pull request #238 from hierynomus/issue-236
Fix for race condition in global request response handling (fixes #236)
2016-03-18 11:29:01 +01:00
Jeroen van Erp
bd67135ffa Fixed race condition in global request response handling 2016-03-18 11:17:09 +01:00
Jeroen van Erp
ca49ca324f Added reproducing testcase 2016-03-18 10:53:15 +01:00
Jeroen van Erp
ac2ffbc367 Added settings.gradle with project name 2015-12-11 14:46:24 +01:00
Jeroen van Erp
dbb0eb0238 Ingoring integration test 2015-11-20 15:00:02 +01:00
Jeroen van Erp
347e6ad655 Set to snapshot 2015-11-20 14:47:38 +01:00
Jeroen van Erp
2622833831 Fixed typo in README 2015-11-20 14:47:17 +01:00
Jeroen van Erp
c0487c9ee5 v0.15.0 2015-11-20 14:46:06 +01:00
Jeroen van Erp
3372db75b5 Updated README with release notes 2015-11-20 13:52:40 +01:00
Jeroen van Erp
db75bad25c Added support for ed25519 keys (Fixes #220) 2015-11-20 13:48:59 +01:00
Jeroen van Erp
a73776ad40 Merge pull request #226 from hierynomus/ecdsa_fix
Correctly calculating ECDSA key fingerprint (Fixes #225)
2015-11-18 22:30:57 +01:00
Jeroen van Erp
237c7d18b6 Correctly calculating ECDSA key fingerprint (Fixes #225) 2015-11-18 22:19:15 +01:00
Jeroen van Erp
b7c8cda851 Refactored test to be reusable for other algorithm variants 2015-11-18 12:41:11 +01:00
Jeroen van Erp
2b6fedc939 Added all RFC Ciphers and some extended ones 2015-11-11 22:10:29 +01:00
Jeroen van Erp
51e1ff24e4 Merge pull request #223 from fingolfin/patch-1
README.adoc: fix typos (exhange -> exchange)
2015-11-10 09:40:38 +01:00
Max Horn
05efcb4889 README.adoc: fix typos (exhange -> exchange) 2015-11-10 08:39:55 +01:00
Jeroen van Erp
d456612d25 Now v0.14.0 for real, forgot buildfile 2015-11-04 10:32:49 +01:00
Jeroen van Erp
6feed72251 v0.14.0 2015-11-04 10:27:51 +01:00
Jeroen van Erp
67e44241d0 Upgraded wrapper 2015-11-04 10:27:46 +01:00
Jeroen van Erp
a2a5923767 Added todo comment 2015-11-04 10:27:39 +01:00
Jeroen van Erp
bdf9ab7452 Added missing key signature algorithm to README 2015-11-04 09:40:50 +01:00
Jeroen van Erp
afdfa91eb7 Added curve25519-sha256@libssh.org to the default config 2015-11-03 16:22:18 +01:00
Jeroen van Erp
29a6cf6f79 Added support for curve25519-sha256@libssh.org (Fixes #171) 2015-11-03 16:18:53 +01:00
Jeroen van Erp
eece80cf48 Enabled ecdh-sha2-nistp521 2015-11-03 13:47:04 +01:00
Jeroen van Erp
7973cb1ff6 Upgraded Apache SSHD to 1.0.0 2015-11-03 13:43:00 +01:00
Jeroen van Erp
75c0ae9a83 Updated readme with new kex algorithms 2015-11-02 15:31:31 +01:00
Jeroen van Erp
f2314e74ed Added support for ecdh-sha2-nistp256 and ecdh-sha2-nistp384 key exchange algorithms 2015-11-02 15:29:47 +01:00
Jeroen van Erp
e041e3e1e3 updated release notes 2015-10-29 12:37:17 +01:00
Jeroen van Erp
47df71c836 Implemented diffie-hellman-group-exchange Kex methods (Fixes #167) 2015-10-29 12:30:58 +01:00
Jeroen van Erp
e24ed6ee7b Merge pull request #216 from juddgaddie/master
Throw a SCPRemoteException when an error occurs on the remote server
2015-10-28 22:46:51 +01:00
gaddiej
10f8645ecd Throw a SCPRemoteException when an error occurs on the remote server. SCPRemoteException contains the error message returned from the remote server. 2015-10-24 13:54:49 +00:00
Jeroen van Erp
d520585a09 SCP remote path escaping is now configurable (Fixes #212, #184, #152) 2015-09-21 14:51:57 +02:00
Jeroen van Erp
28a11b0b45 Merge pull request #210 from iterate-ch/issue-209
Fix issue 209.
2015-08-18 18:55:50 +02:00
Jeroen van Erp
a335185827 Moved to SNAPSHOT 2015-08-18 17:30:25 +02:00
Jeroen van Erp
74a4012023 Merge pull request #208 from lguerin/bandwidth
SCP : limit the used bandwidth
2015-08-18 17:23:55 +02:00
Billy Keyes
c98ad22a7a Skip blank lines when detecting key formats
Some private keys found in the wild start with a blank line, which
breaks SSHJ. OpenSSH utilities worked as expected with these key files.

Also add some basic tests for key formats.
2015-08-18 14:25:13 +02:00
Jeroen van Erp
1c749da957 v0.13.0 2015-08-18 14:25:13 +02:00
David Kocher
5d81e87bce Fix issue 209. 2015-08-17 10:11:55 +02:00
lguerin
d18e9d9961 Refactor SCP arguments 2015-08-13 14:44:45 +02:00
lguerin
84990ada08 Fix typo 2015-08-13 14:41:09 +02:00
lguerin
9c424f9431 Remove underscores from Test method's name 2015-08-13 11:37:15 +02:00
lguerin
dec00efcaa Fix typo and clarify rate transfer comment 2015-08-13 10:49:56 +02:00
Jeroen van Erp
742553912c Move to new travis infra 2015-08-13 10:23:08 +02:00
lguerin
e81fdb8d8b Verbose failed tests 2015-08-13 09:36:02 +02:00
lguerin
782ff9b83e Add an option to limit the used bandwidth with SCP upload and download features 2015-08-12 16:55:08 +02:00
Jeroen van Erp
84d15f4cf5 Removed old pom 2015-08-03 14:06:55 +02:00
Jeroen van Erp
1ebcbb07ba Fixed examples build 2015-08-03 14:06:38 +02:00
Jeroen van Erp
9982e5c30e Added testcase for #194 2015-06-17 21:49:05 +02:00
Jeroen van Erp
3f340d6927 Updated version in default config 2015-06-17 16:17:36 +02:00
Jeroen van Erp
b8eec64a37 Added tests and categories 2015-06-17 16:04:01 +02:00
Jeroen van Erp
314d9d01cf Updated release notes 2015-06-17 13:04:32 +02:00
Jeroen van Erp
c526f8e3de Merge branch 'bkarge-issue-183' 2015-06-17 12:37:55 +02:00
Jeroen van Erp
9529c30105 Reformatted 2015-06-17 12:36:31 +02:00
Jeroen van Erp
6a476858d1 Added RemoteFileTest 2015-06-17 12:28:57 +02:00
Jeroen van Erp
6bfb268c11 Merge branch 'issue-183' of https://github.com/bkarge/sshj into bkarge-issue-183 2015-06-17 12:12:56 +02:00
Jeroen van Erp
e334525da5 Rewritten integration tests 2015-06-17 12:12:37 +02:00
Jeroen van Erp
8776500fa0 Merge pull request #201 from iterate-ch/feature/algorithms-verifier
Add option for client to verify negotiated key exchange algorithms.
2015-06-16 15:50:06 +02:00
David Kocher
a747db88ed Add option for client to verify negotiated key exchange algorithms. 2015-06-16 15:42:01 +02:00
Jeroen van Erp
97065264de Cleared some JavaDoc warnings 2015-06-16 14:12:36 +02:00
Jeroen van Erp
7c26ac669a Started better integration testing setup with Mina 2015-06-16 14:12:24 +02:00
Jeroen van Erp
1c5b462206 Merge pull request #195 from bluekeyes/feature/gss-api
Add support for "gssapi-with-mic" authentication (Kerberos)
2015-06-16 10:33:44 +02:00
Jeroen van Erp
4cb9610cdd Merge pull request #196 from Boris-de/fix_hostname_matching
bugfix: match complete host instead of contains on the hoststring
2015-06-16 10:23:52 +02:00
Billy Keyes
b9d0a03cb3 Add simple test for AuthGssApiWithMic
Mock enough of the JGSS API to avoid needing a real Kerberos
environment. I'm not sure how accurate this is, but it should test that
the client is sending the correct packets in the corect order.
2015-06-11 11:44:44 -07:00
Billy Keyes
4adc83b9df Expose GSSManager in AuthGssApiWithMic
The default implementation only supports Kerberos and encourages
subclassing, so there should be a way to provide subclasses.
2015-06-11 11:38:02 -07:00
Björn Karge
14edb33fa9 fix for issue 183 (sftp.RemoteFile.ReadAheadRemoteFileInputStream) (revised) 2015-06-04 10:50:13 +08:00
Björn Karge
8e74330b0b fix for issue 183 (sftp.RemoteFile.ReadAheadRemoteFileInputStream) 2015-06-03 14:36:23 +08:00
Boris Wachtmeister
5217d34198 bugfix: match complete host instead of contains on the hoststring
The SimpleEntry currently matches the hostname of the connection against
the complete hoststring of the entry. This way substrings also match, so
for example "10.0.0.1" matches on an entry for "10.0.0.10", resulting in
a host-key-changed message if the key differs which is usually does.
2015-05-28 21:57:25 +02:00
Billy Keyes
d3d019c1c2 Remove unused imports in SSHClient 2015-05-19 10:49:20 -07:00
Ben Hamme
49185b044d Added AuthGssApiWithMic for Kerberos auth 2015-05-18 15:00:11 -07:00
Jeroen van Erp
a18d623f44 Release notes for 0.12.0 2015-04-14 13:14:15 +02:00
Jeroen van Erp
6855873ffd removed release plugin 2015-04-14 12:57:40 +02:00
Jeroen van Erp
2ca8d8b19e Upgraded gradle 2015-04-14 12:03:38 +02:00
Jeroen van Erp
da32b145df Added braces to single-line statements 2015-04-13 11:50:34 +02:00
Jeroen van Erp
8ea6bb4a66 Updated README for fixed #181 and #180 issue 2015-04-01 11:28:14 +02:00
Jeroen van Erp
6cf767528a Added comment to check why that field is needed 2015-04-01 11:25:43 +02:00
Jeroen van Erp
b123a6ae30 Merge pull request #181 from iterate-ch/issue-180
Fix length field for SSH_FXP_WRITE packets.
2015-04-01 11:24:30 +02:00
Jeroen van Erp
4250c61e45 Deprecated Proxy connect methods, moved Sockets utility class to backport package 2015-03-31 09:27:13 +02:00
Jeroen van Erp
ace09fa8c8 Added support for HTTP CONNECT proxies by implementing custom Socket (Fixes #170) 2015-03-30 21:53:04 +02:00
Jeroen van Erp
8398b6e3c3 Revert "Added support for (unauthenticated) HTTP proxies (fixes #170)"
This reverts commit fc535a5e76.
2015-03-30 21:48:07 +02:00
Jeroen van Erp
3c1e0c1629 Updated readme 2015-03-27 16:04:42 +01:00
Andrew Kondratovich
e6c7c17664 Correctly closing channel and socket when LocalPortForwarder fails to open it. (Fix #175) 2015-03-27 16:02:07 +01:00
Jeroen van Erp
1e061aef25 Updated readme with work in progress for next release 2015-03-27 15:30:58 +01:00
Jeroen van Erp
66b772bac1 Compiling for JDK6, fixes #179 and #185 2015-03-27 15:25:45 +01:00
Jeroen van Erp
fc535a5e76 Added support for (unauthenticated) HTTP proxies (fixes #170) 2015-03-27 15:19:04 +01:00
Jeroen van Erp
c7373f05cc Merge pull request #186 from bluekeyes/fix/read-end-of-stream
Detect end-of-stream in TransportImpl#init
2015-03-16 10:34:47 +01:00
Billy Keyes
3ebd2eb363 Detect end-of-stream in TransportImpl#init
OpenSSH will drop connections based on the value of MaxStartups when
there are too many unauthenticated connection. When this happens, reads
on the client socket return -1, which was previously inserted into the
identification buffer, leading to the error in #118.
2015-03-13 15:34:18 -07:00
David Kocher
8638091517 Fix length field for SSH_FXP_WRITE packets. 2015-02-24 15:27:08 +01:00
hierynomus
5fc08a3fc8 back to snapshot 2015-01-23 10:08:51 +01:00
hierynomus
92df7c6924 v0.11.0 2015-01-23 10:07:43 +01:00
hierynomus
8c0967ca93 Preparing for 0.11.0 release 2015-01-22 12:40:53 +01:00
hierynomus
cb5b7f0943 Setting up integration testing 2015-01-22 09:47:11 +01:00
hierynomus
de2ede05e7 Added gradle wrapper 2015-01-21 10:27:26 +01:00
hierynomus
4a90f99c5f Not sending EOF on OutputStream close (reopens #143) 2015-01-21 10:25:28 +01:00
hierynomus
e348f698e6 test logging 2015-01-20 19:05:15 +01:00
hierynomus
d59efaa5f9 Fixed KeepAliveRunner for when service not yet set 2015-01-20 17:13:47 +01:00
hierynomus
83c5f2f815 Removed java version check from build file as it breaks project import 2015-01-20 09:32:38 +01:00
hierynomus
b17d3fe867 Fixed some warnings 2015-01-20 09:31:49 +01:00
hierynomus
3cefda5bd3 Processed review comments from @demobox. Thx! 2015-01-20 09:31:24 +01:00
hierynomus
18f364a283 Made signing optional 2015-01-19 22:09:41 +01:00
hierynomus
d68032a9b8 Improved test logging 2015-01-19 21:55:41 +01:00
hierynomus
c73ba8bfa7 Merge branch 'gradle' 2015-01-19 21:32:47 +01:00
hierynomus
7bbfd40627 Moved examples to own 'project' 2015-01-19 21:30:34 +01:00
hierynomus
7ae84be548 Fixed build by adding license headers to new files 2015-01-19 11:54:55 +01:00
hierynomus
f2793d1acf Added osgi bundling info 2015-01-19 10:48:53 +01:00
hierynomus
bca5883422 Gradle build files 2015-01-19 10:23:25 +01:00
hierynomus
3e54e2c955 Merge branch 'heartbeat' 2015-01-19 10:06:23 +01:00
hierynomus
a7802ddcde Added keep-alive mechanism that detects disconnects (Fixes #166) 2015-01-19 10:05:03 +01:00
hierynomus
a7872b394b Added braces and log message to HeartBeater 2015-01-16 10:33:25 +01:00
Jeroen van Erp
3ade3977ef Merge pull request #165 from Boris-de/fix_bsize_bug
Fix bsize bug
2015-01-12 09:51:06 +01:00
Jeroen van Erp
efb2c547f9 Merge pull request #164 from Boris-de/mac_unittests
added unit-tests for the "mac"-package
2015-01-12 09:49:56 +01:00
hierynomus
703a0df09d Revert "no biggie if we don't send EOF on ChannelOutputStream.close()"
This reverts commit d95586508d.
2015-01-12 09:18:42 +01:00
Boris Wachtmeister
73de5b7b08 bugfix: BaseMac would not use bsize in certain cases
The implementation of BaseMac would only take the bsize (size of the
hash) into account if the #doFinal(byte[], int) method was called.
Both other #doFinal methods would behave as if bsize==defbsize and
not cut the hash to the right size.
2015-01-11 21:00:16 +01:00
Boris Wachtmeister
665cbf078a added unit-tests for the "mac"-package 2015-01-11 20:56:36 +01:00
hierynomus
b3ea908996 Upgraded BouncyCastle to 1.51 (Fixes #142) 2015-01-09 14:53:24 +01:00
Jeroen van Erp
11da49a4e7 Merge pull request #141 from ziuchkovski/add-proxy-support
Add proxy support for SocketClient/SSHClient
2015-01-09 14:30:13 +01:00
Jeroen van Erp
5b1f9f2a7d Merge pull request #156 from Boris-de/fix_hmac-sha2
fixed block sizes for hmac-sha2-256 and hmac-sha2-512
2015-01-09 14:15:14 +01:00
hierynomus
268de458e3 Changed log levels (Fixes #161) 2015-01-09 13:45:17 +01:00
hierynomus
834f0f22cd Added gitignore 2015-01-09 13:43:38 +01:00
hierynomus
1daf456cbe Added optional OSGi resolution for jzlib (Fixes #162) 2015-01-09 13:37:01 +01:00
Jeroen van Erp
ea11d34ac8 Merge pull request #157 from Donnerbart/master
Fixed unbounded range in pom.xml
2015-01-09 13:28:25 +01:00
Jeroen van Erp
e961dc1b27 Merge pull request #163 from lichtin/master
Update README.adoc
2015-01-09 13:27:45 +01:00
lichtin
25fbff245f Update README.adoc
Fix link to Google group
2015-01-01 20:23:21 +01:00
Donnerbart
333c23e167 Fixed unbounded range in pom.xml:
[INFO] Failed to resolve artifact.

Unable to get dependency information: Unable to read the metadata file for artifact 'net.schmizz:sshj:jar': Invalid JDK version in profile 'doclint-java8-disable': Unbounded range: [1.8, for project net.schmizz:sshj
  net.schmizz:sshj:jar:0.10.1-SNAPSHOT
2014-11-17 13:37:34 +01:00
Boris Wachtmeister
cf32842d0d added hmac-sha2-256 and hmac-sha2-512 to the README 2014-11-16 17:33:19 +01:00
Boris Wachtmeister
70720de71b fixed block sizes for hmac-sha2-256 and hmac-sha2-512
Both MACs have to use larger block/digest sizes than SHA1.
Additionally the KEX must be changed so that it will resize
the keys "E" and "F" to get keys of the right size for those
MACs (according to section 7.2 of rfc4253)
2014-11-11 19:32:41 +01:00
hierynomus
44e1ce1358 Moved readme to asciidoc format 2014-10-27 10:53:43 +01:00
Jeroen van Erp
921f41f9de Update README.rst 2014-10-01 16:24:37 +02:00
hierynomus
34c4be848a removed default signing and staging plugins 2014-10-01 16:18:48 +02:00
hierynomus
d10e303b1a Added travis config 2014-10-01 16:12:27 +02:00
Shikhar Bhushan
46791c87f5 Merge pull request #148 from bluekeyes/bugfix/await-timeout
Use long for Channel#await timeout
2014-09-18 19:20:29 +05:30
Shikhar Bhushan
af0d873e5b Merge pull request #150 from dkocher/master
Change handle to byte[]. Fix interoperability issue with Tectia SSH Serv...
2014-09-18 19:20:13 +05:30
David Kocher
d37b54b1fd Change handle to byte[]. Fix interoperability issue with Tectia SSH Server. Refer to issue #54. 2014-09-10 11:10:42 +02:00
Billy Keyes
c4408ac6dd Use long for Channel#await duration
This matches the underlying method called by AbstractChannel and is the
standard for timeouts with a TimeUnit.
2014-09-02 15:00:51 -07:00
Bob Ziuchkovski
ebbf440304 Add proxy support for SocketClient/SSHClient 2014-08-13 18:58:45 -06:00
Shikhar Bhushan
ef5a54d33f Merge pull request #139 from dkocher/master
Add constructor with file offset.
2014-08-03 22:06:31 +05:30
David Kocher
66514836c8 Add constructor with file offset. 2014-07-29 14:17:51 +02:00
shikhar
e943d80049 onwards to 0.10.1-SNAPSHOT 2014-07-02 11:44:26 +05:30
shikhar
81931f3b7a restore accidently removed assembly plugin for examples jar 2014-07-02 11:42:15 +05:30
shikhar
b8bfc19ecf release plugin mgmt 2014-07-02 11:36:54 +05:30
shikhar
0cb62c6d44 next release will be 0.10.0 2014-07-02 11:17:40 +05:30
shikhar
0ccc57b5af consistent license headers using plugin 2014-07-02 11:13:22 +05:30
shikhar
4806b1d6c7 Read-ahead input stream moved to its own class, as it will not play nice with mark/reset/skip. Use it by defautl for SFTPFileTransfer.
Closes #76 - no longer a significant difference in scp & sftp transfer speed
2014-06-25 12:42:05 +05:30
shikhar
ecc1d06dc2 StreamCopier logging 2014-06-25 12:38:24 +05:30
shikhar
d95586508d no biggie if we don't send EOF on ChannelOutputStream.close() 2014-06-25 11:21:35 +05:30
shikhar
5ee2f0a417 get rid of over-zealous sending of channel EOF & close messages which was implemented with questionable synchronization
fixes #105

also relevant to #126 since AbstractChannel does not synchronize on
'this' anymore
2014-06-24 17:57:23 +05:30
shikhar
2a7278d239 some small tweaks to PKCS8KeyFile in relation to the PEMReader -> PEMParser transition 2014-06-24 14:21:40 +05:30
shikhar
0875417dde don't close underlying RemoteFile when closing streams of that file - reverts f34667521d 2014-06-24 14:20:04 +05:30
shikhar
0a3ad4f68f not handed over yet 2014-06-24 11:54:06 +05:30
shikhar
fe58ecdee5 Change CONTRIBUTORS to contain the relevant command for getting at this info 2014-06-22 17:25:01 +05:30
shikhar
264e10b40c support multiline password prompts #132 2014-06-22 17:21:54 +05:30
Shikhar Bhushan
a00015969b Merge pull request #136 from dkocher/master
HMAC-SHA2, PuTTY key format, concurrent read for downloads and bug fixes
2014-06-22 17:09:06 +05:30
David Kocher
d6c22fef55 ADd clirr-maven-plugin 2014-06-18 10:16:22 +02:00
David Kocher
9886facf42 Fix test. 2014-06-18 10:08:07 +02:00
David Kocher
01be48508d Throw SSHException for packet length exceeding max size. 2014-06-03 11:55:44 +02:00
David Kocher
bdc541c959 Format client identification. 2014-06-03 11:54:38 +02:00
David Kocher
f2ebbe288f Ignore socket timeout in read which occurs if we have set the timeout to > 0. We should continue reading from the stream unless the reader is interrupted. Note that with the default timeout set to 0, the reader thread will never return. 2014-05-16 22:21:00 +02:00
David Kocher
9297338195 Use plain server message. 2014-05-16 15:33:24 +02:00
David Kocher
a8d2ea2028 Add disconnect message from server. 2014-05-16 15:30:04 +02:00
David Kocher
f34667521d Close remote handles when closing stream. 2014-05-14 23:31:07 +02:00
David Kocher
77f5d7fdb8 Extract encode method for signature. Implement signing for ECDSA. 2014-05-14 12:33:46 +02:00
David Kocher
08d0e59b6b Logging 2014-05-14 11:06:33 +02:00
David Kocher
5c540b6889 Interrupt packet reader thread on close. 2014-05-14 11:03:46 +02:00
David Kocher
baa8c8e995 Merge branch 'master' of https://github.com/xardazz/sshj 2014-05-09 14:04:25 +02:00
David Kocher
f354fd6661 Implement read ahead to speed up transfer rates for downloads by a magnitude. 2014-05-09 13:43:52 +02:00
David Kocher
93f1543af8 Add PuTTY key file implementation. 2014-05-09 10:37:53 +02:00
David Kocher
63424657da Check index length. 2014-05-08 16:17:43 +02:00
David Kocher
131e85c4d0 Add write method to append single entry. 2014-05-07 17:02:18 +02:00
David Kocher
587684c6a8 Fix null pointer. 2014-05-07 17:01:45 +02:00
xardazz
66f67db21b Update KeyType.java
remove my common lib
2014-05-07 13:14:16 +04:00
David Kocher
3356f533d0 Add dependencyManagement. 2014-05-07 10:42:27 +02:00
David Kocher
97535bbcae Merge interfaces. 2014-05-07 10:37:14 +02:00
David Kocher
896b0ea288 Add provider with reader resource. 2014-05-06 21:22:12 +02:00
David Kocher
60d54fa5de Addendum 2014-05-06 21:21:23 +02:00
David Kocher
06e421e752 Extract formats. Add PuTTY to enum. 2014-05-06 15:41:35 +02:00
Alexey Gromov
b5796f5e74 fix version 2014-05-06 12:13:11 +04:00
Alexey Gromov
0f7355a277 add ecdsa 2014-05-06 12:09:50 +04:00
David Kocher
466ff99e1c Update BC dependency to 1.50. 2014-05-05 13:12:48 +02:00
David Kocher
1f992c3fae Ignore user auth banner in transport. 2014-05-05 13:12:10 +02:00
David Kocher
df6019accc Fix type of fileOffset to long. 2014-05-05 13:11:54 +02:00
David Kocher
fdb891b842 Add hmac-sha2-256 and hmac-sha2-512. 2014-05-05 13:11:27 +02:00
Shikhar Bhushan
5159a799df fix the fix for #90 - need to statExistence of targetCwd not cwd 2013-09-07 11:39:28 -04:00
shikhar
78e5a2e30e bump ident for 0.9.1 before i forget 2013-08-11 22:35:19 -04:00
shikhar
db22f08f97 [maven-release-plugin] prepare for next development iteration 2013-08-11 22:25:50 -04:00
shikhar
c8cfc796af [maven-release-plugin] prepare release v0.9.0 2013-08-11 22:25:46 -04:00
shikhar
d9c0c6725c for 0.9.0 2013-08-11 22:08:26 -04:00
shikhar
b2297c6b44 version bumps 2013-08-11 18:56:46 -04:00
shikhar
e10ad28f2f inherit from sonatype oss parent pom 2013-08-11 18:56:46 -04:00
shikhar
61fc00a90a fix javadoc warning 2013-08-11 18:56:46 -04:00
shikhar
c8ef7ff0ca 0.9.0 snapshot 2013-08-11 17:27:04 -04:00
shikhar
e6c4f6ae69 #90 - only update cwd state if stat succeeds 2013-08-11 17:16:40 -04:00
shikhar
3418df7a56 #114 - visibility issue 2013-08-11 16:04:49 -04:00
shikhar
0ddd1f38c5 Simplify the UserAuth.authenticate(..) interface, move the multi-auth-method trial-and-error into SSHClient API 2013-04-15 22:56:24 -04:00
shikhar
0ec6918d7a minor javadoc 2013-03-24 19:09:21 -04:00
shikhar
88a88c5dba change transport layer to use millisecond timeouts 2013-03-24 17:36:11 -04:00
shikhar
6656214803 change connection layer to use millisecond timeouts 2013-03-24 17:27:36 -04:00
shikhar
c781724028 whitespace 2013-03-24 14:55:09 -04:00
shikhar
eefaa26882 missing flush() during banner exchange 2013-03-24 14:54:38 -04:00
Shikhar Bhushan
0d52441f01 Add 'unconfirmed writes' feature to SFTP RemoteFileOutputStream, allowing for major speedups
Thanks to @romainreuillon for the idea and initial implementation! #97
2013-02-23 18:16:29 -05:00
Shikhar Bhushan
9539ff6b7a In SFTPEngine / Requester, move from using TimeUnit.SECONDS to TimeUnit.MILLISECONDS, and start using some more explicit naming 2013-02-23 16:26:37 -05:00
Shikhar Bhushan
1ced1d4fdc Get rid of Requester.doRequest(), replace with request() method that returns the response promise. Make getTimeout() part of the interface. 2013-02-23 16:22:28 -05:00
Shikhar Bhushan
77924fd0be Revert "Implement concurent write requests."
This reverts commit 9acff6202c.
2013-02-23 16:00:53 -05:00
Shikhar Bhushan
3f195649fa Merge pull request #98 from andreaturli/master
Updated bouncycastle dependency
2013-02-23 03:41:44 -08:00
Shikhar Bhushan
42a4358f5c Merge pull request #104 from mpoindexter/master
ArrayIndexOutOfBounds when writing to a SFTP RemoteFile's OutputStream with large buffer
2013-02-23 03:41:19 -08:00
mpoindexter
61ce0f4868 Fix ArrayIndexOutOfBounds when writing big buffer
If ChannelOutputStream.write(byte[], int, int) was called with a buffer larger 
than bufferSize the loop in that method would call DataBuffer.write with a small len
and a large off.  This would cause the calculation in line 90 to return a negative n
leading to a ArrayIndexOutOfBounds.  The offset should not be taken into account when
calculating the number of bytes to put in the buffer.
2013-02-21 21:05:20 -08:00
Shikhar Bhushan
777995af3b Merge pull request #97 from romainreuillon/master
Make write a lot faster
2013-01-06 12:30:14 -08:00
Andrea Turli
635cf88acd updatet bouncycastle dep to the latest version 2012-12-31 01:44:10 +01:00
Romain Reuillon
ce515fddcd Change the scope back to protected, the change was unwanted. 2012-12-12 08:33:32 +01:00
Romain Reuillon
9acff6202c Implement concurent write requests. 2012-12-12 08:29:26 +01:00
Shikhar Bhushan
cbd118e0b1 fix #84 - debug log good enough 2012-10-21 02:13:55 +05:30
Shikhar Bhushan
a8cf749d95 #87 - include full exception trace when logging transport death 2012-10-21 01:45:13 +05:30
Shikhar Bhushan
f3d4707ef0 fix #89 - use IllegalStateException from SSHClient when sanity-check assertions fail 2012-10-21 01:40:07 +05:30
Shikhar Bhushan
4c5da634ad don't do a looped cond.await(timeout, unit) as that handles spurious wakeups, and it'll be buggy if the wakeup is due to a call to clear() 2012-10-21 01:21:36 +05:30
Shikhar Bhushan
2fdafb76fd [maven-release-plugin] prepare for next development iteration 2012-07-08 09:55:32 -04:00
Shikhar Bhushan
80b164a299 [maven-release-plugin] prepare release v0.8.1 2012-07-08 09:55:22 -04:00
Shikhar Bhushan
75418f33b7 Next release to be 0.8.1 2012-07-08 09:50:43 -04:00
Shikhar Bhushan
732de2b605 make logs less chatty
#80
2012-07-05 00:10:40 +05:30
Shikhar Bhushan
4fb56b868f Per #77 use regex matching inside PasswordResponseProvider. Also remove the 'gaveAlready' state, we can leave such logic to the PasswordFinder to implement if needed. 2012-06-06 23:59:41 +01:00
Shikhar Bhushan
a877ec1448 AbstractChannel#close() should be no-op if already closed. Fixes #53. 2012-06-06 22:57:27 +01:00
Shikhar Bhushan
b44631ea97 Better naming for some AbstractChannel's lock/event members 2012-06-06 22:51:25 +01:00
Shikhar Bhushan
a50962ba2f Small cleanup 2012-05-19 11:18:30 +01:00
Shikhar Bhushan
e8215e4af2 Update NOTICE 2012-05-14 11:33:05 +02:00
Shikhar Bhushan
3c2bda3196 docfix - not part of the contract 2012-05-12 22:13:22 +01:00
Shikhar Bhushan
b13e22084b [maven-release-plugin] prepare for next development iteration 2012-05-12 21:48:45 +01:00
Shikhar Bhushan
e7ba0e1e26 [maven-release-plugin] prepare release v0.8.0 2012-05-12 21:48:39 +01:00
Shikhar Bhushan
f712720538 Update CONTRIBUTORS 2012-05-12 17:33:07 +02:00
Shikhar Bhushan
540708e540 Provide a preference SFTPFileTransfer.setPreserveAttributes() to not set file attributes post upload or download.
Should address issue #42 / pull request #43
2012-05-12 16:24:01 +01:00
Shikhar Bhushan
e4d3a1f866 Some documentation on the FileTransfer interface. 2012-05-12 16:03:57 +01:00
Shikhar Bhushan
33969340e2 small tweak 2012-05-12 14:37:07 +01:00
Shikhar Bhushan
d65df3c9bc - Move trailing slash removal from SFTPEngine.mkdirs() to PathHelper.getComponents()
- Try to make the PathHelper.getComponents() code clearer
- Added some tests for PathHelper.getComponents()
2012-05-12 14:28:28 +01:00
Shikhar Bhushan
d2b9248535 Decouple PathHelper and SFTPEngine, introduce Canonicalizer interface 2012-05-12 11:23:44 +01:00
Shikhar Bhushan
431be8e7c7 Lower the ceiling on max remote packet size (so we don't allocate huge buffers) & spell it out mor explicitly 2012-05-12 11:09:41 +01:00
Shikhar Bhushan
885c602ab8 Merge pull request #66 from UrsKR/trailingseparator
SFTP client no longer tries to create folders twice when path has trailing separator
2012-05-12 03:09:04 -07:00
Shikhar Bhushan
8262e8fc98 Update CONTRIBUTORS 2012-04-28 13:21:47 +02:00
Shikhar Bhushan
844c5d7f77 Merge pull request #73 from aledsage/Issue-72-Buffer-Too-Large
Issue 72: fix for infinite loop if allocate too large a buffer
2012-04-28 04:16:16 -07:00
Aled Sage
fb690c4fb0 Issue 72: fix for infinite loop if allocate too large a buffer (due to invalid packet size) 2012-04-26 11:43:29 +01:00
Shikhar Bhushan
ab04596a20 Merge pull request #69 from ludoza/patch-1
fixed simple example.
2012-04-15 03:00:18 -07:00
ludoza
9ffdc35f93 fixed simple example. 2012-04-11 18:02:40 +03:00
Shikhar Bhushan
93e23f4cfb Don't try to send a disconnect packet if never connected. Fixes GH-67. 2012-04-05 12:30:56 -04:00
Shikhar Bhushan
504637099d copyright 2012-04-05 12:30:55 -04:00
Shikhar Bhushan
cafd9217bf whitespace 2012-04-05 12:30:55 -04:00
Urs Reupke
c627fabebd MkDirs no longer tries to create folders twice when path has trailing slash. 2012-03-23 10:58:42 +01:00
Shikhar Bhushan
1c4781a65d Merge pull request #65 from ryantenney/logging-fix
Avoid string concatenation in log statements
2012-03-20 01:10:52 -07:00
Ryan Tenney
aac7af2827 Avoid string concatenation in log statements. 2012-03-19 13:34:38 -04:00
Shikhar Bhushan
11c286b9b9 . 2012-02-08 20:01:58 +00:00
Shikhar Bhushan
7fae513fd8 google group 2012-02-08 20:01:39 +00:00
Shikhar Bhushan
53ad9d2288 int->long 2012-02-06 23:36:18 +00:00
Shikhar Bhushan
ee07072846 Make window size a long, as it can be upto (2^32 - 1)
Fix for #57
2012-02-06 22:24:52 +00:00
Shikhar Bhushan
d38bbbcdf7 clearer... 2012-02-05 19:54:42 +00:00
Shikhar Bhushan
bc59c81dbc Refactor TransferListener interface to support thread-safe, immutable implementation.
Fix #56
2012-01-29 22:54:17 +00:00
Shikhar Bhushan
d70d37cf4e Version string update 2012-01-29 22:52:59 +00:00
Shikhar Bhushan
777d82912c Merge pull request #55 from hierynomus/default-tty
Set default tty to vt100, as specified in the javadoc
2012-01-26 13:52:39 -08:00
hierynomus
f5db3e1563 Set default tty to vt100, as specified in the javadoc 2012-01-19 10:19:19 +01:00
Shikhar Bhushan
7e524f5c6f Make disconnect() an operation that can be repeated without side-effects beyond the first call. 2012-01-08 10:20:46 +00:00
Shikhar Bhushan
dbb3f62e82 [maven-release-plugin] prepare for next development iteration 2012-01-08 09:32:47 +00:00
Shikhar Bhushan
16a363fef6 [maven-release-plugin] prepare release v0.7.0 2012-01-08 09:32:41 +00:00
Shikhar Bhushan
9b0d39a798 Remove the SFTPClient.getFileTansfer() method that has typo altogether as this is a simple change to make for clients. 2012-01-08 09:30:05 +00:00
Shikhar Bhushan
81e36153d7 wrapping 2012-01-08 09:10:07 +00:00
Shikhar Bhushan
3026be282a Refactored the local port forwarding API; give caller control over initializing and cleaning up the server socket used.
Also removed 'server socket factory' stuff from SocketClient.
2012-01-05 22:26:44 +00:00
Shikhar Bhushan
8eedeb25fa Merge pull request #50 from iocanel/master
Remove bouncycastle version range from OSGi metadata.
2012-01-02 06:52:50 -08:00
Ioannis Canellos
de11880648 Removed package version from bouncycastle imports 2012-01-02 15:04:12 +02:00
Shikhar Bhushan
1ff4772f3f update id string 2011-12-20 11:12:35 +00:00
Shikhar Bhushan
22a5ffe735 fix for #47 - should send data down rather than sitting around waiting for an adjustment if there is window space available 2011-12-20 10:41:49 +00:00
Shikhar Bhushan
7a77f85ced docfix 2011-12-20 10:37:32 +00:00
Shikhar Bhushan
0002fe8b40 Made some Buffer subclasses final 2011-12-19 22:52:41 +00:00
Shikhar Bhushan
3028e7f218 Fix logging of window adjustments 2011-12-19 21:56:44 +00:00
Shikhar Bhushan
333e1cb7b8 small cleanup 2011-12-04 19:10:34 +00:00
Shikhar Bhushan
945d430916 Removed deprecated Session.Command's methods - getOutputAsString() and getErrorAsString() 2011-12-04 18:26:05 +00:00
Shikhar Bhushan
73b903784a Next version will be 0.7.0 2011-12-04 18:24:00 +00:00
Shikhar Bhushan
7d53649a85 . 2011-12-04 18:23:15 +00:00
Shikhar Bhushan
e193db9a14 Fix example in SSHClient doc 2011-12-04 18:14:27 +00:00
Shikhar Bhushan
a942edb911 Add SFTPClient.getFileTransfer() and deprecate getFileTansfer() which has typo 2011-12-04 18:11:30 +00:00
Shikhar Bhushan
137a7f5956 (reformat) 2011-12-04 17:48:42 +00:00
Shikhar Bhushan
718ff503df Merge pull request #41 from hierynomus/known-hosts
OpenSSH Known hosts format re-implemented
2011-12-04 09:35:58 -08:00
Shikhar Bhushan
d933b2538e Upgrade maven-bundle-plugin to 2.3.6 to fix #37 [https://issues.apache.org/jira/browse/FELIX-3058] 2011-12-04 17:10:33 +00:00
Shikhar Bhushan
ea6f9ceed2 Correct version 2011-12-04 13:54:19 +00:00
rws
07c61b14e8 Change SocketClient to public so that SSHClient can be mocked for testing. 2011-12-04 21:51:58 +08:00
hierynomus
4b175e6938 Re-implemented OpenSSHKnownHostsVerifier to deal with the real format 2011-11-10 09:51:18 +01:00
Shikhar Bhushan
f7e47cffa0 [maven-release-plugin] prepare for next development iteration 2011-10-02 22:17:46 +01:00
Shikhar Bhushan
42dddc7f7e [maven-release-plugin] prepare release v0.6.1 2011-10-02 22:17:36 +01:00
Shikhar Bhushan
f1b3dbb102 Restore mutual exclusion of sendChannelRequest() and gotResponse() in AbstractChannel (but rather than make methods synchronized do it on the queue, which itself doesn't need to be thread-safe). Regression due to 1a2351c5ee. Fixes #35. 2011-10-02 09:47:49 +01:00
Shikhar Bhushan
f83bf2cd3f [maven-release-plugin] prepare for next development iteration 2011-09-26 12:41:23 +01:00
Shikhar Bhushan
be11cbb848 [maven-release-plugin] prepare release v0.6.0 2011-09-26 12:41:17 +01:00
Shikhar Bhushan
43b0599e1f let's make next release sshj 0.6.0 2011-09-26 12:37:21 +01:00
Shikhar Bhushan
b218186cae Merge pull request #34 from hierynomus/scp-filter-copy
Added upload filter capability to SCPUploadClient
2011-09-26 04:11:24 -07:00
hierynomus
184236c3d5 Added upload filter capability to SCPUploadClient 2011-09-26 11:49:07 +02:00
Shikhar Bhushan
cb1d773659 Merge branch 'master' of github.com:shikhar/sshj 2011-09-14 23:06:05 +01:00
Shikhar Bhushan
378665cb46 update contrib 2011-09-14 23:37:31 +02:00
Shikhar Bhushan
a5272dc413 Merge branch 'master' of github.com:shikhar/sshj 2011-09-14 22:11:29 +01:00
Shikhar Bhushan
60552fd001 Merge pull request #31 from hierynomus/filemode-typemask
Fixed bug in SFTP FileMode for AIX/Unix directory mask
2011-09-14 11:43:59 -07:00
hierynomus
ef082c668a Fixed bug in SFTP FileMode for AIX/Unix directory mask 2011-09-14 11:02:35 +02:00
Shikhar Bhushan
e66386eb1c Local window exhaustion -> ConnectionException 2011-09-07 21:45:44 +01:00
Shikhar Bhushan
0937ec9800 minor 2011-09-07 21:24:49 +01:00
Shikhar Bhushan
4b2f42804e Added version in pom.xml for maven-bundle-plugin 2011-08-29 16:49:49 +01:00
Shikhar Bhushan
01765d24d2 AbstractChannel - no reason for channel request response events to share the same underlying lock object. #27 2011-08-29 16:45:12 +01:00
Shikhar Bhushan
1a2351c5ee AbstractChannel - make chanReqResponseEvents a ConcurrentLinkedQueue, so don't have to have sendChannelRequest() & gotResponse() as synchronized methods. #27 2011-08-29 16:41:27 +01:00
Shikhar Bhushan
1cec011401 chown / chmod / chgrp in StatefulSFTPClient -- these all delegate to setattr which is overriden in StatefulSFTPClient to do cwdification. #28 2011-08-29 16:21:10 +01:00
Shikhar Bhushan
52338c13cb Merge pull request #28 from neilprosser/master
StatefulSFTPClient doesn't cwdify all commands
2011-08-27 04:23:07 -07:00
Neil Prosser
09cf21f61a Some stateful methods that needed cwdifying 2011-08-27 00:30:20 +01:00
Shikhar Bhushan
04c2e7b6b8 Client version string update 2011-07-27 19:52:27 +01:00
Shikhar Bhushan
822f196dd8 update contrib 2011-07-27 19:38:56 +01:00
Shikhar Bhushan
a88a574b10 [maven-release-plugin] prepare for next development iteration 2011-07-27 19:33:32 +01:00
438 changed files with 22886 additions and 6361 deletions

8
.bettercodehub.yml Normal file
View File

@@ -0,0 +1,8 @@
exclude:
- /build-publishing.gradle
- /build.gradle
- /settings.gradle
component_depth: 1
languages:
- groovy
- java

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.bat text eol=crlf

2
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,2 @@
* @hierynomus

55
.github/workflows/gradle.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Build SSHJ
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
java12:
name: Build with Java 12
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 12
uses: actions/setup-java@v1
with:
java-version: 12
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew check
# java10:
# name: Build with Java 10
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - name: Set up JDK 10
# uses: actions/setup-java@v1
# with:
# java-version: 10
# - name: Grant execute permission for gradlew
# run: chmod +x gradlew
# - name: Build with Gradle
# run: ./gradlew check -xanimalsnifferMain -xanimalsnifferTest
integration:
name: Integration test
needs: [java12]
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- uses: actions/setup-java@v1
with:
java-version: 12
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew integrationTest

26
.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
# IntelliJ IDEA
.idea/
*.iml
*.ipr
*.iws
# Eclipe
.project
.classpath
.settings/
# Output dirs
out/
target/
classes/
bin/
build/
docs/
.gradle/
sshj.jar
# MacOS X
.DS_Store
# VSCode
.metals/

1
.java-version Normal file
View File

@@ -0,0 +1 @@
11.0

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"java.checkstyle.configuration": "${workspaceFolder}/gradle/config/checkstyle/checkstyle.xml",
"files.watcherExclude": {
"**/target": true
}
}

View File

@@ -1,5 +1 @@
Shikhar Bhushan <shikhar@schmizz.net>
Cyril Ledru <cledru@keynectis.net>
Incendium <incendium@gmail.com>
Philip Langdale <philipl@cloudera.com>
Adar Dembo <adar@cloudera.com>
git log --format='%aN <%aE>' | awk '{arr[$0]++} END{for (i in arr){print arr[i], i;}}' | sort -rn | cut -d\ -f2-

13
LICENSE_HEADER Normal file
View File

@@ -0,0 +1,13 @@
Copyright (C)2009 - SSHJ Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

4
NOTICE
View File

@@ -1,5 +1,5 @@
sshj - SSHv2 library for Java
Copyright 2010-2011 sshj contributors
Copyright 2010-2012 sshj contributors
This product includes code derived from software developed at
The Apache Software Foundation (http://www.apache.org/):
@@ -15,7 +15,7 @@ The Apache Software Foundation (http://www.apache.org/):
== in this case for the SSHD distribution. ==
=========================================================================
This product contains software developped by JCraft,Inc. and subject to
This product contains software developed by JCraft,Inc. and subject to
the following license:
Copyright (c) 2002,2003,2004,2005,2006,2007,2008 Atsuhiko Yamanaka, JCraft,Inc.

250
README.adoc Normal file
View File

@@ -0,0 +1,250 @@
= sshj - SSHv2 library for Java
Jeroen van Erp
:sshj_groupid: com.hierynomus
:sshj_version: 0.31.0
:source-highlighter: pygments
image:https://api.bintray.com/packages/hierynomus/maven/sshj/images/download.svg[link="https://bintray.com/hierynomus/maven/sshj/_latestVersion"]
image:https://travis-ci.org/hierynomus/sshj.svg?branch=master[link="https://travis-ci.org/hierynomus/sshj"]
image:https://api.codacy.com/project/badge/Grade/14a0a316bb9149739b5ea26dbfa8da8a["Codacy code quality", link="https://www.codacy.com/app/jeroen_2/sshj?utm_source=github.com&utm_medium=referral&utm_content=hierynomus/sshj&utm_campaign=Badge_Grade"]
image:https://codecov.io/gh/hierynomus/sshj/branch/master/graph/badge.svg["codecov", link="https://codecov.io/gh/hierynomus/sshj"]
image:http://www.javadoc.io/badge/com.hierynomus/sshj.svg?color=blue["JavaDocs", link="http://www.javadoc.io/doc/com.hierynomus/sshj"]
image:https://maven-badges.herokuapp.com/maven-central/com.hierynomus/sshj/badge.svg["Maven Central",link="https://maven-badges.herokuapp.com/maven-central/com.hierynomus/sshj"]
To get started, have a look at one of the examples. Hopefully you will find the API pleasant to work with :)
== Getting SSHJ
To get SSHJ, you have two options:
. Add a dependency to SSHJ to your project.
. Build SSHJ yourself.
And, if you want, you can also run the SSHJ examples.
Binary releases of SSHJ are not provided here, but you can download it http://search.maven.org/#artifactdetails%7C{sshj_groupid}%7Csshj%7C{sshj_version}%7Cjar[straight from the Maven Central repository] if you want to.
== Depending on SSHJ
If you're building your project using Maven, you can add the following dependency to the `pom.xml`:
[source,xml,subs="verbatim,attributes"]
----
<dependency>
<groupId>{sshj_groupid}</groupId>
<artifactId>sshj</artifactId>
<version>{sshj_version}</version>
</dependency>
----
If your project is built using another build tool that uses the Maven Central repository, translate this dependency into the format used by your build tool.
== Building SSHJ
. Clone the SSHJ repository.
. Ensure you have Java6 installed with the http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html[Unlimited strength Java Cryptography Extensions (JCE)].
. Run the command `./gradlew clean build`.
== Running the examples
In the `examples` directory, there is a separate Maven project that shows how the library can be used in some sample cases. If you want to run them, follow these guidelines:
. Install http://maven.apache.org/[Maven 2.2.1] or up.
. Clone the Overthere repository.
. Go into the `examples` directory and run the command `mvn eclipse:eclipse`.
. Import the `examples` project into Eclipse.
. Change the login details in the example classes (address, username and password) and run them!
== Features of the library include:
* reading known_hosts files for host key verification
* publickey, password and keyboard-interactive authentication
* command, subsystem and shell channels
* local and remote port forwarding
* scp + complete sftp version 0-3 implementation
== Supported algorithms
Implementations / adapters for the following algorithms are included:
ciphers::
`aes{128,192,256}-{cbc,ctr}`, `aes{128,256}-gcm@openssh.com`, `blowfish-{cbc,ctr}`, `3des-{cbc,ctr}`, `twofish{128,192,256}-{cbc,ctr}`, `twofish-cbc`, `serpent{128,192,256}-{cbc,ctr}`, `idea-{cbc,ctr}`, `cast128-{cbc,ctr}`, `arcfour`, `arcfour{128,256}`
SSHJ also supports the following extended (non official) ciphers: `camellia{128,192,256}-{cbc,ctr}`, `camellia{128,192,256}-{cbc,ctr}@openssh.org`
key exchange::
`diffie-hellman-group1-sha1`, `diffie-hellman-group14-sha1`,
`diffie-hellman-group14-sha256`, `diffie-hellman-group15-sha512`, `diffie-hellman-group16-sha512`, `diffie-hellman-group17-sha512`, `diffie-hellman-group18-sha512`
`diffie-hellman-group-exchange-sha1`, `diffie-hellman-group-exchange-sha256`,
`ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `curve25519-sha256@libssh.org`
SSHJ also supports the following extended (non official) key exchange algorithms:
`diffie-hellman-group14-sha256@ssh.com`, `diffie-hellman-group15-sha256`, `diffie-hellman-group15-sha256@ssh.com`, `diffie-hellman-group15-sha384@ssh.com`,
`diffie-hellman-group16-sha256`, `diffie-hellman-group16-sha384@ssh.com`, `diffie-hellman-group16-sha512@ssh.com`, `diffie-hellman-group18-sha512@ssh.com`
signatures::
`ssh-rsa`, `ssh-dss`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`, `ssh-rsa2-256`, `ssh-rsa2-512`
mac::
`hmac-md5`, `hmac-md5-96`, `hmac-sha1`, `hmac-sha1-96`, `hmac-sha2-256`, `hmac-sha2-512`, `hmac-ripemd160`, `hmac-ripemd160@openssh.com`
`hmac-md5-etm@openssh.com`, `hmac-md5-96-etm@openssh.com`, `hmac-sha1-etm@openssh.com`, `hmac-sha1-96-etm@openssh.com`, `hmac-sha2-256-etm@openssh.com`, `hmac-sha2-512-etm@openssh.com`, `hmac-ripemd160-etm@openssh.com`
compression::
`zlib` and `zlib@openssh.com` (delayed zlib)
private key files::
`pkcs5`, `pkcs8`, `openssh-key-v1`, `ssh-rsa-cert-v01@openssh.com`, `ssh-dsa-cert-v01@openssh.com`
If you need something that is not included, it shouldn't be too hard to add (do contribute it!)
== Comparing to other implementations
http://ssh-comparison.quendi.de/comparison.html[SSH Implementation Comparison]
== Dependencies
Java 6+. http://www.slf4j.org/download.html[slf4j] is required. http://www.bouncycastle.org/java.html[bouncycastle] is highly recommended and required for using some of the crypto algorithms. http://www.jcraft.com/jzlib/[jzlib] is required for using zlib compression.
== Reporting bugs
Issue tracker: https://github.com/hierynomus/sshj/issues
== Contributing
Fork away!
== Release history
SSHJ 0.31.0 (2021-02-08)::
* Bump dependencies (asn-one 0.5.0, BouncyCastle 1.68, slf4j-api 1.7.30)
* Merged https://github.com/hierynomus/sshj/pull/660[#660]: Support ED25519 and ECDSA keys in PuTTY format
* Merged https://github.com/hierynomus/sshj/pull/655[#655]: Bump BouncyCastle due to CVE
* Merged https://github.com/hierynomus/sshj/pull/653[#653]: Make Parameters class useable as HashMap key
* Merged https://github.com/hierynomus/sshj/pull/647[#647]: Reduce log level for identification parser
* Merged https://github.com/hierynomus/sshj/pull/630[#630]: Add support for `aes128-gcm@openssh.com` and `aes256-gcm@openssh.com` ciphers
* Merged https://github.com/hierynomus/sshj/pull/636[#636]: Improved Android compatibility
* Merged https://github.com/hierynomus/sshj/pull/627[#627]: Prevent key leakage
SSHJ 0.30.0 (2020-08-17)::
* **BREAKING CHANGE**: Removed `setSignatureFactories` and `getSignatureFactories` from the Config and switched them for `getKeyAlgorithms` and `setKeyAlgorithms`
* Fixed https://github.com/hierynomus/sshj/pull/588[#588]: Add support for `ssh-rsa2-256` and `ssh-rsa2-512` signatures
* Merged https://github.com/hierynomus/sshj/pull/579[#579]: Fix NPE in OpenSSHKnownHosts
* Merged https://github.com/hierynomus/sshj/pull/587[#587]: Add passwordfinder retry for OpenSSHKeyV1KeyFile
* Merged https://github.com/hierynomus/sshj/pull/586[#586]: Make KeyType compatible with Android Store
* Merged https://github.com/hierynomus/sshj/pull/593[#593]: Change `UserAuth.getAllowedMethods()` to Collection return type
* Merged https://github.com/hierynomus/sshj/pull/595[#595]: Allow reading arbitrary length keys
* Merged https://github.com/hierynomus/sshj/pull/591[#591]: Allow to query SFTP extensions
* Merged https://github.com/hierynomus/sshj/pull/603[#603]: Add method to create Stateful SFTP client
* Merged https://github.com/hierynomus/sshj/pull/605[#605]: Use Daemon threads to avoid blocking JVM shutdown
* Merged https://github.com/hierynomus/sshj/pull/606[#606]: Always use the JCERandom RNG by default
* Merged https://github.com/hierynomus/sshj/pull/609[#609]: Clear passphrase after use to prevent security issues
* Merged https://github.com/hierynomus/sshj/pull/618[#618]: Fix localport of DirectConnection for use with OpenSSH > 8.0
* Merged https://github.com/hierynomus/sshj/pull/619[#619]: Upgraded BouncyCastle to 1.66
* Merged https://github.com/hierynomus/sshj/pull/622[#622]: Send 'ext-info-c' with KEX algorithms
* Merged https://github.com/hierynomus/sshj/pull/623[#623]: Fix transport encoding of `nistp521` signatures
* Merged https://github.com/hierynomus/sshj/pull/607[#607]: Fix mathing pubkeys to key algorithms
* Merged https://github.com/hierynomus/sshj/pull/602[#602]: Fix RSA certificate key determination
SSHJ 0.27.0 (2019-01-24)::
* Fixed https://github.com/hierynomus/sshj/issues/415[#415]: Fixed wrongly prefixed '/' to path in SFTPClient.mkdirs
* Added support for ETM (Encrypt-then-Mac) MAC algorithms.
* Fixed https://github.com/hierynomus/sshj/issues/454[#454]: Added missing capacity check for Buffer.putUint64
* Fixed https://github.com/hierynomus/sshj/issues/466[#466]: Added lock timeout for remote action to prevent hanging
* Fixed https://github.com/hierynomus/sshj/issues/470[#470]: Made EdDSA the default (first) signature factory
* Fixed https://github.com/hierynomus/sshj/issues/467[#467]: Added AES256-CBC as cipher mode in openssh-key-v1 support
* Fixed https://github.com/hierynomus/sshj/issues/464[#464]: Enabled curve25519-sha256@openssh.org in DefaultConfig
* Fixed https://github.com/hierynomus/sshj/issues/472[#472]: Handle server initiated global requests
* Fixed https://github.com/hierynomus/sshj/issues/485[#485]: Added support for all keytypes to openssh-key-v1 keyfiles.
SSHJ 0.26.0 (2018-07-24)::
* Fixed https://github.com/hierynomus/sshj/issues/413[#413]: Use UTF-8 for PrivateKeyFileResource
* Fixed https://github.com/hierynomus/sshj/issues/427[#427]: Support encrypted ed25519 openssh-key-v1 files
* Upgraded BouncyCastle to 1.60
* Added support for hmac-ripemd160@openssh.com MAC
SSHJ 0.24.0 (2018-04-04)::
* Added support for hmac-ripemd160
* Fixed https://github.com/hierynomus/sshj/issues/382[#382]: Fixed escaping in WildcardHostmatcher
* Added integration testsuite using Docker against OpenSSH
* Fixed https://github.com/hierynomus/sshj/issues/187[#187]: Fixed length bug in Buffer.putString
* Fixed https://github.com/hierynomus/sshj/issues/405[#405]: Continue host verification if first hostkey does not match.
SSHJ 0.23.0 (2017-10-13)::
* Merged https://github.com/hierynomus/sshj/pull/372[#372]: Upgrade to 'net.i2p.crypto:eddsa:0.2.0'
* Fixed https://github.com/hierynomus/sshj/issues/355[#355] and https://github.com/hierynomus/sshj/issues/354[#354]: Correctly decode signature bytes
* Fixed https://github.com/hierynomus/sshj/issues/365[#365]: Added support for new-style OpenSSH fingerprints of server keys
* Fixed https://github.com/hierynomus/sshj/issues/356[#356]: Fixed key type detection for ECDSA public keys
* Made SSHJ Java9 compatible
SSHJ 0.22.0 (2017-08-24)::
* Fixed https://github.com/hierynomus/sshj/pull/341[#341]: Fixed path walking during recursive copy
* Merged https://github.com/hierynomus/sshj/pull/338[#338]: Added ConsolePasswordFinder to read password from stdin
* Merged https://github.com/hierynomus/sshj/pull/336[#336]: Added support for ecdsa-sha2-nistp384 and ecdsa-sha2-nistp521 signatures
* Fixed https://github.com/hierynomus/sshj/issues/331[#331]: Added support for wildcards in known_hosts file
SSHJ 0.21.1 (2017-04-25)::
* Merged https://github.com/hierynomus/sshj/pull/322[#322]: Fix regression from 40f956b (invalid length parameter on outputstream)
SSHJ 0.21.0 (2017-04-14)::
* Merged https://github.com/hierynomus/sshj/pull/319[#319]: Added support for `ssh-rsa-cert-v01@openssh.com` and `ssh-dsa-cert-v01@openssh.com` certificate key files
* Upgraded Gradle to 3.4.1
* Merged https://github.com/hierynomus/sshj/pull/305[#305]: Added support for custom string encoding
* Fixed https://github.com/hierynomus/sshj/issues/312[#312]: Upgraded BouncyCastle to 1.56
SSHJ 0.20.0 (2017-02-09)::
* Merged https://github.com/hierynomus/sshj/pull/294[#294]: Reference ED25519 by constant instead of name
* Merged https://github.com/hierynomus/sshj/pull/293[#293], https://github.com/hierynomus/sshj/pull/295[#295] and https://github.com/hierynomus/sshj/pull/301[#301]: Fixed OSGi packaging
* Added new Diffie Hellman groups 15-18 for stronger KeyExchange algorithms
SSHJ 0.19.1 (2016-12-30)::
* Enabled PKCS5 Key files in DefaultConfig
* Merged https://github.com/hierynomus/sshj/pull/291[#291]: Fixed sshj.properties loading and chained exception messages
* Merged https://github.com/hierynomus/sshj/pull/284[#284]: Correctly catch interrupt in keepalive thread
* Fixed https://github.com/hierynomus/sshj/issues/292[#292]: Pass the configured RandomFactory to Diffie Hellman KEX
* Fixed https://github.com/hierynomus/sshj/issues/256[#256]: SSHJ now builds if no git repository present
* LocalPortForwarder now correctly interrupts its own thread on close()
SSHJ 0.19.0 (2016-11-25)::
* Fixed https://github.com/hierynomus/sshj/issues/276[#276]: Add support for ed-25519 and new OpenSSH key format
* Fixed https://github.com/hierynomus/sshj/issues/280[#280]: Read version from a generated sshj.properties file to correctly output version during negotiation
SSHJ 0.18.0 (2016-09-30)::
* Fixed Android compatibility
* Upgrade to Gradle 3.0
* Merged https://github.com/hierynomus/sshj/pull/271[#271]: Load known_hosts without requiring BouncyCastle
* Merged https://github.com/hierynomus/sshj/pull/269[#269]: Brought back Java6 support by popular demand
* Merged https://github.com/hierynomus/sshj/pull/267[#267]: Added support for per connection logging (Fixes https://github.com/hierynomus/sshj/issues/264[#264])
* Merged https://github.com/hierynomus/sshj/pull/262[#262], https://github.com/hierynomus/sshj/pull/265[#265] and https://github.com/hierynomus/sshj/pull/266[#266]: Added PKCS5 key file support
* Fixed toString of sftp FileAttributes (Fixes https://github.com/hierynomus/sshj/pull/258[#258])
* Fixed https://github.com/hierynomus/sshj/issues/255[#255]: No longer depending on 'privately marked' classes in `net.i2p.crypto.eddsa.math` package, fixes OSGI dependencies
SSHJ 0.17.2 (2016-07-07)::
* Treating SSH Server identification line ending in '\n' instead of '\r\n' leniently.
SSHJ 0.17.1 (2016-07-06)::
* Improved parsing of the SSH Server identification. Too long header lines now no longer break the protocol.
SSHJ 0.17.0 (2016-07-05)::
* *Introduced breaking change in SFTP copy behaviour*: Previously an SFTP copy operation would behave differently if both source and target were folders with different names.
In this case instead of copying the contents of the source into the target directory, the directory itself was copied as a sub directory of the target directory.
This behaviour has been removed in favour of the default behaviour which is to copy the contents of the source into the target. Bringing the behaviour in line with how SCP works.
* Fixed https://github.com/hierynomus/sshj/issues/252[#252] (via: https://github.com/hierynomus/sshj/pull/253[#253]): Same name subdirs are no longer merged by accident
SSHJ 0.16.0 (2016-04-11)::
* Fixed https://github.com/hierynomus/sshj/issues/239[#239]: Remote port forwards did not work if you used the empty string as address, or a catch-all address.
* Fixed https://github.com/hierynomus/sshj/issues/242[#242]: Added OSGI headers to sources jar manifest
* Fixed https://github.com/hierynomus/sshj/issues/236[#236]: Remote Port forwarding with dynamic port allocation fails with BufferUnderflowException
* Upgraded gradle distribution to 2.12
* Closed https://github.com/hierynomus/sshj/issues/234[#234]: Dropped Java6 support (0.15.0 was already Java6 incompatible due to Java7 dependency)
* Fixed https://github.com/hierynomus/sshj/issues/118[#118]: Added configuration switch for waiting on a server ident before sending the client ident.
* Fixed https://github.com/hierynomus/sshj/issues/114[#114]: Added javadoc that you always need to call close() on a Command before inspecting the exit codes.
* Fixed https://github.com/hierynomus/sshj/issues/237[#237]: Fixed race condition if a `hostkeys-00@openssh.com` global request is received directly after a successful auth.
SSHJ 0.15.0 (2015-11-20)::
* Fixed https://github.com/hierynomus/sshj/issues/220[#220]: Added support for `ssh-ed25519` host keys
* Fixed https://github.com/hierynomus/sshj/issues/225[#225]: Fixed bug in ECDSA fingerprint calculation that sometimes produced an incorrect fingerprint
* Added `arcfour` Stream Ciphers from RFC4253 and RFC4345
* Added all Block Ciphers from RFC4344 and RFC4253
SSHJ 0.14.0 (2015-11-04)::
* Fixed https://github.com/hierynomus/sshj/issues/171[#171]: Added support for `curve25519-sha256@libssh.org` key exchange algorithm
* Added support for `ecdh-sha2-nistp256`, `ecdh-sha2-nistp384` and `ecdh-sha2-nistp521` key exchange algorithms
* Fixed https://github.com/hierynomus/sshj/issues/167[#167]: Added support for `diffie-hellman-group-exchange-sha1` and `diffie-hellman-group-exchange-sha256` key exchange methods
* Fixed https://github.com/hierynomus/sshj/issues/212[#212]: Configure path escaping to enable shell expansion to work correctly
* Merged https://github.com/hierynomus/sshj/issues/210[#210]: RemoteFileInputStream.skip returns wrong value (Fixes https://github.com/hierynomus/sshj/issues/209[#209])
* Merged https://github.com/hierynomus/sshj/issues/208[#208]: Added SCP bandwidth limitation support
* Merged https://github.com/hierynomus/sshj/issues/211[#211]: Made keyfile format detection more robust
SSHJ 0.13.0 (2015-08-18)::
* Merged https://github.com/hierynomus/sshj/issues/199[#199]: Fix for IndexOutOfBoundsException in ReadAheadRemoteFileInputStream, fixes https://github.com/hierynomus/sshj/issues/183[#183]
* Merged https://github.com/hierynomus/sshj/issues/195[#195]: New authentication supported: `gssapi-with-mic`
* Merged https://github.com/hierynomus/sshj/issues/201[#201]: New option to verify negotiated key exchange algorithms
* Merged https://github.com/hierynomus/sshj/issues/196[#196]: Fix for looking up complete hostname in known hosts file
SSHJ 0.12.0 (2015-04-14)::
* Added support for HTTP proxies when running JDK6 or JDK7, fixes: https://github.com/hierynomus/sshj/issues/170[#170]
* Merged https://github.com/hierynomus/sshj/issues/186[#186]: Fix for detecting end-of-stream
* Compiling to JDK6, fixes https://github.com/hierynomus/sshj/issues/179[#179] and https://github.com/hierynomus/sshj/issues/185[#185]
* Correctly close socket and channel when LocalPortForwarder fails to open and start the channel (Fixes https://github.com/hierynomus/sshj/issues/175[#175] and https://github.com/hierynomus/sshj/issues/176[#176])
* Merged https://github.com/hierynomus/sshj/issues/181[#181]: Invalid write packet length when reading with offset (Fixes https://github.com/hierynomus/sshj/issues/180[#180])
SSHJ 0.11.0 (2015-01-23)::
* New maven coordinates `com.hierynomus:sshj:0.11.0` as https://github.com/hierynomus[@hierynomus] took over as maintainer of SSHJ
* Migrated build system to Gradle 2.2.1
* Merged https://github.com/hierynomus/sshj/issues/150[#150]: Fix for incorrect file handle on some SSH servers, fixes: https://github.com/hierynomus/sshj/issues/54[#54], https://github.com/hierynomus/sshj/issues/119[#119], https://github.com/hierynomus/sshj/issues/168[#168], https://github.com/hierynomus/sshj/issues/169[#169]
* Made `jzlib` optional in OSGi bundling, fixes: https://github.com/hierynomus/sshj/issues/162[#162]
* Improved some log levels, fixes: https://github.com/hierynomus/sshj/issues/161[#161]
* Merged https://github.com/hierynomus/sshj/issues/156[#156], https://github.com/hierynomus/sshj/issues/164[#164], https://github.com/hierynomus/sshj/issues/165[#165]: Fixed block sizes for `hmac-sha2-256` and `hmac-sha2-512`
* Merged https://github.com/hierynomus/sshj/issues/141[#141]: Add proxy support
* Merged https://github.com/hierynomus/sshj/issues/157[#157], https://github.com/hierynomus/sshj/issues/163[#163]: Doc and build fixes
* Upgraded BouncyCastle to 1.51, fixes: https://github.com/hierynomus/sshj/issues/142[#142]
* Implemented keep-alive with connection drop detection, fixes https://github.com/hierynomus/sshj/issues/166[#166]

View File

@@ -1,58 +0,0 @@
sshj - SSHv2 library for Java
==============================
To get started, have a look at one of the examples. Hopefully you will find the API pleasant to work with :)
Features of the library include:
* reading known_hosts files for host key verification
* publickey, password and keyboard-interactive authentication
* command, subsystem and shell channels
* local and remote port forwarding
* scp + complete sftp version 0-3 implementation
Implementations / adapters for the following algorithms are included:
ciphers
``aes{128,192,256}-{cbc,ctr}``, ``blowfish-cbc``, ``3des-cbc``
key exchange
``diffie-hellman-group1-sha1``, ``diffie-hellman-group14-sha1``
signatures
``ssh-rsa``, ``ssh-dss``
mac
``hmac-md5``, ``hmac-md5-96``, ``hmac-sha1``, ``hmac-sha1-96``
compression
``zlib`` and ``zlib@openssh.com`` (delayed zlib)
private key files
``pkcs8`` encoded (what openssh uses)
If you need something that is not included, it shouldn't be too hard to add (do contribute it!)
Dependencies
-------------
Java 6+. slf4j_ is required. bouncycastle_ is highly recommended and required for using some of the crypto algorithms. jzlib_ is required for using zlib compression.
Bugs, questions
----------------
`Issue tracker <https://github.com/shikhar/sshj/issues>`_
Contributing
------------
Fork away!
.. _slf4j: http://www.slf4j.org/download.html
.. _bouncycastle: http://www.bouncycastle.org/java.html
.. _jzlib: http://www.jcraft.com/jzlib/

177
build-publishing.gradle Normal file
View File

@@ -0,0 +1,177 @@
apply plugin: "java"
apply plugin: "maven-publish"
apply plugin: "signing"
group = "nl.javadude"
version = "0.10.1-SNAPSHOT"
repositories {
mavenCentral()
mavenLocal()
}
configurations {
compile {
transitive = false
}
pom
}
def bouncycastleVersion = "1.67"
dependencies {
compile "org.slf4j:slf4j-api:1.7.7"
compile "org.bouncycastle:bcprov-jdk15on:$bouncycastleVersion"
compile "org.bouncycastle:bcpkix-jdk15on:$bouncycastleVersion"
compile "com.jcraft:jzlib:1.1.3"
testCompile "junit:junit:4.11"
testCompile "org.mockito:mockito-core:1.9.5"
testCompile "org.apache.sshd:sshd-core:0.11.0"
testRuntime "ch.qos.logback:logback-classic:1.1.2"
}
task javadocJar(type: Jar) {
classifier = 'javadoc'
from javadoc
}
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allSource
}
task generatePom(type: GenerateMavenPom) {
destination = file("$buildDir/generated-pom.xml")
}
artifacts {
archives javadocJar, sourcesJar
pom generatePom.destination
}
signing {
sign configurations.archives
}
task signPom(type: Sign) {
sign configurations.pom
}
def getSignatureFiles = {
def allFiles = project.tasks.signArchives.signatureFiles.collect { it }
def signedSources = allFiles.find { it.name.contains('-sources') }
def signedJavadoc = allFiles.find { it.name.contains('-javadoc') }
def signedJar = (allFiles - [signedSources, signedJavadoc])[0]
return [
[archive: signedSources, classifier: 'sources', extension: 'jar.asc'],
[archive: signedJavadoc, classifier: 'javadoc', extension: 'jar.asc'],
[archive: signedJar, classifier: null, extension: 'jar.asc']
]
}
def getPomSignature = {
return project.tasks.signPom.signatureFiles.collect{it}[0]
}
publishing {
publications {
gpgJars(MavenPublication) {
getSignatureFiles().each {signature ->
artifact (signature.archive) {
classifier = signature.classifier
extension = signature.extension
}
}
}
gpgPom(MavenPublication) {
artifact(getPomSignature()) {
classifier = null
extension = "pom.asc"
}
}
maven(MavenPublication) {
from components.java
artifact (javadocJar) {
classifier = 'javadoc'
}
artifact (sourcesJar) {
classifier = 'sources'
}
pom.withXml {
asNode().children().last() + {
resolveStrategy = Closure.DELEGATE_FIRST
name "sshj"
description "SSHv2 library for Java"
url "https://github.com/hierynomus/sshj"
inceptionYear "2009"
issueManagement {
system "github"
url "https://github.com/hierynomus/sshj/issues"
}
scm {
connection "scm:git:git://github.com/hierynomus/sshj.git"
developerConnection "scm:git:git@github.com:hierynomus/sshj.git"
url "https://github.com/hierynomus/sshj.git"
}
licenses {
license {
name "Apache 2"
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
distribution "repo"
}
}
developers {
developer {
id "hierynomus"
name "Jeroen van Erp"
email "jeroen@javadude.nl"
roles {
role "Lead developer"
}
}
developer {
id "shikhar"
name "Shikhar Bhushan"
email "shikhar@schmizz.net"
url "http://schmizz.net"
roles {
role "Previous lead developer"
}
}
developer {
id "iterate"
name "David Kocher"
email "dkocher@iterate.ch"
organization "iterage GmbH"
organizationUrl "https://iterate.ch"
roles {
role "Developer"
}
}
}
}
}
}
}
repositories {
maven {
url "file:/${project.projectDir}/artifacts"
}
}
}
project.afterEvaluate { p ->
p.tasks.publishGpgPomPublicationToMavenRepository.dependsOn("generatePom", "signPom")
}
generatePom.configure {
pom = publishing.publications.getByName("maven").pom
}

294
build.gradle Normal file
View File

@@ -0,0 +1,294 @@
import java.text.SimpleDateFormat
import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*
plugins {
id "java"
id "groovy"
id "jacoco"
id "com.github.blindpirate.osgi" version '0.0.3'
id "maven-publish"
id 'pl.allegro.tech.build.axion-release' version '1.11.0'
id "com.bmuschko.docker-remote-api" version "6.4.0"
id "com.github.hierynomus.license" version "0.12.1"
id "com.jfrog.bintray" version "1.8.5"
id 'ru.vyarus.java-lib' version '1.0.5'
// id 'ru.vyarus.pom' version '1.0.3'
id 'ru.vyarus.github-info' version '1.1.0'
}
group = "com.hierynomus"
scmVersion {
tag {
prefix = 'v'
versionSeparator = ''
}
hooks {
pre 'fileUpdate', [file: 'README.adoc', pattern: { v, c -> /:sshj_version: .*/}, replacement: { v, c -> ":sshj_version: $v" }]
pre 'commit'
}
}
project.version = scmVersion.version
defaultTasks "build"
repositories {
mavenCentral()
}
configurations.compile.transitive = false
def bouncycastleVersion = "1.68"
def sshdVersion = "2.1.0"
dependencies {
implementation "org.slf4j:slf4j-api:1.7.30"
implementation "org.bouncycastle:bcprov-jdk15on:$bouncycastleVersion"
implementation "org.bouncycastle:bcpkix-jdk15on:$bouncycastleVersion"
implementation "com.jcraft:jzlib:1.1.3"
implementation "com.hierynomus:asn-one:0.5.0"
implementation "net.i2p.crypto:eddsa:0.3.0"
testImplementation "junit:junit:4.12"
testImplementation 'org.spockframework:spock-core:1.3-groovy-2.4'
testImplementation "org.mockito:mockito-core:2.28.2"
testImplementation "org.apache.sshd:sshd-core:$sshdVersion"
testImplementation "org.apache.sshd:sshd-sftp:$sshdVersion"
testImplementation "org.apache.sshd:sshd-scp:$sshdVersion"
testRuntimeOnly "ch.qos.logback:logback-classic:1.2.3"
testImplementation 'org.glassfish.grizzly:grizzly-http-server:2.4.4'
testImplementation 'org.apache.httpcomponents:httpclient:4.5.9'
}
license {
header rootProject.file('LICENSE_HEADER')
strictCheck true
mapping {
java = 'SLASHSTAR_STYLE'
}
excludes(['**/djb/Curve25519.java', '**/sshj/common/Base64.java', '**/org/mindrot/jbcrypt/*.java'])
}
if (!JavaVersion.current().isJava9Compatible()) {
throw new GradleScriptException("Minimum compilation version is Java 9")
}
// This disables the pedantic doclint feature of JDK8
if (JavaVersion.current().isJava8Compatible()) {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
compileJava {
options.compilerArgs.addAll(['--release', '7'])
}
task writeSshjVersionProperties {
doLast {
project.file("${project.buildDir}/resources/main").mkdirs()
project.file("${project.buildDir}/resources/main/sshj.properties").withWriter { w ->
w.append("sshj.version=${version}")
}
}
}
jar.dependsOn writeSshjVersionProperties
jar {
manifest {
// please see http://bnd.bndtools.org/chapters/390-wrapping.html
instruction "Bundle-Description", "SSHv2 library for Java"
instruction "Bundle-License", "http://www.apache.org/licenses/LICENSE-2.0.txt"
instruction "Import-Package", "!net.schmizz.*"
instruction "Import-Package", "!com.hierynomus.sshj.*"
instruction "Import-Package", "javax.crypto*"
instruction "Import-Package", "!net.i2p.crypto.eddsa.math"
instruction "Import-Package", "net.i2p*"
instruction "Import-Package", "com.jcraft.jzlib*;version=\"[1.1,2)\";resolution:=optional"
instruction "Import-Package", "org.slf4j*;version=\"[1.7,5)\""
instruction "Import-Package", "org.bouncycastle*;resolution:=optional"
instruction "Import-Package", "org.bouncycastle.jce.provider;resolution:=optional"
instruction "Import-Package", "*"
instruction "Export-Package", "com.hierynomus.sshj.*;version=\"${project.jar.manifest.version}\""
instruction "Export-Package", "net.schmizz.*;version=\"${project.jar.manifest.version}\""
}
}
sourcesJar {
manifest {
attributes(
// Add the needed OSGI attributes
"Bundle-ManifestVersion": "2",
"Bundle-Name": "${project.jar.manifest.name} Source",
"Bundle-Version": project.jar.manifest.version,
"Eclipse-SourceBundle": "${project.jar.manifest.symbolicName};version=\"${project.jar.manifest.version}\";roots:=\".\"",
"Bundle-SymbolicName": "${project.jar.manifest.symbolicName}.source"
)
}
}
configurations {
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
}
sourceSets {
integrationTest {
groovy {
compileClasspath += sourceSets.main.output + sourceSets.test.output
runtimeClasspath += sourceSets.main.output + sourceSets.test.output
srcDir file('src/itest/groovy')
}
resources.srcDir file('src/itest/resources')
}
}
task integrationTest(type: Test) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
tasks.withType(Test) {
testLogging {
exceptionFormat = 'full'
}
include "**/*Test.*"
include "**/*Spec.*"
if (!project.hasProperty("allTests")) {
useJUnit {
excludeCategories 'com.hierynomus.sshj.test.SlowTests'
excludeCategories 'com.hierynomus.sshj.test.KnownFailingTests'
}
}
afterSuite { descriptor, result ->
if (descriptor.className != null) {
def indicator = "\u001B[32m✓\u001b[0m"
if (result.failedTestCount > 0) {
indicator = "\u001B[31m✘\u001b[0m"
}
logger.lifecycle("$indicator Test ${descriptor.name}; Executed: ${result.testCount}/\u001B[32m${result.successfulTestCount}\u001B[0m/\u001B[31m${result.failedTestCount}\u001B[0m")
}
}
}
project.tasks.compileGroovy.onlyIf { false }
github {
user 'hierynomus'
license 'Apache'
}
pom {
description "SSHv2 library for Java"
url "https://github.com/hierynomus/sshj"
inceptionYear "2009"
developers {
developer {
id "hierynomus"
name "Jeroen van Erp"
email "jeroen@javadude.nl"
roles {
role "Lead developer"
}
}
developer {
id "shikhar"
name "Shikhar Bhushan"
email "shikhar@schmizz.net"
url "http://schmizz.net"
roles {
role "Previous lead developer"
}
}
developer {
id "iterate"
name "David Kocher"
email "dkocher@iterate.ch"
organization "iterage GmbH"
organizationUrl "https://iterate.ch"
roles {
role "Developer"
}
}
}
}
if (project.hasProperty("bintrayUsername") && project.hasProperty("bintrayApiKey")) {
bintray {
user = project.property("bintrayUsername")
key = project.property("bintrayApiKey")
publish = true
publications = ["maven"]
pkg {
repo = "maven"
name = "${project.name}"
licenses = ["Apache-2.0"]
vcsUrl = "https://github.com/hierynomus/sshj.git"
labels = ["ssh", "sftp", "secure-shell", "network", "file-transfer"]
githubRepo = "hierynomus/sshj"
version {
name = "${project.version}"
vcsTag = "v${project.version}"
released = new SimpleDateFormat('yyyy-MM-dd\'T\'HH:mm:ss.SSSZZ').format(new Date())
gpg {
sign = true
passphrase = project.property("signing.password")
}
mavenCentralSync {
sync = true
user = project.property("sonatypeUsername")
password = project.property("sonatypePassword")
close = 1
}
}
}
}
}
jacocoTestReport {
reports {
xml.enabled true
html.enabled true
}
}
task buildItestImage(type: DockerBuildImage) {
inputDir = file('src/itest/docker-image')
images.add('sshj/sshd-itest:latest')
}
task createItestContainer(type: DockerCreateContainer) {
dependsOn buildItestImage
targetImageId buildItestImage.getImageId()
hostConfig.portBindings = ['2222:22']
hostConfig.autoRemove = true
}
task startItestContainer(type: DockerStartContainer) {
dependsOn createItestContainer
targetContainerId createItestContainer.getContainerId()
}
task stopItestContainer(type: DockerStopContainer) {
targetContainerId createItestContainer.getContainerId()
}
task forkedUploadRelease(type: GradleBuild) {
buildFile = project.buildFile
tasks = ["bintrayUpload"]
}
project.tasks.integrationTest.dependsOn(startItestContainer)
project.tasks.integrationTest.finalizedBy(stopItestContainer)
project.tasks.release.dependsOn([project.tasks.integrationTest, project.tasks.build])
project.tasks.release.finalizedBy(project.tasks.forkedUploadRelease)
project.tasks.jacocoTestReport.dependsOn(project.tasks.test)
project.tasks.check.dependsOn(project.tasks.jacocoTestReport)

101
examples/pom.xml Normal file
View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2009 sshj contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hierynomus</groupId>
<artifactId>sshj-examples</artifactId>
<packaging>jar</packaging>
<version>0.19.1</version>
<name>sshj-examples</name>
<description>Examples for SSHv2 library for Java</description>
<url>http://github.com/hierynomus/sshj</url>
<inceptionYear>2015</inceptionYear>
<issueManagement>
<system>github</system>
<url>http://github.com/hierynomus/sshj/issues</url>
</issueManagement>
<scm>
<connection>scm:git:git://github.com/hierynomus/sshj.git</connection>
<developerConnection>scm:git:git@github.com:hierynomus/sshj.git</developerConnection>
<url>http://github.com/hierynomus/sshj</url>
</scm>
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>com.hierynomus</groupId>
<artifactId>sshj</artifactId>
<version>0.31.0</version>
</dependency>
</dependencies>
<developers>
<developer>
<id>hierynomus</id>
<name>Jeroen van Erp</name>
<email>jeroen@hierynomus.com</email>
</developer>
<developer>
<id>shikhar</id>
<name>Shikhar Bhushan</name>
<email>shikhar@schmizz.net</email>
<url>http://schmizz.net</url>
</developer>
<developer>
<id>iterate</id>
<name>David Kocher</name>
<email>dkocher@iterate.ch</email>
<organization>iterate GmbH</organization>
<organizationUrl>https://iterate.ch</organizationUrl>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,42 @@
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.connection.channel.direct.Session.Command;
import java.io.Console;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/** This examples demonstrates how a remote command can be executed. */
public class Exec {
private static final Console con = System.console();
public static void main(String... args)
throws IOException {
final SSHClient ssh = new SSHClient();
ssh.loadKnownHosts();
ssh.connect("localhost");
Session session = null;
try {
ssh.authPublickey(System.getProperty("user.name"));
session = ssh.startSession();
final Command cmd = session.exec("ping -c 1 google.com");
con.writer().print(IOUtils.readFully(cmd.getInputStream()).toString());
cmd.join(5, TimeUnit.SECONDS);
con.writer().print("\n** exit status: " + cmd.getExitStatus());
} finally {
try {
if (session != null) {
session.close();
}
} catch (IOException e) {
// Do Nothing
}
ssh.disconnect();
}
}
}

View File

@@ -0,0 +1,31 @@
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;
import net.schmizz.sshj.xfer.FileSystemFile;
import java.io.*;
import java.nio.charset.Charset;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
/** This examples demonstrates how to configure {@link net.schmizz.sshj.SSHClient} client with an in-memory known_hosts file */
public class InMemoryKnownHosts {
public static void main(String[] args) throws IOException {
InputStream entry = new ByteArrayInputStream("localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPmhSBtMctNa4hsZt8QGlsYSE5/gMkjeand69Vj4ir13".getBytes(Charset.defaultCharset()));
SSHClient ssh = new SSHClient();
ssh.addHostKeyVerifier(new OpenSSHKnownHosts(new InputStreamReader(entry, Charset.defaultCharset())));
ssh.connect("localhost");
try {
ssh.authPublickey(System.getProperty("user.name"));
ssh.newSCPFileTransfer().download("test_file", new FileSystemFile("/tmp/"));
} finally {
ssh.disconnect();
}
}
}

View File

@@ -0,0 +1,50 @@
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.connection.channel.direct.DirectConnection;
import net.schmizz.sshj.connection.channel.direct.Session;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* This example demonstrates connecting via an intermediate "jump" server using a direct TCP/IP channel.
*/
public class Jump {
public static void main(String... args)
throws IOException {
SSHClient firstHop = new SSHClient();
firstHop.loadKnownHosts();
firstHop.connect("localhost");
try {
firstHop.authPublickey(System.getProperty("user.name"));
DirectConnection tunnel = firstHop.newDirectConnection("localhost", 22);
SSHClient ssh = new SSHClient();
try {
ssh.loadKnownHosts();
ssh.connectVia(tunnel);
ssh.authPublickey(System.getProperty("user.name"));
final Session session = ssh.startSession();
try {
final Session.Command cmd = session.exec("ping -c 1 google.com");
System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
cmd.join(5, TimeUnit.SECONDS);
System.out.println("\n** exit status: " + cmd.getExitStatus());
} finally {
session.close();
}
} finally {
ssh.disconnect();
}
} finally {
firstHop.disconnect();
}
}
}

View File

@@ -0,0 +1,37 @@
package net.schmizz.sshj.examples;
import net.schmizz.keepalive.KeepAliveProvider;
import net.schmizz.sshj.DefaultConfig;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/** This examples demonstrates how to setup keep-alive to detect connection dropping. */
public class KeepAlive {
public static void main(String... args)
throws IOException, InterruptedException {
DefaultConfig defaultConfig = new DefaultConfig();
defaultConfig.setKeepAliveProvider(KeepAliveProvider.KEEP_ALIVE);
final SSHClient ssh = new SSHClient(defaultConfig);
try {
ssh.addHostKeyVerifier(new PromiscuousVerifier());
ssh.connect(args[0]);
ssh.getConnection().getKeepAlive().setKeepAliveInterval(5); //every 60sec
ssh.authPassword(args[1], args[2]);
Session session = ssh.startSession();
session.allocateDefaultPTY();
new CountDownLatch(1).await();
try {
session.allocateDefaultPTY();
} finally {
session.close();
}
} finally {
ssh.disconnect();
}
}
}

View File

@@ -1,24 +1,12 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder;
import net.schmizz.sshj.connection.channel.direct.Parameters;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
/**
* This example demonstrates local port forwarding, i.e. when we listen on a particular address and port; and forward
@@ -41,8 +29,16 @@ public class LocalPF {
* _We_ listen on localhost:8080 and forward all connections on to server, which then forwards it to
* google.com:80
*/
ssh.newLocalPortForwarder(new InetSocketAddress("localhost", 8080), "google.com", 80)
.listen();
final Parameters params
= new Parameters("0.0.0.0", 8080, "google.com", 80);
final ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(params.getLocalHost(), params.getLocalPort()));
try {
ssh.newLocalPortForwarder(params, ss).listen();
} finally {
ss.close();
}
} finally {
ssh.disconnect();

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.channel.forwarded.RemotePortForwarder.Forward;

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.StreamCopier;
@@ -24,6 +9,7 @@ import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;
import java.io.File;
import java.io.IOException;
import net.schmizz.sshj.common.LoggerFactory;
/** A very rudimentary psuedo-terminal based on console I/O. */
class RudimentaryPTY {
@@ -48,18 +34,18 @@ class RudimentaryPTY {
final Shell shell = session.startShell();
new StreamCopier(shell.getInputStream(), System.out)
new StreamCopier(shell.getInputStream(), System.out, LoggerFactory.DEFAULT)
.bufSize(shell.getLocalMaxPacketSize())
.spawn("stdout");
new StreamCopier(shell.getErrorStream(), System.err)
new StreamCopier(shell.getErrorStream(), System.err, LoggerFactory.DEFAULT)
.bufSize(shell.getLocalMaxPacketSize())
.spawn("stderr");
// Now make System.in act as stdin. To exit, hit Ctrl+D (since that results in an EOF on System.in)
// This is kinda messy because java only allows console input after you hit return
// But this is just an example... a GUI app could implement a proper PTY
new StreamCopier(System.in, shell.getOutputStream())
new StreamCopier(System.in, shell.getOutputStream(), LoggerFactory.DEFAULT)
.bufSize(shell.getRemoteMaxPacketSize())
.copy();

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.xfer.FileSystemFile;
@@ -37,4 +22,4 @@ public class SCPDownload {
}
}
}
}

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.xfer.FileSystemFile;
@@ -42,4 +27,4 @@ public class SCPUpload {
ssh.disconnect();
}
}
}
}

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
@@ -42,4 +27,4 @@ public class SFTPDownload {
}
}
}
}

View File

@@ -1,19 +1,4 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
@@ -44,4 +29,4 @@ public class SFTPUpload {
}
}
}
}

View File

@@ -1,25 +1,11 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
package net.schmizz.sshj.examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.StreamCopier;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.connection.channel.direct.Session.Command;
import net.schmizz.sshj.connection.channel.forwarded.SocketForwardingConnectListener;
import net.schmizz.sshj.common.LoggerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -57,8 +43,8 @@ public class X11 {
final Command cmd = sess.exec("/usr/X11/bin/xcalc");
new StreamCopier(cmd.getInputStream(), System.out).spawn("stdout");
new StreamCopier(cmd.getErrorStream(), System.err).spawn("stderr");
new StreamCopier(cmd.getInputStream(), System.out, LoggerFactory.DEFAULT).spawn("stdout");
new StreamCopier(cmd.getErrorStream(), System.err, LoggerFactory.DEFAULT).spawn("stderr");
// Wait for session & X11 channel to get closed
ssh.getConnection().join();
@@ -67,4 +53,4 @@ public class X11 {
ssh.disconnect();
}
}
}
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

183
gradlew vendored Executable file
View File

@@ -0,0 +1,183 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

103
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,103 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

257
pom.xml
View File

@@ -1,257 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.schmizz</groupId>
<artifactId>sshj</artifactId>
<packaging>bundle</packaging>
<version>0.5.0</version>
<name>sshj</name>
<description>SSHv2 library for Java</description>
<url>http://github.com/shikhar/sshj</url>
<inceptionYear>2009</inceptionYear>
<issueManagement>
<system>github</system>
<url>http://github.com/shikhar/sshj/issues</url>
</issueManagement>
<scm>
<connection>scm:git:git://github.com/shikhar/sshj.git</connection>
<developerConnection>scm:git:git@github.com:shikhar/sshj.git</developerConnection>
<url>http://github.com/shikhar/sshj</url>
</scm>
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jzlib</artifactId>
<version>1.0.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>0.5.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>0.9.29</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.29</version>
<scope>test</scope>
</dependency>
</dependencies>
<developers>
<developer>
<id>shikhar</id>
<name>Shikhar Bhushan</name>
<email>shikhar@schmizz.net</email>
<url>http://schmizz.net</url>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<excludes>
<exclude>examples/*.java</exclude>
</excludes>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<mavenExecutorId>forked-path</mavenExecutorId>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptors>
<descriptor>src/assemble/examples.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>
!net.schmizz.*,
javax.crypto*,
com.jcraft.jzlib*;version="[1.0,2)",
org.slf4j*;version="[1.6,2)",
org.bouncycastle*;version="[1.4,2)",
*
</Import-Package>
<Export-Package>net.schmizz.*</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>sonatype-nexus-staging</id>
<name>Nexus Release Repository</name>
<url>http://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<profiles>
<profile>
<id>full-deps</id>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.45</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jzlib</artifactId>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>0.9.24</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.24</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.3</version>
<configuration>
<passphrase>${gpg.passphrase}</passphrase>
</configuration>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

1
settings.gradle Normal file
View File

@@ -0,0 +1 @@
rootProject.name = "sshj"

View File

@@ -1,15 +0,0 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>examples</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>src/main/java/examples</directory>
<includes/>
<outputDirectory>examples</outputDirectory>
</fileSet>
</fileSets>
</assembly>

13
src/etc/license-header Normal file
View File

@@ -0,0 +1,13 @@
Copyright ${project.inceptionYear} ${owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,26 @@
FROM sickp/alpine-sshd:7.5-r2
ADD authorized_keys /home/sshj/.ssh/authorized_keys
ADD test-container/ssh_host_dsa_key /etc/ssh/ssh_host_dsa_key
ADD test-container/ssh_host_dsa_key.pub /etc/ssh/ssh_host_dsa_key.pub
ADD test-container/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key
ADD test-container/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub
ADD test-container/ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key
ADD test-container/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_ed25519_key.pub
ADD test-container/sshd_config /etc/ssh/sshd_config
ADD test-container/users_rsa_ca.pub /etc/ssh/users_rsa_ca.pub
RUN apk add --no-cache tini
RUN \
echo "root:smile" | chpasswd && \
adduser -D -s /bin/ash sshj && \
passwd -u sshj && \
chmod 600 /home/sshj/.ssh/authorized_keys && \
chmod 600 /etc/ssh/ssh_host_ecdsa_key && \
chmod 644 /etc/ssh/ssh_host_ecdsa_key.pub && \
chmod 600 /etc/ssh/ssh_host_ed25519_key && \
chmod 644 /etc/ssh/ssh_host_ed25519_key.pub && \
chown -R sshj:sshj /home/sshj
ENTRYPOINT ["/sbin/tini", "/entrypoint.sh", "-o", "LogLevel=DEBUG2"]

View File

@@ -0,0 +1,9 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOEQcvowiV3igdRO7rKPrZrao1hCQrnC4tgsxqSJdQCbABI+vHrdbJRfWZNuSk48aAtARJzJVmkn/r63EPJgkh8= root@itgcpkerberosstack-cbgateway-0-20151117031915
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHQiZm0wBbmI8gohA/N9ir1O+egikL6S9FjZS8GHbx4rTHI1V+vbXxx2O9bFWtep1PFb4iowtZkxf6gvRjGkL6M= ajvanerp@Heimdall.local
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDAdJiRkkBM8yC8seTEoAn2PfwbLKrkcahZ0xxPoWICJ root@sshj
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8ww4hJG/gHJYdkjTTBDF1GNz+228nuWprPV+NbQauA ajvanerp@Heimdall.local
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaWrwt3drIOjeBq2LSHRavxAT7ja2f+5soOUJl/zKSI ajvanerp@Heimdall.xebialabs.com
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoZ9l6Tkm2aL1tSBy2yw4xU5s8BE9MfqS/4J7DzvsYJxF6oQmTIjmStuhH/CT7UjuDtKXdXZUsIhKtafiizxGO8kHSzKDeitpth2RSr8ddMzZKyD6RNs7MfsgjA3UTtrrSrCXEY6O43S2cnuJrWzkPxtwxaQ3zOvDbS2tiulzyq0VzYmuhA/a4CyuQtJBuu+P2oqmu6pU/VB6IzONpvBvYbNPsH1WDmP7zko5wHPihXPCliztspKxS4DRtOZ7BGXyvg44UmIy0Kf4jOkaBV/eCCA4qH7ZHz71/5ceMOpszPcNOEmLGGYhwI+P3OuGMpkrSAv1f8IY6R8spZNncP6UaQ== no-passphrase
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKRyZAtOJJfAhPU6xE6ZXY564vwErAI3n3Yn4lTHL9bxev9Ily6eCqPLcV0WbSV04pztngFn9MjT7yb8mcXheHpIaWEH569sMpmpOtyfn4p68SceuXBGyyPGMIcfOTknkASd1JYSD4EPkd9rZmCzcx3vEnLu8ChnA/G221xSVQ5VC/jD/c/CgNUayhQ+xbn57qHKKtZwfTa21QmwIabGYJNwlVjlKTCdddeVnZfKqKrG7cxHQApsxd21rhM9IT/C/f4Y/Tx3WUUVeam0iZ265oiPHoPALqJIWSQIUheRYAxYAQqJwSQ0Or9MM8XXun2Iy3RUSGk6eIvrCsFbNURsHNs7Pu0UnpYv6FZ3vCkFep/1pAT6fQvY7pDOOWDHKXArD4watc9gIWaQBH73wDW/KgBcnMRSoGWgQjsYqIamP4oV1+HqUI3lRAsXZaX+eiBGt3+3A5KebP27UJ1YUwhwlzs7wzTKaCu0OaL+hOsP1F2AxAa995bgFksMd23645ux3YCJKXG4sGpJ1Z/Hs49K72gv+QjLZVxXqY623c8+3OUhlixqoEFd4iG7UMc5a552ch/VA+jaspmLZoFhPz99aBRVb1oCSPxSwLw+Q/wxv6pZmT+14rqTzY2farjU53hM+CsUPh7dnWXhGG7RuA5wCdeOXOYjuksfzAoHIZhPqTgQ== ajvanerp@Heimdall.local
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBMvfRYSe44VQGwxexOMibcM3+fWeUP1jrBofOxFDRRrzRF8dK/vll2svqTPXMRnITnT1UoemEcB5OHtvH4hzfh/HFeDxJ5S7UncYxoClTSa8MeMFG2Zj9CoUZs1SHbwSGg== root@sshj
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHquUYgkU9wJrcxDWVtdqtfqf6SBDdPDRxwDl7OCohV2UNu2KdjJwSj8j0fsPeMdHjSiv9OCnHYrVilQ+W5WW5q5wGXwk10oIcV0JJscohLA0nS7mKinBrxUwVHnNZbPExFciicnEArcYRb1BuT7HF8hfjuSSpWS0rob6kloSSi/jV7ZA== root@sshj

View File

@@ -0,0 +1,21 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH
NzAAAAgQDGUD3XnEQf3S4iB8LbVAw9diSaTTbaKGRt+D89d6QWHJ75I684F6iehXzr7iKq
PmmVy2Bp3BfSM1m6P4wJftHbVW6dbJSeVW1Ov6SIRA5XEG/hrY1DmlC9aXhksqYKUKffYx
WOEg4p2eCtvGyu/j9EucGrC76BraEboAHpXsojNwAAABUAuEexd+FsMSbNSsJz99HcNO7M
hy8AAACBAL++FvcyX8PZ7VeQj+gu0CkDhZM14IpNGKKOBDFvZTUILHHG7TnkjBR1HJw/bR
lwkvrvYC+155sT/BC2OKpVkiUyCw1LKGVtJBas7UlqmTa4m1fEGjaWX0b1Op2hpwpxCkmj
qS07HlC/nEHsEEMdCa9HxCfbEdMmUdLNSwEVJrPAAAAAgAGb6J24Ra4fz55vlK1vt34u39
0YdMg1RLiCa4dFubc8khEMYKpwBIoyECglJyDdLXnuJQiwVzNgX1azx10G84d5QCoAZPQK
WK1oWjj8rB+4gtEjE1sB7fZkxSXF/BaRJQPiglm0kN9gJU6RZSz4vKZIE8Bk/+htXgcXvv
8R0eShAAAB6EMk1g1DJNYNAAAAB3NzaC1kc3MAAACBAMZQPdecRB/dLiIHwttUDD12JJpN
NtooZG34Pz13pBYcnvkjrzgXqJ6FfOvuIqo+aZXLYGncF9IzWbo/jAl+0dtVbp1slJ5VbU
6/pIhEDlcQb+GtjUOaUL1peGSypgpQp99jFY4SDinZ4K28bK7+P0S5wasLvoGtoRugAele
yiM3AAAAFQC4R7F34WwxJs1KwnP30dw07syHLwAAAIEAv74W9zJfw9ntV5CP6C7QKQOFkz
Xgik0Yoo4EMW9lNQgsccbtOeSMFHUcnD9tGXCS+u9gL7XnmxP8ELY4qlWSJTILDUsoZW0k
FqztSWqZNribV8QaNpZfRvU6naGnCnEKSaOpLTseUL+cQewQQx0Jr0fEJ9sR0yZR0s1LAR
Ums8AAAACAAZvonbhFrh/Pnm+UrW+3fi7f3Rh0yDVEuIJrh0W5tzySEQxgqnAEijIQKCUn
IN0tee4lCLBXM2BfVrPHXQbzh3lAKgBk9ApYrWhaOPysH7iC0SMTWwHt9mTFJcX8FpElA+
KCWbSQ32AlTpFlLPi8pkgTwGT/6G1eBxe+/xHR5KEAAAAUCbVJM+EkJ5K/JWd08304hz+O
Cq8AAAANYWp2YW5lcnBAdGhvcgECAwQF
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBAMZQPdecRB/dLiIHwttUDD12JJpNNtooZG34Pz13pBYcnvkjrzgXqJ6FfOvuIqo+aZXLYGncF9IzWbo/jAl+0dtVbp1slJ5VbU6/pIhEDlcQb+GtjUOaUL1peGSypgpQp99jFY4SDinZ4K28bK7+P0S5wasLvoGtoRugAeleyiM3AAAAFQC4R7F34WwxJs1KwnP30dw07syHLwAAAIEAv74W9zJfw9ntV5CP6C7QKQOFkzXgik0Yoo4EMW9lNQgsccbtOeSMFHUcnD9tGXCS+u9gL7XnmxP8ELY4qlWSJTILDUsoZW0kFqztSWqZNribV8QaNpZfRvU6naGnCnEKSaOpLTseUL+cQewQQx0Jr0fEJ9sR0yZR0s1LARUms8AAAACAAZvonbhFrh/Pnm+UrW+3fi7f3Rh0yDVEuIJrh0W5tzySEQxgqnAEijIQKCUnIN0tee4lCLBXM2BfVrPHXQbzh3lAKgBk9ApYrWhaOPysH7iC0SMTWwHt9mTFJcX8FpElA+KCWbSQ32AlTpFlLPi8pkgTwGT/6G1eBxe+/xHR5KE= ajvanerp@thor

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOpOBFjqe0hjK/hs4WZ3dZqnzanq1L3/JbvV1TCkbe4ToAoGCCqGSM49
AwEHoUQDQgAEVzkrS7Yj0nXML7A3mE08YDthfBR/ZbyYJDIq1vTzcqs6KTaCT529
swNXWLHO+mbHviZcRiI57ULXHZ1emom/Jw==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFc5K0u2I9J1zC+wN5hNPGA7YXwUf2W8mCQyKtb083KrOik2gk+dvbMDV1ixzvpmx74mXEYiOe1C1x2dXpqJvyc= root@404b27be2bf4

View File

@@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBFG9PKAq8FtH0me+LHUE6YaVANCMqy/Znkffzief1W/gAAAKCyyoBkssqA
ZAAAAAtzc2gtZWQyNTUxOQAAACBFG9PKAq8FtH0me+LHUE6YaVANCMqy/Znkffzief1W/g
AAAED+Yfza2xk5LqP9pN6TpvhWYP0L60zOQJpHhbEuiS3LLkUb08oCrwW0fSZ74sdQTphp
UA0IyrL9meR9/OJ5/Vb+AAAAF2FqdmFuZXJwQEhlaW1kYWxsLmxvY2FsAQIDBAUG
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEUb08oCrwW0fSZ74sdQTphpUA0IyrL9meR9/OJ5/Vb+ ajvanerp@Heimdall.local

View File

@@ -0,0 +1,140 @@
# $OpenBSD: sshd_config,v 1.101 2017/03/14 07:19:07 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/bin:/usr/bin:/sbin:/usr/sbin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
#UsePAM no
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# override default of no subsystems
Subsystem sftp /usr/lib/ssh/sftp-server
# the following are HPN related configuration options
# tcp receive buffer polling. disable in non autotuning kernels
#TcpRcvBufPoll yes
# disable hpn performance boosts
#HPNDisabled no
# buffer size for hpn to non-hpn connections
#HPNBufferSize 2048
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
TrustedUserCAKeys /etc/ssh/users_rsa_ca.pub
KexAlgorithms +diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1
macs +hmac-ripemd160-etm@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com
Ciphers +3des-cbc,blowfish-cbc,aes128-cbc,aes192-cbc,aes256-cbc
PubKeyAcceptedKeyTypes +ssh-dss
HostKeyAlgorithms +ssh-dss
HostbasedAcceptedKeyTypes +ssh-dss

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDN70b/cYHZQMD1YW0mlncXqC2l++sEWrVYlIUCzNxNhRYjI4UmEVEq3ru1h6K3ZVAJi1DcZuf5ne1ZXtwJ1Uw1JA4wGdKw+9TwAb5Gubn+VEowgt62kLAPeChiPucTXD0FDDhIUOBv3KxytdrJIYAtzZT27STsBiDF1+7Ld3wk/1Dg9NAaI6q40PmuicTEACQRHn5snI1t9+LgZTd3/PPE5pjJM0ow9+r6mlUUM5oHCk5sZ8DBuRR1Ram4sxp/LFQM+9feMmW3ZM2C5AN0JG4A7NXnlwiTKmNVrGI0iFucBBKhjxN1qdgBF11/42cCrerC9UW1auTTi9mqwEIqBGL30VOPy+dCPQQViP+C09CBgyr3wpZciPKP1mvmcOkC5FDzKg9e3v1JBq0fqZgwt+PPG8cGnxRCGEQ+ZMLDuAixkQUEwDWeMskHLkbjUEiVZydViCPSzFczGtKatQiQVZA5Zx0Gn2sUaQjykhWzqKNL8oIbolEdkH9ubOZWNi0brzU= root@sshj

6
src/itest/generate.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
# Don't call it frequently. It's rather a documentation how everything is generated.
ssh-keygen -f resources/users_rsa_ca -t rsa -N ''
mv resources/users_rsa_ca.pub docker-image/test-container
ssh-keygen -f resources/keyfiles/id_rsa2 -t rsa -m pem -N ''
ssh-keygen -s resources/users_rsa_ca -I my_key_id -n sshj resources/keyfiles/id_rsa2.pub

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj
import net.schmizz.sshj.Config
import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.transport.verification.PromiscuousVerifier
import spock.lang.Specification
class IntegrationBaseSpec extends Specification {
protected static final int DOCKER_PORT = 2222
protected static final String USERNAME = "sshj"
protected static final String KEYFILE = "src/itest/resources/keyfiles/id_rsa"
protected final static String SERVER_IP = System.getProperty("serverIP", "127.0.0.1")
protected static SSHClient getConnectedClient(Config config) {
SSHClient sshClient = new SSHClient(config)
sshClient.addHostKeyVerifier(new PromiscuousVerifier())
sshClient.connect(SERVER_IP, DOCKER_PORT)
return sshClient
}
protected static SSHClient getConnectedClient() throws IOException {
return getConnectedClient(new DefaultConfig())
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj
import com.hierynomus.sshj.key.KeyAlgorithms
import com.hierynomus.sshj.transport.kex.DHGroups
import com.hierynomus.sshj.transport.cipher.BlockCiphers
import com.hierynomus.sshj.transport.mac.Macs
import net.schmizz.sshj.transport.verification.PromiscuousVerifier
import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.transport.TransportException
import net.schmizz.sshj.userauth.UserAuthException
import spock.lang.Unroll
class IntegrationSpec extends IntegrationBaseSpec {
@Unroll
def "should accept correct key for #signatureName"() {
given:
def config = new DefaultConfig()
config.setKeyAlgorithms(Collections.singletonList(signatureFactory))
SSHClient sshClient = new SSHClient(config)
sshClient.addHostKeyVerifier(fingerprint) // test-containers/ssh_host_ecdsa_key's fingerprint
when:
sshClient.connect(SERVER_IP, DOCKER_PORT)
then:
sshClient.isConnected()
where:
signatureFactory << [KeyAlgorithms.ECDSASHANistp256(), KeyAlgorithms.EdDSA25519()]
fingerprint << ["d3:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3", "dc:68:38:ce:fc:6f:2c:d6:6d:6b:34:eb:5c:f0:41:6a"]
signatureName = signatureFactory.getName()
}
def "should decline wrong key"() throws IOException {
given:
SSHClient sshClient = new SSHClient(new DefaultConfig())
sshClient.addHostKeyVerifier("d4:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3")
when:
sshClient.connect(SERVER_IP, DOCKER_PORT)
then:
thrown(TransportException.class)
}
@Unroll
def "should authenticate with key #key"() {
given:
SSHClient client = getConnectedClient()
when:
def keyProvider = passphrase != null ? client.loadKeys("src/itest/resources/keyfiles/$key", passphrase) : client.loadKeys("src/itest/resources/keyfiles/$key")
client.authPublickey(USERNAME, keyProvider)
then:
client.isAuthenticated()
where:
key | passphrase
// "id_ecdsa_nistp256" | null // TODO: Need to improve PKCS8 key support.
"id_ecdsa_opensshv1" | null
"id_ed25519_opensshv1" | null
"id_ed25519_opensshv1_aes256cbc.pem" | "foobar"
"id_ed25519_opensshv1_protected" | "sshjtest"
"id_rsa" | null
"id_rsa_opensshv1" | null
"id_ecdsa_nistp384_opensshv1" | null
"id_ecdsa_nistp521_opensshv1" | null
}
def "should not authenticate with wrong key"() {
given:
SSHClient client = getConnectedClient()
when:
client.authPublickey("sshj", "src/itest/resources/keyfiles/id_unknown_key")
then:
thrown(UserAuthException.class)
!client.isAuthenticated()
}
def "should correctly connect using parameters in #670"() {
given:
def config = new DefaultConfig()
// config.setKeyAlgorithms(Collections.singletonList(KeyAlgorithms.SSHDSA())) // Can't get openssh to offer ssh-dss
config.setKeyExchangeFactories(DHGroups.Group1SHA1())
config.setCipherFactories(BlockCiphers.TripleDESCBC())
config.setMACFactories(Macs.HMACSHA1())
SSHClient sshClient = new SSHClient(config)
sshClient.addHostKeyVerifier(new PromiscuousVerifier())
when:
sshClient.connect(SERVER_IP, DOCKER_PORT)
then:
sshClient.isConnected()
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.sftp
import com.hierynomus.sshj.IntegrationBaseSpec
import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.sftp.OpenMode
import net.schmizz.sshj.sftp.RemoteFile
import net.schmizz.sshj.sftp.SFTPClient
import java.nio.charset.StandardCharsets
import static org.codehaus.groovy.runtime.IOGroovyMethods.withCloseable
class FileWriteSpec extends IntegrationBaseSpec {
def "should append to file (GH issue #390)"() {
given:
SSHClient client = getConnectedClient()
client.authPublickey("sshj", "src/test/resources/id_rsa")
SFTPClient sftp = client.newSFTPClient()
def file = "/home/sshj/test.txt"
def initialText = "This is the initial text.\n".getBytes(StandardCharsets.UTF_16)
def appendText = "And here's the appended text.\n".getBytes(StandardCharsets.UTF_16)
when:
withCloseable(sftp.open(file, EnumSet.of(OpenMode.WRITE, OpenMode.CREAT))) { RemoteFile initial ->
initial.write(0, initialText, 0, initialText.length)
}
then:
withCloseable(sftp.open(file, EnumSet.of(OpenMode.READ))) { RemoteFile read ->
def bytes = new byte[initialText.length]
read.read(0, bytes, 0, bytes.length)
bytes == initialText
}
when:
withCloseable(sftp.open(file, EnumSet.of(OpenMode.WRITE, OpenMode.APPEND))) { RemoteFile append ->
append.write(0, appendText, 0, appendText.length)
}
then:
withCloseable(sftp.open(file, EnumSet.of(OpenMode.READ))) { RemoteFile read ->
def bytes = new byte[initialText.length + appendText.length]
read.read(0, bytes, 0, bytes.length)
Arrays.copyOfRange(bytes, 0, initialText.length) == initialText
Arrays.copyOfRange(bytes, initialText.length, initialText.length + appendText.length) == appendText
}
cleanup:
sftp.close()
client.close()
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.signature
import com.hierynomus.sshj.IntegrationBaseSpec
import net.schmizz.sshj.DefaultConfig
import spock.lang.Unroll
class RsaSignatureClientKeySpec extends IntegrationBaseSpec {
@Unroll
def "should correctly connect using publickey auth with RSA key with signature"() {
given:
def client = getConnectedClient(new DefaultConfig())
when:
client.authPublickey(USERNAME, "src/itest/resources/keyfiles/id_rsa2")
then:
client.authenticated
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.signature
import com.hierynomus.sshj.IntegrationBaseSpec
import com.hierynomus.sshj.key.KeyAlgorithms
import net.schmizz.sshj.DefaultConfig
import spock.lang.Unroll
class SignatureSpec extends IntegrationBaseSpec {
@Unroll
def "should correctly connect with #sig Signature"() {
given:
def cfg = new DefaultConfig()
cfg.setKeyAlgorithms(Collections.singletonList(sigFactory))
def client = getConnectedClient(cfg)
when:
client.authPublickey(USERNAME, KEYFILE)
then:
client.authenticated
where:
sigFactory << [KeyAlgorithms.SSHRSA(), KeyAlgorithms.RSASHA256(), KeyAlgorithms.RSASHA512()]
sig = sigFactory.name
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher
import com.hierynomus.sshj.IntegrationBaseSpec
import net.schmizz.sshj.DefaultConfig
import spock.lang.Unroll
class CipherSpec extends IntegrationBaseSpec {
@Unroll
def "should correctly connect with #cipher Cipher"() {
given:
def cfg = new DefaultConfig()
cfg.setCipherFactories(cipherFactory)
def client = getConnectedClient(cfg)
when:
client.authPublickey(USERNAME, KEYFILE)
then:
client.authenticated
cleanup:
client.disconnect()
where:
cipherFactory << [BlockCiphers.TripleDESCBC(),
BlockCiphers.BlowfishCBC(),
BlockCiphers.AES128CBC(),
BlockCiphers.AES128CTR(),
BlockCiphers.AES192CBC(),
BlockCiphers.AES192CTR(),
BlockCiphers.AES256CBC(),
BlockCiphers.AES256CTR(),
GcmCiphers.AES128GCM(),
GcmCiphers.AES256GCM()]
cipher = cipherFactory.name
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.kex
import com.hierynomus.sshj.IntegrationBaseSpec
import com.hierynomus.sshj.transport.mac.Macs
import net.schmizz.sshj.DefaultConfig
import net.schmizz.sshj.transport.kex.Curve25519DH
import net.schmizz.sshj.transport.kex.Curve25519SHA256
import net.schmizz.sshj.transport.kex.DH
import net.schmizz.sshj.transport.kex.DHGexSHA1
import net.schmizz.sshj.transport.kex.DHGexSHA256
import net.schmizz.sshj.transport.kex.ECDH
import net.schmizz.sshj.transport.kex.ECDHNistP
import spock.lang.Unroll
class KexSpec extends IntegrationBaseSpec {
@Unroll
def "should correctly connect with #kex Key Exchange"() {
given:
def cfg = new DefaultConfig()
cfg.setKeyExchangeFactories(kexFactory)
def client = getConnectedClient(cfg)
when:
client.authPublickey(USERNAME, KEYFILE)
then:
client.authenticated
where:
kexFactory << [DHGroups.Group1SHA1(),
DHGroups.Group14SHA1(),
DHGroups.Group14SHA256(),
DHGroups.Group16SHA512(),
DHGroups.Group18SHA512(),
new DHGexSHA1.Factory(),
new DHGexSHA256.Factory(),
new Curve25519SHA256.Factory(),
new Curve25519SHA256.FactoryLibSsh(),
new ECDHNistP.Factory256(),
new ECDHNistP.Factory384(),
new ECDHNistP.Factory521()]
kex = kexFactory.name
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.mac
import com.hierynomus.sshj.IntegrationBaseSpec
import net.schmizz.sshj.DefaultConfig
import spock.lang.Unroll
class MacSpec extends IntegrationBaseSpec {
@Unroll
def "should correctly connect with #mac MAC"() {
given:
def cfg = new DefaultConfig()
cfg.setMACFactories(macFactory)
def client = getConnectedClient(cfg)
when:
client.authPublickey(USERNAME, KEYFILE)
then:
client.authenticated
cleanup:
client.disconnect()
where:
macFactory << [Macs.HMACRIPEMD160(), Macs.HMACRIPEMD160OpenSsh(), Macs.HMACSHA2256(), Macs.HMACSHA2512()]
mac = macFactory.name
}
@Unroll
def "should correctly connect with Encrypt-Then-Mac #mac MAC"() {
given:
def cfg = new DefaultConfig()
cfg.setMACFactories(macFactory)
def client = getConnectedClient(cfg)
when:
client.authPublickey(USERNAME, KEYFILE)
then:
client.authenticated
cleanup:
client.disconnect()
where:
macFactory << [Macs.HMACRIPEMD160Etm(), Macs.HMACSHA2256Etm(), Macs.HMACSHA2512Etm()]
mac = macFactory.name
}
}

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJUMlsSlXqCZmCjlN4kV7hzP+p9pu0fwJ8r4m1qle58SoAoGCCqGSM49
AwEHoUQDQgAE4RBy+jCJXeKB1E7uso+tmtqjWEJCucLi2CzGpIl1AJsAEj68et1s
lF9Zk25KTjxoC0BEnMlWaSf+vrcQ8mCSHw==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,10 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS
1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQTL30WEnuOFUBsMXsTjIm3DN/n1nlD9
Y6waHzsRQ0Ua80RfHSv75ZdrL6kz1zEZyE509VKHphHAeTh7bx+Ic34fxxXg8SeUu1J3GM
aApU0mvDHjBRtmY/QqFGbNUh28EhoAAADYHWlHLx1pRy8AAAATZWNkc2Etc2hhMi1uaXN0
cDM4NAAAAAhuaXN0cDM4NAAAAGEEy99FhJ7jhVAbDF7E4yJtwzf59Z5Q/WOsGh87EUNFGv
NEXx0r++WXay+pM9cxGchOdPVSh6YRwHk4e28fiHN+H8cV4PEnlLtSdxjGgKVNJrwx4wUb
ZmP0KhRmzVIdvBIaAAAAMQD3sx28SrtkuhN+Yu06BAoFLMMgneIqguM3jowaz0LWfP1Nhx
Rnh9tNKM6YYvygCggAAAAPZmhlbm5la2VATGFwdG9w
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,12 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS
1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQB6rlGIJFPcCa3MQ1lbXarX6n+kgQ3
Tw0ccA5ezgqIVdlDbtinYycEo/I9H7D3jHR40or/Tgpx2K1YpUPluVluaucBl8JNdKCHFd
CSbHKISwNJ0u5iopwa8VMFR5zWWzxMRXIonJxAK3GEW9Qbk+xxfIX47kkqVktK6G+pJaEk
ov41e2QAAAEQwljQZcJY0GUAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ
AAAIUEAeq5RiCRT3AmtzENZW12q1+p/pIEN08NHHAOXs4KiFXZQ27Yp2MnBKPyPR+w94x0
eNKK/04KcditWKVD5blZbmrnAZfCTXSghxXQkmxyiEsDSdLuYqKcGvFTBUec1ls8TEVyKJ
ycQCtxhFvUG5PscXyF+O5JKlZLSuhvqSWhJKL+NXtkAAAAQVXt20tSeLzMU1U2nMv8CEEY
Oyl1WIkGAcRatDBAfsE0+NcJ/eSbPXywWAqCzOElQ5ftNFz9t1kNXwW5qiLaaIBpAAAAD2
ZoZW5uZWtlQExhcHRvcAECAwQ=
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQR0ImZtMAW5iPIKIQPzfYq9TvnoIpC+
kvRY2UvBh28eK0xyNVfr218cdjvWxVrXqdTxW+IqMLWZMX+oL0YxpC+jAAAAsD+6Oow/uj
qMAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHQiZm0wBbmI8goh
A/N9ir1O+egikL6S9FjZS8GHbx4rTHI1V+vbXxx2O9bFWtep1PFb4iowtZkxf6gvRjGkL6
MAAAAgXNC11pInVAOd3xNphiHMoISeitf6h1IKbDM+niLrL5kAAAAXYWp2YW5lcnBASGVp
bWRhbGwubG9jYWwB
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAwHSYkZJATPMgvLHkxKAJ9j38Gyyq5HGoWdMcT6FiAiQAAAJDimgR84poE
fAAAAAtzc2gtZWQyNTUxOQAAACAwHSYkZJATPMgvLHkxKAJ9j38Gyyq5HGoWdMcT6FiAiQ
AAAECmsckQycWnfGQK6XtQpaMGODbAkMQOdJNK6XJSipB7dDAdJiRkkBM8yC8seTEoAn2P
fwbLKrkcahZ0xxPoWICJAAAACXJvb3RAc3NoagECAwQ=
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBLQVXV9f
Wpw8AL9RTpAr//AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIJ8ww4hJG/gHJYdk
jTTBDF1GNz+228nuWprPV+NbQauAAAAAoGHEO7x3fSRBohvrIR52U4XD3uqRnhrPYm01k1
f4HHNNv46m92Zw6JKIB9Trrvp0sdMI8MVb79bN45rbn6mvpABtWl6T5TOTyMnKzDfAOx9c
FTaasWFmgtgkXOsu5pLrYBAQgCHWbzjjz6KoV1DmD4SAn9Ojf9Oh+YdAEKZcsvklgpu+Kj
nzN/DR0jt7Nzep2kNCLAS24QEkvQeATVSDiL8=
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABB/aWL0WG
iYPOTxGlFwvaCNAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIOaWrwt3drIOjeBq
2LSHRavxAT7ja2f+5soOUJl/zKSIAAAAsKplAiFbOhzcOJYFYBYm8sqYbvhPF8jKdQFkbo
LAOeq+vQ0YBV9XUWQQM2tmL+RPjykPJZ2thcHLpVp3PfUEgo4bImCt939b3Ji3cEwD3QuK
MIhjhx1KvSJNF/uhjwPJnttwHG+ld8F5Gv7LpTOUmOzXKGLIgYRuwonhs5ezdNv5ERs+Cq
M9p/SW5ehL5KPJhGa5a+ZQXRojwEH7J4Q5xztH1gviTdIEpFWWQBH8rX6y
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEoAIBAAKCAQEAoZ9l6Tkm2aL1tSBy2yw4xU5s8BE9MfqS/4J7DzvsYJxF6oQm
TIjmStuhH/CT7UjuDtKXdXZUsIhKtafiizxGO8kHSzKDeitpth2RSr8ddMzZKyD6
RNs7MfsgjA3UTtrrSrCXEY6O43S2cnuJrWzkPxtwxaQ3zOvDbS2tiulzyq0VzYmu
hA/a4CyuQtJBuu+P2oqmu6pU/VB6IzONpvBvYbNPsH1WDmP7zko5wHPihXPClizt
spKxS4DRtOZ7BGXyvg44UmIy0Kf4jOkaBV/eCCA4qH7ZHz71/5ceMOpszPcNOEmL
GGYhwI+P3OuGMpkrSAv1f8IY6R8spZNncP6UaQIBIwKCAQBXvO4uJlbrLJQDPYAt
1i1ybGcF+rrR/Q34a2dgCpZDEwFiDTlcv1hxx689OXTf5cMPXGDZXX5udd9p7Wxa
NqnIrvVUtQWLdqcZuEeO+gitHr8IyMJf5Lm8C/u5vl1PYOYhO0qxwmrTP1u6fZPh
zWX2X1p5626/sy+TCisCRDeLRyes+Dtfs3bDjUq+zF3D/DmeYY55LUx0XS27uXNS
QuUDMSnymFyj4o+jPK0q/j5w4bB+0rbsij+EP7S//jOFrSEcZgBhhIj0rHA5fo6w
NrgtgRKD3HKFBM3b4VM8TdMbHsmf+nT9DjiDqcs+IxXMGlb1XTjtQFIN2eyRtNLd
eQ0bAoGBAMwgv3rGytRjVbR4TT77eF81svzitOJWRdfXuKB5gqM3jsPR08f1MEtZ
44kaI5ByJ3mBDt/EwNgLRdmBddPrLu3so9VLdRmWKI+KNGxwkcxzJv1xXdicgw+w
S5WgigJryuUbtdylXQTlRArLUKsXULk/MndhGiD+a4fZ3dUtktF9AoGBAMqxh6tr
S0ao0rN4hc9I92gwPubD1+XQr9TJQEEqGv3g5O3BdfDrTvizfaeNArahrIqyO5SK
7iDg0xcHqdxmVmmCJ8CkIWBPXLU6erQ1QNlBJmnzYn5lR0Ksx2h/myjeXztvJKEM
q4xUjAEzWjmwxxU3Y6l3FokvgIU4kOVoE4JdAoGARfyZa+xizHnUPeAae/5yaclE
rnmdGma43En2KGQsyj7vHpEVaSDdW6nKWuRj9wKRMPkMafpQvxnOzjsD06EXZ4RV
bbN4mw7pVcj8B+wUuyAqoAmchMfya8dqXy+6SfkSXS4Sd4knNODkIPVAOqjoegcJ
/QtZamXbuYyGkjuCy3sCgYBLSUEFJ9ohjymwX/cvvAQfYmCBmTLu9b2mzmhSt94j
yI+Lgl8BtnxrANbmdjQ1NLxuB6+61IRVWtIP3kZnzj1aY4sbqq1PqHLkOkrVOFnq
S2YKGJJMND8KIur67ZFm84J1KUgej61uow9uKQRBUEnx8AByJOsdAwPZteys+sVq
7wKBgAc3BL6ttDVYlL8U8fgvTCGuIajItvOQQj1n8RKyRLblYXBKAtY+pbULzmF+
HscRgJMcwEIosEbTzzBNEVQm6dS6R/Q534C00Fpsw1z/PFTI8AOdUzTROGjuN8Fg
YZoqMQLhk/PB8V4l7yJmPrE971RmJBBDlLDt6hZwOYEI2yF4
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG5QIBAAKCAYEA0MZ2xduy86/VbzZWnOnzSqUVeU7ajzwc3LF9vR9ZbufZdCB8
pYRzpQ4B9v3umDZ3nX9qPM4f2iMVDfiz241SwmvV5s7WiOHPhy3ij5mUpRXOn3a8
byVIjdraaVawL642p98cLKB9WKEjKaDw633aD7xzSIomqQboVZrMHNjvIanyd3U6
j9mnoydXD1cIuceZx4S/Av8IQru9AiZYJ7rAfZwz3ip9YWcgT0yIohDbBSX7fsX2
7KF6txIfRXJCJg0QO0kOYoMQmLYJtkVApwixdV29Vx2g5PBKXDQ12FwGXTnZG36v
YYZ7ng12PV+xMyC1xPLdXnzrNR/lO4BGtT14GYJbwVM3gjBDrceavaayVW4SjFrq
R5XDLjldKAfKtCHEavLv16Df1eAwnPlGAwmODlRqTHvL5oxBQibvNjDzVpvfqEsF
RqP/d4AbYjARsKCkeu3PzUI+rq5AtwZ52XKgGdg13wURoAkIsNXonKo92avLnomq
skdTYpfBEOUMSZO9AgMBAAECggGAadURhH84mft6kKPVCDo4UJCa8CGe/ZkVcHKx
MNvhdC0nuIx3Y1hfXz5YlKJo/tQtkrNyYVyEHQpHtAts8VEUsOYFSrlzW3RMxVPn
U7AhAAar9X41S4p02yQkL9339lOz9SlOmPjKUdFth77EIjxr/ColrpIJwwlzYWHV
MpJttnz2IsRUaXOGXVil82rFS5f5RoDua1BpGZsd1yck7Q7oYUR7rpWPdX7XjBtZ
7/3naRa2BK/J2m6JTKBtJcEj8zIPK4HXVO7NriQvhMyFAc5FRR+0ZQFp0bNdCELT
k7nbDaHL8QPfzRiH9zLHe/WHJKNZxTcXctU1v/aBBNPAwsT4NHLydrtVagzBZ/YO
ZBB1JKfpdmnQ54vNI1jlkNCbhkMNPZuDCCk3l4qq6JLi3DrYYqi1B8qzVxivw8ps
0eNt4tMHqmOGwMBEzaYcAXfn66Lea84+QyGc5ibwPuBPtuQcNvHdY4BzXFerDqDI
i/rdMH0ELvTPbgpgl3SrIqCWCoMpAoHBAPZcpWDK22owtw0D0QDylO/H3rkf3WX5
5bo9FzoKtZdHNhZJUYFPBC26xHKXJgSKh6OuL9IlXtpQD3u4EctBevnJU8OZxKAM
MJZ/vIXxnAGONuhcDs/kns0Bu9QNgdUOdYW1DomNaePQ669awhXtwaxVeBqwl6AT
v6PnlzyRZK9Di/9xwkh/g0h4258ef0grD2oDUIxDvEnm9Ul9mE8MIqUjQw/dfpuA
D2mW0nh+FK861VbGRrlumhr4y33KNIs5SwKBwQDY8WGyGlPvjPBUD4kHaledNCYu
vMBvlo8UKlk9SpcRpHUqOm5IFmKmmLQdEqYip4PULGZVFjbrfil4LKV9pMxtmn56
HKqteoWP1VuqhC1j2RdnX1KuIqB+sv30BkWsrOsOC6YwaDHl5eLPJv0BbFWApBEm
/g2n2wpoHvGr2uSl0+B2mRw/BFcWw3zLcBB6OP/U4hjpPgEfwHLp2tG8DraT/dOm
7o+DYQQz6ACqz8pzrMyzS/6uaR/YK70Q8RKPihcCgcEAliiH4EQkkkfY+oTN+h7h
KnkPRpSmdEZpgCdGJelrHyaXT+QmWoNXz6ubmyCHWpM480ny+covUy8jEMxzhAiI
NQFCHeF2V/q2DrUSqi1GYihVTTD3Ej2NkPSykCAfd0XV2cYucyaPWPz4+it+SrFc
r3Z0uwfRkw8Waod4xcD0tmKcTPkAawHVefG4IvcKq2kbfwlAKg4LEJxF+yIjGGMU
JsUkVeIyDgNy4W+9HxXx85APglFdwB4qra/hD+2UMxubAoHBAIRUeOtS8/AjYFVm
RIepblgN/1xy9k8a35vFWTnxzcSNNIrVqX9/aB2G+Bbj0UNCOz+o9aLhMg7jnhgX
47qIU8pnes6xvcqj+eSKmKeiiK1nNsdvddeSd6PROucnDEkQETE4Gd9dL1K0r2z8
s0ey9VTKv0uxnFLPYcGxXmkd1GrymvC85GXsF9Ni2zSc3vAu5J7Oa7OahsT/dxj+
yQCVWPlc00X4LsJM42tmEUIgDbYRqauUp31r0mjiBSnYYyH7cQKBwQC+2mw3oRsu
La9Yj11WcwWy6in26JyITYmEnfwydDTdX8tn9XdPva94frC/TJkDmoh9gYSNZc8r
zm9y/l9LpO98jIG+jH9wFRKO7xgCffZl4tbvu1DsGbh86IS7gvRbIwN5mnrKC61g
4c/+PYAJnyC7+0oXhY2W7h2STUWi3/AvT/EnGLv7k41+9H3Hj5oqkWEt+DITgBia
sTT3iRK6YVtXBg+AyG7nbobwTtZu98uFBjHwzGaelSPGGiWsUx4/u2Y=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1 @@
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgUsee85QZv49JUmGGA6cN852mR2cSsEst9KDH7gk3Lq4AAAADAQABAAABgQDQxnbF27Lzr9VvNlac6fNKpRV5TtqPPBzcsX29H1lu59l0IHylhHOlDgH2/e6YNnedf2o8zh/aIxUN+LPbjVLCa9XmztaI4c+HLeKPmZSlFc6fdrxvJUiN2tppVrAvrjan3xwsoH1YoSMpoPDrfdoPvHNIiiapBuhVmswc2O8hqfJ3dTqP2aejJ1cPVwi5x5nHhL8C/whCu70CJlgnusB9nDPeKn1hZyBPTIiiENsFJft+xfbsoXq3Eh9FckImDRA7SQ5igxCYtgm2RUCnCLF1Xb1XHaDk8EpcNDXYXAZdOdkbfq9hhnueDXY9X7EzILXE8t1efOs1H+U7gEa1PXgZglvBUzeCMEOtx5q9prJVbhKMWupHlcMuOV0oB8q0IcRq8u/XoN/V4DCc+UYDCY4OVGpMe8vmjEFCJu82MPNWm9+oSwVGo/93gBtiMBGwoKR67c/NQj6urkC3BnnZcqAZ2DXfBRGgCQiw1eicqj3Zq8ueiaqyR1Nil8EQ5QxJk70AAAAAAAAAAAAAAAEAAAAJbXlfa2V5X2lkAAAACAAAAARzc2hqAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQDN70b/cYHZQMD1YW0mlncXqC2l++sEWrVYlIUCzNxNhRYjI4UmEVEq3ru1h6K3ZVAJi1DcZuf5ne1ZXtwJ1Uw1JA4wGdKw+9TwAb5Gubn+VEowgt62kLAPeChiPucTXD0FDDhIUOBv3KxytdrJIYAtzZT27STsBiDF1+7Ld3wk/1Dg9NAaI6q40PmuicTEACQRHn5snI1t9+LgZTd3/PPE5pjJM0ow9+r6mlUUM5oHCk5sZ8DBuRR1Ram4sxp/LFQM+9feMmW3ZM2C5AN0JG4A7NXnlwiTKmNVrGI0iFucBBKhjxN1qdgBF11/42cCrerC9UW1auTTi9mqwEIqBGL30VOPy+dCPQQViP+C09CBgyr3wpZciPKP1mvmcOkC5FDzKg9e3v1JBq0fqZgwt+PPG8cGnxRCGEQ+ZMLDuAixkQUEwDWeMskHLkbjUEiVZydViCPSzFczGtKatQiQVZA5Zx0Gn2sUaQjykhWzqKNL8oIbolEdkH9ubOZWNi0brzUAAAGUAAAADHJzYS1zaGEyLTUxMgAAAYBxPe4yc3IwnjwULBv1tk3uTr35MKqIiDrIuWX9+7w/EJ9hQPjSZjtiOABP/C63F2c43zvN1XUqJ1Yvrh1dqpI5nIxexMLFRgJrawALHNsc5h5uLBL6q9rgyJsUNWXMgl9nOUGDDh+Jg6yM6SUVd44WuDTbgxtIwc5Uq6fE+HFowM35Xt0u9UEOBqOzpyBNYjNEsCMfPxkbzYGcLW9Y2C28ygrizRn+rhXFG3sQxraiCPVAL+d9NMGV3TaFXScEoCuXKRyHab1ch9g613FBL16k2rxZWoHfwI07bAUrpcv5upR5RMeeYrNmE7mrQ5WHemACd6QJtknPxOfxgAKOck486b29dgAt5C6P81T0mL0+52bu0LkbRYxVEExdeDurvhue2ZzGG11PbEJdLpVbgcPJr7dUkPPG2nPW4JLqqnzlulqu7Me07mgJuVK1OnXUKKziQ8BcDqx6lsdBg/CuKvL4PedFkSh32W+7VIQq7e9sVEV+Q5CngWfr2sYFh3cu3kw= lagunov@unit-1381

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQxnbF27Lzr9VvNlac6fNKpRV5TtqPPBzcsX29H1lu59l0IHylhHOlDgH2/e6YNnedf2o8zh/aIxUN+LPbjVLCa9XmztaI4c+HLeKPmZSlFc6fdrxvJUiN2tppVrAvrjan3xwsoH1YoSMpoPDrfdoPvHNIiiapBuhVmswc2O8hqfJ3dTqP2aejJ1cPVwi5x5nHhL8C/whCu70CJlgnusB9nDPeKn1hZyBPTIiiENsFJft+xfbsoXq3Eh9FckImDRA7SQ5igxCYtgm2RUCnCLF1Xb1XHaDk8EpcNDXYXAZdOdkbfq9hhnueDXY9X7EzILXE8t1efOs1H+U7gEa1PXgZglvBUzeCMEOtx5q9prJVbhKMWupHlcMuOV0oB8q0IcRq8u/XoN/V4DCc+UYDCY4OVGpMe8vmjEFCJu82MPNWm9+oSwVGo/93gBtiMBGwoKR67c/NQj6urkC3BnnZcqAZ2DXfBRGgCQiw1eicqj3Zq8ueiaqyR1Nil8EQ5QxJk70= lagunov@unit-1381

View File

@@ -0,0 +1,49 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAgEAykcmQLTiSXwIT1OsROmV2OeuL8BKwCN592J+JUxy/W8Xr/SJcung
qjy3FdFm0ldOKc7Z4BZ/TI0+8m/JnF4Xh6SGlhB+evbDKZqTrcn5+KevEnHrlwRssjxjCH
Hzk5J5AEndSWEg+BD5Hfa2Zgs3Md7xJy7vAoZwPxtttcUlUOVQv4w/3PwoDVGsoUPsW5+e
6hyirWcH02ttUJsCGmxmCTcJVY5SkwnXXXlZ2Xyqiqxu3MR0AKbMXdta4TPSE/wv3+GP08
d1lFFXmptImduuaIjx6DwC6iSFkkCFIXkWAMWAEKicEkNDq/TDPF17p9iMt0VEhpOniL6w
rBWzVEbBzbOz7tFJ6WL+hWd7wpBXqf9aQE+n0L2O6QzjlgxylwKw+MGrXPYCFmkAR+98A1
vyoAXJzEUqBloEI7GKiGpj+KFdfh6lCN5UQLF2Wl/nogRrd/twOSnmz9u1CdWFMIcJc7O8
M0ymgrtDmi/oTrD9RdgMQGvfeW4BZLDHdt+uObsd2AiSlxuLBqSdWfx7OPSu9oL/kIy2Vc
V6mOtt3PPtzlIZYsaqBBXeIhu1DHOWuednIf1QPo2rKZi2aBYT8/fWgUVW9aAkj8UsC8Pk
P8Mb+qWZk/teK6k82Nn2q41Od4TPgrFD4e3Z1l4Rhu0bgOcAnXjlzmI7pLH8wKByGYT6k4
EAAAdQ3L5mFty+ZhYAAAAHc3NoLXJzYQAAAgEAykcmQLTiSXwIT1OsROmV2OeuL8BKwCN5
92J+JUxy/W8Xr/SJcungqjy3FdFm0ldOKc7Z4BZ/TI0+8m/JnF4Xh6SGlhB+evbDKZqTrc
n5+KevEnHrlwRssjxjCHHzk5J5AEndSWEg+BD5Hfa2Zgs3Md7xJy7vAoZwPxtttcUlUOVQ
v4w/3PwoDVGsoUPsW5+e6hyirWcH02ttUJsCGmxmCTcJVY5SkwnXXXlZ2Xyqiqxu3MR0AK
bMXdta4TPSE/wv3+GP08d1lFFXmptImduuaIjx6DwC6iSFkkCFIXkWAMWAEKicEkNDq/TD
PF17p9iMt0VEhpOniL6wrBWzVEbBzbOz7tFJ6WL+hWd7wpBXqf9aQE+n0L2O6Qzjlgxylw
Kw+MGrXPYCFmkAR+98A1vyoAXJzEUqBloEI7GKiGpj+KFdfh6lCN5UQLF2Wl/nogRrd/tw
OSnmz9u1CdWFMIcJc7O8M0ymgrtDmi/oTrD9RdgMQGvfeW4BZLDHdt+uObsd2AiSlxuLBq
SdWfx7OPSu9oL/kIy2VcV6mOtt3PPtzlIZYsaqBBXeIhu1DHOWuednIf1QPo2rKZi2aBYT
8/fWgUVW9aAkj8UsC8PkP8Mb+qWZk/teK6k82Nn2q41Od4TPgrFD4e3Z1l4Rhu0bgOcAnX
jlzmI7pLH8wKByGYT6k4EAAAADAQABAAACAEeOg+nAE40LY6UsZHS8bVYeH3ClBcySwELT
hOyM7uDYu/hy+Wy9b8zJTbtaKJWgbPY9RrYPP1lFXk9FXH0EjC5f9XyAuT2mrcO5+yQvn0
5ng3dy9XSnDAzBcAc8yH4cAtInTzD2O0OGPZpr/Hp83Tm3NHg4EjVCedLZUSZMZ7cGaFpa
svzp9wE/M2KZNLP087K+Do5pNEuGZVVugH/4eOApqBOsFWoOwTFADJjzkSEdftp6ZM8WMp
XBU5T3UAnh3M3GbartlJqza9o1tKk5Ham9SFZvZFiQMvBaAr6kpzP+qh86hnuvb/EU1Tw1
ldj6skzjJCq3cTzeuIEn7BiUL1qEECjpjx7OG6L9/lWyOy27nU/tiQ1MCUDMs/u/Kpnm8X
1kvEYzq1iEQVjqEaKHQBA35GB5krXzVLK2XNMYzZDM4+bGbffX04t4CpVbJHY7mFrbO584
JlqsCxKvhDDJpNuWhT4HUrAMPCJRvFC57n12+wjLrDsBKMOGRwo1NqnaR75QOR5gtboav+
6P/o35U/gATyiePDF3HD/213gJcOwRXpH9oFleRStqiU2OsfcULlrjD6gIXCAQOOrt4l15
uEh8fnUdFbgmFfuTapKHHm6nVGs6K0JWpqlqlsiwsJxSBwRhRFO3G/iAsmxKDvWaq1yBIJ
yhDRTeA7fyCw8k+wsBAAABAGeNiRwkVyn/iUA61drLC5Y/0Gd+a540VrLMwyV3LGlDZPH3
RQFHH+HldhLqmp2ikHZWFq36vjTDr/ubCuwQNlJo4TAo5/RQk1/ChBqXj2IdT+vBysH+bK
IuZQoWXsfISMfQ7o+F5vv7WdItS9w44HpXayH12Q8D1Qr4Qnt0CeMIhrrV7MPsGVTIOpOU
FxH4xu9ovBWDnyloC4rWkBmeAzLCFtO1V1iGN7Six/OXvnxnbif+BsfdQt+OxHIYBOue5G
+Dkss+1xR8l8xrZsOpN2uY1QFIaE6UyElFleAEhtYL2vvuXTrL3EJKqRtIcWenL/wxYlkt
X1CJQS02JW+PtNUAAAEBAPWFstL1hWK4Fp5ipJSGSkDNvGGuzamAYEgqr6n5Zzb1R1HPyE
x6uEMB7ELQjOG4FENIQYBBnBRnMOWWFJp0V5UjFKDft1FabLiozqBtLCRnHnIGllFIWJK+
u/h9OL4OWXGUJx2Em4XdJBPqp0g56VI237AsnTbTGS0tGLOErLWbQY7npZeBFct/501RTP
M5i7F0QEDLjEDZbDxvCz8a5tjfvyP1awK2SyluiE4VPeYr5Op1JNPTJMz5U3YFsIZxdZHJ
AK5mX8hNzTHpTApkS7o0DvExn5DVB8OHOQFdc+BjBIqQwa953f3FaAw9V3o6Dt1zXe9OJR
tBUiBeurvDFk0AAAEBANLpAv9NDf3c8k0PAYhwu+SWoo0OclOWQSZes/93UeB0ch57LD+v
KVPR3hw2AzAsgZn/PcMbIC3SPLNnAlNftfTa98avQOEfmYqrH499zVPuMb7fieS/eQZ4LF
rsZ0o+W4CDVmzImgOe1hENWcfSeUKajEwpgtj440mJlBls37G/zHMMe5DkA2TAxKldiHOR
fmHOtFKT3fnKFa6PWbwlLFnWIod4zheWrwV7E1coBhh+CA5SlgQANRFs7J8zxPznOtIK2O
cF2+/92cM0TijlBk8u5jnN44cUmk4V1nYboCVb0JD2B7yF9ZYP6IB03jt5GEZSfHHCrZP8
vCxMmXDxtAUAAAAXYWp2YW5lcnBASGVpbWRhbGwubG9jYWwBAgME
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,15 @@
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9B6744BB12A8EA8F
pzZw5s3zDVHYdejZxdTpaRx00Yd1grbJe6mIJGvZRB0Jm0hKXoOX71PUI814mc5+
a5pzbyO98aciL/Eat5m3P692WQ0yOPMuphRnklsM3s4qrCjp2aRRbWvbyV/QV9bp
Xz2yYvNqU3WJC3UJIaFFMvRo/lC/Wsz9OvHSSl3LnsXXhiOCeaE32etoOYdlk9ro
N9NqDdaw28t9//iiHhuQK4afK6TZkU6DatFljJHILCC416Xh9+DDK9E+CDKzmlcw
jSwtzgFKEhgrT0XKoZR9LJZDolT1YpFy7M3cFRYIuYvJfuLcjxVEldJE900QlaJS
ybb6RxV6SRVwQYXTbIClcXes+oNJMv59DivAfajxECQC5sAynW/FnY1sz0igmz6D
scclJuJIbawqiuV/Lv6bvgzMa/ZXL4b9JeJPuQELa7tCpvj4fpNk1IiftYISlwoT
iG5pL8yLhPL4/fxGnKJzUPCA9mbwiloW2cAZZxTd+Utqmhemcl9gF0JGNR2XeYwS
3obEjbkqMF0WR3AcVZU9B5d9SKUaAzTp4vu5yZtNVEIaiVlnI3hMwWMs2Jgahswo
QF9MCPsRYsxLs7/u4a4qoQ==
-----END DSA PRIVATE KEY-----

View File

@@ -0,0 +1,38 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAze9G/3GB2UDA9WFtJpZ3F6gtpfvrBFq1WJSFAszcTYUWIyOFJhFR
Kt67tYeit2VQCYtQ3Gbn+Z3tWV7cCdVMNSQOMBnSsPvU8AG+Rrm5/lRKMILetpCwD3goYj
7nE1w9BQw4SFDgb9yscrXaySGALc2U9u0k7AYgxdfuy3d8JP9Q4PTQGiOquND5ronExAAk
ER5+bJyNbffi4GU3d/zzxOaYyTNKMPfq+ppVFDOaBwpObGfAwbkUdUWpuLMafyxUDPvX3j
Jlt2TNguQDdCRuAOzV55cIkypjVaxiNIhbnAQSoY8TdanYARddf+NnAq3qwvVFtWrk04vZ
qsBCKgRi99FTj8vnQj0EFYj/gtPQgYMq98KWXIjyj9Zr5nDpAuRQ8yoPXt79SQatH6mYML
fjzxvHBp8UQhhEPmTCw7gIsZEFBMA1njLJBy5G41BIlWcnVYgj0sxXMxrSmrUIkFWQOWcd
Bp9rFGkI8pIVs6ijS/KCG6JRHZB/bmzmVjYtG681AAAFiJrvSX6a70l+AAAAB3NzaC1yc2
EAAAGBAM3vRv9xgdlAwPVhbSaWdxeoLaX76wRatViUhQLM3E2FFiMjhSYRUSreu7WHordl
UAmLUNxm5/md7Vle3AnVTDUkDjAZ0rD71PABvka5uf5USjCC3raQsA94KGI+5xNcPQUMOE
hQ4G/crHK12skhgC3NlPbtJOwGIMXX7st3fCT/UOD00BojqrjQ+a6JxMQAJBEefmycjW33
4uBlN3f888TmmMkzSjD36vqaVRQzmgcKTmxnwMG5FHVFqbizGn8sVAz7194yZbdkzYLkA3
QkbgDs1eeXCJMqY1WsYjSIW5wEEqGPE3Wp2AEXXX/jZwKt6sL1RbVq5NOL2arAQioEYvfR
U4/L50I9BBWI/4LT0IGDKvfCllyI8o/Wa+Zw6QLkUPMqD17e/UkGrR+pmDC3488bxwafFE
IYRD5kwsO4CLGRBQTANZ4yyQcuRuNQSJVnJ1WII9LMVzMa0pq1CJBVkDlnHQafaxRpCPKS
FbOoo0vyghuiUR2Qf25s5lY2LRuvNQAAAAMBAAEAAAGABvaYR/rmkRoHbESnFC7yR/J/2K
T0BWmryBr9hGK48EYXwYhp8CeVvwVZA4Jaliju0+PKECnKnj4g0GzMs+hqc0GM2UOGREW/
pX3pmSqeh2MCPzGtpi6uRVeixe+qkJUF2y3WmVtiu2WSzy4m/7YKR4I0D0VlgjWS1h2/DV
I0+GtJqNGeV8Ps+eLXDnfKF3aJwapuS+3fOmCvYzcI8R20gGvrrqH1WEKJx3+AcPZttt86
V6AKfIJtlqmMW5pywuoUveYGDLCbg1oajqh7o06eTiFqZuCzbKjJUahzc1IvjsMRmP8rij
WVAVZdUV5NiLYjmPczxS12zcUCmPJo5geDQLpCJdfgFYWCk9nr08MCLXmD973S4egrfw33
+WMblW7R6vkHFUYK1Nfxe+Ume3mag+KbRJc0fYrO4Y+1BrhnsO5lqRHjkvl4jldYkAoqly
jnbk9PwWn4+u/FZ5mUyP7RCEK4INvXah/dG44GwRfY/OyoeQMM4P0BDedp5pGJn73hAAAA
wQDvs3FzKxF8uZPyDBZjEbn61m6oTVXE9PRl1kSzxD2wPqmZUPr1WtK/1ugWSMBoFTk72J
z5wXfaFVifz7U5EzQ23yZkBN2aL6jzu7H5OcxgZZVS3sL2WYfZ/lRphX0kHYBcM7ZChIbV
sDmheqE0wVTdTP809j1NX/sQOBShVg7vj20VTRYQs7SCBzsPEAmXE6a1haWBKfrZfhPN/3
xZJ162n2FA21LQjDcfHLWeSzSHjzdOK/3YSr/8o7EGqK7iTbYAAADBAPodvvOQvHm0k9Ki
7BzTQCCWCog0jR26rKeH5QlCi6fwmWBFR1vVjrqBRzhPUIH0sml6yOlYqpiKi0cNTZZ3dP
QuUU2U63AnyQyuSTAnOWy9mh9aAguWK4IdtuToH+rJCi4lyy4khFaeyzbbb6iD4HDR/sYF
AARMj/rAHypcnUSwkwSRiRoFy2w/h21roIocgBFfrVJUe1RDHTB9tiDFTqQ/WKWJFPfBSV
I4bqpWlFKFAIkbIaCEe2DIKHMp6ywNJwAAAMEA0sd18i4dOzDt0Sx+aYpK5tcx7G1Oen67
8WddT5bO63R4yQ4gCumiH2GQTaEnQIe9iTZ5hMQiwJJcfP9zI60g0RgMabicAX6TmW6ej8
4ZVfZhkQoCU15Ih4uIuCreSbwo/Q1FT48GA6UScqrDuSzaEenDuWKAv0NWap9B0Rro9eCb
ppaSE8QmSoojWAEAnOjaL/ig7j808xaDlNiMXKnmMdV4Lrj2OzyhqE5LpL7fShqhQ5CryY
l4Kj1BWsuKzJJDAAAAEWxhZ3Vub3ZAdW5pdC0xMzgxAQ==
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.backport;
public class JavaVersion {
public static boolean isJava7OrEarlier() {
String property = System.getProperty("java.specification.version");
float diff = Float.parseFloat(property) - 1.7f;
return diff < 0.01;
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.backport;
import net.schmizz.sshj.common.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
public class Jdk7HttpProxySocket extends Socket {
private Proxy httpProxy = null;
public Jdk7HttpProxySocket(Proxy proxy) {
super(proxy.type() == Proxy.Type.HTTP ? Proxy.NO_PROXY : proxy);
if (proxy.type() == Proxy.Type.HTTP) {
this.httpProxy = proxy;
}
}
@Override
public void connect(SocketAddress endpoint, int timeout) throws IOException {
if (httpProxy != null) {
connectHttpProxy(endpoint, timeout);
} else {
super.connect(endpoint, timeout);
}
}
private void connectHttpProxy(SocketAddress endpoint, int timeout) throws IOException {
super.connect(httpProxy.address(), timeout);
if (!(endpoint instanceof InetSocketAddress)) {
throw new SocketException("Expected an InetSocketAddress to connect to, got: " + endpoint);
}
InetSocketAddress isa = (InetSocketAddress) endpoint;
String httpConnect = "CONNECT " + isa.getHostName() + ":" + isa.getPort() + " HTTP/1.0\n\n";
getOutputStream().write(httpConnect.getBytes(IOUtils.UTF8));
checkAndFlushProxyResponse();
}
private void checkAndFlushProxyResponse()throws IOException {
InputStream socketInput = getInputStream();
byte[] tmpBuffer = new byte[512];
int len = socketInput.read(tmpBuffer, 0, tmpBuffer.length);
if (len == 0) {
throw new SocketException("Empty response from proxy");
}
String proxyResponse = new String(tmpBuffer, 0, len, IOUtils.UTF8);
// Expecting HTTP/1.x 200 OK
if (proxyResponse.contains("200")) {
// Flush any outstanding message in buffer
if (socketInput.available() > 0) {
socketInput.skip(socketInput.available());
}
// Proxy Connect Successful
} else {
throw new SocketException("Fail to create Socket\nResponse was:" + proxyResponse);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.backport;
import java.io.Closeable;
import java.io.IOException;
import java.net.Socket;
public class Sockets {
/**
* Java 7 and up have Socket implemented as Closeable, whereas Java6 did not have this inheritance.
* @param socket The socket to wrap as Closeable
* @return The (potentially wrapped) Socket as a Closeable.
*/
public static Closeable asCloseable(final Socket socket) {
if (Closeable.class.isAssignableFrom(socket.getClass())) {
return Closeable.class.cast(socket);
} else {
return new Closeable() {
@Override
public void close() throws IOException {
socket.close();
}
};
}
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.common;
public class KeyAlgorithm {
public static final String RSA = "RSA";
public static final String DSA = "DSA";
/** Elliptic curve signature key algorithm for use with BouncyCastle **/
public static final String ECDSA = "ECDSA";
/** General elliptic curve algorithm identifier for use with BouncyCastle **/
public static final String EC_BC = "EC";
/** General elliptic curve algorithm identifier for use with the Android Keystore **/
public static final String EC_KEYSTORE = "EC";
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.common;
import org.bouncycastle.openssl.EncryptionException;
import java.io.IOException;
/**
* Thrown when a key file could not be decrypted correctly, e.g. if its checkInts differed in the case of an OpenSSH
* key file.
*/
@SuppressWarnings("serial")
public class KeyDecryptionFailedException extends IOException {
public static final String MESSAGE = "Decryption of the key failed. A supplied passphrase may be incorrect.";
public KeyDecryptionFailedException() {
super(MESSAGE);
}
public KeyDecryptionFailedException(EncryptionException cause) {
super(MESSAGE, cause);
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.key;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.Factory;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.signature.Signature;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
public class BaseKeyAlgorithm implements KeyAlgorithm {
private final String keyAlgorithm;
private final Factory.Named<Signature> signature;
private final KeyType keyFormat;
public BaseKeyAlgorithm(String keyAlgorithm, Factory.Named<Signature> signature, KeyType keyFormat) {
this.keyAlgorithm = keyAlgorithm;
this.signature = signature;
this.keyFormat = keyFormat;
}
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
keyFormat.putPubKeyIntoBuffer(pk, buf);
}
@Override
public PublicKey readPubKeyFromBuffer(Buffer<?> buf) throws GeneralSecurityException {
return keyFormat.readPubKeyFromBuffer(buf);
}
@Override
public String getKeyAlgorithm() {
return keyAlgorithm;
}
@Override
public KeyType getKeyFormat() {
return keyFormat;
}
@Override
public Signature newSignature() {
return this.signature.create();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.key;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.signature.Signature;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
/**
* In [RFC4252], the concept "public key algorithm" is used to establish
* a relationship between one algorithm name, and:
* <p>
* A. procedures used to generate and validate a private/public
* keypair;
* B. a format used to encode a public key; and
* C. procedures used to calculate, encode, and verify a signature.
*/
public interface KeyAlgorithm {
PublicKey readPubKeyFromBuffer(Buffer<?> buf) throws GeneralSecurityException;
void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf);
String getKeyAlgorithm();
KeyType getKeyFormat();
Signature newSignature();
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.key;
import com.hierynomus.sshj.signature.SignatureEdDSA;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.signature.Signature;
import net.schmizz.sshj.signature.SignatureDSA;
import net.schmizz.sshj.signature.SignatureECDSA;
import net.schmizz.sshj.signature.SignatureRSA;
import java.util.Arrays;
import java.util.List;
public class KeyAlgorithms {
public static List<String> SSH_RSA_SHA2_ALGORITHMS = Arrays.asList("rsa-sha2-512", "rsa-sha2-256");
public static Factory SSHRSA() { return new Factory("ssh-rsa", new SignatureRSA.FactorySSHRSA(), KeyType.RSA); }
public static Factory SSHRSACertV01() { return new Factory("ssh-rsa-cert-v01@openssh.com", new SignatureRSA.FactoryCERT(), KeyType.RSA_CERT); }
public static Factory RSASHA256() { return new Factory("rsa-sha2-256", new SignatureRSA.FactoryRSASHA256(), KeyType.RSA); }
public static Factory RSASHA512() { return new Factory("rsa-sha2-512", new SignatureRSA.FactoryRSASHA512(), KeyType.RSA); }
public static Factory SSHDSA() { return new Factory(KeyType.DSA.toString(), new SignatureDSA.Factory(), KeyType.DSA); }
public static Factory SSHDSSCertV01() { return new Factory(KeyType.DSA_CERT.toString(), new SignatureDSA.Factory(), KeyType.DSA_CERT); }
public static Factory ECDSASHANistp256() { return new Factory(KeyType.ECDSA256.toString(), new SignatureECDSA.Factory256(), KeyType.ECDSA256); }
public static Factory ECDSASHANistp384() { return new Factory(KeyType.ECDSA384.toString(), new SignatureECDSA.Factory384(), KeyType.ECDSA384); }
public static Factory ECDSASHANistp521() { return new Factory(KeyType.ECDSA521.toString(), new SignatureECDSA.Factory521(), KeyType.ECDSA521); }
public static Factory EdDSA25519() { return new Factory(KeyType.ED25519.toString(), new SignatureEdDSA.Factory(), KeyType.ED25519); }
public static class Factory implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
private final String algorithmName;
private final Named<Signature> signatureFactory;
private final KeyType keyType;
public Factory(String algorithmName, Named<Signature> signatureFactory, KeyType keyType) {
this.algorithmName = algorithmName;
this.signatureFactory = signatureFactory;
this.keyType = keyType;
}
@Override
public String getName() {
return algorithmName;
}
@Override
public KeyAlgorithm create() {
return new BaseKeyAlgorithm(algorithmName, signatureFactory, keyType);
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.secg;
import net.schmizz.sshj.common.SSHRuntimeException;
import java.math.BigInteger;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
import java.util.Arrays;
public class SecgUtils {
/**
* SECG 2.3.4 Octet String to ECPoint
*/
public static ECPoint getDecoded(byte[] M, EllipticCurve curve) {
int elementSize = getElementSize(curve);
if (M.length != 2 * elementSize + 1 || M[0] != 0x04) {
throw new SSHRuntimeException("Invalid 'f' for Elliptic Curve " + curve.toString());
}
byte[] xBytes = new byte[elementSize];
byte[] yBytes = new byte[elementSize];
System.arraycopy(M, 1, xBytes, 0, elementSize);
System.arraycopy(M, 1 + elementSize, yBytes, 0, elementSize);
return new ECPoint(new BigInteger(1, xBytes), new BigInteger(1, yBytes));
}
/**
* SECG 2.3.3 ECPoint to Octet String
*/
public static byte[] getEncoded(ECPoint point, EllipticCurve curve) {
int elementSize = getElementSize(curve);
byte[] M = new byte[2 * elementSize + 1];
M[0] = 0x04;
byte[] xBytes = stripLeadingZeroes(point.getAffineX().toByteArray());
byte[] yBytes = stripLeadingZeroes(point.getAffineY().toByteArray());
System.arraycopy(xBytes, 0, M, 1 + elementSize - xBytes.length, xBytes.length);
System.arraycopy(yBytes, 0, M, 1 + 2 * elementSize - yBytes.length, yBytes.length);
return M;
}
private static byte[] stripLeadingZeroes(byte[] bytes) {
int start = 0;
while (bytes[start] == 0x0) {
start++;
}
return Arrays.copyOfRange(bytes, start, bytes.length);
}
private static int getElementSize(EllipticCurve curve) {
int fieldSize = curve.getField().getFieldSize();
return (fieldSize + 7) / 8;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.signature;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
import net.schmizz.sshj.common.SSHRuntimeException;
import java.util.Arrays;
/**
* Our own extension of the EdDSAPublicKey that comes from ECC-25519, as that class does not implement equality.
* The code uses the equality of the keys as an indicator whether they're the same during host key verification.
*/
@SuppressWarnings("serial")
public class Ed25519PublicKey extends EdDSAPublicKey {
public Ed25519PublicKey(EdDSAPublicKeySpec spec) {
super(spec);
EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName("Ed25519");
if (!spec.getParams().getCurve().equals(ed25519.getCurve())) {
throw new SSHRuntimeException("Cannot create Ed25519 Public Key from wrong spec");
}
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Ed25519PublicKey)) {
return false;
}
Ed25519PublicKey otherKey = (Ed25519PublicKey) other;
return Arrays.equals(getAbyte(), otherKey.getAbyte());
}
@Override
public int hashCode() {
return getA().hashCode();
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.signature;
import net.i2p.crypto.eddsa.EdDSAEngine;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.signature.AbstractSignature;
import net.schmizz.sshj.signature.Signature;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
public class SignatureEdDSA extends AbstractSignature {
public static class Factory implements net.schmizz.sshj.common.Factory.Named<Signature> {
@Override
public String getName() {
return KeyType.ED25519.toString();
}
@Override
public Signature create() {
return new SignatureEdDSA();
}
}
SignatureEdDSA() {
super(getEngine(), KeyType.ED25519.toString());
}
private static EdDSAEngine getEngine() {
try {
return new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
} catch (NoSuchAlgorithmException e) {
throw new SSHRuntimeException(e);
}
}
@Override
public byte[] encode(byte[] signature) {
return signature;
}
@Override
public boolean verify(byte[] sig) {
try {
return signature.verify(extractSig(sig, "ssh-ed25519"));
} catch (SignatureException e) {
throw new SSHRuntimeException(e);
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.ByteArrayUtils;
import net.schmizz.sshj.common.LoggerFactory;
import net.schmizz.sshj.transport.TransportException;
import org.slf4j.Logger;
import java.io.IOException;
import java.util.Arrays;
public class IdentificationStringParser {
private final Logger log;
private final Buffer.PlainBuffer buffer;
private byte[] EXPECTED_START_BYTES = new byte[] {'S', 'S', 'H', '-'};
public IdentificationStringParser(Buffer.PlainBuffer buffer) {
this(buffer, LoggerFactory.DEFAULT);
}
public IdentificationStringParser(Buffer.PlainBuffer buffer, LoggerFactory loggerFactory) {
this.log = loggerFactory.getLogger(IdentificationStringParser.class);
this.buffer = buffer;
}
public String parseIdentificationString() throws IOException {
for (;;) {
Buffer.PlainBuffer lineBuffer = new Buffer.PlainBuffer();
int lineStartPos = buffer.rpos();
for (;;) {
if (buffer.available() == 0) {
buffer.rpos(lineStartPos);
return "";
}
byte b = buffer.readByte();
lineBuffer.putByte(b);
if (b == '\n') {
if (checkForIdentification(lineBuffer)) {
return readIdentification(lineBuffer);
} else {
logHeaderLine(lineBuffer);
}
break;
}
}
}
}
private void logHeaderLine(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException {
byte[] bytes = new byte[lineBuffer.available()];
lineBuffer.readRawBytes(bytes);
String header = new String(bytes, 0, bytes.length - 1);
log.debug("Received header: {}", header);
}
private String readIdentification(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException, TransportException {
byte[] bytes = new byte[lineBuffer.available()];
lineBuffer.readRawBytes(bytes);
if (bytes.length > 255) {
log.error("Incorrect identification String received, line was longer than expected: {}", new String(bytes));
log.error("Just for good measure, bytes were: {}", ByteArrayUtils.printHex(bytes, 0, bytes.length));
throw new TransportException("Incorrect identification: line too long: " + ByteArrayUtils.printHex(bytes, 0, bytes.length));
}
if (bytes[bytes.length - 2] != '\r') {
String ident = new String(bytes, 0, bytes.length - 1);
log.info("Server identification has bad line ending, was expecting a '\\r\\n' however got: '{}' (hex: {})", (char) (bytes[bytes.length - 2] & 0xFF), Integer.toHexString(bytes[bytes.length - 2] & 0xFF));
log.info("Will treat the identification of this server '{}' leniently", ident);
return ident;
}
// Strip off the \r\n
return new String(bytes, 0, bytes.length - 2);
}
private boolean checkForIdentification(Buffer.PlainBuffer lineBuffer) throws Buffer.BufferException {
if (lineBuffer.available() < 4) {
return false;
}
byte[] buf = new byte[4];
lineBuffer.readRawBytes(buf);
// Reset
lineBuffer.rpos(0);
return Arrays.equals(EXPECTED_START_BYTES, buf);
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher;
import net.schmizz.sshj.transport.cipher.BlockCipher;
import net.schmizz.sshj.transport.cipher.Cipher;
/**
* All BlockCiphers supported by SSH according to the following RFCs:
*
* <ul>
* <li>https://tools.ietf.org/html/rfc4344#section-3.1</li>
* <li>https://tools.ietf.org/html/rfc4253#section-6.3</li>
* <li>TODO: https://tools.ietf.org/html/rfc5647</li>
* </ul>
*
* Some of the Ciphers are still implemented in net.schmizz.sshj.transport.cipher.*. These are deprecated and scheduled to be removed.
*/
@SuppressWarnings("PMD.MethodNamingConventions")
public class BlockCiphers {
public static final String COUNTER_MODE = "CTR";
public static final String CIPHER_BLOCK_CHAINING_MODE = "CBC";
public static Factory AES128CTR() {
return new Factory(16, 128, "aes128-ctr", "AES", COUNTER_MODE);
}
public static Factory AES192CTR() {
return new Factory(16, 192, "aes192-ctr", "AES", COUNTER_MODE);
}
public static Factory AES256CTR() {
return new Factory(16, 256, "aes256-ctr", "AES", COUNTER_MODE);
}
public static Factory AES128CBC() {
return new Factory(16, 128, "aes128-cbc", "AES", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory AES192CBC() {
return new Factory(16, 192, "aes192-cbc", "AES", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory AES256CBC() {
return new Factory(16, 256, "aes256-cbc", "AES", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory BlowfishCTR() {
return new Factory(8, 256, "blowfish-ctr", "Blowfish", COUNTER_MODE);
}
public static Factory BlowfishCBC() {
return new Factory(8, 128, "blowfish-cbc", "Blowfish", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Twofish128CTR() {
return new Factory(16, 128, "twofish128-ctr", "Twofish", COUNTER_MODE);
}
public static Factory Twofish192CTR() {
return new Factory(16, 192, "twofish192-ctr", "Twofish", COUNTER_MODE);
}
public static Factory Twofish256CTR() {
return new Factory(16, 256, "twofish256-ctr", "Twofish", COUNTER_MODE);
}
public static Factory Twofish128CBC() {
return new Factory(16, 128, "twofish128-cbc", "Twofish", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Twofish192CBC() {
return new Factory(16, 192, "twofish192-cbc", "Twofish", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Twofish256CBC() {
return new Factory(16, 256, "twofish256-cbc", "Twofish", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory TwofishCBC() {
return new Factory(16, 256, "twofish-cbc", "Twofish", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Serpent128CTR() {
return new Factory(16, 128, "serpent128-ctr", "Serpent", COUNTER_MODE);
}
public static Factory Serpent192CTR() {
return new Factory(16, 192, "serpent192-ctr", "Serpent", COUNTER_MODE);
}
public static Factory Serpent256CTR() {
return new Factory(16, 256, "serpent256-ctr", "Serpent", COUNTER_MODE);
}
public static Factory Serpent128CBC() {
return new Factory(16, 128, "serpent128-cbc", "Serpent", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Serpent192CBC() {
return new Factory(16, 192, "serpent192-cbc", "Serpent", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Serpent256CBC() {
return new Factory(16, 256, "serpent256-cbc", "Serpent", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory IDEACTR() {
return new Factory(8, 128, "idea-ctr", "IDEA", COUNTER_MODE);
}
public static Factory IDEACBC() {
return new Factory(8, 128, "idea-cbc", "IDEA", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory Cast128CTR() {
return new Factory(8, 128, "cast128-ctr", "CAST5", COUNTER_MODE);
}
public static Factory Cast128CBC() {
return new Factory(8, 128, "cast128-cbc", "CAST5", CIPHER_BLOCK_CHAINING_MODE);
}
public static Factory TripleDESCTR() {
return new Factory(8, 192, "3des-ctr", "DESede", COUNTER_MODE);
}
public static Factory TripleDESCBC() {
return new Factory(8, 192, "3des-cbc", "DESede", CIPHER_BLOCK_CHAINING_MODE);
}
/** Named factory for BlockCipher */
public static class Factory
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
private int keysize;
private String cipher;
private String mode;
private String name;
private int ivsize;
/**
* @param ivsize
* @param keysize The keysize used in bits.
* @param name
* @param cipher
* @param mode
*/
public Factory(int ivsize, int keysize, String name, String cipher, String mode) {
this.name = name;
this.keysize = keysize;
this.cipher = cipher;
this.mode = mode;
this.ivsize = ivsize;
}
@Override
public Cipher create() {
return new BlockCipher(ivsize, keysize / 8, cipher, cipher + "/" + mode + "/NoPadding");
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher;
import static com.hierynomus.sshj.transport.cipher.BlockCiphers.CIPHER_BLOCK_CHAINING_MODE;
import static com.hierynomus.sshj.transport.cipher.BlockCiphers.COUNTER_MODE;
/**
* Set of Block Ciphers that are (not yet) part of any of the official RFCs for SSH, but
* that are either supported by other SSH implementations, or are being pushed for to be
* included in a new RFC.
*
* - http://tools.ietf.org/id/draft-kanno-secsh-camellia-01.txt
*/
@SuppressWarnings("PMD.MethodNamingConventions")
public class ExtendedBlockCiphers {
public static BlockCiphers.Factory Camellia128CTR() {
return new BlockCiphers.Factory(16, 128, "camellia128-ctr", "Camellia", COUNTER_MODE);
}
public static BlockCiphers.Factory Camellia128CTROpenSSHOrg() {
return new BlockCiphers.Factory(16, 128, "camellia128-ctr@openssh.org", "Camellia", COUNTER_MODE);
}
public static BlockCiphers.Factory Camellia192CTR() {
return new BlockCiphers.Factory(16, 192, "camellia192-ctr", "Camellia", COUNTER_MODE);
}
public static BlockCiphers.Factory Camellia192CTROpenSSHOrg() {
return new BlockCiphers.Factory(16, 192, "camellia192-ctr@openssh.org", "Camellia", COUNTER_MODE);
}
public static BlockCiphers.Factory Camellia256CTR() {
return new BlockCiphers.Factory(16, 256, "camellia256-ctr", "Camellia", COUNTER_MODE);
}
public static BlockCiphers.Factory Camellia256CTROpenSSHOrg() {
return new BlockCiphers.Factory(16, 256, "camellia256-ctr@openssh.org", "Camellia", COUNTER_MODE);
}
public static BlockCiphers.Factory Camellia128CBC() {
return new BlockCiphers.Factory(16, 128, "camellia128-cbc", "Camellia", CIPHER_BLOCK_CHAINING_MODE);
}
public static BlockCiphers.Factory Camellia128CBCOpenSSHOrg() {
return new BlockCiphers.Factory(16, 128, "camellia128-cbc@openssh.org", "Camellia", CIPHER_BLOCK_CHAINING_MODE);
}
public static BlockCiphers.Factory Camellia192CBC() {
return new BlockCiphers.Factory(16, 192, "camellia192-cbc", "Camellia", CIPHER_BLOCK_CHAINING_MODE);
}
public static BlockCiphers.Factory Camellia192CBCOpenSSHOrg() {
return new BlockCiphers.Factory(16, 192, "camellia192-cbc@openssh.org", "Camellia", CIPHER_BLOCK_CHAINING_MODE);
}
public static BlockCiphers.Factory Camellia256CBC() {
return new BlockCiphers.Factory(16, 256, "camellia256-cbc", "Camellia", CIPHER_BLOCK_CHAINING_MODE);
}
public static BlockCiphers.Factory Camellia256CBCOpenSSHOrg() {
return new BlockCiphers.Factory(16, 256, "camellia256-cbc@openssh.org", "Camellia", CIPHER_BLOCK_CHAINING_MODE);
}
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.transport.cipher.BaseCipher;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
public class GcmCipher extends BaseCipher {
protected int authSize;
protected Mode mode;
protected boolean initialized;
protected CounterGCMParameterSpec parameters;
protected SecretKey secretKey;
public GcmCipher(int ivsize, int authSize, int bsize, String algorithm, String transformation) {
super(ivsize, bsize, algorithm, transformation);
this.authSize = authSize;
}
@Override
public int getAuthenticationTagSize() {
return authSize;
}
protected Cipher getInitializedCipherInstance() throws GeneralSecurityException {
if (!initialized) {
cipher.init(mode == Mode.Encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKey, parameters);
initialized = true;
}
return cipher;
}
@Override
protected void initCipher(Cipher cipher, Mode mode, byte[] key, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException {
this.mode = mode;
this.secretKey = getKeySpec(key);
this.parameters = new CounterGCMParameterSpec(getAuthenticationTagSize() * Byte.SIZE, iv);
cipher.init(getMode(mode), secretKey, parameters);
initialized = true;
}
@Override
public void updateAAD(byte[] data, int offset, int length) {
try {
Cipher cipher = getInitializedCipherInstance();
cipher.updateAAD(data, offset, length);
} catch (GeneralSecurityException e) {
throw new SSHRuntimeException("Error updating data through cipher", e);
}
}
@Override
public void update(byte[] input, int inputOffset, int inputLen) {
if (mode == Mode.Decrypt) {
inputLen += getAuthenticationTagSize();
}
try {
Cipher cipher = getInitializedCipherInstance();
cipher.doFinal(input, inputOffset, inputLen, input, inputOffset);
} catch (GeneralSecurityException e) {
throw new SSHRuntimeException("Error updating data through cipher", e);
}
/*
* As the RFC stated, the IV used in AES-GCM cipher for SSH is a 4-byte constant plus a 8-byte invocation
* counter. After cipher.doFinal() is called, IV invocation counter is increased by 1, and changes to the IV
* requires reinitializing the cipher, so initialized have to be false here, for the next invocation.
*
* Refer to RFC5647, Section 7.1
*/
parameters.incrementCounter();
initialized = false;
}
/**
* Algorithm parameters for AES/GCM that assumes the IV uses an 8-byte counter field as its most significant bytes.
*/
protected static class CounterGCMParameterSpec extends GCMParameterSpec {
protected final byte[] iv;
protected CounterGCMParameterSpec(int tLen, byte[] src) {
super(tLen, src);
if (src.length != 12) {
throw new IllegalArgumentException("GCM nonce must be 12 bytes, but given len=" + src.length);
}
iv = src.clone();
}
protected void incrementCounter() {
int off = iv.length - 8;
long counter = getLong(iv, off, 8);
putLong(addExact(counter, 1L), iv, off, 8);
}
@Override
public byte[] getIV() {
// JCE implementation of GCM will complain if the reference doesn't change between inits
return iv.clone();
}
static long addExact(long var0, long var2) {
long var4 = var0 + var2;
if (((var0 ^ var4) & (var2 ^ var4)) < 0L) {
throw new ArithmeticException("long overflow");
} else {
return var4;
}
}
static long getLong(byte[] buf, int off, int len) {
if (len < 8) {
throw new IllegalArgumentException("Not enough data for a long: required=8, available=" + len);
}
long l = (long) buf[off] << 56;
l |= ((long) buf[off + 1] & 0xff) << 48;
l |= ((long) buf[off + 2] & 0xff) << 40;
l |= ((long) buf[off + 3] & 0xff) << 32;
l |= ((long) buf[off + 4] & 0xff) << 24;
l |= ((long) buf[off + 5] & 0xff) << 16;
l |= ((long) buf[off + 6] & 0xff) << 8;
l |= (long) buf[off + 7] & 0xff;
return l;
}
static int putLong(long value, byte[] buf, int off, int len) {
if (len < 8) {
throw new IllegalArgumentException("Not enough data for a long: required=8, available=" + len);
}
buf[off] = (byte) (value >> 56);
buf[off + 1] = (byte) (value >> 48);
buf[off + 2] = (byte) (value >> 40);
buf[off + 3] = (byte) (value >> 32);
buf[off + 4] = (byte) (value >> 24);
buf[off + 5] = (byte) (value >> 16);
buf[off + 6] = (byte) (value >> 8);
buf[off + 7] = (byte) value;
return 8;
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher;
import net.schmizz.sshj.transport.cipher.Cipher;
public class GcmCiphers {
public static final String GALOIS_COUNTER_MODE = "GCM";
public static Factory AES128GCM() {
return new Factory(12, 16, 128, "aes128-gcm@openssh.com", "AES", GALOIS_COUNTER_MODE);
}
public static Factory AES256GCM() {
return new Factory(12, 16, 256, "aes256-gcm@openssh.com", "AES", GALOIS_COUNTER_MODE);
}
/** Named factory for BlockCipher */
public static class Factory
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
private int keysize;
private int authSize;
private String cipher;
private String mode;
private String name;
private int ivsize;
/**
* @param ivsize
* @param keysize The keysize used in bits.
* @param name
* @param cipher
* @param mode
*/
public Factory(int ivsize, int authSize, int keysize, String name, String cipher, String mode) {
this.name = name;
this.keysize = keysize;
this.cipher = cipher;
this.mode = mode;
this.ivsize = ivsize;
this.authSize = authSize;
}
@Override
public Cipher create() {
return new GcmCipher(ivsize, authSize, keysize / 8, cipher, cipher + "/" + mode + "/NoPadding");
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher;
import net.schmizz.sshj.transport.cipher.BaseCipher;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
public class StreamCipher extends BaseCipher {
public StreamCipher(int bsize, String algorithm, String transformation) {
super(0, bsize, algorithm, transformation);
}
@Override
protected void initCipher(javax.crypto.Cipher cipher, Mode mode, byte[] key, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException {
cipher.init(getMode(mode), getKeySpec(key));
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.cipher;
import net.schmizz.sshj.transport.cipher.Cipher;
/**
* Implementations of the Stream Ciphers that are defined in the RFCs
*
* - https://tools.ietf.org/html/rfc4253#section-6.3
* - https://tools.ietf.org/html/rfc4345
*/
@SuppressWarnings("PMD.MethodNamingConventions")
public class StreamCiphers {
public static Factory Arcfour() {
return new Factory(128, "arcfour", "ARCFOUR", "ECB");
}
public static Factory Arcfour128() {
return new Factory(128, "arcfour128", "RC4", "ECB");
}
public static Factory Arcfour256() {
return new Factory(256, "arcfour256", "RC4", "ECB");
}
/** Named factory for BlockCipher */
public static class Factory
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
private int keysize;
private String cipher;
private String mode;
private String name;
/**
* @param keysize The keysize used in bits.
* @param name
* @param cipher
* @param mode
*/
public Factory(int keysize, String name, String cipher, String mode) {
this.name = name;
this.keysize = keysize;
this.cipher = cipher;
this.mode = mode;
}
@Override
public Cipher create() {
return new StreamCipher(keysize / 8, cipher, cipher + "/" + mode + "/NoPadding");
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.kex;
import net.schmizz.sshj.transport.digest.Digest;
import net.schmizz.sshj.transport.kex.AbstractDHG;
import net.schmizz.sshj.transport.kex.DH;
import net.schmizz.sshj.transport.kex.DHBase;
import javax.crypto.spec.DHParameterSpec;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
/**
*
*/
public class DHG extends AbstractDHG {
private BigInteger group;
private BigInteger generator;
public DHG(BigInteger group, BigInteger generator, Digest digest) {
super(new DH(), digest);
this.group = group;
this.generator = generator;
}
@Override
protected void initDH(DHBase dh) throws GeneralSecurityException {
dh.init(new DHParameterSpec(group, generator), trans.getConfig().getRandomFactory());
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.kex;
import net.schmizz.sshj.transport.digest.Digest;
import net.schmizz.sshj.transport.digest.SHA1;
import net.schmizz.sshj.transport.digest.SHA256;
import net.schmizz.sshj.transport.digest.SHA512;
import net.schmizz.sshj.transport.kex.KeyExchange;
import java.math.BigInteger;
import static net.schmizz.sshj.transport.kex.DHGroupData.*;
/**
* Factory methods for Diffie Hellman KEX algorithms based on MODP groups / Oakley Groups
*
* - https://tools.ietf.org/html/rfc4253
* - https://tools.ietf.org/html/draft-ietf-curdle-ssh-modp-dh-sha2-01
*/
@SuppressWarnings("PMD.MethodNamingConventions")
public class DHGroups {
public static DHGroups.Factory Group1SHA1() {
return new DHGroups.Factory("diffie-hellman-group1-sha1", P1, G, new SHA1.Factory());
}
public static DHGroups.Factory Group14SHA1() {
return new DHGroups.Factory("diffie-hellman-group14-sha1", P14, G, new SHA1.Factory());
}
public static DHGroups.Factory Group14SHA256() {
return new DHGroups.Factory("diffie-hellman-group14-sha256", P14, G, new SHA256.Factory());
}
public static DHGroups.Factory Group15SHA512() {
return new DHGroups.Factory("diffie-hellman-group15-sha512", P15, G, new SHA512.Factory());
}
public static DHGroups.Factory Group16SHA512() {
return new DHGroups.Factory("diffie-hellman-group16-sha512", P16, G, new SHA512.Factory());
}
public static DHGroups.Factory Group17SHA512() {
return new DHGroups.Factory("diffie-hellman-group17-sha512", P17, G, new SHA512.Factory());
}
public static DHGroups.Factory Group18SHA512() {
return new DHGroups.Factory("diffie-hellman-group18-sha512", P18, G, new SHA512.Factory());
}
/**
* Named factory for DHG1 key exchange
*/
public static class Factory
implements net.schmizz.sshj.common.Factory.Named<KeyExchange> {
private String name;
private BigInteger group;
private BigInteger generator;
private Factory.Named<Digest> digestFactory;
public Factory(String name, BigInteger group, BigInteger generator, Named<Digest> digestFactory) {
this.name = name;
this.group = group;
this.generator = generator;
this.digestFactory = digestFactory;
}
@Override
public KeyExchange create() {
return new DHG(group, generator, digestFactory.create());
}
@Override
public String getName() {
return name;
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.kex;
import net.schmizz.sshj.transport.kex.KeyExchange;
/**
* Stub kex algorithm factory that indicates support for SSH2_MSG_EXT_INFO.
* Some servers will not send `rsa-sha2-*` signatures if the client doesn't indicate support.
*
* Note: Since the server sends `ext-info-s` to indicate support, this fake kex algorithm is never negotiated.
*/
public class ExtInfoClientFactory implements net.schmizz.sshj.common.Factory.Named<KeyExchange> {
@Override
public String getName() {
return "ext-info-c";
}
@Override
public KeyExchange create() {
return null;
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.kex;
import net.schmizz.sshj.transport.digest.SHA256;
import net.schmizz.sshj.transport.digest.SHA384;
import net.schmizz.sshj.transport.digest.SHA512;
import static net.schmizz.sshj.transport.kex.DHGroupData.*;
/**
* Set of KEX methods that are not in official RFCs but are supported by some SSH servers.
*/
@SuppressWarnings("PMD.MethodNamingConventions")
public class ExtendedDHGroups {
public static DHGroups.Factory Group14SHA256AtSSH() {
return new DHGroups.Factory("diffie-hellman-group14-sha256@ssh.com", P14, G, new SHA256.Factory());
}
public static DHGroups.Factory Group15SHA256() {
return new DHGroups.Factory("diffie-hellman-group15-sha256", P15, G, new SHA256.Factory());
}
public static DHGroups.Factory Group15SHA256AtSSH() {
return new DHGroups.Factory("diffie-hellman-group15-sha256@ssh.com", P15, G, new SHA256.Factory());
}
public static DHGroups.Factory Group15SHA384AtSSH() {
return new DHGroups.Factory("diffie-hellman-group15-sha384@ssh.com", P15, G, new SHA384.Factory());
}
public static DHGroups.Factory Group16SHA256() {
return new DHGroups.Factory("diffie-hellman-group16-sha256", P16, G, new SHA256.Factory());
}
public static DHGroups.Factory Group16SHA384AtSSH() {
return new DHGroups.Factory("diffie-hellman-group16-sha384@ssh.com", P16, G, new SHA384.Factory());
}
public static DHGroups.Factory Group16SHA512AtSSH() {
return new DHGroups.Factory("diffie-hellman-group16-sha512@ssh.com", P16, G, new SHA512.Factory());
}
public static DHGroups.Factory Group18SHA512AtSSH() {
return new DHGroups.Factory("diffie-hellman-group18-sha512@ssh.com", P18, G, new SHA512.Factory());
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.mac;
import net.schmizz.sshj.transport.mac.BaseMAC;
import net.schmizz.sshj.transport.mac.MAC;
@SuppressWarnings("PMD.MethodNamingConventions")
public class Macs {
public static Factory HMACMD5() {
return new Factory("hmac-md5", "HmacMD5", 16, 16, false);
}
public static Factory HMACMD596() {
return new Factory("hmac-md5-96", "HmacMD5", 12, 16, false);
}
public static Factory HMACMD5Etm() {
return new Factory("hmac-md5-etm@openssh.com", "HmacMD5", 16, 16, true);
}
public static Factory HMACMD596Etm() {
return new Factory("hmac-md5-96-etm@openssh.com", "HmacMD5", 12, 16, true);
}
public static Factory HMACRIPEMD160() {
return new Factory("hmac-ripemd160", "HMACRIPEMD160", 20, 20, false);
}
public static Factory HMACRIPEMD16096() {
return new Factory("hmac-ripemd160-96", "HMACRIPEMD160", 12, 20, false);
}
public static Factory HMACRIPEMD160Etm() {
return new Factory("hmac-ripemd160-etm@openssh.com", "HMACRIPEMD160", 20, 20, true);
}
public static Factory HMACRIPEMD160OpenSsh() {
return new Factory("hmac-ripemd160@openssh.com", "HMACRIPEMD160", 20, 20, false);
}
public static Factory HMACSHA1() {
return new Factory("hmac-sha1", "HmacSHA1", 20, 20, false);
}
public static Factory HMACSHA196() {
return new Factory("hmac-sha1-96", "HmacSHA1", 12, 20, false);
}
public static Factory HMACSHA1Etm() {
return new Factory("hmac-sha1-etm@openssh.com", "HmacSHA1", 20, 20, true);
}
public static Factory HMACSHA196Etm() {
return new Factory("hmac-sha1-96@openssh.com", "HmacSHA1", 12, 20, true);
}
public static Factory HMACSHA2256() {
return new Factory("hmac-sha2-256", "HmacSHA256", 32, 32, false);
}
public static Factory HMACSHA2256Etm() {
return new Factory("hmac-sha2-256-etm@openssh.com", "HmacSHA256", 32, 32, true);
}
public static Factory HMACSHA2512() {
return new Factory("hmac-sha2-512", "HmacSHA512", 64, 64, false);
}
public static Factory HMACSHA2512Etm() {
return new Factory("hmac-sha2-512-etm@openssh.com", "HmacSHA512", 64, 64, true);
}
public static class Factory implements net.schmizz.sshj.common.Factory.Named<MAC> {
private String name;
private String algorithm;
private int bSize;
private int defBSize;
private final boolean etm;
public Factory(String name, String algorithm, int bSize, int defBSize, boolean etm) {
this.name = name;
this.algorithm = algorithm;
this.bSize = bSize;
this.defBSize = defBSize;
this.etm = etm;
}
@Override
public String getName() {
return name;
}
@Override
public BaseMAC create() {
return new BaseMAC(algorithm, bSize, defBSize, etm);
}
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.transport.verification;
import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.common.SSHException;
import net.schmizz.sshj.transport.mac.MAC;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import com.hierynomus.sshj.transport.mac.Macs;
public class KnownHostMatchers {
public static HostMatcher createMatcher(String hostEntry) throws SSHException {
if (hostEntry.contains(",")) {
return new AnyHostMatcher(hostEntry);
}
if (hostEntry.startsWith("!")) {
return new NegateHostMatcher(hostEntry);
}
if (hostEntry.startsWith("|1|")) {
return new HashedHostMatcher(hostEntry);
}
if (hostEntry.contains("*") || hostEntry.contains("?")) {
return new WildcardHostMatcher(hostEntry);
}
return new EquiHostMatcher(hostEntry);
}
public interface HostMatcher {
boolean match(String hostname) throws IOException;
}
private static class EquiHostMatcher implements HostMatcher {
private String host;
public EquiHostMatcher(String host) {
this.host = host;
}
@Override
public boolean match(String hostname) {
return host.equals(hostname);
}
}
private static class HashedHostMatcher implements HostMatcher {
private final MAC sha1 = Macs.HMACSHA1().create();
private final String hash;
private final String salt;
private byte[] saltyBytes;
HashedHostMatcher(String hash) throws SSHException {
this.hash = hash;
final String[] hostParts = hash.split("\\|");
if (hostParts.length != 4) {
throw new SSHException("Unrecognized format for hashed hostname");
}
salt = hostParts[2];
}
@Override
public boolean match(String hostname) throws IOException {
return hash.equals(hashHost(hostname));
}
private String hashHost(String host) throws IOException {
sha1.init(getSaltyBytes());
return "|1|" + salt + "|" + Base64.encodeBytes(sha1.doFinal(host.getBytes(IOUtils.UTF8)));
}
private byte[] getSaltyBytes() throws IOException {
if (saltyBytes == null) {
saltyBytes = Base64.decode(salt);
}
return saltyBytes;
}
}
private static class AnyHostMatcher implements HostMatcher {
private final List<HostMatcher> matchers;
AnyHostMatcher(String hostEntry) throws SSHException {
matchers = new ArrayList<HostMatcher>();
for (String subEntry : hostEntry.split(",")) {
matchers.add(KnownHostMatchers.createMatcher(subEntry));
}
}
@Override
public boolean match(String hostname) throws IOException {
for (HostMatcher matcher : matchers) {
if (matcher.match(hostname)) {
return true;
}
}
return false;
}
}
private static class NegateHostMatcher implements HostMatcher {
private final HostMatcher matcher;
NegateHostMatcher(String hostEntry) throws SSHException {
this.matcher = createMatcher(hostEntry.substring(1));
}
@Override
public boolean match(String hostname) throws IOException {
return !matcher.match(hostname);
}
}
private static class WildcardHostMatcher implements HostMatcher {
private final Pattern pattern;
public WildcardHostMatcher(String hostEntry) {
this.pattern = Pattern.compile("^" + hostEntry.replace("[", "\\[").replace("]", "\\]").replace(".", "\\.").replace("*", ".*").replace("?", ".") + "$");
}
@Override
public boolean match(String hostname) throws IOException {
return pattern.matcher(hostname).matches();
}
@Override
public String toString() {
return "WildcardHostMatcher[" + pattern + ']';
}
}
}

View File

@@ -0,0 +1,258 @@
package com.hierynomus.sshj.userauth.certificate;
import java.math.BigInteger;
import java.security.PublicKey;
import java.util.Date;
import java.util.List;
import java.util.Map;
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Certificate wrapper for public keys, created to help implement
* protocol described here:
*
* https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD
*
* Consumed primarily by net.shmizz.sshj.common.KeyType
*
* @param <T> inner public key type
*/
public class Certificate<T extends PublicKey> implements PublicKey {
private static final long serialVersionUID = 1L;
private final T publicKey;
private final byte[] nonce;
private final BigInteger serial;
private final long type;
private final String id;
private final List<String> validPrincipals;
private final Date validAfter;
private final Date validBefore;
private final Map<String, String> critOptions;
private final Map<String, String> extensions;
private final byte[] signatureKey;
private final byte[] signature;
Certificate(Builder<T> builder) {
this.publicKey = builder.getPublicKey();
this.nonce = builder.getNonce();
this.serial = builder.getSerial();
this.type = builder.getType();
this.id = builder.getId();
this.validPrincipals = builder.getValidPrincipals();
this.validAfter = builder.getValidAfter();
this.validBefore = builder.getValidBefore();
this.critOptions = builder.getCritOptions();
this.extensions = builder.getExtensions();
this.signatureKey = builder.getSignatureKey();
this.signature = builder.getSignature();
}
public static <P extends PublicKey> Builder<P> getBuilder() {
return new Builder<P>();
}
public byte[] getNonce() {
return nonce;
}
public BigInteger getSerial() {
return serial;
}
public long getType() {
return type;
}
public String getId() {
return id;
}
public List<String> getValidPrincipals() {
return validPrincipals;
}
public Date getValidAfter() {
return validAfter;
}
public Date getValidBefore() {
return validBefore;
}
public Map<String, String> getCritOptions() {
return critOptions;
}
public Map<String, String> getExtensions() {
return extensions;
}
public byte[] getSignatureKey() {
return signatureKey;
}
public byte[] getSignature() {
return signature;
}
public T getKey() {
return publicKey;
}
@Override
public byte[] getEncoded() {
return publicKey.getEncoded();
}
@Override
public String getAlgorithm() {
return publicKey.getAlgorithm();
}
@Override
public String getFormat() {
return publicKey.getFormat();
}
public static class Builder<T extends PublicKey> {
private T publicKey;
private byte[] nonce;
private BigInteger serial;
private long type;
private String id;
private List<String> validPrincipals;
private Date validAfter;
private Date validBefore;
private Map<String, String> critOptions;
private Map<String, String> extensions;
private byte[] signatureKey;
private byte[] signature;
public Certificate<T> build() {
return new Certificate<T>(this);
}
public T getPublicKey() {
return publicKey;
}
public Builder<T> publicKey(T publicKey) {
this.publicKey = publicKey;
return this;
}
public byte[] getNonce() {
return nonce;
}
public Builder<T> nonce(byte[] nonce) {
this.nonce = nonce;
return this;
}
public BigInteger getSerial() {
return serial;
}
public Builder<T> serial(BigInteger serial) {
this.serial = serial;
return this;
}
public long getType() {
return type;
}
public Builder<T> type(long type) {
this.type = type;
return this;
}
public String getId() {
return id;
}
public Builder<T> id(String id) {
this.id = id;
return this;
}
public List<String> getValidPrincipals() {
return validPrincipals;
}
public Builder<T> validPrincipals(List<String> validPrincipals) {
this.validPrincipals = validPrincipals;
return this;
}
public Date getValidAfter() {
return validAfter;
}
public Builder<T> validAfter(Date validAfter) {
this.validAfter = validAfter;
return this;
}
public Date getValidBefore() {
return validBefore;
}
public Builder<T> validBefore(Date validBefore) {
this.validBefore = validBefore;
return this;
}
public Map<String, String> getCritOptions() {
return critOptions;
}
public Builder<T> critOptions(Map<String, String> critOptions) {
this.critOptions = critOptions;
return this;
}
public Map<String, String> getExtensions() {
return extensions;
}
public Builder<T> extensions(Map<String, String> extensions) {
this.extensions = extensions;
return this;
}
public byte[] getSignatureKey() {
return signatureKey;
}
public Builder<T> signatureKey(byte[] signatureKey) {
this.signatureKey = signatureKey;
return this;
}
public byte[] getSignature() {
return signature;
}
public Builder<T> signature(byte[] signature) {
this.signature = signature;
return this;
}
}
}

View File

@@ -0,0 +1,258 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.userauth.keyprovider;
import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.common.KeyDecryptionFailedException;
import com.hierynomus.sshj.transport.cipher.BlockCiphers;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.schmizz.sshj.common.*;
import net.schmizz.sshj.common.Buffer.PlainBuffer;
import net.schmizz.sshj.transport.cipher.Cipher;
import net.schmizz.sshj.userauth.keyprovider.BaseFileKeyProvider;
import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
import net.schmizz.sshj.userauth.keyprovider.KeyFormat;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.mindrot.jbcrypt.BCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.util.Arrays;
/**
* Reads a key file in the new OpenSSH format.
* The format is described in the following document: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
*/
public class OpenSSHKeyV1KeyFile extends BaseFileKeyProvider {
private static final Logger logger = LoggerFactory.getLogger(OpenSSHKeyV1KeyFile.class);
private static final String BEGIN = "-----BEGIN ";
private static final String END = "-----END ";
private static final byte[] AUTH_MAGIC = "openssh-key-v1\0".getBytes();
public static final String OPENSSH_PRIVATE_KEY = "OPENSSH PRIVATE KEY-----";
public static final String BCRYPT = "bcrypt";
public static class Factory
implements net.schmizz.sshj.common.Factory.Named<FileKeyProvider> {
@Override
public FileKeyProvider create() {
return new OpenSSHKeyV1KeyFile();
}
@Override
public String getName() {
return KeyFormat.OpenSSHv1.name();
}
}
@Override
protected KeyPair readKeyPair() throws IOException {
BufferedReader reader = new BufferedReader(resource.getReader());
try {
if (!checkHeader(reader)) {
throw new IOException("This key is not in 'openssh-key-v1' format");
}
String keyFile = readKeyFile(reader);
byte[] decode = Base64.decode(keyFile);
PlainBuffer keyBuffer = new PlainBuffer(decode);
return readDecodedKeyPair(keyBuffer);
} catch (GeneralSecurityException e) {
throw new SSHRuntimeException(e);
} finally {
IOUtils.closeQuietly(reader);
}
}
private KeyPair readDecodedKeyPair(final PlainBuffer keyBuffer) throws IOException, GeneralSecurityException {
byte[] bytes = new byte[AUTH_MAGIC.length];
keyBuffer.readRawBytes(bytes); // byte[] AUTH_MAGIC
if (!ByteArrayUtils.equals(bytes, 0, AUTH_MAGIC, 0, AUTH_MAGIC.length)) {
throw new IOException("This key does not contain the 'openssh-key-v1' format magic header");
}
String cipherName = keyBuffer.readString(); // string ciphername
String kdfName = keyBuffer.readString(); // string kdfname
byte[] kdfOptions = keyBuffer.readBytes(); // string kdfoptions
int nrKeys = keyBuffer.readUInt32AsInt(); // int number of keys N; Should be 1
if (nrKeys != 1) {
throw new IOException("We don't support having more than 1 key in the file (yet).");
}
PublicKey publicKey = readPublicKey(new PlainBuffer(keyBuffer.readBytes())); // string publickey1
PlainBuffer privateKeyBuffer = new PlainBuffer(keyBuffer.readBytes()); // string (possibly) encrypted, padded list of private keys
if ("none".equals(cipherName)) {
logger.debug("Reading unencrypted keypair");
return readUnencrypted(privateKeyBuffer, publicKey);
} else {
logger.info("Keypair is encrypted with: " + cipherName + ", " + kdfName + ", " + Arrays.toString(kdfOptions));
while (true) {
PlainBuffer decryptionBuffer = new PlainBuffer(privateKeyBuffer);
PlainBuffer decrypted = decryptBuffer(decryptionBuffer, cipherName, kdfName, kdfOptions);
try {
return readUnencrypted(decrypted, publicKey);
} catch (KeyDecryptionFailedException e) {
if (pwdf == null || !pwdf.shouldRetry(resource))
throw e;
}
}
// throw new IOException("Cannot read encrypted keypair with " + cipherName + " yet.");
}
}
private PlainBuffer decryptBuffer(PlainBuffer privateKeyBuffer, String cipherName, String kdfName, byte[] kdfOptions) throws IOException {
Cipher cipher = createCipher(cipherName);
initializeCipher(kdfName, kdfOptions, cipher);
byte[] array = privateKeyBuffer.array();
cipher.update(array, 0, privateKeyBuffer.available());
return new PlainBuffer(array);
}
private void initializeCipher(String kdfName, byte[] kdfOptions, Cipher cipher) throws Buffer.BufferException {
if (kdfName.equals(BCRYPT)) {
PlainBuffer opts = new PlainBuffer(kdfOptions);
byte[] passphrase = new byte[0];
if (pwdf != null) {
CharBuffer charBuffer = CharBuffer.wrap(pwdf.reqPassword(null));
ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
passphrase = Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
Arrays.fill(charBuffer.array(), '\u0000');
Arrays.fill(byteBuffer.array(), (byte) 0);
}
byte[] keyiv = new byte[48];
new BCrypt().pbkdf(passphrase, opts.readBytes(), opts.readUInt32AsInt(), keyiv);
Arrays.fill(passphrase, (byte) 0);
byte[] key = Arrays.copyOfRange(keyiv, 0, 32);
byte[] iv = Arrays.copyOfRange(keyiv, 32, 48);
cipher.init(Cipher.Mode.Decrypt, key, iv);
} else {
throw new IllegalStateException("No support for KDF '" + kdfName + "'.");
}
}
private Cipher createCipher(String cipherName) {
if (cipherName.equals(BlockCiphers.AES256CTR().getName())) {
return BlockCiphers.AES256CTR().create();
} else if (cipherName.equals(BlockCiphers.AES256CBC().getName())) {
return BlockCiphers.AES256CBC().create();
}
throw new IllegalStateException("Cipher '" + cipherName + "' not currently implemented for openssh-key-v1 format");
}
private PublicKey readPublicKey(final PlainBuffer plainBuffer) throws Buffer.BufferException, GeneralSecurityException {
return KeyType.fromString(plainBuffer.readString()).readPubKeyFromBuffer(plainBuffer);
}
private String readKeyFile(final BufferedReader reader) throws IOException {
StringBuilder sb = new StringBuilder();
String line = reader.readLine();
while (!line.startsWith(END)) {
sb.append(line);
line = reader.readLine();
}
return sb.toString();
}
private boolean checkHeader(final BufferedReader reader) throws IOException {
String line = reader.readLine();
while (line != null && !line.startsWith(BEGIN)) {
line = reader.readLine();
}
line = line.substring(BEGIN.length());
return line.startsWith(OPENSSH_PRIVATE_KEY);
}
private KeyPair readUnencrypted(final PlainBuffer keyBuffer, final PublicKey publicKey) throws IOException, GeneralSecurityException {
int privKeyListSize = keyBuffer.available();
if (privKeyListSize % 8 != 0) {
throw new IOException("The private key section must be a multiple of the block size (8)");
}
int checkInt1 = keyBuffer.readUInt32AsInt(); // uint32 checkint1
int checkInt2 = keyBuffer.readUInt32AsInt(); // uint32 checkint2
if (checkInt1 != checkInt2) {
throw new KeyDecryptionFailedException();
}
// The private key section contains both the public key and the private key
String keyType = keyBuffer.readString(); // string keytype
KeyType kt = KeyType.fromString(keyType);
logger.info("Read key type: {}", keyType, kt);
KeyPair kp;
switch (kt) {
case ED25519:
keyBuffer.readBytes(); // string publickey (again...)
keyBuffer.readUInt32(); // length of privatekey+publickey
byte[] privKey = new byte[32];
keyBuffer.readRawBytes(privKey); // string privatekey
keyBuffer.readRawBytes(new byte[32]); // string publickey (again...)
kp = new KeyPair(publicKey, new EdDSAPrivateKey(new EdDSAPrivateKeySpec(privKey, EdDSANamedCurveTable.getByName("Ed25519"))));
break;
case RSA:
BigInteger n = keyBuffer.readMPInt(); // Modulus
keyBuffer.readMPInt(); // Public Exponent
BigInteger d = keyBuffer.readMPInt(); // Private Exponent
keyBuffer.readMPInt(); // iqmp (q^-1 mod p)
keyBuffer.readMPInt(); // p (Prime 1)
keyBuffer.readMPInt(); // q (Prime 2)
kp = new KeyPair(publicKey, SecurityUtils.getKeyFactory(KeyAlgorithm.RSA).generatePrivate(new RSAPrivateKeySpec(n, d)));
break;
case ECDSA256:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-256"));
break;
case ECDSA384:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-384"));
break;
case ECDSA521:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-521"));
break;
default:
throw new IOException("Cannot decode keytype " + keyType + " in openssh-key-v1 files (yet).");
}
keyBuffer.readString(); // string comment
byte[] padding = new byte[keyBuffer.available()];
keyBuffer.readRawBytes(padding); // char[] padding
for (int i = 0; i < padding.length; i++) {
if ((int) padding[i] != i + 1) {
throw new IOException("Padding of key format contained wrong byte at position: " + i);
}
}
return kp;
}
private PrivateKey createECDSAPrivateKey(KeyType kt, PlainBuffer buffer, String name) throws GeneralSecurityException, Buffer.BufferException {
kt.readPubKeyFromBuffer(buffer); // Public key
BigInteger s = new BigInteger(1, buffer.readBytes());
X9ECParameters ecParams = NISTNamedCurves.getByName(name);
ECNamedCurveSpec ecCurveSpec = new ECNamedCurveSpec(name, ecParams.getCurve(), ecParams.getG(), ecParams.getN());
ECPrivateKeySpec pks = new ECPrivateKeySpec(s, ecCurveSpec);
return SecurityUtils.getKeyFactory(KeyAlgorithm.ECDSA).generatePrivate(pks);
}
}

View File

@@ -0,0 +1,918 @@
/* Ported from C to Java by Dmitry Skiba [sahn0], 23/02/08.
* Original: http://cds.xs4all.nl:8081/ecdh/
*/
/* Generic 64-bit integer implementation of Curve25519 ECDH
* Written by Matthijs van Duin, 200608242056
* Public domain.
*
* Based on work by Daniel J Bernstein, http://cr.yp.to/ecdh.html
*/
package djb;
public class Curve25519 {
/* key size */
public static final int KEY_SIZE = 32;
/* 0 */
public static final byte[] ZERO = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* the prime 2^255-19 */
public static final byte[] PRIME = {
(byte)237, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)255,
(byte)255, (byte)255, (byte)255, (byte)127
};
/* group order (a prime near 2^252+2^124) */
public static final byte[] ORDER = {
(byte)237, (byte)211, (byte)245, (byte)92,
(byte)26, (byte)99, (byte)18, (byte)88,
(byte)214, (byte)156, (byte)247, (byte)162,
(byte)222, (byte)249, (byte)222, (byte)20,
(byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)16
};
/********* KEY AGREEMENT *********/
/* Private key clamping
* k [out] your private key for key agreement
* k [in] 32 random bytes
*/
public static final void clamp(byte[] k) {
k[31] &= 0x7F;
k[31] |= 0x40;
k[ 0] &= 0xF8;
}
/* Key-pair generation
* P [out] your public key
* s [out] your private key for signing
* k [out] your private key for key agreement
* k [in] 32 random bytes
* s may be NULL if you don't care
*
* WARNING: if s is not NULL, this function has data-dependent timing */
public static final void keygen(byte[] P, byte[] s, byte[] k) {
clamp(k);
core(P, s, k, null);
}
/* Key agreement
* Z [out] shared secret (needs hashing before use)
* k [in] your private key for key agreement
* P [in] peer's public key
*/
public static final void curve(byte[] Z, byte[] k, byte[] P) {
core(Z, null, k, P);
}
/********* DIGITAL SIGNATURES *********/
/* deterministic EC-KCDSA
*
* s is the private key for signing
* P is the corresponding public key
* Z is the context data (signer public key or certificate, etc)
*
* signing:
*
* m = hash(Z, message)
* x = hash(m, s)
* keygen25519(Y, NULL, x);
* r = hash(Y);
* h = m XOR r
* sign25519(v, h, x, s);
*
* output (v,r) as the signature
*
* verification:
*
* m = hash(Z, message);
* h = m XOR r
* verify25519(Y, v, h, P)
*
* confirm r == hash(Y)
*
* It would seem to me that it would be simpler to have the signer directly do
* h = hash(m, Y) and send that to the recipient instead of r, who can verify
* the signature by checking h == hash(m, Y). If there are any problems with
* such a scheme, please let me know.
*
* Also, EC-KCDSA (like most DS algorithms) picks x random, which is a waste of
* perfectly good entropy, but does allow Y to be calculated in advance of (or
* parallel to) hashing the message.
*/
/* Signature generation primitive, calculates (x-h)s mod q
* v [out] signature value
* h [in] signature hash (of message, signature pub key, and context data)
* x [in] signature private key
* s [in] private key for signing
* returns true on success, false on failure (use different x or h)
*/
public static final boolean sign(byte[] v, byte[] h, byte[] x, byte[] s) {
// v = (x - h) s mod q
int w, i;
byte[] h1 = new byte[32], x1 = new byte[32];
byte[] tmp1 = new byte[64];
byte[] tmp2 = new byte[64];
// Don't clobber the arguments, be nice!
cpy32(h1, h);
cpy32(x1, x);
// Reduce modulo group order
byte[] tmp3=new byte[32];
divmod(tmp3, h1, 32, ORDER, 32);
divmod(tmp3, x1, 32, ORDER, 32);
// v = x1 - h1
// If v is negative, add the group order to it to become positive.
// If v was already positive we don't have to worry about overflow
// when adding the order because v < ORDER and 2*ORDER < 2^256
mula_small(v, x1, 0, h1, 32, -1);
mula_small(v, v , 0, ORDER, 32, 1);
// tmp1 = (x-h)*s mod q
mula32(tmp1, v, s, 32, 1);
divmod(tmp2, tmp1, 64, ORDER, 32);
for (w = 0, i = 0; i < 32; i++)
w |= v[i] = tmp1[i];
return w != 0;
}
/* Signature verification primitive, calculates Y = vP + hG
* Y [out] signature public key
* v [in] signature value
* h [in] signature hash
* P [in] public key
*/
public static final void verify(byte[] Y, byte[] v, byte[] h, byte[] P) {
/* Y = v abs(P) + h G */
byte[] d=new byte[32];
long10[]
p=new long10[]{new long10(),new long10()},
s=new long10[]{new long10(),new long10()},
yx=new long10[]{new long10(),new long10(),new long10()},
yz=new long10[]{new long10(),new long10(),new long10()},
t1=new long10[]{new long10(),new long10(),new long10()},
t2=new long10[]{new long10(),new long10(),new long10()};
int vi = 0, hi = 0, di = 0, nvh=0, i, j, k;
/* set p[0] to G and p[1] to P */
set(p[0], 9);
unpack(p[1], P);
/* set s[0] to P+G and s[1] to P-G */
/* s[0] = (Py^2 + Gy^2 - 2 Py Gy)/(Px - Gx)^2 - Px - Gx - 486662 */
/* s[1] = (Py^2 + Gy^2 + 2 Py Gy)/(Px - Gx)^2 - Px - Gx - 486662 */
x_to_y2(t1[0], t2[0], p[1]); /* t2[0] = Py^2 */
sqrt(t1[0], t2[0]); /* t1[0] = Py or -Py */
j = is_negative(t1[0]); /* ... check which */
t2[0]._0 += 39420360; /* t2[0] = Py^2 + Gy^2 */
mul(t2[1], BASE_2Y, t1[0]);/* t2[1] = 2 Py Gy or -2 Py Gy */
sub(t1[j], t2[0], t2[1]); /* t1[0] = Py^2 + Gy^2 - 2 Py Gy */
add(t1[1-j], t2[0], t2[1]);/* t1[1] = Py^2 + Gy^2 + 2 Py Gy */
cpy(t2[0], p[1]); /* t2[0] = Px */
t2[0]._0 -= 9; /* t2[0] = Px - Gx */
sqr(t2[1], t2[0]); /* t2[1] = (Px - Gx)^2 */
recip(t2[0], t2[1], 0); /* t2[0] = 1/(Px - Gx)^2 */
mul(s[0], t1[0], t2[0]); /* s[0] = t1[0]/(Px - Gx)^2 */
sub(s[0], s[0], p[1]); /* s[0] = t1[0]/(Px - Gx)^2 - Px */
s[0]._0 -= 9 + 486662; /* s[0] = X(P+G) */
mul(s[1], t1[1], t2[0]); /* s[1] = t1[1]/(Px - Gx)^2 */
sub(s[1], s[1], p[1]); /* s[1] = t1[1]/(Px - Gx)^2 - Px */
s[1]._0 -= 9 + 486662; /* s[1] = X(P-G) */
mul_small(s[0], s[0], 1); /* reduce s[0] */
mul_small(s[1], s[1], 1); /* reduce s[1] */
/* prepare the chain */
for (i = 0; i < 32; i++) {
vi = (vi >> 8) ^ (v[i] & 0xFF) ^ ((v[i] & 0xFF) << 1);
hi = (hi >> 8) ^ (h[i] & 0xFF) ^ ((h[i] & 0xFF) << 1);
nvh = ~(vi ^ hi);
di = (nvh & (di & 0x80) >> 7) ^ vi;
di ^= nvh & (di & 0x01) << 1;
di ^= nvh & (di & 0x02) << 1;
di ^= nvh & (di & 0x04) << 1;
di ^= nvh & (di & 0x08) << 1;
di ^= nvh & (di & 0x10) << 1;
di ^= nvh & (di & 0x20) << 1;
di ^= nvh & (di & 0x40) << 1;
d[i] = (byte)di;
}
di = ((nvh & (di & 0x80) << 1) ^ vi) >> 8;
/* initialize state */
set(yx[0], 1);
cpy(yx[1], p[di]);
cpy(yx[2], s[0]);
set(yz[0], 0);
set(yz[1], 1);
set(yz[2], 1);
/* y[0] is (even)P + (even)G
* y[1] is (even)P + (odd)G if current d-bit is 0
* y[1] is (odd)P + (even)G if current d-bit is 1
* y[2] is (odd)P + (odd)G
*/
vi = 0;
hi = 0;
/* and go for it! */
for (i = 32; i--!=0; ) {
vi = (vi << 8) | (v[i] & 0xFF);
hi = (hi << 8) | (h[i] & 0xFF);
di = (di << 8) | (d[i] & 0xFF);
for (j = 8; j--!=0; ) {
mont_prep(t1[0], t2[0], yx[0], yz[0]);
mont_prep(t1[1], t2[1], yx[1], yz[1]);
mont_prep(t1[2], t2[2], yx[2], yz[2]);
k = ((vi ^ vi >> 1) >> j & 1)
+ ((hi ^ hi >> 1) >> j & 1);
mont_dbl(yx[2], yz[2], t1[k], t2[k], yx[0], yz[0]);
k = (di >> j & 2) ^ ((di >> j & 1) << 1);
mont_add(t1[1], t2[1], t1[k], t2[k], yx[1], yz[1],
p[di >> j & 1]);
mont_add(t1[2], t2[2], t1[0], t2[0], yx[2], yz[2],
s[((vi ^ hi) >> j & 2) >> 1]);
}
}
k = (vi & 1) + (hi & 1);
recip(t1[0], yz[k], 0);
mul(t1[1], yx[k], t1[0]);
pack(t1[1], Y);
}
///////////////////////////////////////////////////////////////////////////
/* sahn0:
* Using this class instead of long[10] to avoid bounds checks. */
private static final class long10 {
public long10() {}
public long10(
long _0, long _1, long _2, long _3, long _4,
long _5, long _6, long _7, long _8, long _9)
{
this._0=_0; this._1=_1; this._2=_2;
this._3=_3; this._4=_4; this._5=_5;
this._6=_6; this._7=_7; this._8=_8;
this._9=_9;
}
public long _0,_1,_2,_3,_4,_5,_6,_7,_8,_9;
}
/********************* radix 2^8 math *********************/
private static final void cpy32(byte[] d, byte[] s) {
int i;
for (i = 0; i < 32; i++)
d[i] = s[i];
}
/* p[m..n+m-1] = q[m..n+m-1] + z * x */
/* n is the size of x */
/* n+m is the size of p and q */
private static final int mula_small(byte[] p,byte[] q,int m,byte[] x,int n,int z) {
int v=0;
for (int i=0;i<n;++i) {
v+=(q[i+m] & 0xFF)+z*(x[i] & 0xFF);
p[i+m]=(byte)v;
v>>=8;
}
return v;
}
/* p += x * y * z where z is a small integer
* x is size 32, y is size t, p is size 32+t
* y is allowed to overlap with p+32 if you don't care about the upper half */
private static final int mula32(byte[] p, byte[] x, byte[] y, int t, int z) {
final int n = 31;
int w = 0;
int i = 0;
for (; i < t; i++) {
int zy = z * (y[i] & 0xFF);
w += mula_small(p, p, i, x, n, zy) +
(p[i+n] & 0xFF) + zy * (x[n] & 0xFF);
p[i+n] = (byte)w;
w >>= 8;
}
p[i+n] = (byte)(w + (p[i+n] & 0xFF));
return w >> 8;
}
/* divide r (size n) by d (size t), returning quotient q and remainder r
* quotient is size n-t+1, remainder is size t
* requires t > 0 && d[t-1] != 0
* requires that r[-1] and d[-1] are valid memory locations
* q may overlap with r+t */
private static final void divmod(byte[] q, byte[] r, int n, byte[] d, int t) {
int rn = 0;
int dt = ((d[t-1] & 0xFF) << 8);
if (t>1) {
dt |= (d[t-2] & 0xFF);
}
while (n-- >= t) {
int z = (rn << 16) | ((r[n] & 0xFF) << 8);
if (n>0) {
z |= (r[n-1] & 0xFF);
}
z/=dt;
rn += mula_small(r,r, n-t+1, d, t, -z);
q[n-t+1] = (byte)((z + rn) & 0xFF); /* rn is 0 or -1 (underflow) */
mula_small(r,r, n-t+1, d, t, -rn);
rn = (r[n] & 0xFF);
r[n] = 0;
}
r[t-1] = (byte)rn;
}
private static final int numsize(byte[] x,int n) {
while (n--!=0 && x[n]==0)
;
return n+1;
}
/* Returns x if a contains the gcd, y if b.
* Also, the returned buffer contains the inverse of a mod b,
* as 32-byte signed.
* x and y must have 64 bytes space for temporary use.
* requires that a[-1] and b[-1] are valid memory locations */
private static final byte[] egcd32(byte[] x,byte[] y,byte[] a,byte[] b) {
int an, bn = 32, qn, i;
for (i = 0; i < 32; i++)
x[i] = y[i] = 0;
x[0] = 1;
an = numsize(a, 32);
if (an==0)
return y; /* division by zero */
byte[] temp=new byte[32];
while (true) {
qn = bn - an + 1;
divmod(temp, b, bn, a, an);
bn = numsize(b, bn);
if (bn==0)
return x;
mula32(y, x, temp, qn, -1);
qn = an - bn + 1;
divmod(temp, a, an, b, bn);
an = numsize(a, an);
if (an==0)
return y;
mula32(x, y, temp, qn, -1);
}
}
/********************* radix 2^25.5 GF(2^255-19) math *********************/
private static final int P25=33554431; /* (1 << 25) - 1 */
private static final int P26=67108863; /* (1 << 26) - 1 */
/* Convert to internal format from little-endian byte format */
private static final void unpack(long10 x,byte[] m) {
x._0 = ((m[0] & 0xFF)) | ((m[1] & 0xFF))<<8 |
(m[2] & 0xFF)<<16 | ((m[3] & 0xFF)& 3)<<24;
x._1 = ((m[3] & 0xFF)&~ 3)>>2 | (m[4] & 0xFF)<<6 |
(m[5] & 0xFF)<<14 | ((m[6] & 0xFF)& 7)<<22;
x._2 = ((m[6] & 0xFF)&~ 7)>>3 | (m[7] & 0xFF)<<5 |
(m[8] & 0xFF)<<13 | ((m[9] & 0xFF)&31)<<21;
x._3 = ((m[9] & 0xFF)&~31)>>5 | (m[10] & 0xFF)<<3 |
(m[11] & 0xFF)<<11 | ((m[12] & 0xFF)&63)<<19;
x._4 = ((m[12] & 0xFF)&~63)>>6 | (m[13] & 0xFF)<<2 |
(m[14] & 0xFF)<<10 | (m[15] & 0xFF) <<18;
x._5 = (m[16] & 0xFF) | (m[17] & 0xFF)<<8 |
(m[18] & 0xFF)<<16 | ((m[19] & 0xFF)& 1)<<24;
x._6 = ((m[19] & 0xFF)&~ 1)>>1 | (m[20] & 0xFF)<<7 |
(m[21] & 0xFF)<<15 | ((m[22] & 0xFF)& 7)<<23;
x._7 = ((m[22] & 0xFF)&~ 7)>>3 | (m[23] & 0xFF)<<5 |
(m[24] & 0xFF)<<13 | ((m[25] & 0xFF)&15)<<21;
x._8 = ((m[25] & 0xFF)&~15)>>4 | (m[26] & 0xFF)<<4 |
(m[27] & 0xFF)<<12 | ((m[28] & 0xFF)&63)<<20;
x._9 = ((m[28] & 0xFF)&~63)>>6 | (m[29] & 0xFF)<<2 |
(m[30] & 0xFF)<<10 | (m[31] & 0xFF) <<18;
}
/* Check if reduced-form input >= 2^255-19 */
private static final boolean is_overflow(long10 x) {
return (
((x._0 > P26-19)) &&
((x._1 & x._3 & x._5 & x._7 & x._9) == P25) &&
((x._2 & x._4 & x._6 & x._8) == P26)
) || (x._9 > P25);
}
/* Convert from internal format to little-endian byte format. The
* number must be in a reduced form which is output by the following ops:
* unpack, mul, sqr
* set -- if input in range 0 .. P25
* If you're unsure if the number is reduced, first multiply it by 1. */
private static final void pack(long10 x,byte[] m) {
int ld = 0, ud = 0;
long t;
ld = (is_overflow(x)?1:0) - ((x._9 < 0)?1:0);
ud = ld * -(P25+1);
ld *= 19;
t = ld + x._0 + (x._1 << 26);
m[ 0] = (byte)t;
m[ 1] = (byte)(t >> 8);
m[ 2] = (byte)(t >> 16);
m[ 3] = (byte)(t >> 24);
t = (t >> 32) + (x._2 << 19);
m[ 4] = (byte)t;
m[ 5] = (byte)(t >> 8);
m[ 6] = (byte)(t >> 16);
m[ 7] = (byte)(t >> 24);
t = (t >> 32) + (x._3 << 13);
m[ 8] = (byte)t;
m[ 9] = (byte)(t >> 8);
m[10] = (byte)(t >> 16);
m[11] = (byte)(t >> 24);
t = (t >> 32) + (x._4 << 6);
m[12] = (byte)t;
m[13] = (byte)(t >> 8);
m[14] = (byte)(t >> 16);
m[15] = (byte)(t >> 24);
t = (t >> 32) + x._5 + (x._6 << 25);
m[16] = (byte)t;
m[17] = (byte)(t >> 8);
m[18] = (byte)(t >> 16);
m[19] = (byte)(t >> 24);
t = (t >> 32) + (x._7 << 19);
m[20] = (byte)t;
m[21] = (byte)(t >> 8);
m[22] = (byte)(t >> 16);
m[23] = (byte)(t >> 24);
t = (t >> 32) + (x._8 << 12);
m[24] = (byte)t;
m[25] = (byte)(t >> 8);
m[26] = (byte)(t >> 16);
m[27] = (byte)(t >> 24);
t = (t >> 32) + ((x._9 + ud) << 6);
m[28] = (byte)t;
m[29] = (byte)(t >> 8);
m[30] = (byte)(t >> 16);
m[31] = (byte)(t >> 24);
}
/* Copy a number */
private static final void cpy(long10 out, long10 in) {
out._0=in._0; out._1=in._1;
out._2=in._2; out._3=in._3;
out._4=in._4; out._5=in._5;
out._6=in._6; out._7=in._7;
out._8=in._8; out._9=in._9;
}
/* Set a number to value, which must be in range -185861411 .. 185861411 */
private static final void set(long10 out, int in) {
out._0=in; out._1=0;
out._2=0; out._3=0;
out._4=0; out._5=0;
out._6=0; out._7=0;
out._8=0; out._9=0;
}
/* Add/subtract two numbers. The inputs must be in reduced form, and the
* output isn't, so to do another addition or subtraction on the output,
* first multiply it by one to reduce it. */
private static final void add(long10 xy, long10 x, long10 y) {
xy._0 = x._0 + y._0; xy._1 = x._1 + y._1;
xy._2 = x._2 + y._2; xy._3 = x._3 + y._3;
xy._4 = x._4 + y._4; xy._5 = x._5 + y._5;
xy._6 = x._6 + y._6; xy._7 = x._7 + y._7;
xy._8 = x._8 + y._8; xy._9 = x._9 + y._9;
}
private static final void sub(long10 xy, long10 x, long10 y) {
xy._0 = x._0 - y._0; xy._1 = x._1 - y._1;
xy._2 = x._2 - y._2; xy._3 = x._3 - y._3;
xy._4 = x._4 - y._4; xy._5 = x._5 - y._5;
xy._6 = x._6 - y._6; xy._7 = x._7 - y._7;
xy._8 = x._8 - y._8; xy._9 = x._9 - y._9;
}
/* Multiply a number by a small integer in range -185861411 .. 185861411.
* The output is in reduced form, the input x need not be. x and xy may point
* to the same buffer. */
private static final long10 mul_small(long10 xy, long10 x, long y) {
long t;
t = (x._8*y);
xy._8 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x._9*y);
xy._9 = (t & ((1 << 25) - 1));
t = 19 * (t >> 25) + (x._0*y);
xy._0 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x._1*y);
xy._1 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x._2*y);
xy._2 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x._3*y);
xy._3 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x._4*y);
xy._4 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x._5*y);
xy._5 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x._6*y);
xy._6 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x._7*y);
xy._7 = (t & ((1 << 25) - 1));
t = (t >> 25) + xy._8;
xy._8 = (t & ((1 << 26) - 1));
xy._9 += (t >> 26);
return xy;
}
/* Multiply two numbers. The output is in reduced form, the inputs need not
* be. */
private static final long10 mul(long10 xy, long10 x, long10 y) {
/* sahn0:
* Using local variables to avoid class access.
* This seem to improve performance a bit...
*/
long
x_0=x._0,x_1=x._1,x_2=x._2,x_3=x._3,x_4=x._4,
x_5=x._5,x_6=x._6,x_7=x._7,x_8=x._8,x_9=x._9;
long
y_0=y._0,y_1=y._1,y_2=y._2,y_3=y._3,y_4=y._4,
y_5=y._5,y_6=y._6,y_7=y._7,y_8=y._8,y_9=y._9;
long t;
t = (x_0*y_8) + (x_2*y_6) + (x_4*y_4) + (x_6*y_2) +
(x_8*y_0) + 2 * ((x_1*y_7) + (x_3*y_5) +
(x_5*y_3) + (x_7*y_1)) + 38 *
(x_9*y_9);
xy._8 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x_0*y_9) + (x_1*y_8) + (x_2*y_7) +
(x_3*y_6) + (x_4*y_5) + (x_5*y_4) +
(x_6*y_3) + (x_7*y_2) + (x_8*y_1) +
(x_9*y_0);
xy._9 = (t & ((1 << 25) - 1));
t = (x_0*y_0) + 19 * ((t >> 25) + (x_2*y_8) + (x_4*y_6)
+ (x_6*y_4) + (x_8*y_2)) + 38 *
((x_1*y_9) + (x_3*y_7) + (x_5*y_5) +
(x_7*y_3) + (x_9*y_1));
xy._0 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x_0*y_1) + (x_1*y_0) + 19 * ((x_2*y_9)
+ (x_3*y_8) + (x_4*y_7) + (x_5*y_6) +
(x_6*y_5) + (x_7*y_4) + (x_8*y_3) +
(x_9*y_2));
xy._1 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x_0*y_2) + (x_2*y_0) + 19 * ((x_4*y_8)
+ (x_6*y_6) + (x_8*y_4)) + 2 * (x_1*y_1)
+ 38 * ((x_3*y_9) + (x_5*y_7) +
(x_7*y_5) + (x_9*y_3));
xy._2 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x_0*y_3) + (x_1*y_2) + (x_2*y_1) +
(x_3*y_0) + 19 * ((x_4*y_9) + (x_5*y_8) +
(x_6*y_7) + (x_7*y_6) +
(x_8*y_5) + (x_9*y_4));
xy._3 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x_0*y_4) + (x_2*y_2) + (x_4*y_0) + 19 *
((x_6*y_8) + (x_8*y_6)) + 2 * ((x_1*y_3) +
(x_3*y_1)) + 38 *
((x_5*y_9) + (x_7*y_7) + (x_9*y_5));
xy._4 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x_0*y_5) + (x_1*y_4) + (x_2*y_3) +
(x_3*y_2) + (x_4*y_1) + (x_5*y_0) + 19 *
((x_6*y_9) + (x_7*y_8) + (x_8*y_7) +
(x_9*y_6));
xy._5 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x_0*y_6) + (x_2*y_4) + (x_4*y_2) +
(x_6*y_0) + 19 * (x_8*y_8) + 2 * ((x_1*y_5) +
(x_3*y_3) + (x_5*y_1)) + 38 *
((x_7*y_9) + (x_9*y_7));
xy._6 = (t & ((1 << 26) - 1));
t = (t >> 26) + (x_0*y_7) + (x_1*y_6) + (x_2*y_5) +
(x_3*y_4) + (x_4*y_3) + (x_5*y_2) +
(x_6*y_1) + (x_7*y_0) + 19 * ((x_8*y_9) +
(x_9*y_8));
xy._7 = (t & ((1 << 25) - 1));
t = (t >> 25) + xy._8;
xy._8 = (t & ((1 << 26) - 1));
xy._9 += (t >> 26);
return xy;
}
/* Square a number. Optimization of mul25519(x2, x, x) */
private static final long10 sqr(long10 x2, long10 x) {
long
x_0=x._0,x_1=x._1,x_2=x._2,x_3=x._3,x_4=x._4,
x_5=x._5,x_6=x._6,x_7=x._7,x_8=x._8,x_9=x._9;
long t;
t = (x_4*x_4) + 2 * ((x_0*x_8) + (x_2*x_6)) + 38 *
(x_9*x_9) + 4 * ((x_1*x_7) + (x_3*x_5));
x2._8 = (t & ((1 << 26) - 1));
t = (t >> 26) + 2 * ((x_0*x_9) + (x_1*x_8) + (x_2*x_7) +
(x_3*x_6) + (x_4*x_5));
x2._9 = (t & ((1 << 25) - 1));
t = 19 * (t >> 25) + (x_0*x_0) + 38 * ((x_2*x_8) +
(x_4*x_6) + (x_5*x_5)) + 76 * ((x_1*x_9)
+ (x_3*x_7));
x2._0 = (t & ((1 << 26) - 1));
t = (t >> 26) + 2 * (x_0*x_1) + 38 * ((x_2*x_9) +
(x_3*x_8) + (x_4*x_7) + (x_5*x_6));
x2._1 = (t & ((1 << 25) - 1));
t = (t >> 25) + 19 * (x_6*x_6) + 2 * ((x_0*x_2) +
(x_1*x_1)) + 38 * (x_4*x_8) + 76 *
((x_3*x_9) + (x_5*x_7));
x2._2 = (t & ((1 << 26) - 1));
t = (t >> 26) + 2 * ((x_0*x_3) + (x_1*x_2)) + 38 *
((x_4*x_9) + (x_5*x_8) + (x_6*x_7));
x2._3 = (t & ((1 << 25) - 1));
t = (t >> 25) + (x_2*x_2) + 2 * (x_0*x_4) + 38 *
((x_6*x_8) + (x_7*x_7)) + 4 * (x_1*x_3) + 76 *
(x_5*x_9);
x2._4 = (t & ((1 << 26) - 1));
t = (t >> 26) + 2 * ((x_0*x_5) + (x_1*x_4) + (x_2*x_3))
+ 38 * ((x_6*x_9) + (x_7*x_8));
x2._5 = (t & ((1 << 25) - 1));
t = (t >> 25) + 19 * (x_8*x_8) + 2 * ((x_0*x_6) +
(x_2*x_4) + (x_3*x_3)) + 4 * (x_1*x_5) +
76 * (x_7*x_9);
x2._6 = (t & ((1 << 26) - 1));
t = (t >> 26) + 2 * ((x_0*x_7) + (x_1*x_6) + (x_2*x_5) +
(x_3*x_4)) + 38 * (x_8*x_9);
x2._7 = (t & ((1 << 25) - 1));
t = (t >> 25) + x2._8;
x2._8 = (t & ((1 << 26) - 1));
x2._9 += (t >> 26);
return x2;
}
/* Calculates a reciprocal. The output is in reduced form, the inputs need not
* be. Simply calculates y = x^(p-2) so it's not too fast. */
/* When sqrtassist is true, it instead calculates y = x^((p-5)/8) */
private static final void recip(long10 y, long10 x, int sqrtassist) {
long10
t0=new long10(),
t1=new long10(),
t2=new long10(),
t3=new long10(),
t4=new long10();
int i;
/* the chain for x^(2^255-21) is straight from djb's implementation */
sqr(t1, x); /* 2 == 2 * 1 */
sqr(t2, t1); /* 4 == 2 * 2 */
sqr(t0, t2); /* 8 == 2 * 4 */
mul(t2, t0, x); /* 9 == 8 + 1 */
mul(t0, t2, t1); /* 11 == 9 + 2 */
sqr(t1, t0); /* 22 == 2 * 11 */
mul(t3, t1, t2); /* 31 == 22 + 9
== 2^5 - 2^0 */
sqr(t1, t3); /* 2^6 - 2^1 */
sqr(t2, t1); /* 2^7 - 2^2 */
sqr(t1, t2); /* 2^8 - 2^3 */
sqr(t2, t1); /* 2^9 - 2^4 */
sqr(t1, t2); /* 2^10 - 2^5 */
mul(t2, t1, t3); /* 2^10 - 2^0 */
sqr(t1, t2); /* 2^11 - 2^1 */
sqr(t3, t1); /* 2^12 - 2^2 */
for (i = 1; i < 5; i++) {
sqr(t1, t3);
sqr(t3, t1);
} /* t3 */ /* 2^20 - 2^10 */
mul(t1, t3, t2); /* 2^20 - 2^0 */
sqr(t3, t1); /* 2^21 - 2^1 */
sqr(t4, t3); /* 2^22 - 2^2 */
for (i = 1; i < 10; i++) {
sqr(t3, t4);
sqr(t4, t3);
} /* t4 */ /* 2^40 - 2^20 */
mul(t3, t4, t1); /* 2^40 - 2^0 */
for (i = 0; i < 5; i++) {
sqr(t1, t3);
sqr(t3, t1);
} /* t3 */ /* 2^50 - 2^10 */
mul(t1, t3, t2); /* 2^50 - 2^0 */
sqr(t2, t1); /* 2^51 - 2^1 */
sqr(t3, t2); /* 2^52 - 2^2 */
for (i = 1; i < 25; i++) {
sqr(t2, t3);
sqr(t3, t2);
} /* t3 */ /* 2^100 - 2^50 */
mul(t2, t3, t1); /* 2^100 - 2^0 */
sqr(t3, t2); /* 2^101 - 2^1 */
sqr(t4, t3); /* 2^102 - 2^2 */
for (i = 1; i < 50; i++) {
sqr(t3, t4);
sqr(t4, t3);
} /* t4 */ /* 2^200 - 2^100 */
mul(t3, t4, t2); /* 2^200 - 2^0 */
for (i = 0; i < 25; i++) {
sqr(t4, t3);
sqr(t3, t4);
} /* t3 */ /* 2^250 - 2^50 */
mul(t2, t3, t1); /* 2^250 - 2^0 */
sqr(t1, t2); /* 2^251 - 2^1 */
sqr(t2, t1); /* 2^252 - 2^2 */
if (sqrtassist!=0) {
mul(y, x, t2); /* 2^252 - 3 */
} else {
sqr(t1, t2); /* 2^253 - 2^3 */
sqr(t2, t1); /* 2^254 - 2^4 */
sqr(t1, t2); /* 2^255 - 2^5 */
mul(y, t1, t0); /* 2^255 - 21 */
}
}
/* checks if x is "negative", requires reduced input */
private static final int is_negative(long10 x) {
return (int)(((is_overflow(x) || (x._9 < 0))?1:0) ^ (x._0 & 1));
}
/* a square root */
private static final void sqrt(long10 x, long10 u) {
long10 v=new long10(), t1=new long10(), t2=new long10();
add(t1, u, u); /* t1 = 2u */
recip(v, t1, 1); /* v = (2u)^((p-5)/8) */
sqr(x, v); /* x = v^2 */
mul(t2, t1, x); /* t2 = 2uv^2 */
t2._0--; /* t2 = 2uv^2-1 */
mul(t1, v, t2); /* t1 = v(2uv^2-1) */
mul(x, u, t1); /* x = uv(2uv^2-1) */
}
/********************* Elliptic curve *********************/
/* y^2 = x^3 + 486662 x^2 + x over GF(2^255-19) */
/* t1 = ax + az
* t2 = ax - az */
private static final void mont_prep(long10 t1, long10 t2, long10 ax, long10 az) {
add(t1, ax, az);
sub(t2, ax, az);
}
/* A = P + Q where
* X(A) = ax/az
* X(P) = (t1+t2)/(t1-t2)
* X(Q) = (t3+t4)/(t3-t4)
* X(P-Q) = dx
* clobbers t1 and t2, preserves t3 and t4 */
private static final void mont_add(long10 t1, long10 t2, long10 t3, long10 t4,long10 ax, long10 az, long10 dx) {
mul(ax, t2, t3);
mul(az, t1, t4);
add(t1, ax, az);
sub(t2, ax, az);
sqr(ax, t1);
sqr(t1, t2);
mul(az, t1, dx);
}
/* B = 2 * Q where
* X(B) = bx/bz
* X(Q) = (t3+t4)/(t3-t4)
* clobbers t1 and t2, preserves t3 and t4 */
private static final void mont_dbl(long10 t1, long10 t2, long10 t3, long10 t4,long10 bx, long10 bz) {
sqr(t1, t3);
sqr(t2, t4);
mul(bx, t1, t2);
sub(t2, t1, t2);
mul_small(bz, t2, 121665);
add(t1, t1, bz);
mul(bz, t1, t2);
}
/* Y^2 = X^3 + 486662 X^2 + X
* t is a temporary */
private static final void x_to_y2(long10 t, long10 y2, long10 x) {
sqr(t, x);
mul_small(y2, x, 486662);
add(t, t, y2);
t._0++;
mul(y2, t, x);
}
/* P = kG and s = sign(P)/k */
private static final void core(byte[] Px, byte[] s, byte[] k, byte[] Gx) {
long10
dx=new long10(),
t1=new long10(),
t2=new long10(),
t3=new long10(),
t4=new long10();
long10[]
x=new long10[]{new long10(),new long10()},
z=new long10[]{new long10(),new long10()};
int i, j;
/* unpack the base */
if (Gx!=null)
unpack(dx, Gx);
else
set(dx, 9);
/* 0G = point-at-infinity */
set(x[0], 1);
set(z[0], 0);
/* 1G = G */
cpy(x[1], dx);
set(z[1], 1);
for (i = 32; i--!=0; ) {
if (i==0) {
i=0;
}
for (j = 8; j--!=0; ) {
/* swap arguments depending on bit */
int bit1 = (k[i] & 0xFF) >> j & 1;
int bit0 = ~(k[i] & 0xFF) >> j & 1;
long10 ax = x[bit0];
long10 az = z[bit0];
long10 bx = x[bit1];
long10 bz = z[bit1];
/* a' = a + b */
/* b' = 2 b */
mont_prep(t1, t2, ax, az);
mont_prep(t3, t4, bx, bz);
mont_add(t1, t2, t3, t4, ax, az, dx);
mont_dbl(t1, t2, t3, t4, bx, bz);
}
}
recip(t1, z[0], 0);
mul(dx, x[0], t1);
pack(dx, Px);
/* calculate s such that s abs(P) = G .. assumes G is std base point */
if (s!=null) {
x_to_y2(t2, t1, dx); /* t1 = Py^2 */
recip(t3, z[1], 0); /* where Q=P+G ... */
mul(t2, x[1], t3); /* t2 = Qx */
add(t2, t2, dx); /* t2 = Qx + Px */
t2._0 += 9 + 486662; /* t2 = Qx + Px + Gx + 486662 */
dx._0 -= 9; /* dx = Px - Gx */
sqr(t3, dx); /* t3 = (Px - Gx)^2 */
mul(dx, t2, t3); /* dx = t2 (Px - Gx)^2 */
sub(dx, dx, t1); /* dx = t2 (Px - Gx)^2 - Py^2 */
dx._0 -= 39420360; /* dx = t2 (Px - Gx)^2 - Py^2 - Gy^2 */
mul(t1, dx, BASE_R2Y); /* t1 = -Py */
if (is_negative(t1)!=0) /* sign is 1, so just copy */
cpy32(s, k);
else /* sign is -1, so negate */
mula_small(s, ORDER_TIMES_8, 0, k, 32, -1);
/* reduce s mod q
* (is this needed? do it just in case, it's fast anyway) */
//divmod((dstptr) t1, s, 32, order25519, 32);
/* take reciprocal of s mod q */
byte[] temp1=new byte[32];
byte[] temp2=new byte[64];
byte[] temp3=new byte[64];
cpy32(temp1, ORDER);
cpy32(s, egcd32(temp2, temp3, s, temp1));
if ((s[31] & 0x80)!=0)
mula_small(s, s, 0, ORDER, 32, 1);
}
}
/* smallest multiple of the order that's >= 2^255 */
private static final byte[] ORDER_TIMES_8 = {
(byte)104, (byte)159, (byte)174, (byte)231,
(byte)210, (byte)24, (byte)147, (byte)192,
(byte)178, (byte)230, (byte)188, (byte)23,
(byte)245, (byte)206, (byte)247, (byte)166,
(byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)0,
(byte)0, (byte)0, (byte)0, (byte)128
};
/* constants 2Gy and 1/(2Gy) */
private static final long10 BASE_2Y = new long10(
39999547, 18689728, 59995525, 1648697, 57546132,
24010086, 19059592, 5425144, 63499247, 16420658
);
private static final long10 BASE_R2Y = new long10(
5744, 8160848, 4790893, 13779497, 35730846,
12541209, 49101323, 30047407, 40071253, 6226132
);
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2010, 2011 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.connection.channel.direct.Session.Command;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/** This examples demonstrates how a remote command can be executed. */
public class Exec {
public static void main(String... args)
throws IOException {
final SSHClient ssh = new SSHClient();
ssh.loadKnownHosts();
ssh.connect("localhost");
try {
ssh.authPublickey(System.getProperty("user.name"));
final Session session = ssh.startSession();
try {
final Command cmd = session.exec("ping -c 1 google.com");
System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
cmd.join(5, TimeUnit.SECONDS);
System.out.println("\n** exit status: " + cmd.getExitStatus());
} finally {
session.close();
}
} finally {
ssh.disconnect();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,23 @@ import java.util.Collection;
public class ErrorDeliveryUtil {
public static void alertPromises(Throwable x, Promise... promises) {
for (Promise p : promises)
public static void alertPromises(Throwable x, Promise<?, ?>... promises) {
for (Promise<?, ?> p : promises)
p.deliverError(x);
}
public static void alertPromises(Throwable x, Collection<? extends Promise> promises) {
for (Promise p : promises)
public static void alertPromises(Throwable x, Collection<? extends Promise<?, ?>> promises) {
for (Promise<?, ?> p : promises)
p.deliverError(x);
}
public static void alertEvents(Throwable x, Event... events) {
for (Event e : events)
public static void alertEvents(Throwable x, Event<?>... events) {
for (Event<?> e : events)
e.deliverError(x);
}
public static void alertEvents(Throwable x, Collection<? extends Event> events) {
for (Event e : events)
public static void alertEvents(Throwable x, Collection<? extends Event<?>> events) {
for (Event<?> e : events)
e.deliverError(x);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package net.schmizz.concurrent;
import net.schmizz.sshj.common.LoggerFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@@ -42,8 +44,8 @@ public class Event<T extends Throwable> {
* @param name name of this event
* @param chainer {@link ExceptionChainer} that will be used for chaining exceptions
*/
public Event(String name, ExceptionChainer<T> chainer) {
promise = new Promise<Object, T>(name, chainer);
public Event(String name, ExceptionChainer<T> chainer, LoggerFactory loggerFactory) {
promise = new Promise<Object, T>(name, chainer, loggerFactory);
}
/**
@@ -53,8 +55,8 @@ public class Event<T extends Throwable> {
* @param chainer {@link ExceptionChainer} that will be used for chaining exceptions
* @param lock lock to use
*/
public Event(String name, ExceptionChainer<T> chainer, ReentrantLock lock) {
promise = new Promise<Object, T>(name, chainer, lock);
public Event(String name, ExceptionChainer<T> chainer, ReentrantLock lock, LoggerFactory loggerFactory) {
promise = new Promise<Object, T>(name, chainer, lock, loggerFactory);
}
/** Sets this event to be {@code true}. Short for {@code set(true)}. */
@@ -143,4 +145,4 @@ public class Event<T extends Throwable> {
return promise.toString();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ package net.schmizz.concurrent;
* if (t instanceof SomeException)
* return (SomeException) t;
* else
* return new SomeExcepion(t);
* return new SomeException(t);
* }
* };
* </pre>
@@ -37,4 +37,4 @@ public interface ExceptionChainer<Z extends Throwable> {
Z chain(Throwable t);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
*/
package net.schmizz.concurrent;
import net.schmizz.sshj.common.LoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -32,8 +32,7 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class Promise<V, T extends Throwable> {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Logger log;
private final String name;
private final ExceptionChainer<T> chainer;
private final ReentrantLock lock;
@@ -49,8 +48,8 @@ public class Promise<V, T extends Throwable> {
* @param name name of this promise
* @param chainer {@link ExceptionChainer} that will be used for chaining exceptions
*/
public Promise(String name, ExceptionChainer<T> chainer) {
this(name, chainer, null);
public Promise(String name, ExceptionChainer<T> chainer, LoggerFactory loggerFactory) {
this(name, chainer, null, loggerFactory);
}
/**
@@ -60,10 +59,11 @@ public class Promise<V, T extends Throwable> {
* @param chainer {@link ExceptionChainer} that will be used for chaining exceptions
* @param lock lock to use
*/
public Promise(String name, ExceptionChainer<T> chainer, ReentrantLock lock) {
public Promise(String name, ExceptionChainer<T> chainer, ReentrantLock lock, LoggerFactory loggerFactory) {
this.name = name;
this.chainer = chainer;
this.lock = lock == null ? new ReentrantLock() : lock;
this.log = loggerFactory.getLogger(getClass());
this.cond = this.lock.newCondition();
}
@@ -162,11 +162,14 @@ public class Promise<V, T extends Throwable> {
if (val != null)
return val;
log.debug("Awaiting <<{}>>", name);
while (val == null && pendingEx == null)
if (timeout == 0)
if (timeout == 0) {
while (val == null && pendingEx == null) {
cond.await();
else if (!cond.await(timeout, unit))
}
} else {
if (!cond.await(timeout, unit))
return null;
}
if (pendingEx != null) {
log.error("<<{}>> woke to: {}", name, pendingEx.toString());
throw pendingEx;
@@ -199,6 +202,16 @@ public class Promise<V, T extends Throwable> {
}
}
/** @return whether this promise was fulfilled with either a value or an error. */
public boolean isFulfilled() {
lock.lock();
try {
return pendingEx != null || val != null;
} finally {
lock.unlock();
}
}
/** @return whether this promise has threads waiting on it. */
public boolean hasWaiters() {
lock.lock();

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