mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-09 00:18:39 +03:00
Compare commits
201 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fddc943565 | ||
|
|
ae834134d0 | ||
|
|
bc41908694 | ||
|
|
bf1a855647 | ||
|
|
cd3b0a5bd6 | ||
|
|
b01eccda4a | ||
|
|
4c9ebc306d | ||
|
|
c3f75cda19 | ||
|
|
1f0e2b1e69 | ||
|
|
8e55e50fd9 | ||
|
|
eb8b7b51ca | ||
|
|
a2cccd5cef | ||
|
|
50403483da | ||
|
|
3c230a0fc4 | ||
|
|
4f152749ce | ||
|
|
e0df6a5fb5 | ||
|
|
f36c011844 | ||
|
|
94113eb6f5 | ||
|
|
0532f27a78 | ||
|
|
bd67135ffa | ||
|
|
ca49ca324f | ||
|
|
ac2ffbc367 | ||
|
|
dbb0eb0238 | ||
|
|
347e6ad655 | ||
|
|
2622833831 | ||
|
|
c0487c9ee5 | ||
|
|
3372db75b5 | ||
|
|
db75bad25c | ||
|
|
a73776ad40 | ||
|
|
237c7d18b6 | ||
|
|
b7c8cda851 | ||
|
|
2b6fedc939 | ||
|
|
51e1ff24e4 | ||
|
|
05efcb4889 | ||
|
|
d456612d25 | ||
|
|
6feed72251 | ||
|
|
67e44241d0 | ||
|
|
a2a5923767 | ||
|
|
bdf9ab7452 | ||
|
|
afdfa91eb7 | ||
|
|
29a6cf6f79 | ||
|
|
eece80cf48 | ||
|
|
7973cb1ff6 | ||
|
|
75c0ae9a83 | ||
|
|
f2314e74ed | ||
|
|
e041e3e1e3 | ||
|
|
47df71c836 | ||
|
|
e24ed6ee7b | ||
|
|
10f8645ecd | ||
|
|
d520585a09 | ||
|
|
28a11b0b45 | ||
|
|
a335185827 | ||
|
|
74a4012023 | ||
|
|
c98ad22a7a | ||
|
|
1c749da957 | ||
|
|
5d81e87bce | ||
|
|
d18e9d9961 | ||
|
|
84990ada08 | ||
|
|
9c424f9431 | ||
|
|
dec00efcaa | ||
|
|
742553912c | ||
|
|
e81fdb8d8b | ||
|
|
782ff9b83e | ||
|
|
84d15f4cf5 | ||
|
|
1ebcbb07ba | ||
|
|
9982e5c30e | ||
|
|
3f340d6927 | ||
|
|
b8eec64a37 | ||
|
|
314d9d01cf | ||
|
|
c526f8e3de | ||
|
|
9529c30105 | ||
|
|
6a476858d1 | ||
|
|
6bfb268c11 | ||
|
|
e334525da5 | ||
|
|
8776500fa0 | ||
|
|
a747db88ed | ||
|
|
97065264de | ||
|
|
7c26ac669a | ||
|
|
1c5b462206 | ||
|
|
4cb9610cdd | ||
|
|
b9d0a03cb3 | ||
|
|
4adc83b9df | ||
|
|
14edb33fa9 | ||
|
|
8e74330b0b | ||
|
|
5217d34198 | ||
|
|
d3d019c1c2 | ||
|
|
49185b044d | ||
|
|
a18d623f44 | ||
|
|
6855873ffd | ||
|
|
2ca8d8b19e | ||
|
|
da32b145df | ||
|
|
8ea6bb4a66 | ||
|
|
6cf767528a | ||
|
|
b123a6ae30 | ||
|
|
4250c61e45 | ||
|
|
ace09fa8c8 | ||
|
|
8398b6e3c3 | ||
|
|
3c1e0c1629 | ||
|
|
e6c7c17664 | ||
|
|
1e061aef25 | ||
|
|
66b772bac1 | ||
|
|
fc535a5e76 | ||
|
|
c7373f05cc | ||
|
|
3ebd2eb363 | ||
|
|
8638091517 | ||
|
|
5fc08a3fc8 | ||
|
|
92df7c6924 | ||
|
|
8c0967ca93 | ||
|
|
cb5b7f0943 | ||
|
|
de2ede05e7 | ||
|
|
4a90f99c5f | ||
|
|
e348f698e6 | ||
|
|
d59efaa5f9 | ||
|
|
83c5f2f815 | ||
|
|
b17d3fe867 | ||
|
|
3cefda5bd3 | ||
|
|
18f364a283 | ||
|
|
d68032a9b8 | ||
|
|
c73ba8bfa7 | ||
|
|
7bbfd40627 | ||
|
|
7ae84be548 | ||
|
|
f2793d1acf | ||
|
|
bca5883422 | ||
|
|
3e54e2c955 | ||
|
|
a7802ddcde | ||
|
|
a7872b394b | ||
|
|
3ade3977ef | ||
|
|
efb2c547f9 | ||
|
|
703a0df09d | ||
|
|
73de5b7b08 | ||
|
|
665cbf078a | ||
|
|
b3ea908996 | ||
|
|
11da49a4e7 | ||
|
|
5b1f9f2a7d | ||
|
|
268de458e3 | ||
|
|
834f0f22cd | ||
|
|
1daf456cbe | ||
|
|
ea11d34ac8 | ||
|
|
e961dc1b27 | ||
|
|
25fbff245f | ||
|
|
333c23e167 | ||
|
|
cf32842d0d | ||
|
|
70720de71b | ||
|
|
44e1ce1358 | ||
|
|
921f41f9de | ||
|
|
34c4be848a | ||
|
|
d10e303b1a | ||
|
|
46791c87f5 | ||
|
|
af0d873e5b | ||
|
|
d37b54b1fd | ||
|
|
c4408ac6dd | ||
|
|
ebbf440304 | ||
|
|
ef5a54d33f | ||
|
|
66514836c8 | ||
|
|
e943d80049 | ||
|
|
81931f3b7a | ||
|
|
b8bfc19ecf | ||
|
|
0cb62c6d44 | ||
|
|
0ccc57b5af | ||
|
|
4806b1d6c7 | ||
|
|
ecc1d06dc2 | ||
|
|
d95586508d | ||
|
|
5ee2f0a417 | ||
|
|
2a7278d239 | ||
|
|
0875417dde | ||
|
|
0a3ad4f68f | ||
|
|
fe58ecdee5 | ||
|
|
264e10b40c | ||
|
|
a00015969b | ||
|
|
d6c22fef55 | ||
|
|
9886facf42 | ||
|
|
01be48508d | ||
|
|
bdc541c959 | ||
|
|
f2ebbe288f | ||
|
|
9297338195 | ||
|
|
a8d2ea2028 | ||
|
|
f34667521d | ||
|
|
77f5d7fdb8 | ||
|
|
08d0e59b6b | ||
|
|
5c540b6889 | ||
|
|
baa8c8e995 | ||
|
|
f354fd6661 | ||
|
|
93f1543af8 | ||
|
|
63424657da | ||
|
|
131e85c4d0 | ||
|
|
587684c6a8 | ||
|
|
66f67db21b | ||
|
|
3356f533d0 | ||
|
|
97535bbcae | ||
|
|
896b0ea288 | ||
|
|
60d54fa5de | ||
|
|
06e421e752 | ||
|
|
b5796f5e74 | ||
|
|
0f7355a277 | ||
|
|
466ff99e1c | ||
|
|
1f992c3fae | ||
|
|
df6019accc | ||
|
|
fdb891b842 | ||
|
|
5159a799df | ||
|
|
78e5a2e30e | ||
|
|
db22f08f97 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.bat text eol=crlf
|
||||||
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# IntelliJ IDEA
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# Eclipe
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
# Output dirs
|
||||||
|
target/
|
||||||
|
build/
|
||||||
|
.gradle/
|
||||||
|
|
||||||
|
|
||||||
2
.travis.yml
Normal file
2
.travis.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
language: java
|
||||||
|
sudo: false
|
||||||
12
CONTRIBUTORS
12
CONTRIBUTORS
@@ -1,11 +1 @@
|
|||||||
Shikhar Bhushan <shikhar@schmizz.net>
|
git log --format='%aN <%aE>' | awk '{arr[$0]++} END{for (i in arr){print arr[i], i;}}' | sort -rn | cut -d\ -f2-
|
||||||
Cyril Ledru <cledru@keynectis.net>
|
|
||||||
Incendium <incendium@gmail.com>
|
|
||||||
Philip Langdale <philipl@cloudera.com>
|
|
||||||
Adar Dembo <adar@cloudera.com>
|
|
||||||
Ioannis Canellos <iocanel@gmail.com>
|
|
||||||
Neil Prosser <neil.prosser@gmail.com>
|
|
||||||
hierynomus <jeroen@hierynomus.com>
|
|
||||||
Ryan Tenney <ryan@10e.us>
|
|
||||||
Aled Sage <aled.sage@gmail.com>
|
|
||||||
Urs Reupke <ur@idos.de>
|
|
||||||
|
|||||||
13
LICENSE_HEADER
Normal file
13
LICENSE_HEADER
Normal 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.
|
||||||
142
README.adoc
Normal file
142
README.adoc
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
= sshj - SSHv2 library for Java
|
||||||
|
Jeroen van Erp
|
||||||
|
:sshj_groupid: com.hierynomus
|
||||||
|
:sshj_version: 0.15.0
|
||||||
|
:source-highlighter: pygments
|
||||||
|
|
||||||
|
image::https://travis-ci.org/hierynomus/sshj.svg?branch=master[]
|
||||||
|
|
||||||
|
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 Overthere 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}`, `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-group-exchange-sha1`, `diffie-hellman-group-exchange-sha256`,
|
||||||
|
`ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `curve25519-sha256@libssh.org`
|
||||||
|
|
||||||
|
signatures::
|
||||||
|
`ssh-rsa`, `ssh-dss`, `ecdsa-sha2-nistp256`, `ssh-ed25519`
|
||||||
|
|
||||||
|
mac::
|
||||||
|
`hmac-md5`, `hmac-md5-96`, `hmac-sha1`, `hmac-sha1-96`, `hmac-sha2-256`, `hmac-sha2-512`
|
||||||
|
|
||||||
|
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!)
|
||||||
|
|
||||||
|
== 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
|
||||||
|
|
||||||
|
== Discussion
|
||||||
|
Google Group: http://groups.google.com/group/sshj-users
|
||||||
|
|
||||||
|
== Contributing
|
||||||
|
Fork away!
|
||||||
|
|
||||||
|
== Release history
|
||||||
|
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]
|
||||||
62
README.rst
62
README.rst
@@ -1,62 +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.
|
|
||||||
|
|
||||||
Reporting bugs
|
|
||||||
----------------
|
|
||||||
|
|
||||||
`Issue tracker <https://github.com/shikhar/sshj/issues>`_
|
|
||||||
|
|
||||||
Discussion
|
|
||||||
------------
|
|
||||||
|
|
||||||
`Google Group <http://groups.google.com/group/sshj-users>`_
|
|
||||||
|
|
||||||
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
177
build-publishing.gradle
Normal 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.50"
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
198
build.gradle
Normal file
198
build.gradle
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
plugins {
|
||||||
|
id "java"
|
||||||
|
id "maven"
|
||||||
|
id "idea"
|
||||||
|
id "signing"
|
||||||
|
id "osgi"
|
||||||
|
id "org.ajoberstar.release-opinion" version "1.4.0-rc.1"
|
||||||
|
id "com.github.hierynomus.license" version "0.12.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.hierynomus"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = 1.7
|
||||||
|
targetCompatibility = 1.7
|
||||||
|
|
||||||
|
configurations.compile.transitive = false
|
||||||
|
|
||||||
|
idea {
|
||||||
|
module {
|
||||||
|
downloadJavadoc = true
|
||||||
|
downloadSources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
license {
|
||||||
|
mapping {
|
||||||
|
java = 'SLASHSTAR_STYLE'
|
||||||
|
}
|
||||||
|
header rootProject.file('LICENSE_HEADER')
|
||||||
|
strictCheck true
|
||||||
|
}
|
||||||
|
|
||||||
|
release {
|
||||||
|
grgit = org.ajoberstar.grgit.Grgit.open(project.projectDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
testLogging {
|
||||||
|
exceptionFormat = 'full'
|
||||||
|
}
|
||||||
|
include "**/*Test.*"
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def bouncycastleVersion = "1.51"
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
compile "net.vrallev.ecc:ecc-25519-java:1.0.1"
|
||||||
|
|
||||||
|
testCompile "junit:junit:4.11"
|
||||||
|
testCompile "org.mockito:mockito-core:1.9.5"
|
||||||
|
testCompile "org.apache.sshd:sshd-core:1.1.0"
|
||||||
|
testRuntime "ch.qos.logback:logback-classic:1.1.2"
|
||||||
|
testCompile 'org.glassfish.grizzly:grizzly-http-server:2.3.17'
|
||||||
|
testCompile 'org.apache.httpcomponents:httpclient:4.5.2'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
manifest {
|
||||||
|
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", "javax.crypto*"
|
||||||
|
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*"
|
||||||
|
instruction "Import-Package", "*"
|
||||||
|
instruction "Export-Package", "net.schmizz.*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task javadocJar(type: Jar) {
|
||||||
|
classifier = 'javadoc'
|
||||||
|
from javadoc
|
||||||
|
}
|
||||||
|
|
||||||
|
task sourcesJar(type: Jar) {
|
||||||
|
classifier = 'sources'
|
||||||
|
from sourceSets.main.allSource
|
||||||
|
manifest = project.tasks.jar.manifest
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
archives javadocJar, sourcesJar
|
||||||
|
}
|
||||||
|
|
||||||
|
signing {
|
||||||
|
required { !version.toString().contains("SNAPSHOT") && gradle.taskGraph.hasTask("uploadArchives") }
|
||||||
|
sign configurations.archives
|
||||||
|
}
|
||||||
|
|
||||||
|
// This disables the pedantic doclint feature of JDK8
|
||||||
|
if (JavaVersion.current().isJava8Compatible()) {
|
||||||
|
tasks.withType(Javadoc) {
|
||||||
|
options.addStringOption('Xdoclint:none', '-quiet')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadArchives {
|
||||||
|
if (project.hasProperty('sonatypeUsername')) {
|
||||||
|
repositories.mavenDeployer {
|
||||||
|
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
||||||
|
|
||||||
|
configuration = configurations.archives
|
||||||
|
|
||||||
|
repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') {
|
||||||
|
authentication(userName: sonatypeUsername, password: sonatypePassword)
|
||||||
|
}
|
||||||
|
snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') {
|
||||||
|
authentication(userName: sonatypeUsername, password: sonatypePassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
pom.project {
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.release.dependsOn 'build', 'uploadArchives'
|
||||||
101
examples/pom.xml
Normal file
101
examples/pom.xml
Normal 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.14.0</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.15.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>
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.common.IOUtils;
|
import net.schmizz.sshj.common.IOUtils;
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package net.schmizz.sshj.examples;
|
||||||
|
|
||||||
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
|
import net.schmizz.sshj.DefaultConfig;
|
||||||
|
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 net.schmizz.sshj.transport.verification.PromiscuousVerifier;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/** 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder;
|
import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder;
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.connection.channel.forwarded.RemotePortForwarder.Forward;
|
import net.schmizz.sshj.connection.channel.forwarded.RemotePortForwarder.Forward;
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.common.StreamCopier;
|
import net.schmizz.sshj.common.StreamCopier;
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||||
@@ -37,4 +22,4 @@ public class SCPDownload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||||
@@ -42,4 +27,4 @@ public class SCPUpload {
|
|||||||
ssh.disconnect();
|
ssh.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.sftp.SFTPClient;
|
import net.schmizz.sshj.sftp.SFTPClient;
|
||||||
@@ -42,4 +27,4 @@ public class SFTPDownload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.sftp.SFTPClient;
|
import net.schmizz.sshj.sftp.SFTPClient;
|
||||||
@@ -44,4 +29,4 @@ public class SFTPUpload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,4 @@
|
|||||||
/*
|
package net.schmizz.sshj.examples;
|
||||||
* Copyright 2010-2012 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.SSHClient;
|
||||||
import net.schmizz.sshj.common.StreamCopier;
|
import net.schmizz.sshj.common.StreamCopier;
|
||||||
@@ -67,4 +52,4 @@ public class X11 {
|
|||||||
ssh.disconnect();
|
ssh.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Fri Mar 18 11:26:35 CET 2016
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-all.zip
|
||||||
164
gradlew
vendored
Executable file
164
gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# 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
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
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" ] ; 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, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# 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=$((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
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||||
90
gradlew.bat
vendored
Normal file
90
gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
@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
|
||||||
|
|
||||||
|
@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=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@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 Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_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=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
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
257
pom.xml
@@ -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.9.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>
|
|
||||||
<tag>v0.9.0</tag>
|
|
||||||
</scm>
|
|
||||||
|
|
||||||
<licenses>
|
|
||||||
<license>
|
|
||||||
<name>Apache 2</name>
|
|
||||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
|
||||||
<distribution>repo</distribution>
|
|
||||||
</license>
|
|
||||||
</licenses>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.sonatype.oss</groupId>
|
|
||||||
<artifactId>oss-parent</artifactId>
|
|
||||||
<version>7</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
<version>1.7.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcpkix-jdk15on</artifactId>
|
|
||||||
<version>1.49</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
|
||||||
<version>1.49</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jcraft</groupId>
|
|
||||||
<artifactId>jzlib</artifactId>
|
|
||||||
<version>1.1.2</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.sshd</groupId>
|
|
||||||
<artifactId>sshd-core</artifactId>
|
|
||||||
<version>0.8.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-core</artifactId>
|
|
||||||
<version>1.0.13</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.11</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<version>1.0.13</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-all</artifactId>
|
|
||||||
<version>1.9.5</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>3.1</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.4.1</version>
|
|
||||||
<configuration>
|
|
||||||
<mavenExecutorId>forked-path</mavenExecutorId>
|
|
||||||
</configuration>
|
|
||||||
</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.9.1</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>
|
|
||||||
<version>2.4.0</version>
|
|
||||||
<extensions>true</extensions>
|
|
||||||
<configuration>
|
|
||||||
<instructions>
|
|
||||||
<Import-Package>
|
|
||||||
!net.schmizz.*,
|
|
||||||
javax.crypto*,
|
|
||||||
com.jcraft.jzlib*;version="[1.1,2)",
|
|
||||||
org.slf4j*;version="[1.7,5)",
|
|
||||||
org.bouncycastle*,
|
|
||||||
*
|
|
||||||
</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-jdk15on</artifactId>
|
|
||||||
<version>1.49</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>1.0.13</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<version>1.0.13</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.4</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
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "sshj"
|
||||||
@@ -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
13
src/etc/license-header
Normal 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.
|
||||||
26
src/main/java/com/hierynomus/sshj/backport/JavaVersion.java
Normal file
26
src/main/java/com/hierynomus/sshj/backport/JavaVersion.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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.backport;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
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(Charset.forName("UTF-8")));
|
||||||
|
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, "UTF-8");
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/main/java/com/hierynomus/sshj/backport/Sockets.java
Normal file
41
src/main/java/com/hierynomus/sshj/backport/Sockets.java
Normal 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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
src/main/java/com/hierynomus/sshj/secg/SecgUtils.java
Normal file
70
src/main/java/com/hierynomus/sshj/secg/SecgUtils.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public class Ed25519PublicKey extends EdDSAPublicKey {
|
||||||
|
|
||||||
|
public Ed25519PublicKey(EdDSAPublicKeySpec spec) {
|
||||||
|
super(spec);
|
||||||
|
|
||||||
|
EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName("ed25519-sha-512");
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
109
src/main/java/com/hierynomus/sshj/signature/SignatureEdDSA.java
Normal file
109
src/main/java/com/hierynomus/sshj/signature/SignatureEdDSA.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* 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.Buffer;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.common.SSHRuntimeException;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
|
||||||
|
import java.security.*;
|
||||||
|
|
||||||
|
public class SignatureEdDSA implements Signature {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final EdDSAEngine engine;
|
||||||
|
|
||||||
|
protected SignatureEdDSA() {
|
||||||
|
try {
|
||||||
|
engine = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new SSHRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(PublicKey pubkey, PrivateKey prvkey) {
|
||||||
|
try {
|
||||||
|
if (pubkey != null) {
|
||||||
|
engine.initVerify(pubkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prvkey != null) {
|
||||||
|
engine.initSign(prvkey);
|
||||||
|
}
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
throw new SSHRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(byte[] H) {
|
||||||
|
update(H, 0, H.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(byte[] H, int off, int len) {
|
||||||
|
try {
|
||||||
|
engine.update(H, off, len);
|
||||||
|
} catch (SignatureException e) {
|
||||||
|
throw new SSHRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] sign() {
|
||||||
|
try {
|
||||||
|
return engine.sign();
|
||||||
|
} catch (SignatureException e) {
|
||||||
|
throw new SSHRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] encode(byte[] signature) {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verify(byte[] sig) {
|
||||||
|
try {
|
||||||
|
Buffer.PlainBuffer plainBuffer = new Buffer.PlainBuffer(sig);
|
||||||
|
String algo = plainBuffer.readString();
|
||||||
|
if (!"ssh-ed25519".equals(algo)) {
|
||||||
|
throw new SSHRuntimeException("Expected 'ssh-ed25519' key algorithm, but was: " + algo);
|
||||||
|
}
|
||||||
|
byte[] bytes = plainBuffer.readBytes();
|
||||||
|
return engine.verify(bytes);
|
||||||
|
} catch (SignatureException e) {
|
||||||
|
throw new SSHRuntimeException(e);
|
||||||
|
} catch (Buffer.BufferException e) {
|
||||||
|
throw new SSHRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* - https://tools.ietf.org/html/rfc4344#section-3.1
|
||||||
|
* - https://tools.ietf.org/html/rfc4253#section-6.3
|
||||||
|
*
|
||||||
|
* TODO: https://tools.ietf.org/html/rfc5647
|
||||||
|
*
|
||||||
|
* Some of the Ciphers are still implemented in net.schmizz.sshj.transport.cipher.*. These are scheduled to be migrated to here.
|
||||||
|
*/
|
||||||
|
public class BlockCiphers {
|
||||||
|
|
||||||
|
public static final String COUNTER_MODE = "CTR";
|
||||||
|
public static final String CIPHER_BLOCK_CHAINING_MODE = "CBC";
|
||||||
|
|
||||||
|
public static Factory BlowfishCTR() {
|
||||||
|
return new Factory(8, 256, "blowfish-ctr", "Blowfish", COUNTER_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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.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
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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.transport.cipher;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.transport.cipher.BaseCipher;
|
||||||
|
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
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), new SecureRandom());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -143,4 +143,4 @@ public class Event<T extends Throwable> {
|
|||||||
return promise.toString();
|
return promise.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -37,4 +37,4 @@ public interface ExceptionChainer<Z extends Throwable> {
|
|||||||
|
|
||||||
Z chain(Throwable t);
|
Z chain(Throwable t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -202,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. */
|
/** @return whether this promise has threads waiting on it. */
|
||||||
public boolean hasWaiters() {
|
public boolean hasWaiters() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
|||||||
34
src/main/java/net/schmizz/keepalive/Heartbeater.java
Normal file
34
src/main/java/net/schmizz/keepalive/Heartbeater.java
Normal 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 net.schmizz.keepalive;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.common.Message;
|
||||||
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
|
import net.schmizz.sshj.connection.ConnectionImpl;
|
||||||
|
import net.schmizz.sshj.transport.TransportException;
|
||||||
|
|
||||||
|
final class Heartbeater
|
||||||
|
extends KeepAlive {
|
||||||
|
|
||||||
|
Heartbeater(ConnectionImpl conn) {
|
||||||
|
super(conn, "heartbeater");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doKeepAlive() throws TransportException {
|
||||||
|
conn.getTransport().write(new SSHPacket(Message.IGNORE));
|
||||||
|
}
|
||||||
|
}
|
||||||
81
src/main/java/net/schmizz/keepalive/KeepAlive.java
Normal file
81
src/main/java/net/schmizz/keepalive/KeepAlive.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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 net.schmizz.keepalive;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.connection.ConnectionException;
|
||||||
|
import net.schmizz.sshj.connection.ConnectionImpl;
|
||||||
|
import net.schmizz.sshj.transport.TransportException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public abstract class KeepAlive extends Thread {
|
||||||
|
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
protected final ConnectionImpl conn;
|
||||||
|
|
||||||
|
protected int keepAliveInterval = 0;
|
||||||
|
|
||||||
|
protected KeepAlive(ConnectionImpl conn, String name) {
|
||||||
|
this.conn = conn;
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int getKeepAliveInterval() {
|
||||||
|
return keepAliveInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setKeepAliveInterval(int keepAliveInterval) {
|
||||||
|
this.keepAliveInterval = keepAliveInterval;
|
||||||
|
if (keepAliveInterval > 0 && getState() == State.NEW) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized protected int getPositiveInterval()
|
||||||
|
throws InterruptedException {
|
||||||
|
while (keepAliveInterval <= 0) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
return keepAliveInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
log.debug("Starting {}, sending keep-alive every {} seconds", getClass().getSimpleName(), keepAliveInterval);
|
||||||
|
try {
|
||||||
|
while (!isInterrupted()) {
|
||||||
|
final int hi = getPositiveInterval();
|
||||||
|
if (conn.getTransport().isRunning()) {
|
||||||
|
log.debug("Sending keep-alive since {} seconds elapsed", hi);
|
||||||
|
doKeepAlive();
|
||||||
|
}
|
||||||
|
Thread.sleep(hi * 1000);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If we weren't interrupted, kill the transport, then this exception was unexpected.
|
||||||
|
// Else we're in shutdown-mode already, so don't forcibly kill the transport.
|
||||||
|
if (!isInterrupted()) {
|
||||||
|
conn.getTransport().die(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Stopping {}", getClass().getSimpleName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void doKeepAlive() throws TransportException, ConnectionException;
|
||||||
|
}
|
||||||
39
src/main/java/net/schmizz/keepalive/KeepAliveProvider.java
Normal file
39
src/main/java/net/schmizz/keepalive/KeepAliveProvider.java
Normal 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 net.schmizz.keepalive;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.connection.ConnectionImpl;
|
||||||
|
|
||||||
|
public abstract class KeepAliveProvider {
|
||||||
|
|
||||||
|
public static final KeepAliveProvider HEARTBEAT = new KeepAliveProvider() {
|
||||||
|
@Override
|
||||||
|
public KeepAlive provide(ConnectionImpl connection) {
|
||||||
|
return new Heartbeater(connection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final KeepAliveProvider KEEP_ALIVE = new KeepAliveProvider() {
|
||||||
|
@Override
|
||||||
|
public KeepAlive provide(ConnectionImpl connection) {
|
||||||
|
return new KeepAliveRunner(connection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract KeepAlive provide(ConnectionImpl connection);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
76
src/main/java/net/schmizz/keepalive/KeepAliveRunner.java
Normal file
76
src/main/java/net/schmizz/keepalive/KeepAliveRunner.java
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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 net.schmizz.keepalive;
|
||||||
|
|
||||||
|
import net.schmizz.concurrent.Promise;
|
||||||
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
|
import net.schmizz.sshj.connection.ConnectionException;
|
||||||
|
import net.schmizz.sshj.connection.ConnectionImpl;
|
||||||
|
import net.schmizz.sshj.transport.TransportException;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static net.schmizz.sshj.common.DisconnectReason.CONNECTION_LOST;
|
||||||
|
|
||||||
|
public class KeepAliveRunner extends KeepAlive {
|
||||||
|
|
||||||
|
/** The max number of keep-alives that should be unanswered before killing the connection. */
|
||||||
|
private int maxAliveCount = 5;
|
||||||
|
|
||||||
|
/** The queue of promises. */
|
||||||
|
private final Queue<Promise<SSHPacket, ConnectionException>> queue =
|
||||||
|
new LinkedList<Promise<SSHPacket, ConnectionException>>();
|
||||||
|
|
||||||
|
KeepAliveRunner(ConnectionImpl conn) {
|
||||||
|
super(conn, "keep-alive");
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized public int getMaxAliveCount() {
|
||||||
|
return maxAliveCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized public void setMaxAliveCount(int maxAliveCount) {
|
||||||
|
this.maxAliveCount = maxAliveCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doKeepAlive() throws TransportException, ConnectionException {
|
||||||
|
// Ensure the service is set... This means that the key exchange is done and the connection is up.
|
||||||
|
if (conn.equals(conn.getTransport().getService())) {
|
||||||
|
emptyQueue(queue);
|
||||||
|
checkMaxReached(queue);
|
||||||
|
queue.add(conn.sendGlobalRequest("keepalive@openssh.com", true, new byte[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkMaxReached(Queue<Promise<SSHPacket, ConnectionException>> queue) throws ConnectionException {
|
||||||
|
if (queue.size() >= maxAliveCount) {
|
||||||
|
throw new ConnectionException(CONNECTION_LOST,
|
||||||
|
format("Did not receive any keep-alive response for %s seconds", maxAliveCount * keepAliveInterval));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void emptyQueue(Queue<Promise<SSHPacket, ConnectionException>> queue) {
|
||||||
|
Promise<SSHPacket, ConnectionException> peek = queue.peek();
|
||||||
|
while (peek != null && peek.isFulfilled()) {
|
||||||
|
log.debug("Received response from server to our keep-alive.");
|
||||||
|
queue.remove();
|
||||||
|
peek = queue.peek();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
import net.schmizz.sshj.signature.Signature;
|
import net.schmizz.sshj.signature.Signature;
|
||||||
import net.schmizz.sshj.transport.cipher.Cipher;
|
import net.schmizz.sshj.transport.cipher.Cipher;
|
||||||
@@ -144,4 +145,34 @@ public interface Config {
|
|||||||
*/
|
*/
|
||||||
void setVersion(String version);
|
void setVersion(String version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The provider that creates the keep-alive implementation of choice.
|
||||||
|
*/
|
||||||
|
KeepAliveProvider getKeepAliveProvider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the provider that provides the keep-alive implementation.
|
||||||
|
* @param keepAliveProvider keep-alive provider
|
||||||
|
*/
|
||||||
|
void setKeepAliveProvider(KeepAliveProvider keepAliveProvider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the client should first wait for a received server ident, before sending the client ident.
|
||||||
|
* <p/>
|
||||||
|
* <stong>NB:</stong> This is non-standard behaviour, and can potentially deadlock if the server also waits on the client ident.
|
||||||
|
*
|
||||||
|
* The default value is set to false.
|
||||||
|
*
|
||||||
|
* @return Whether to first wait for the server ident.
|
||||||
|
*/
|
||||||
|
boolean isWaitForServerIdentBeforeSendingClientIdent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the SSH client should wait for a received server ident, before sending the client ident.
|
||||||
|
* <p/>
|
||||||
|
* <stong>NB:</stong> This is non-standard behaviour, and can potentially deadlock if the server also waits on the client ident.
|
||||||
|
|
||||||
|
* @param waitForServerIdentBeforeSendingClientIdent Whether to wait for the server ident.
|
||||||
|
*/
|
||||||
|
void setWaitForServerIdentBeforeSendingClientIdent(boolean waitForServerIdentBeforeSendingClientIdent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,29 +12,10 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
import net.schmizz.sshj.signature.Signature;
|
import net.schmizz.sshj.signature.Signature;
|
||||||
import net.schmizz.sshj.transport.cipher.Cipher;
|
import net.schmizz.sshj.transport.cipher.Cipher;
|
||||||
@@ -54,6 +35,7 @@ public class ConfigImpl
|
|||||||
private String version;
|
private String version;
|
||||||
|
|
||||||
private Factory<Random> randomFactory;
|
private Factory<Random> randomFactory;
|
||||||
|
private KeepAliveProvider keepAliveProvider;
|
||||||
|
|
||||||
private List<Factory.Named<KeyExchange>> kexFactories;
|
private List<Factory.Named<KeyExchange>> kexFactories;
|
||||||
private List<Factory.Named<Cipher>> cipherFactories;
|
private List<Factory.Named<Cipher>> cipherFactories;
|
||||||
@@ -62,6 +44,8 @@ public class ConfigImpl
|
|||||||
private List<Factory.Named<Signature>> signatureFactories;
|
private List<Factory.Named<Signature>> signatureFactories;
|
||||||
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
||||||
|
|
||||||
|
private boolean waitForServerIdentBeforeSendingClientIdent = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Factory.Named<Cipher>> getCipherFactories() {
|
public List<Factory.Named<Cipher>> getCipherFactories() {
|
||||||
return cipherFactories;
|
return cipherFactories;
|
||||||
@@ -166,4 +150,23 @@ public class ConfigImpl
|
|||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public KeepAliveProvider getKeepAliveProvider() {
|
||||||
|
return keepAliveProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setKeepAliveProvider(KeepAliveProvider keepAliveProvider) {
|
||||||
|
this.keepAliveProvider = keepAliveProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWaitForServerIdentBeforeSendingClientIdent() {
|
||||||
|
return waitForServerIdentBeforeSendingClientIdent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWaitForServerIdentBeforeSendingClientIdent(boolean waitForServerIdentBeforeSendingClientIdent) {
|
||||||
|
this.waitForServerIdentBeforeSendingClientIdent = waitForServerIdentBeforeSendingClientIdent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,33 +12,17 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.signature.SignatureEdDSA;
|
||||||
|
import com.hierynomus.sshj.transport.cipher.BlockCiphers;
|
||||||
|
import com.hierynomus.sshj.transport.cipher.StreamCiphers;
|
||||||
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
import net.schmizz.sshj.common.SecurityUtils;
|
import net.schmizz.sshj.common.SecurityUtils;
|
||||||
import net.schmizz.sshj.signature.SignatureDSA;
|
import net.schmizz.sshj.signature.SignatureDSA;
|
||||||
|
import net.schmizz.sshj.signature.SignatureECDSA;
|
||||||
import net.schmizz.sshj.signature.SignatureRSA;
|
import net.schmizz.sshj.signature.SignatureRSA;
|
||||||
import net.schmizz.sshj.transport.cipher.AES128CBC;
|
import net.schmizz.sshj.transport.cipher.AES128CBC;
|
||||||
import net.schmizz.sshj.transport.cipher.AES128CTR;
|
import net.schmizz.sshj.transport.cipher.AES128CTR;
|
||||||
@@ -50,42 +34,46 @@ import net.schmizz.sshj.transport.cipher.BlowfishCBC;
|
|||||||
import net.schmizz.sshj.transport.cipher.Cipher;
|
import net.schmizz.sshj.transport.cipher.Cipher;
|
||||||
import net.schmizz.sshj.transport.cipher.TripleDESCBC;
|
import net.schmizz.sshj.transport.cipher.TripleDESCBC;
|
||||||
import net.schmizz.sshj.transport.compression.NoneCompression;
|
import net.schmizz.sshj.transport.compression.NoneCompression;
|
||||||
import net.schmizz.sshj.transport.kex.DHG1;
|
import net.schmizz.sshj.transport.kex.*;
|
||||||
import net.schmizz.sshj.transport.kex.DHG14;
|
|
||||||
import net.schmizz.sshj.transport.mac.HMACMD5;
|
import net.schmizz.sshj.transport.mac.HMACMD5;
|
||||||
import net.schmizz.sshj.transport.mac.HMACMD596;
|
import net.schmizz.sshj.transport.mac.HMACMD596;
|
||||||
import net.schmizz.sshj.transport.mac.HMACSHA1;
|
import net.schmizz.sshj.transport.mac.HMACSHA1;
|
||||||
import net.schmizz.sshj.transport.mac.HMACSHA196;
|
import net.schmizz.sshj.transport.mac.HMACSHA196;
|
||||||
|
import net.schmizz.sshj.transport.mac.HMACSHA2256;
|
||||||
|
import net.schmizz.sshj.transport.mac.HMACSHA2512;
|
||||||
import net.schmizz.sshj.transport.random.BouncyCastleRandom;
|
import net.schmizz.sshj.transport.random.BouncyCastleRandom;
|
||||||
import net.schmizz.sshj.transport.random.JCERandom;
|
import net.schmizz.sshj.transport.random.JCERandom;
|
||||||
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
|
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile;
|
import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile;
|
import net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile;
|
||||||
|
import net.schmizz.sshj.userauth.keyprovider.PuTTYKeyFile;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.awt.image.ByteLookupTable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Config} that is initialized as follows. Items marked with an asterisk are added to the config only if
|
* A {@link net.schmizz.sshj.Config} that is initialized as follows. Items marked with an asterisk are added to the config only if
|
||||||
* BouncyCastle is in the classpath.
|
* BouncyCastle is in the classpath.
|
||||||
* <p/>
|
* <p/>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link ConfigImpl#setKeyExchangeFactories Key exchange}: {@link DHG14}*, {@link DHG1}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setKeyExchangeFactories Key exchange}: {@link net.schmizz.sshj.transport.kex.DHG14}*, {@link net.schmizz.sshj.transport.kex.DHG1}</li>
|
||||||
* <li>{@link ConfigImpl#setCipherFactories Ciphers} [1]: {@link AES128CTR}, {@link AES192CTR}, {@link AES256CTR},
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setCipherFactories Ciphers} [1]: {@link net.schmizz.sshj.transport.cipher.AES128CTR}, {@link net.schmizz.sshj.transport.cipher.AES192CTR}, {@link net.schmizz.sshj.transport.cipher.AES256CTR},
|
||||||
* {@link
|
* {@link
|
||||||
* AES128CBC}, {@link AES192CBC}, {@link AES256CBC}, {@link AES192CBC}, {@link TripleDESCBC}, {@link BlowfishCBC}</li>
|
* net.schmizz.sshj.transport.cipher.AES128CBC}, {@link net.schmizz.sshj.transport.cipher.AES192CBC}, {@link net.schmizz.sshj.transport.cipher.AES256CBC}, {@link net.schmizz.sshj.transport.cipher.AES192CBC}, {@link net.schmizz.sshj.transport.cipher.TripleDESCBC}, {@link net.schmizz.sshj.transport.cipher.BlowfishCBC}</li>
|
||||||
* <li>{@link ConfigImpl#setMACFactories MAC}: {@link HMACSHA1}, {@link HMACSHA196}, {@link HMACMD5}, {@link
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setMACFactories MAC}: {@link net.schmizz.sshj.transport.mac.HMACSHA1}, {@link net.schmizz.sshj.transport.mac.HMACSHA196}, {@link net.schmizz.sshj.transport.mac.HMACMD5}, {@link
|
||||||
* HMACMD596}</li>
|
* net.schmizz.sshj.transport.mac.HMACMD596}</li>
|
||||||
* <li>{@link ConfigImpl#setCompressionFactories Compression}: {@link NoneCompression}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setCompressionFactories Compression}: {@link net.schmizz.sshj.transport.compression.NoneCompression}</li>
|
||||||
* <li>{@link ConfigImpl#setSignatureFactories Signature}: {@link SignatureRSA}, {@link SignatureDSA}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setSignatureFactories Signature}: {@link net.schmizz.sshj.signature.SignatureRSA}, {@link net.schmizz.sshj.signature.SignatureDSA}</li>
|
||||||
* <li>{@link ConfigImpl#setRandomFactory PRNG}: {@link BouncyCastleRandom}* or {@link JCERandom}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setRandomFactory PRNG}: {@link net.schmizz.sshj.transport.random.BouncyCastleRandom}* or {@link net.schmizz.sshj.transport.random.JCERandom}</li>
|
||||||
* <li>{@link ConfigImpl#setFileKeyProviderFactories Key file support}: {@link PKCS8KeyFile}*, {@link
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setFileKeyProviderFactories Key file support}: {@link net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile}*, {@link
|
||||||
* OpenSSHKeyFile}*</li>
|
* net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile}*</li>
|
||||||
* <li>{@link ConfigImpl#setVersion Client version}: {@code "NET_3_0"}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setVersion Client version}: {@code "NET_3_0"}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p/>
|
* <p/>
|
||||||
* [1] It is worth noting that Sun's JRE does not have the unlimited cryptography extension enabled by default. This
|
* [1] It is worth noting that Sun's JRE does not have the unlimited cryptography extension enabled by default. This
|
||||||
@@ -96,7 +84,7 @@ public class DefaultConfig
|
|||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
private static final String VERSION = "SSHJ_0_9_0";
|
private static final String VERSION = "SSHJ_0_14_0";
|
||||||
|
|
||||||
public DefaultConfig() {
|
public DefaultConfig() {
|
||||||
setVersion(VERSION);
|
setVersion(VERSION);
|
||||||
@@ -108,13 +96,21 @@ public class DefaultConfig
|
|||||||
initCompressionFactories();
|
initCompressionFactories();
|
||||||
initMACFactories();
|
initMACFactories();
|
||||||
initSignatureFactories();
|
initSignatureFactories();
|
||||||
|
setKeepAliveProvider(KeepAliveProvider.HEARTBEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initKeyExchangeFactories(boolean bouncyCastleRegistered) {
|
protected void initKeyExchangeFactories(boolean bouncyCastleRegistered) {
|
||||||
if (bouncyCastleRegistered)
|
if (bouncyCastleRegistered)
|
||||||
setKeyExchangeFactories(new DHG14.Factory(), new DHG1.Factory());
|
setKeyExchangeFactories(new Curve25519SHA256.Factory(),
|
||||||
|
new DHGexSHA256.Factory(),
|
||||||
|
new ECDHNistP.Factory521(),
|
||||||
|
new ECDHNistP.Factory384(),
|
||||||
|
new ECDHNistP.Factory256(),
|
||||||
|
new DHGexSHA1.Factory(),
|
||||||
|
new DHG14.Factory(),
|
||||||
|
new DHG1.Factory());
|
||||||
else
|
else
|
||||||
setKeyExchangeFactories(new DHG1.Factory());
|
setKeyExchangeFactories(new DHG1.Factory(), new DHGexSHA1.Factory());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initRandomFactory(boolean bouncyCastleRegistered) {
|
protected void initRandomFactory(boolean bouncyCastleRegistered) {
|
||||||
@@ -124,7 +120,7 @@ public class DefaultConfig
|
|||||||
|
|
||||||
protected void initFileKeyProviderFactories(boolean bouncyCastleRegistered) {
|
protected void initFileKeyProviderFactories(boolean bouncyCastleRegistered) {
|
||||||
if (bouncyCastleRegistered) {
|
if (bouncyCastleRegistered) {
|
||||||
setFileKeyProviderFactories(new PKCS8KeyFile.Factory(), new OpenSSHKeyFile.Factory());
|
setFileKeyProviderFactories(new PKCS8KeyFile.Factory(), new OpenSSHKeyFile.Factory(), new PuTTYKeyFile.Factory());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +134,29 @@ public class DefaultConfig
|
|||||||
new AES192CBC.Factory(),
|
new AES192CBC.Factory(),
|
||||||
new AES256CBC.Factory(),
|
new AES256CBC.Factory(),
|
||||||
new TripleDESCBC.Factory(),
|
new TripleDESCBC.Factory(),
|
||||||
new BlowfishCBC.Factory()));
|
new BlowfishCBC.Factory(),
|
||||||
|
BlockCiphers.BlowfishCTR(),
|
||||||
|
BlockCiphers.Cast128CBC(),
|
||||||
|
BlockCiphers.Cast128CTR(),
|
||||||
|
BlockCiphers.IDEACBC(),
|
||||||
|
BlockCiphers.IDEACTR(),
|
||||||
|
BlockCiphers.Serpent128CBC(),
|
||||||
|
BlockCiphers.Serpent128CTR(),
|
||||||
|
BlockCiphers.Serpent192CBC(),
|
||||||
|
BlockCiphers.Serpent192CTR(),
|
||||||
|
BlockCiphers.Serpent256CBC(),
|
||||||
|
BlockCiphers.Serpent256CTR(),
|
||||||
|
BlockCiphers.TripleDESCTR(),
|
||||||
|
BlockCiphers.Twofish128CBC(),
|
||||||
|
BlockCiphers.Twofish128CTR(),
|
||||||
|
BlockCiphers.Twofish192CBC(),
|
||||||
|
BlockCiphers.Twofish192CTR(),
|
||||||
|
BlockCiphers.Twofish256CBC(),
|
||||||
|
BlockCiphers.Twofish256CTR(),
|
||||||
|
BlockCiphers.TwofishCBC(),
|
||||||
|
StreamCiphers.Arcfour(),
|
||||||
|
StreamCiphers.Arcfour128(),
|
||||||
|
StreamCiphers.Arcfour256()));
|
||||||
|
|
||||||
boolean warn = false;
|
boolean warn = false;
|
||||||
// Ref. https://issues.apache.org/jira/browse/SSHD-24
|
// Ref. https://issues.apache.org/jira/browse/SSHD-24
|
||||||
@@ -152,6 +170,7 @@ public class DefaultConfig
|
|||||||
c.init(Cipher.Mode.Encrypt, key, iv);
|
c.init(Cipher.Mode.Encrypt, key, iv);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
warn = true;
|
warn = true;
|
||||||
|
log.warn(e.getCause().getMessage());
|
||||||
i.remove();
|
i.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,15 +178,16 @@ public class DefaultConfig
|
|||||||
log.warn("Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy");
|
log.warn("Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy");
|
||||||
|
|
||||||
setCipherFactories(avail);
|
setCipherFactories(avail);
|
||||||
|
log.debug("Available cipher factories: {}", avail);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initSignatureFactories() {
|
protected void initSignatureFactories() {
|
||||||
setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory());
|
setSignatureFactories(new SignatureECDSA.Factory(), new SignatureRSA.Factory(), new SignatureDSA.Factory(), new SignatureEdDSA.Factory());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initMACFactories() {
|
protected void initMACFactories() {
|
||||||
setMACFactories(new HMACSHA1.Factory(), new HMACSHA196.Factory(), new HMACMD5.Factory(),
|
setMACFactories(new HMACSHA1.Factory(), new HMACSHA196.Factory(), new HMACMD5.Factory(),
|
||||||
new HMACMD596.Factory());
|
new HMACMD596.Factory(), new HMACSHA2256.Factory(), new HMACSHA2512.Factory());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initCompressionFactories() {
|
protected void initCompressionFactories() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
@@ -40,33 +39,41 @@ import net.schmizz.sshj.transport.TransportImpl;
|
|||||||
import net.schmizz.sshj.transport.compression.DelayedZlibCompression;
|
import net.schmizz.sshj.transport.compression.DelayedZlibCompression;
|
||||||
import net.schmizz.sshj.transport.compression.NoneCompression;
|
import net.schmizz.sshj.transport.compression.NoneCompression;
|
||||||
import net.schmizz.sshj.transport.compression.ZlibCompression;
|
import net.schmizz.sshj.transport.compression.ZlibCompression;
|
||||||
|
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||||
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;
|
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;
|
||||||
import net.schmizz.sshj.userauth.UserAuth;
|
import net.schmizz.sshj.userauth.UserAuth;
|
||||||
import net.schmizz.sshj.userauth.UserAuthException;
|
import net.schmizz.sshj.userauth.UserAuthException;
|
||||||
import net.schmizz.sshj.userauth.UserAuthImpl;
|
import net.schmizz.sshj.userauth.UserAuthImpl;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
|
import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
|
||||||
|
import net.schmizz.sshj.userauth.keyprovider.KeyFormat;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.KeyPairWrapper;
|
import net.schmizz.sshj.userauth.keyprovider.KeyPairWrapper;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
|
import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.KeyProviderUtil;
|
import net.schmizz.sshj.userauth.keyprovider.KeyProviderUtil;
|
||||||
|
import net.schmizz.sshj.userauth.method.AuthGssApiWithMic;
|
||||||
import net.schmizz.sshj.userauth.method.AuthKeyboardInteractive;
|
import net.schmizz.sshj.userauth.method.AuthKeyboardInteractive;
|
||||||
import net.schmizz.sshj.userauth.method.AuthMethod;
|
import net.schmizz.sshj.userauth.method.AuthMethod;
|
||||||
import net.schmizz.sshj.userauth.method.AuthPassword;
|
import net.schmizz.sshj.userauth.method.AuthPassword;
|
||||||
import net.schmizz.sshj.userauth.method.AuthPublickey;
|
import net.schmizz.sshj.userauth.method.AuthPublickey;
|
||||||
import net.schmizz.sshj.userauth.method.PasswordResponseProvider;
|
import net.schmizz.sshj.userauth.method.PasswordResponseProvider;
|
||||||
import net.schmizz.sshj.userauth.password.PasswordFinder;
|
import net.schmizz.sshj.userauth.password.PasswordFinder;
|
||||||
|
import net.schmizz.sshj.userauth.password.PasswordUpdateProvider;
|
||||||
import net.schmizz.sshj.userauth.password.PasswordUtils;
|
import net.schmizz.sshj.userauth.password.PasswordUtils;
|
||||||
import net.schmizz.sshj.userauth.password.Resource;
|
import net.schmizz.sshj.userauth.password.Resource;
|
||||||
import net.schmizz.sshj.xfer.scp.SCPFileTransfer;
|
import net.schmizz.sshj.xfer.scp.SCPFileTransfer;
|
||||||
|
import org.ietf.jgss.Oid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.security.auth.login.LoginContext;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -144,19 +151,28 @@ public class SSHClient
|
|||||||
*/
|
*/
|
||||||
public SSHClient(Config config) {
|
public SSHClient(Config config) {
|
||||||
super(DEFAULT_PORT);
|
super(DEFAULT_PORT);
|
||||||
this.trans = new TransportImpl(config);
|
this.trans = new TransportImpl(config, this);
|
||||||
this.auth = new UserAuthImpl(trans);
|
this.auth = new UserAuthImpl(trans);
|
||||||
this.conn = new ConnectionImpl(trans);
|
this.conn = new ConnectionImpl(trans, config.getKeepAliveProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a {@link HostKeyVerifier} which will be invoked for verifying host key during connection establishment and
|
* Add a {@link HostKeyVerifier} which will be invoked for verifying host key during connection establishment and
|
||||||
* future key exchanges.
|
* future key exchanges.
|
||||||
*
|
*
|
||||||
* @param hostKeyVerifier {@link HostKeyVerifier} instance
|
* @param verifier {@link HostKeyVerifier} instance
|
||||||
*/
|
*/
|
||||||
public void addHostKeyVerifier(HostKeyVerifier hostKeyVerifier) {
|
public void addHostKeyVerifier(HostKeyVerifier verifier) {
|
||||||
trans.addHostKeyVerifier(hostKeyVerifier);
|
trans.addHostKeyVerifier(verifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link AlgorithmsVerifier} which will be invoked for verifying negotiated algorithms.
|
||||||
|
*
|
||||||
|
* @param verifier {@link AlgorithmsVerifier} instance
|
||||||
|
*/
|
||||||
|
public void addAlgorithmsVerifier(AlgorithmsVerifier verifier) {
|
||||||
|
trans.addAlgorithmsVerifier(verifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,7 +221,7 @@ public class SSHClient
|
|||||||
public void auth(String username, Iterable<AuthMethod> methods)
|
public void auth(String username, Iterable<AuthMethod> methods)
|
||||||
throws UserAuthException, TransportException {
|
throws UserAuthException, TransportException {
|
||||||
checkConnected();
|
checkConnected();
|
||||||
final Deque<UserAuthException> savedEx = new LinkedList<UserAuthException>();
|
final Deque<UserAuthException> savedEx = new LinkedList<>();
|
||||||
for (AuthMethod method: methods) {
|
for (AuthMethod method: methods) {
|
||||||
try {
|
try {
|
||||||
if (auth.authenticate(username, (Service) conn, method, trans.getTimeoutMs()))
|
if (auth.authenticate(username, (Service) conn, method, trans.getTimeoutMs()))
|
||||||
@@ -278,6 +294,22 @@ public class SSHClient
|
|||||||
auth(username, new AuthPassword(pfinder), new AuthKeyboardInteractive(new PasswordResponseProvider(pfinder)));
|
auth(username, new AuthPassword(pfinder), new AuthKeyboardInteractive(new PasswordResponseProvider(pfinder)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate {@code username} using the {@code "password"} authentication method and as a fallback basic
|
||||||
|
* challenge-response authentication.
|
||||||
|
*
|
||||||
|
* @param username user to authenticate
|
||||||
|
* @param pfinder the {@link PasswordFinder} to use for authentication
|
||||||
|
* @param newPasswordProvider the {@link PasswordUpdateProvider} to use when a new password is being requested from the user.
|
||||||
|
*
|
||||||
|
* @throws UserAuthException in case of authentication failure
|
||||||
|
* @throws TransportException if there was a transport-layer error
|
||||||
|
*/
|
||||||
|
public void authPassword(String username, PasswordFinder pfinder, PasswordUpdateProvider newPasswordProvider)
|
||||||
|
throws UserAuthException, TransportException {
|
||||||
|
auth(username, new AuthPassword(pfinder, newPasswordProvider), new AuthKeyboardInteractive(new PasswordResponseProvider(pfinder)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate {@code username} using the {@code "publickey"} authentication method, with keys from some common
|
* Authenticate {@code username} using the {@code "publickey"} authentication method, with keys from some common
|
||||||
* locations on the file system. This method relies on {@code ~/.ssh/id_rsa} and {@code ~/.ssh/id_dsa}.
|
* locations on the file system. This method relies on {@code ~/.ssh/id_rsa} and {@code ~/.ssh/id_dsa}.
|
||||||
@@ -310,7 +342,7 @@ public class SSHClient
|
|||||||
*/
|
*/
|
||||||
public void authPublickey(String username, Iterable<KeyProvider> keyProviders)
|
public void authPublickey(String username, Iterable<KeyProvider> keyProviders)
|
||||||
throws UserAuthException, TransportException {
|
throws UserAuthException, TransportException {
|
||||||
final List<AuthMethod> am = new LinkedList<AuthMethod>();
|
final List<AuthMethod> am = new LinkedList<>();
|
||||||
for (KeyProvider kp : keyProviders)
|
for (KeyProvider kp : keyProviders)
|
||||||
am.add(new AuthPublickey(kp));
|
am.add(new AuthPublickey(kp));
|
||||||
auth(username, am);
|
auth(username, am);
|
||||||
@@ -353,7 +385,7 @@ public class SSHClient
|
|||||||
*/
|
*/
|
||||||
public void authPublickey(String username, String... locations)
|
public void authPublickey(String username, String... locations)
|
||||||
throws UserAuthException, TransportException {
|
throws UserAuthException, TransportException {
|
||||||
final List<KeyProvider> keyProviders = new LinkedList<KeyProvider>();
|
final List<KeyProvider> keyProviders = new LinkedList<>();
|
||||||
for (String loc : locations) {
|
for (String loc : locations) {
|
||||||
try {
|
try {
|
||||||
log.debug("Attempting to load key from: {}", loc);
|
log.debug("Attempting to load key from: {}", loc);
|
||||||
@@ -365,6 +397,30 @@ public class SSHClient
|
|||||||
authPublickey(username, keyProviders);
|
authPublickey(username, keyProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate {@code username} using the {@code "gssapi-with-mic"} authentication method, given a login context
|
||||||
|
* for the peer GSS machine and a list of supported OIDs.
|
||||||
|
* <p/>
|
||||||
|
* Supported OIDs should be ordered by preference as the SSH server will choose the first OID that it also
|
||||||
|
* supports. At least one OID is required
|
||||||
|
*
|
||||||
|
* @param username user to authenticate
|
||||||
|
* @param context {@code LoginContext} for the peer GSS machine
|
||||||
|
* @param supportedOid first supported OID
|
||||||
|
* @param supportedOids other supported OIDs
|
||||||
|
*
|
||||||
|
* @throws UserAuthException in case of authentication failure
|
||||||
|
* @throws TransportException if there was a transport-layer error
|
||||||
|
*/
|
||||||
|
public void authGssApiWithMic(String username, LoginContext context, Oid supportedOid, Oid... supportedOids)
|
||||||
|
throws UserAuthException, TransportException {
|
||||||
|
// insert supportedOid to the front of the list since ordering matters
|
||||||
|
List<Oid> oids = new ArrayList<>(Arrays.asList(supportedOids));
|
||||||
|
oids.add(0, supportedOid);
|
||||||
|
|
||||||
|
auth(username, new AuthGssApiWithMic(context, oids));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects from the connected SSH server. {@code SSHClient} objects are not reusable therefore it is incorrect
|
* Disconnects from the connected SSH server. {@code SSHClient} objects are not reusable therefore it is incorrect
|
||||||
* to attempt connection after this method has been called.
|
* to attempt connection after this method has been called.
|
||||||
@@ -485,7 +541,7 @@ public class SSHClient
|
|||||||
public KeyProvider loadKeys(String location, PasswordFinder passwordFinder)
|
public KeyProvider loadKeys(String location, PasswordFinder passwordFinder)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final File loc = new File(location);
|
final File loc = new File(location);
|
||||||
final FileKeyProvider.Format format = KeyProviderUtil.detectKeyFileFormat(loc);
|
final KeyFormat format = KeyProviderUtil.detectKeyFileFormat(loc);
|
||||||
final FileKeyProvider fkp =
|
final FileKeyProvider fkp =
|
||||||
Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format.toString());
|
Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format.toString());
|
||||||
if (fkp == null)
|
if (fkp == null)
|
||||||
@@ -529,7 +585,7 @@ public class SSHClient
|
|||||||
*/
|
*/
|
||||||
public KeyProvider loadKeys(String privateKey, String publicKey, PasswordFinder passwordFinder)
|
public KeyProvider loadKeys(String privateKey, String publicKey, PasswordFinder passwordFinder)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FileKeyProvider.Format format = KeyProviderUtil.detectKeyFileFormat(privateKey, publicKey != null);
|
final KeyFormat format = KeyProviderUtil.detectKeyFileFormat(privateKey, publicKey != null);
|
||||||
final FileKeyProvider fkp =
|
final FileKeyProvider fkp =
|
||||||
Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format.toString());
|
Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format.toString());
|
||||||
if (fkp == null)
|
if (fkp == null)
|
||||||
@@ -720,4 +776,4 @@ public class SSHClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,35 +12,19 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file incorporates work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.backport.JavaVersion;
|
||||||
|
import com.hierynomus.sshj.backport.Jdk7HttpProxySocket;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
public abstract class SocketClient {
|
public abstract class SocketClient {
|
||||||
@@ -64,21 +48,53 @@ public abstract class SocketClient {
|
|||||||
this.defaultPort = defaultPort;
|
this.defaultPort = defaultPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(InetAddress host, int port)
|
public void connect(InetAddress host, int port) throws IOException {
|
||||||
throws IOException {
|
|
||||||
socket = socketFactory.createSocket();
|
socket = socketFactory.createSocket();
|
||||||
socket.connect(new InetSocketAddress(host, port), connectTimeout);
|
socket.connect(new InetSocketAddress(host, port), connectTimeout);
|
||||||
onConnect();
|
onConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(String hostname, int port)
|
|
||||||
throws IOException {
|
/**
|
||||||
|
* Connect to a host via a proxy.
|
||||||
|
* @param host The host address to connect to.
|
||||||
|
* @param port The port to connect to.
|
||||||
|
* @param proxy The proxy to connect via.
|
||||||
|
* @deprecated This method will be removed after v0.12.0. If you want to connect via a proxy, you can do this by injecting a {@link javax.net.SocketFactory}
|
||||||
|
* into the SocketClient. The SocketFactory should create sockets using the {@link java.net.Socket#Socket(java.net.Proxy)} constructor.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void connect(InetAddress host, int port, Proxy proxy) throws IOException {
|
||||||
|
if (JavaVersion.isJava7OrEarlier() && proxy.type() == Proxy.Type.HTTP) {
|
||||||
|
// Java7 and earlier have no support for HTTP Connect proxies, return our custom socket.
|
||||||
|
socket = new Jdk7HttpProxySocket(proxy);
|
||||||
|
} else {
|
||||||
|
socket = new Socket(proxy);
|
||||||
|
}
|
||||||
|
socket.connect(new InetSocketAddress(host, port), connectTimeout);
|
||||||
|
onConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect(String hostname, int port) throws IOException {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
connect(InetAddress.getByName(hostname), port);
|
connect(InetAddress.getByName(hostname), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(InetAddress host, int port,
|
/**
|
||||||
InetAddress localAddr, int localPort)
|
* Connect to a host via a proxy.
|
||||||
|
* @param hostname The host name to connect to.
|
||||||
|
* @param port The port to connect to.
|
||||||
|
* @param proxy The proxy to connect via.
|
||||||
|
* @deprecated This method will be removed after v0.12.0. If you want to connect via a proxy, you can do this by injecting a {@link javax.net.SocketFactory}
|
||||||
|
* into the SocketClient. The SocketFactory should create sockets using the {@link java.net.Socket#Socket(java.net.Proxy)} constructor.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void connect(String hostname, int port, Proxy proxy) throws IOException {
|
||||||
|
this.hostname = hostname;
|
||||||
|
connect(InetAddress.getByName(hostname), port, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect(InetAddress host, int port, InetAddress localAddr, int localPort)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
socket = socketFactory.createSocket();
|
socket = socketFactory.createSocket();
|
||||||
socket.bind(new InetSocketAddress(localAddr, localPort));
|
socket.bind(new InetSocketAddress(localAddr, localPort));
|
||||||
@@ -86,25 +102,44 @@ public abstract class SocketClient {
|
|||||||
onConnect();
|
onConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(String hostname, int port,
|
public void connect(String hostname, int port, InetAddress localAddr, int localPort) throws IOException {
|
||||||
InetAddress localAddr, int localPort)
|
|
||||||
throws IOException {
|
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
connect(InetAddress.getByName(hostname), port, localAddr, localPort);
|
connect(InetAddress.getByName(hostname), port, localAddr, localPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(InetAddress host)
|
public void connect(InetAddress host) throws IOException {
|
||||||
throws IOException {
|
|
||||||
connect(host, defaultPort);
|
connect(host, defaultPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(String hostname)
|
public void connect(String hostname) throws IOException {
|
||||||
throws IOException {
|
|
||||||
connect(hostname, defaultPort);
|
connect(hostname, defaultPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect()
|
/**
|
||||||
throws IOException {
|
* Connect to a host via a proxy.
|
||||||
|
* @param host The host address to connect to.
|
||||||
|
* @param proxy The proxy to connect via.
|
||||||
|
* @deprecated This method will be removed after v0.12.0. If you want to connect via a proxy, you can do this by injecting a {@link javax.net.SocketFactory}
|
||||||
|
* into the SocketClient. The SocketFactory should create sockets using the {@link java.net.Socket#Socket(java.net.Proxy)} constructor.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void connect(InetAddress host, Proxy proxy) throws IOException {
|
||||||
|
connect(host, defaultPort, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to a host via a proxy.
|
||||||
|
* @param hostname The host name to connect to.
|
||||||
|
* @param proxy The proxy to connect via.
|
||||||
|
* @deprecated This method will be removed after v0.12.0. If you want to connect via a proxy, you can do this by injecting a {@link javax.net.SocketFactory}
|
||||||
|
* into the SocketClient. The SocketFactory should create sockets using the {@link java.net.Socket#Socket(java.net.Proxy)} constructor.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void connect(String hostname, Proxy proxy) throws IOException {
|
||||||
|
connect(hostname, defaultPort, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() throws IOException {
|
||||||
if (socket != null) {
|
if (socket != null) {
|
||||||
socket.close();
|
socket.close();
|
||||||
socket = null;
|
socket = null;
|
||||||
@@ -127,7 +162,6 @@ public abstract class SocketClient {
|
|||||||
return socket.getLocalPort();
|
return socket.getLocalPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public InetAddress getLocalAddress() {
|
public InetAddress getLocalAddress() {
|
||||||
return socket.getLocalAddress();
|
return socket.getLocalAddress();
|
||||||
}
|
}
|
||||||
@@ -145,10 +179,11 @@ public abstract class SocketClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setSocketFactory(SocketFactory factory) {
|
public void setSocketFactory(SocketFactory factory) {
|
||||||
if (factory == null)
|
if (factory == null) {
|
||||||
socketFactory = SocketFactory.getDefault();
|
socketFactory = SocketFactory.getDefault();
|
||||||
else
|
} else {
|
||||||
socketFactory = factory;
|
socketFactory = factory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocketFactory getSocketFactory() {
|
public SocketFactory getSocketFactory() {
|
||||||
@@ -183,11 +218,10 @@ public abstract class SocketClient {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onConnect()
|
void onConnect() throws IOException {
|
||||||
throws IOException {
|
|
||||||
socket.setSoTimeout(timeout);
|
socket.setSoTimeout(timeout);
|
||||||
input = socket.getInputStream();
|
input = socket.getInputStream();
|
||||||
output = socket.getOutputStream();
|
output = socket.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,21 +15,35 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.secg.SecgUtils;
|
||||||
|
import com.hierynomus.sshj.signature.Ed25519PublicKey;
|
||||||
|
import net.i2p.crypto.eddsa.EdDSAPublicKey;
|
||||||
|
import net.i2p.crypto.eddsa.math.GroupElement;
|
||||||
|
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
|
||||||
|
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
||||||
|
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
|
||||||
|
import org.bouncycastle.asn1.nist.NISTNamedCurves;
|
||||||
|
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||||
|
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||||
|
import org.bouncycastle.jce.spec.ECPublicKeySpec;
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.interfaces.DSAPrivateKey;
|
import java.security.interfaces.*;
|
||||||
import java.security.interfaces.DSAPublicKey;
|
|
||||||
import java.security.interfaces.RSAPrivateKey;
|
|
||||||
import java.security.interfaces.RSAPublicKey;
|
|
||||||
import java.security.spec.DSAPublicKeySpec;
|
import java.security.spec.DSAPublicKeySpec;
|
||||||
import java.security.spec.RSAPublicKeySpec;
|
import java.security.spec.RSAPublicKeySpec;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/** Type of key e.g. rsa, dsa */
|
/** Type of key e.g. rsa, dsa */
|
||||||
public enum KeyType {
|
public enum KeyType {
|
||||||
|
|
||||||
|
|
||||||
/** SSH identifier for RSA keys */
|
/** SSH identifier for RSA keys */
|
||||||
RSA("ssh-rsa") {
|
RSA("ssh-rsa") {
|
||||||
@Override
|
@Override
|
||||||
@@ -96,6 +110,108 @@ public enum KeyType {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** SSH identifier for ECDSA keys */
|
||||||
|
ECDSA("ecdsa-sha2-nistp256") {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
|
||||||
|
throws GeneralSecurityException {
|
||||||
|
try {
|
||||||
|
// final String algo = buf.readString(); it has been already read
|
||||||
|
final String curveName = buf.readString();
|
||||||
|
final int keyLen = buf.readUInt32AsInt();
|
||||||
|
final byte x04 = buf.readByte(); // it must be 0x04, but don't think we need that check
|
||||||
|
final byte[] x = new byte[(keyLen - 1) / 2];
|
||||||
|
final byte[] y = new byte[(keyLen - 1) / 2];
|
||||||
|
buf.readRawBytes(x);
|
||||||
|
buf.readRawBytes(y);
|
||||||
|
if(log.isDebugEnabled()) {
|
||||||
|
log.debug(String.format("Key algo: %s, Key curve: %s, Key Len: %s, 0x04: %s\nx: %s\ny: %s",
|
||||||
|
type,
|
||||||
|
curveName,
|
||||||
|
keyLen,
|
||||||
|
x04,
|
||||||
|
Arrays.toString(x),
|
||||||
|
Arrays.toString(y))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NISTP_CURVE.equals(curveName)) {
|
||||||
|
throw new GeneralSecurityException(String.format("Unknown curve %s", curveName));
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger bigX = new BigInteger(1, x);
|
||||||
|
BigInteger bigY = new BigInteger(1, y);
|
||||||
|
|
||||||
|
X9ECParameters ecParams = NISTNamedCurves.getByName("p-256");
|
||||||
|
ECPoint pPublicPoint = ecParams.getCurve().createPoint(bigX, bigY);
|
||||||
|
ECParameterSpec spec = new ECParameterSpec(ecParams.getCurve(),
|
||||||
|
ecParams.getG(), ecParams.getN());
|
||||||
|
ECPublicKeySpec publicSpec = new ECPublicKeySpec(pPublicPoint, spec);
|
||||||
|
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA");
|
||||||
|
return keyFactory.generatePublic(publicSpec);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new GeneralSecurityException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||||
|
final ECPublicKey ecdsa = (ECPublicKey) pk;
|
||||||
|
byte[] encoded = SecgUtils.getEncoded(ecdsa.getW(), ecdsa.getParams().getCurve());
|
||||||
|
|
||||||
|
buf.putString(sType)
|
||||||
|
.putString(NISTP_CURVE)
|
||||||
|
.putBytes(encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isMyType(Key key) {
|
||||||
|
return ("ECDSA".equals(key.getAlgorithm()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ED25519("ssh-ed25519") {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(KeyType.class);
|
||||||
|
@Override
|
||||||
|
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf) throws GeneralSecurityException {
|
||||||
|
try {
|
||||||
|
final int keyLen = buf.readUInt32AsInt();
|
||||||
|
final byte[] p = new byte[keyLen];
|
||||||
|
buf.readRawBytes(p);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(String.format("Key algo: %s, Key curve: 25519, Key Len: %s\np: %s",
|
||||||
|
type,
|
||||||
|
keyLen,
|
||||||
|
Arrays.toString(p))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName("ed25519-sha-512");
|
||||||
|
GroupElement point = ed25519.getCurve().createPoint(p, true);
|
||||||
|
EdDSAPublicKeySpec publicSpec = new EdDSAPublicKeySpec(point, ed25519);
|
||||||
|
return new Ed25519PublicKey(publicSpec);
|
||||||
|
|
||||||
|
} catch (Buffer.BufferException be) {
|
||||||
|
throw new SSHRuntimeException(be);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||||
|
EdDSAPublicKey key = (EdDSAPublicKey) pk;
|
||||||
|
buf.putString(sType).putBytes(key.getAbyte());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isMyType(Key key) {
|
||||||
|
return "EdDSA".equals(key.getAlgorithm());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/** Unrecognized */
|
/** Unrecognized */
|
||||||
UNKNOWN("unknown") {
|
UNKNOWN("unknown") {
|
||||||
@Override
|
@Override
|
||||||
@@ -113,10 +229,11 @@ public enum KeyType {
|
|||||||
protected boolean isMyType(Key key) {
|
protected boolean isMyType(Key key) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private static final String NISTP_CURVE = "nistp256";
|
||||||
|
|
||||||
protected final String sType;
|
protected final String sType;
|
||||||
|
|
||||||
private KeyType(String type) {
|
private KeyType(String type) {
|
||||||
@@ -149,4 +266,4 @@ public enum KeyType {
|
|||||||
return sType;
|
return sType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -30,7 +30,7 @@ public enum Message {
|
|||||||
|
|
||||||
KEXDH_INIT(30),
|
KEXDH_INIT(30),
|
||||||
|
|
||||||
/** { KEXDH_REPLY, KEXDH_GEX_GROUP } */
|
/** { KEXDH_REPLY, KEXDH_GEX_GROUP, SSH_MSG_KEX_ECDH_REPLY } */
|
||||||
KEXDH_31(31),
|
KEXDH_31(31),
|
||||||
|
|
||||||
KEX_DH_GEX_INIT(32),
|
KEX_DH_GEX_INIT(32),
|
||||||
@@ -46,6 +46,9 @@ public enum Message {
|
|||||||
USERAUTH_60(60),
|
USERAUTH_60(60),
|
||||||
USERAUTH_INFO_RESPONSE(61),
|
USERAUTH_INFO_RESPONSE(61),
|
||||||
|
|
||||||
|
USERAUTH_GSSAPI_EXCHANGE_COMPLETE(63),
|
||||||
|
USERAUTH_GSSAPI_MIC(66),
|
||||||
|
|
||||||
GLOBAL_REQUEST(80),
|
GLOBAL_REQUEST(80),
|
||||||
REQUEST_SUCCESS(81),
|
REQUEST_SUCCESS(81),
|
||||||
REQUEST_FAILURE(82),
|
REQUEST_FAILURE(82),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.common;
|
package net.schmizz.sshj.common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -107,7 +107,7 @@ public class StreamCopier {
|
|||||||
log.debug("Done copying from {}", in);
|
log.debug("Done copying from {}", in);
|
||||||
doneEvent.set();
|
doneEvent.set();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
log.error("In pipe from {} to {}: {}", new Object[] { in, out, ioe });
|
log.error("In pipe from {} to {}: {}", in, out, ioe);
|
||||||
doneEvent.deliverError(ioe);
|
doneEvent.deliverError(ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ public class StreamCopier {
|
|||||||
|
|
||||||
final double timeSeconds = (System.currentTimeMillis() - startTime) / 1000.0;
|
final double timeSeconds = (System.currentTimeMillis() - startTime) / 1000.0;
|
||||||
final double sizeKiB = count / 1024.0;
|
final double sizeKiB = count / 1024.0;
|
||||||
log.debug("{} KiB transferred in {} seconds ({} KiB/s)", new Object[] { sizeKiB, timeSeconds, (sizeKiB / timeSeconds) });
|
log.debug("{} KiB transferred in {} seconds ({} KiB/s)", sizeKiB, timeSeconds, (sizeKiB / timeSeconds));
|
||||||
|
|
||||||
if (length != -1 && read == -1)
|
if (length != -1 && read == -1)
|
||||||
throw new IOException("Encountered EOF, could not transfer " + length + " bytes");
|
throw new IOException("Encountered EOF, could not transfer " + length + " bytes");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
package net.schmizz.sshj.connection;
|
package net.schmizz.sshj.connection;
|
||||||
|
|
||||||
import net.schmizz.concurrent.Promise;
|
import net.schmizz.concurrent.Promise;
|
||||||
|
import net.schmizz.keepalive.KeepAlive;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
import net.schmizz.sshj.connection.channel.Channel;
|
import net.schmizz.sshj.connection.channel.Channel;
|
||||||
import net.schmizz.sshj.connection.channel.OpenFailException;
|
import net.schmizz.sshj.connection.channel.OpenFailException;
|
||||||
@@ -150,4 +151,9 @@ public interface Connection {
|
|||||||
* @param timeout timeout in milliseconds
|
* @param timeout timeout in milliseconds
|
||||||
*/
|
*/
|
||||||
void setTimeoutMs(int timeout);
|
void setTimeoutMs(int timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The configured {@link net.schmizz.keepalive.KeepAlive} mechanism.
|
||||||
|
*/
|
||||||
|
KeepAlive getKeepAlive();
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,6 +17,8 @@ package net.schmizz.sshj.connection;
|
|||||||
|
|
||||||
import net.schmizz.concurrent.ErrorDeliveryUtil;
|
import net.schmizz.concurrent.ErrorDeliveryUtil;
|
||||||
import net.schmizz.concurrent.Promise;
|
import net.schmizz.concurrent.Promise;
|
||||||
|
import net.schmizz.keepalive.KeepAlive;
|
||||||
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
import net.schmizz.sshj.AbstractService;
|
import net.schmizz.sshj.AbstractService;
|
||||||
import net.schmizz.sshj.common.Buffer;
|
import net.schmizz.sshj.common.Buffer;
|
||||||
import net.schmizz.sshj.common.DisconnectReason;
|
import net.schmizz.sshj.common.DisconnectReason;
|
||||||
@@ -51,6 +53,9 @@ public class ConnectionImpl
|
|||||||
|
|
||||||
private final Queue<Promise<SSHPacket, ConnectionException>> globalReqPromises = new LinkedList<Promise<SSHPacket, ConnectionException>>();
|
private final Queue<Promise<SSHPacket, ConnectionException>> globalReqPromises = new LinkedList<Promise<SSHPacket, ConnectionException>>();
|
||||||
|
|
||||||
|
/** {@code keep-alive} mechanism */
|
||||||
|
private final KeepAlive keepAlive;
|
||||||
|
|
||||||
private long windowSize = 2048 * 1024;
|
private long windowSize = 2048 * 1024;
|
||||||
private int maxPacketSize = 32 * 1024;
|
private int maxPacketSize = 32 * 1024;
|
||||||
|
|
||||||
@@ -60,10 +65,12 @@ public class ConnectionImpl
|
|||||||
* Create with an associated {@link Transport}.
|
* Create with an associated {@link Transport}.
|
||||||
*
|
*
|
||||||
* @param trans transport layer
|
* @param trans transport layer
|
||||||
|
* @param keepAlive the keep alive provider
|
||||||
*/
|
*/
|
||||||
public ConnectionImpl(Transport trans) {
|
public ConnectionImpl(Transport trans, KeepAliveProvider keepAlive) {
|
||||||
super("ssh-connection", trans);
|
super("ssh-connection", trans);
|
||||||
timeoutMs = trans.getTimeoutMs();
|
timeoutMs = trans.getTimeoutMs();
|
||||||
|
this.keepAlive = keepAlive.provide(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -208,13 +215,15 @@ public class ConnectionImpl
|
|||||||
throws ConnectionException {
|
throws ConnectionException {
|
||||||
synchronized (globalReqPromises) {
|
synchronized (globalReqPromises) {
|
||||||
Promise<SSHPacket, ConnectionException> gr = globalReqPromises.poll();
|
Promise<SSHPacket, ConnectionException> gr = globalReqPromises.poll();
|
||||||
if (gr == null)
|
if (gr == null) {
|
||||||
throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR,
|
throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR,
|
||||||
"Got a global request response when none was requested");
|
"Got a global request response when none was requested");
|
||||||
else if (response == null)
|
} else if (response == null) {
|
||||||
gr.deliverError(new ConnectionException("Global request [" + gr + "] failed"));
|
gr.deliverError(new ConnectionException("Global request [" + gr + "] failed"));
|
||||||
else
|
} else {
|
||||||
gr.deliver(response);
|
// To prevent a race condition, copy the packet before delivering, as it will be handled in a different thread.
|
||||||
|
gr.deliver(new SSHPacket(response));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +259,7 @@ public class ConnectionImpl
|
|||||||
ErrorDeliveryUtil.alertPromises(error, globalReqPromises);
|
ErrorDeliveryUtil.alertPromises(error, globalReqPromises);
|
||||||
globalReqPromises.clear();
|
globalReqPromises.clear();
|
||||||
}
|
}
|
||||||
|
keepAlive.interrupt();
|
||||||
ErrorNotifiable.Util.alertAll(error, channels.values());
|
ErrorNotifiable.Util.alertAll(error, channels.values());
|
||||||
channels.clear();
|
channels.clear();
|
||||||
}
|
}
|
||||||
@@ -264,4 +274,9 @@ public class ConnectionImpl
|
|||||||
return timeoutMs;
|
return timeoutMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public KeepAlive getKeepAlive() {
|
||||||
|
return keepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.connection.channel;
|
package net.schmizz.sshj.connection.channel;
|
||||||
|
|
||||||
@@ -86,10 +66,7 @@ public abstract class AbstractChannel
|
|||||||
protected final Event<ConnectionException> openEvent;
|
protected final Event<ConnectionException> openEvent;
|
||||||
/** Channel close event */
|
/** Channel close event */
|
||||||
protected final Event<ConnectionException> closeEvent;
|
protected final Event<ConnectionException> closeEvent;
|
||||||
|
/** Whether we have already sent a CHANNEL_CLOSE request to the server */
|
||||||
/* Access to these fields should be synchronized using this object */
|
|
||||||
private boolean eofSent;
|
|
||||||
private boolean eofGot;
|
|
||||||
private boolean closeRequested;
|
private boolean closeRequested;
|
||||||
|
|
||||||
/** Local window */
|
/** Local window */
|
||||||
@@ -277,13 +254,14 @@ public abstract class AbstractChannel
|
|||||||
closeEvent.await();
|
closeEvent.await();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void join(int timeout, TimeUnit unit)
|
public void join(long timeout, TimeUnit unit)
|
||||||
throws ConnectionException {
|
throws ConnectionException {
|
||||||
closeEvent.await(timeout, unit);
|
closeEvent.await(timeout, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected synchronized void sendClose()
|
protected void sendClose()
|
||||||
throws TransportException {
|
throws TransportException {
|
||||||
|
openCloseLock.lock();
|
||||||
try {
|
try {
|
||||||
if (!closeRequested) {
|
if (!closeRequested) {
|
||||||
log.debug("Sending close");
|
log.debug("Sending close");
|
||||||
@@ -291,11 +269,12 @@ public abstract class AbstractChannel
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closeRequested = true;
|
closeRequested = true;
|
||||||
|
openCloseLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean isOpen() {
|
public boolean isOpen() {
|
||||||
openCloseLock.lock();
|
openCloseLock.lock();
|
||||||
try {
|
try {
|
||||||
return openEvent.isSet() && !closeEvent.isSet() && !closeRequested;
|
return openEvent.isSet() && !closeEvent.isSet() && !closeRequested;
|
||||||
@@ -405,13 +384,10 @@ public abstract class AbstractChannel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void gotEOF()
|
private void gotEOF()
|
||||||
throws TransportException {
|
throws TransportException {
|
||||||
log.debug("Got EOF");
|
log.debug("Got EOF");
|
||||||
eofGot = true;
|
|
||||||
eofInputStreams();
|
eofInputStreams();
|
||||||
if (eofSent)
|
|
||||||
sendClose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when EOF has been received. Subclasses can override but must call super. */
|
/** Called when EOF has been received. Subclasses can override but must call super. */
|
||||||
@@ -419,22 +395,6 @@ public abstract class AbstractChannel
|
|||||||
in.eof();
|
in.eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void sendEOF()
|
|
||||||
throws TransportException {
|
|
||||||
try {
|
|
||||||
if (!closeRequested && !eofSent) {
|
|
||||||
log.debug("Sending EOF");
|
|
||||||
trans.write(newBuffer(Message.CHANNEL_EOF));
|
|
||||||
if (eofGot)
|
|
||||||
sendClose();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
eofSent = true;
|
|
||||||
out.setClosed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "< " + type + " channel: id=" + id + ", recipient=" + recipient + ", localWin=" + lwin + ", remoteWin="
|
return "< " + type + " channel: id=" + id + ", recipient=" + recipient + ", localWin=" + lwin + ", remoteWin="
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -119,15 +119,6 @@ public interface Channel
|
|||||||
/** @return whether the channel is open. */
|
/** @return whether the channel is open. */
|
||||||
boolean isOpen();
|
boolean isOpen();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends an EOF message to the server for this channel; indicating that no more data will be sent by us. The {@code
|
|
||||||
* OutputStream} for this channel will be closed and no longer usable.
|
|
||||||
*
|
|
||||||
* @throws TransportException if there is an error sending the EOF message
|
|
||||||
*/
|
|
||||||
void sendEOF()
|
|
||||||
throws TransportException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether local window should automatically expand when data is received, irrespective of whether data has been
|
* Set whether local window should automatically expand when data is received, irrespective of whether data has been
|
||||||
* read from that stream. This is useful e.g. when a remote command produces a lot of output that would fill the
|
* read from that stream. This is useful e.g. when a remote command produces a lot of output that would fill the
|
||||||
@@ -140,7 +131,7 @@ public interface Channel
|
|||||||
void join()
|
void join()
|
||||||
throws ConnectionException;
|
throws ConnectionException;
|
||||||
|
|
||||||
void join(int timeout, TimeUnit unit)
|
void join(long timeout, TimeUnit unit)
|
||||||
throws ConnectionException;
|
throws ConnectionException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,28 +12,7 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.connection.channel;
|
package net.schmizz.sshj.connection.channel;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.Buffer;
|
import net.schmizz.sshj.common.Buffer;
|
||||||
@@ -151,7 +130,12 @@ public final class ChannelInputStream
|
|||||||
buf.putRawBytes(data, offset, len);
|
buf.putRawBytes(data, offset, len);
|
||||||
buf.notifyAll();
|
buf.notifyAll();
|
||||||
}
|
}
|
||||||
win.consume(len);
|
// Potential fix for #203 (window consumed below 0).
|
||||||
|
// This seems to be a race condition if we receive more data, while we're already sending a SSH_MSG_CHANNEL_WINDOW_ADJUST
|
||||||
|
// And the window has not expanded yet.
|
||||||
|
synchronized (win) {
|
||||||
|
win.consume(len);
|
||||||
|
}
|
||||||
if (chan.getAutoExpand())
|
if (chan.getAutoExpand())
|
||||||
checkWindow();
|
checkWindow();
|
||||||
}
|
}
|
||||||
@@ -174,4 +158,4 @@ public final class ChannelInputStream
|
|||||||
return "< ChannelInputStream for Channel #" + chan.getID() + " >";
|
return "< ChannelInputStream for Channel #" + chan.getID() + " >";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.connection.channel;
|
package net.schmizz.sshj.connection.channel;
|
||||||
|
|
||||||
@@ -84,7 +64,7 @@ public final class ChannelOutputStream
|
|||||||
throws TransportException, ConnectionException {
|
throws TransportException, ConnectionException {
|
||||||
final int bufferSize = packet.wpos() - dataOffset;
|
final int bufferSize = packet.wpos() - dataOffset;
|
||||||
if (bufferSize >= win.getMaxPacketSize()) {
|
if (bufferSize >= win.getMaxPacketSize()) {
|
||||||
flush(bufferSize);
|
flush(bufferSize, true);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
final int n = Math.min(len, win.getMaxPacketSize() - bufferSize);
|
final int n = Math.min(len, win.getMaxPacketSize() - bufferSize);
|
||||||
@@ -93,18 +73,23 @@ public final class ChannelOutputStream
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush()
|
boolean flush(boolean canAwaitExpansion)
|
||||||
throws TransportException, ConnectionException {
|
throws TransportException, ConnectionException {
|
||||||
flush(packet.wpos() - dataOffset);
|
return flush(packet.wpos() - dataOffset, canAwaitExpansion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush(int bufferSize)
|
boolean flush(int bufferSize, boolean canAwaitExpansion)
|
||||||
throws TransportException, ConnectionException {
|
throws TransportException, ConnectionException {
|
||||||
while (bufferSize > 0) {
|
while (bufferSize > 0) {
|
||||||
|
|
||||||
long remoteWindowSize = win.getSize();
|
long remoteWindowSize = win.getSize();
|
||||||
if (remoteWindowSize == 0)
|
if (remoteWindowSize == 0) {
|
||||||
remoteWindowSize = win.awaitExpansion(remoteWindowSize);
|
if (canAwaitExpansion) {
|
||||||
|
remoteWindowSize = win.awaitExpansion(remoteWindowSize);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We can only write the min. of
|
// We can only write the min. of
|
||||||
// a) how much data we have
|
// a) how much data we have
|
||||||
@@ -136,6 +121,8 @@ public final class ChannelOutputStream
|
|||||||
|
|
||||||
bufferSize = leftOverBytes;
|
bufferSize = leftOverBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -184,18 +171,14 @@ public final class ChannelOutputStream
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
try {
|
try {
|
||||||
buffer.flush();
|
buffer.flush(false);
|
||||||
chan.sendEOF();
|
// trans.write(new SSHPacket(Message.CHANNEL_EOF).putUInt32(chan.getRecipient()));
|
||||||
} finally {
|
} finally {
|
||||||
setClosed();
|
closed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setClosed() {
|
|
||||||
closed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send all data currently buffered. If window space is exhausted in the process, this will block
|
* Send all data currently buffered. If window space is exhausted in the process, this will block
|
||||||
* until it is expanded by the server.
|
* until it is expanded by the server.
|
||||||
@@ -206,7 +189,7 @@ public final class ChannelOutputStream
|
|||||||
public synchronized void flush()
|
public synchronized void flush()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
checkClose();
|
checkClose();
|
||||||
buffer.flush();
|
buffer.flush(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,11 +18,12 @@ package net.schmizz.sshj.connection.channel;
|
|||||||
import net.schmizz.concurrent.Event;
|
import net.schmizz.concurrent.Event;
|
||||||
import net.schmizz.sshj.common.IOUtils;
|
import net.schmizz.sshj.common.IOUtils;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static com.hierynomus.sshj.backport.Sockets.asCloseable;
|
||||||
|
|
||||||
public class SocketStreamCopyMonitor
|
public class SocketStreamCopyMonitor
|
||||||
extends Thread {
|
extends Thread {
|
||||||
|
|
||||||
@@ -32,16 +33,6 @@ public class SocketStreamCopyMonitor
|
|||||||
setDaemon(true);
|
setDaemon(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Closeable wrapSocket(final Socket socket) {
|
|
||||||
return new Closeable() {
|
|
||||||
@Override
|
|
||||||
public void close()
|
|
||||||
throws IOException {
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void monitor(final int frequency, final TimeUnit unit,
|
public static void monitor(final int frequency, final TimeUnit unit,
|
||||||
final Event<IOException> x, final Event<IOException> y,
|
final Event<IOException> x, final Event<IOException> y,
|
||||||
final Channel channel, final Socket socket) {
|
final Channel channel, final Socket socket) {
|
||||||
@@ -54,7 +45,7 @@ public class SocketStreamCopyMonitor
|
|||||||
}
|
}
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(channel, wrapSocket(socket));
|
IOUtils.closeQuietly(channel, asCloseable(socket));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.connection.channel.direct;
|
package net.schmizz.sshj.connection.channel.direct;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,12 +16,12 @@
|
|||||||
package net.schmizz.sshj.connection.channel.direct;
|
package net.schmizz.sshj.connection.channel.direct;
|
||||||
|
|
||||||
import net.schmizz.concurrent.Event;
|
import net.schmizz.concurrent.Event;
|
||||||
|
import net.schmizz.sshj.common.IOUtils;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
import net.schmizz.sshj.common.StreamCopier;
|
import net.schmizz.sshj.common.StreamCopier;
|
||||||
import net.schmizz.sshj.connection.Connection;
|
import net.schmizz.sshj.connection.Connection;
|
||||||
import net.schmizz.sshj.connection.ConnectionException;
|
|
||||||
import net.schmizz.sshj.connection.channel.SocketStreamCopyMonitor;
|
import net.schmizz.sshj.connection.channel.SocketStreamCopyMonitor;
|
||||||
import net.schmizz.sshj.transport.TransportException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -30,6 +30,8 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static com.hierynomus.sshj.backport.Sockets.asCloseable;
|
||||||
|
|
||||||
public class LocalPortForwarder {
|
public class LocalPortForwarder {
|
||||||
|
|
||||||
public static class Parameters {
|
public static class Parameters {
|
||||||
@@ -112,11 +114,15 @@ public class LocalPortForwarder {
|
|||||||
this.serverSocket = serverSocket;
|
this.serverSocket = serverSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DirectTCPIPChannel openChannel(Socket socket)
|
private void startChannel(Socket socket) throws IOException {
|
||||||
throws TransportException, ConnectionException {
|
DirectTCPIPChannel chan = new DirectTCPIPChannel(conn, socket, parameters);
|
||||||
final DirectTCPIPChannel chan = new DirectTCPIPChannel(conn, socket, parameters);
|
try {
|
||||||
chan.open();
|
chan.open();
|
||||||
return chan;
|
chan.start();
|
||||||
|
} catch (IOException e) {
|
||||||
|
IOUtils.closeQuietly(chan, asCloseable(socket));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,7 +136,7 @@ public class LocalPortForwarder {
|
|||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
final Socket socket = serverSocket.accept();
|
final Socket socket = serverSocket.accept();
|
||||||
log.debug("Got connection from {}", socket.getRemoteSocketAddress());
|
log.debug("Got connection from {}", socket.getRemoteSocketAddress());
|
||||||
openChannel(socket).start();
|
startChannel(socket);
|
||||||
}
|
}
|
||||||
log.debug("Interrupted!");
|
log.debug("Interrupted!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -48,18 +48,24 @@ public interface Session
|
|||||||
/**
|
/**
|
||||||
* If the command exit violently {@link #getExitSignal() with a signal}, an error message would have been
|
* If the command exit violently {@link #getExitSignal() with a signal}, an error message would have been
|
||||||
* received and can be retrieved via this method. Otherwise, this method will return {@code null}.
|
* received and can be retrieved via this method. Otherwise, this method will return {@code null}.
|
||||||
|
* <p/>
|
||||||
|
* <strong>NOTE: </strong> Always call {@link #close()} first before inspecting the exit error message.
|
||||||
*/
|
*/
|
||||||
String getExitErrorMessage();
|
String getExitErrorMessage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Signal signal} if the command exit violently, or {@code null} if this information was not
|
* Returns the {@link Signal signal} if the command exit violently, or {@code null} if this information was not
|
||||||
* received.
|
* received.
|
||||||
|
* <p/>
|
||||||
|
* <strong>NOTE: </strong> Always call {@link #close()} first before inspecting the exit signal.
|
||||||
*/
|
*/
|
||||||
Signal getExitSignal();
|
Signal getExitSignal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the exit status of the command if it was received, or {@code null} if this information was not
|
* Returns the exit status of the command if it was received, or {@code null} if this information was not
|
||||||
* received.
|
* received.
|
||||||
|
* <p/>
|
||||||
|
* <strong>NOTE: </strong> Always call {@link #close()} first before inspecting the exit status.
|
||||||
*/
|
*/
|
||||||
Integer getExitStatus();
|
Integer getExitStatus();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.connection.channel.direct;
|
package net.schmizz.sshj.connection.channel.direct;
|
||||||
|
|
||||||
@@ -117,7 +97,7 @@ public class SessionChannel
|
|||||||
public Command exec(String command)
|
public Command exec(String command)
|
||||||
throws ConnectionException, TransportException {
|
throws ConnectionException, TransportException {
|
||||||
checkReuse();
|
checkReuse();
|
||||||
log.info("Will request to exec `{}`", command);
|
log.debug("Will request to exec `{}`", command);
|
||||||
sendChannelRequest("exec", true, new Buffer.PlainBuffer().putString(command))
|
sendChannelRequest("exec", true, new Buffer.PlainBuffer().putString(command))
|
||||||
.await(conn.getTimeoutMs(), TimeUnit.MILLISECONDS);
|
.await(conn.getTimeoutMs(), TimeUnit.MILLISECONDS);
|
||||||
usedUp = true;
|
usedUp = true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.schmizz.sshj.connection.channel.direct;
|
package net.schmizz.sshj.connection.channel.direct;
|
||||||
|
|
||||||
/** Various signals that may be sent or received. The signals are from POSIX and simply miss the {@code "SIG_"} prefix. */
|
/** Various signals that may be sent or received. The signals are from POSIX and simply miss the {@code "SIG_"} prefix. */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -12,26 +12,6 @@
|
|||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
* This file may incorporate work covered by the following copyright and
|
|
||||||
* permission notice:
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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 net.schmizz.sshj.connection.channel.forwarded;
|
package net.schmizz.sshj.connection.channel.forwarded;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.schmizz.sshj.connection.channel.forwarded;
|
package net.schmizz.sshj.connection.channel.forwarded;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.IOUtils;
|
import net.schmizz.sshj.common.IOUtils;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -117,6 +117,34 @@ public class RemotePortForwarder
|
|||||||
return address + ":" + port;
|
return address + ":" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean handles(ForwardedTCPIPChannel channel) {
|
||||||
|
Forward channelForward = channel.getParentForward();
|
||||||
|
if (channelForward.getPort() != port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ("".equals(address)) {
|
||||||
|
// This forward handles all protocols
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (channelForward.address.equals(address)) {
|
||||||
|
// Addresses match up
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ("localhost".equals(address) && (channelForward.address.equals("127.0.0.1") || channelForward.address.equals("::1"))) {
|
||||||
|
// Localhost special case.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ("::".equals(address) && channelForward.address.indexOf("::") > 0) {
|
||||||
|
// Listen on all IPv6
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ("0.0.0.0".equals(address) && channelForward.address.indexOf('.') > 0) {
|
||||||
|
// Listen on all IPv4
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A {@code forwarded-tcpip} channel. */
|
/** A {@code forwarded-tcpip} channel. */
|
||||||
@@ -224,11 +252,15 @@ public class RemotePortForwarder
|
|||||||
} catch (Buffer.BufferException be) {
|
} catch (Buffer.BufferException be) {
|
||||||
throw new ConnectionException(be);
|
throw new ConnectionException(be);
|
||||||
}
|
}
|
||||||
if (listeners.containsKey(chan.getParentForward()))
|
|
||||||
callListener(listeners.get(chan.getParentForward()), chan);
|
for (Forward forward : listeners.keySet()) {
|
||||||
else
|
if (forward.handles(chan)) {
|
||||||
chan.reject(OpenFailException.Reason.ADMINISTRATIVELY_PROHIBITED, "Forwarding was not requested on `"
|
callListener(listeners.get(forward), chan);
|
||||||
+ chan.getParentForward() + "`");
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chan.reject(OpenFailException.Reason.ADMINISTRATIVELY_PROHIBITED, "Forwarding was not requested on `"
|
||||||
|
+ chan.getParentForward() + "`");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
package net.schmizz.sshj.sftp;
|
package net.schmizz.sshj.sftp;
|
||||||
|
|
||||||
import net.schmizz.concurrent.Promise;
|
import net.schmizz.concurrent.Promise;
|
||||||
|
import net.schmizz.sshj.common.SSHException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -62,7 +64,7 @@ public class PacketReader
|
|||||||
| lenBuf[3] & 0x000000ffL);
|
| lenBuf[3] & 0x000000ffL);
|
||||||
|
|
||||||
if (len > SFTPPacket.MAX_SIZE) {
|
if (len > SFTPPacket.MAX_SIZE) {
|
||||||
throw new IllegalStateException("Invalid packet: indicated length "+len+" too large");
|
throw new SSHException(String.format("Indicated packet length %d too large", len));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) len;
|
return (int) len;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -63,4 +63,4 @@ public class PathComponents {
|
|||||||
return "[parent=" + parent + "; name=" + name + "; path=" + path + "]";
|
return "[parent=" + parent + "; name=" + name + "; path=" + path + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2012 sshj contributors
|
* Copyright (C)2009 - SSHJ Contributors
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user