mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
manual backmerge from netling/
This commit is contained in:
@@ -35,7 +35,6 @@ public class Exec {
|
||||
|
||||
Command cmd = ssh.startSession().exec("ping -c 1 google.com");
|
||||
|
||||
// Pipe.pipe(cmd.getInputStream(), System.out, cmd.getLocalMaxPacketSize(), false);
|
||||
System.out.print(cmd.getOutputAsString());
|
||||
System.out.println("\n** exit status: " + cmd.getExitStatus());
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ public class LocalPF {
|
||||
* _We_ listen on localhost:8080 and forward all connections on to server, which then forwards it to
|
||||
* google.com:80
|
||||
*/
|
||||
|
||||
ssh.newLocalPortForwarder(new InetSocketAddress("localhost", 8080), "google.com", 80)
|
||||
.listen();
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@ class RudimentaryPTY {
|
||||
|
||||
if (shell != null)
|
||||
shell.close();
|
||||
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,13 +25,14 @@ public class SCPDownload {
|
||||
public static void main(String[] args)
|
||||
throws IOException {
|
||||
SSHClient ssh = new SSHClient();
|
||||
// ssh.useCompression(); // Can lead to significant speedup
|
||||
// ssh.useCompression(); // Can lead to significant speedup (needs JZlib in classpath)
|
||||
ssh.loadKnownHosts();
|
||||
ssh.connect("localhost");
|
||||
try {
|
||||
ssh.authPublickey(System.getProperty("user.name"));
|
||||
ssh.newSCPFileTransfer()
|
||||
.download("well", "/tmp/");
|
||||
final String src = "test_file";
|
||||
final String target = "/tmp/";
|
||||
ssh.newSCPFileTransfer().download(src, target);
|
||||
} finally {
|
||||
ssh.disconnect();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package examples;
|
||||
|
||||
import net.schmizz.sshj.SSHClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/** This example demonstrates uploading of a file over SCP to the SSH server. */
|
||||
@@ -31,9 +32,12 @@ public class SCPUpload {
|
||||
ssh.authPublickey(System.getProperty("user.name"));
|
||||
|
||||
// Present here to demo algorithm renegotiation - could have just put this before connect()
|
||||
// Make sure JZlib is in classpath for this to work
|
||||
ssh.useCompression();
|
||||
|
||||
ssh.newSCPFileTransfer().upload("/Users/shikhar/well", "/tmp/");
|
||||
final String src = System.getProperty("user.home") + File.separator + "test_file";
|
||||
final String target = "/tmp/";
|
||||
ssh.newSCPFileTransfer().upload(src, target);
|
||||
} finally {
|
||||
ssh.disconnect();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,9 @@ public class SFTPDownload {
|
||||
ssh.connect("localhost");
|
||||
try {
|
||||
ssh.authPublickey(System.getProperty("user.name"));
|
||||
ssh.newSFTPClient().get("well", "/tmp/");
|
||||
final String src = "test_file";
|
||||
final String target = "/tmp/";
|
||||
ssh.newSFTPClient().get(src, target);
|
||||
} finally {
|
||||
ssh.disconnect();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package examples;
|
||||
|
||||
import net.schmizz.sshj.SSHClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/** This example demonstrates uploading of a file over SFTP to the SSH server. */
|
||||
@@ -29,7 +30,9 @@ public class SFTPUpload {
|
||||
ssh.connect("localhost");
|
||||
try {
|
||||
ssh.authPublickey(System.getProperty("user.name"));
|
||||
ssh.newSFTPClient().put("/Users/shikhar/well", "/tmp/");
|
||||
final String src = System.getProperty("user.home") + File.separator + "test_file";
|
||||
final String target = "/tmp/";
|
||||
ssh.newSFTPClient().put(src, target);
|
||||
} finally {
|
||||
ssh.disconnect();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class X11 {
|
||||
*/
|
||||
sess.reqX11Forwarding("MIT-MAGIC-COOKIE-1", "b0956167c9ad8f34c8a2788878307dc9", 0);
|
||||
|
||||
Command cmd = sess.exec("mate");
|
||||
Command cmd = sess.exec("/usr/X11/bin/xcalc");
|
||||
|
||||
new StreamCopier("stdout", cmd.getInputStream(), System.out).start();
|
||||
new StreamCopier("stderr", cmd.getErrorStream(), System.err).start();
|
||||
|
||||
@@ -44,29 +44,35 @@ public abstract class AbstractService
|
||||
timeout = trans.getTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Message msg, SSHPacket buf)
|
||||
throws SSHException {
|
||||
trans.sendUnimplemented();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyError(SSHException error) {
|
||||
log.debug("Was notified of {}", error.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUnimplemented(long seqNum)
|
||||
throws SSHException {
|
||||
throw new SSHException(DisconnectReason.PROTOCOL_ERROR, "Unexpected: SSH_MSG_UNIMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDisconnect()
|
||||
throws SSHException {
|
||||
log.debug("Was notified of disconnect");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void request()
|
||||
throws TransportException {
|
||||
final Service active = trans.getService();
|
||||
|
||||
@@ -62,34 +62,42 @@ public class ConfigImpl
|
||||
private List<Factory.Named<Signature>> signatureFactories;
|
||||
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<Cipher>> getCipherFactories() {
|
||||
return cipherFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<Compression>> getCompressionFactories() {
|
||||
return compressionFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<FileKeyProvider>> getFileKeyProviderFactories() {
|
||||
return fileKeyProviderFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<KeyExchange>> getKeyExchangeFactories() {
|
||||
return kexFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<MAC>> getMACFactories() {
|
||||
return macFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Factory<Random> getRandomFactory() {
|
||||
return randomFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<Signature>> getSignatureFactories() {
|
||||
return signatureFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
@@ -98,6 +106,7 @@ public class ConfigImpl
|
||||
setCipherFactories(Arrays.asList(cipherFactories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCipherFactories(List<Factory.Named<Cipher>> cipherFactories) {
|
||||
this.cipherFactories = cipherFactories;
|
||||
}
|
||||
@@ -106,6 +115,7 @@ public class ConfigImpl
|
||||
setCompressionFactories(Arrays.asList(compressionFactories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompressionFactories(List<Factory.Named<Compression>> compressionFactories) {
|
||||
this.compressionFactories = compressionFactories;
|
||||
}
|
||||
@@ -114,6 +124,7 @@ public class ConfigImpl
|
||||
setFileKeyProviderFactories(Arrays.asList(fileKeyProviderFactories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileKeyProviderFactories(List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories) {
|
||||
this.fileKeyProviderFactories = fileKeyProviderFactories;
|
||||
}
|
||||
@@ -122,6 +133,7 @@ public class ConfigImpl
|
||||
setKeyExchangeFactories(Arrays.asList(kexFactories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeyExchangeFactories(List<Factory.Named<KeyExchange>> kexFactories) {
|
||||
this.kexFactories = kexFactories;
|
||||
}
|
||||
@@ -130,10 +142,12 @@ public class ConfigImpl
|
||||
setMACFactories(Arrays.asList(macFactories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMACFactories(List<Factory.Named<MAC>> macFactories) {
|
||||
this.macFactories = macFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRandomFactory(Factory<Random> randomFactory) {
|
||||
this.randomFactory = randomFactory;
|
||||
}
|
||||
@@ -142,10 +156,12 @@ public class ConfigImpl
|
||||
setSignatureFactories(Arrays.asList(signatureFactories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSignatureFactories(List<Factory.Named<Signature>> signatureFactories) {
|
||||
this.signatureFactories = signatureFactories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ import java.util.List;
|
||||
* <p/>
|
||||
* <em>A simple example:</em>
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <pre>
|
||||
* client = new SSHClient();
|
||||
* client.initUserKnownHosts();
|
||||
@@ -165,6 +164,7 @@ public class SSHClient
|
||||
*/
|
||||
public void addHostKeyVerifier(final String host, final int port, final String fingerprint) {
|
||||
addHostKeyVerifier(new HostKeyVerifier() {
|
||||
@Override
|
||||
public boolean verify(String h, int p, PublicKey k) {
|
||||
return host.equals(h) && port == p && SecurityUtils.getFingerprint(k).equals(fingerprint);
|
||||
}
|
||||
@@ -587,6 +587,7 @@ public class SSHClient
|
||||
doKex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session startSession()
|
||||
throws ConnectionException, TransportException {
|
||||
assert isConnected() && isAuthenticated();
|
||||
|
||||
@@ -38,12 +38,7 @@ package net.schmizz.sshj.common;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Buffer<T extends Buffer<T>> {
|
||||
@@ -463,53 +458,16 @@ public class Buffer<T extends Buffer<T>> {
|
||||
|
||||
public PublicKey readPublicKey() {
|
||||
try {
|
||||
switch (KeyType.fromString(readString())) {
|
||||
case RSA: {
|
||||
BigInteger e = readMPInt();
|
||||
BigInteger n = readMPInt();
|
||||
KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA");
|
||||
return keyFactory.generatePublic(new RSAPublicKeySpec(n, e));
|
||||
}
|
||||
case DSA: {
|
||||
BigInteger p = readMPInt();
|
||||
BigInteger q = readMPInt();
|
||||
BigInteger g = readMPInt();
|
||||
BigInteger y = readMPInt();
|
||||
KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA");
|
||||
return keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g));
|
||||
}
|
||||
default:
|
||||
assert false;
|
||||
}
|
||||
final String type = readString();
|
||||
return KeyType.fromString(type).readPubKeyFromBuffer(type, this);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new SSHRuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T putPublicKey(PublicKey key) {
|
||||
final KeyType type = KeyType.fromKey(key);
|
||||
switch (type) {
|
||||
case RSA: {
|
||||
final RSAPublicKey rsaKey = (RSAPublicKey) key;
|
||||
putString(type.toString()) // ssh-rsa
|
||||
.putMPInt(rsaKey.getPublicExponent()) // e
|
||||
.putMPInt(rsaKey.getModulus()); // n
|
||||
break;
|
||||
}
|
||||
case DSA: {
|
||||
final DSAPublicKey dsaKey = (DSAPublicKey) key;
|
||||
putString(type.toString()) // ssh-dss
|
||||
.putMPInt(dsaKey.getParams().getP()) // p
|
||||
.putMPInt(dsaKey.getParams().getQ()) // q
|
||||
.putMPInt(dsaKey.getParams().getG()) // g
|
||||
.putMPInt(dsaKey.getY()); // y
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new SSHRuntimeException("Don't know how to encode key: " + key);
|
||||
}
|
||||
KeyType.fromKey(key).putPubKeyIntoBuffer(key, this);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,47 +15,117 @@
|
||||
*/
|
||||
package net.schmizz.sshj.common;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
|
||||
/** Type of key e.g. rsa, dsa */
|
||||
public enum KeyType {
|
||||
|
||||
/** SSH identifier for RSA keys */
|
||||
RSA("ssh-rsa", new KeyChecker() {
|
||||
public boolean isMyType(Key key) {
|
||||
RSA("ssh-rsa") {
|
||||
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
final BigInteger e = buf.readMPInt();
|
||||
final BigInteger n = buf.readMPInt();
|
||||
final KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA");
|
||||
return keyFactory.generatePublic(new RSAPublicKeySpec(n, e));
|
||||
|
||||
}
|
||||
@Override
|
||||
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
final RSAPublicKey rsaKey = (RSAPublicKey) pk;
|
||||
buf.putString(sType)
|
||||
.putMPInt(rsaKey.getPublicExponent()) // e
|
||||
.putMPInt(rsaKey.getModulus()); // n
|
||||
|
||||
}
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return (key instanceof RSAPublicKey || key instanceof RSAPrivateKey);
|
||||
}
|
||||
}),
|
||||
|
||||
},
|
||||
|
||||
/** SSH identifier for DSA keys */
|
||||
DSA("ssh-dss", new KeyChecker() {
|
||||
public boolean isMyType(Key key) {
|
||||
DSA("ssh-dss") {
|
||||
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
final BigInteger p = buf.readMPInt();
|
||||
final BigInteger q = buf.readMPInt();
|
||||
final BigInteger g = buf.readMPInt();
|
||||
final BigInteger y = buf.readMPInt();
|
||||
final KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA");
|
||||
return keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g));
|
||||
}
|
||||
@Override
|
||||
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
final DSAPublicKey dsaKey = (DSAPublicKey) pk;
|
||||
buf.putString(sType)
|
||||
.putMPInt(dsaKey.getParams().getP()) // p
|
||||
.putMPInt(dsaKey.getParams().getQ()) // q
|
||||
.putMPInt(dsaKey.getParams().getG()) // g
|
||||
.putMPInt(dsaKey.getY()); // y
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return (key instanceof DSAPublicKey || key instanceof DSAPrivateKey);
|
||||
}
|
||||
}),
|
||||
|
||||
},
|
||||
|
||||
/** Unrecognized */
|
||||
UNKNOWN("unknown", null);
|
||||
UNKNOWN("unknown") {
|
||||
|
||||
private static interface KeyChecker {
|
||||
boolean isMyType(Key key);
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
throw new UnsupportedOperationException("Don't know how to decode key:" + type);
|
||||
}
|
||||
|
||||
private final String sType;
|
||||
private final KeyChecker checker;
|
||||
@Override
|
||||
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
throw new UnsupportedOperationException("Don't know how to encode key: " + pk);
|
||||
}
|
||||
|
||||
private KeyType(String type, KeyChecker checker) {
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
protected final String sType;
|
||||
|
||||
private KeyType(String type) {
|
||||
this.sType = type;
|
||||
this.checker = checker;
|
||||
}
|
||||
|
||||
public abstract PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
public abstract void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf);
|
||||
|
||||
|
||||
protected abstract boolean isMyType(Key key);
|
||||
|
||||
public static KeyType fromKey(Key key) {
|
||||
for (KeyType kt : values())
|
||||
if (kt.checker != null && kt.checker.isMyType((key)))
|
||||
if (kt.isMyType((key)))
|
||||
return kt;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public class SSHException
|
||||
|
||||
public static final ExceptionChainer<SSHException> chainer = new ExceptionChainer<SSHException>() {
|
||||
|
||||
@Override
|
||||
public SSHException chain(Throwable t) {
|
||||
if (t instanceof SSHException)
|
||||
return (SSHException) t;
|
||||
|
||||
@@ -34,6 +34,7 @@ public class StreamCopier
|
||||
|
||||
public static ErrorCallback closeOnErrorCallback(final Closeable... toClose) {
|
||||
return new ErrorCallback() {
|
||||
@Override
|
||||
public void onError(IOException ioe) {
|
||||
IOUtils.closeQuietly(toClose);
|
||||
}
|
||||
@@ -82,6 +83,7 @@ public class StreamCopier
|
||||
private boolean keepFlushing = true;
|
||||
|
||||
private ErrorCallback errCB = new ErrorCallback() {
|
||||
@Override
|
||||
public void onError(IOException ioe) {
|
||||
}
|
||||
}; // Default null cb
|
||||
|
||||
@@ -24,6 +24,7 @@ public class ConnectionException
|
||||
extends SSHException {
|
||||
|
||||
public static final ExceptionChainer<ConnectionException> chainer = new ExceptionChainer<ConnectionException>() {
|
||||
@Override
|
||||
public ConnectionException chain(Throwable t) {
|
||||
if (t instanceof ConnectionException)
|
||||
return (ConnectionException) t;
|
||||
|
||||
@@ -63,19 +63,23 @@ public class ConnectionImpl
|
||||
super("ssh-connection", trans);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach(Channel chan) {
|
||||
log.info("Attaching `{}` channel (#{})", chan.getType(), chan.getID());
|
||||
channels.put(chan.getID(), chan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel get(int id) {
|
||||
return channels.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForwardedChannelOpener get(String chanType) {
|
||||
return openers.get(chanType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forget(Channel chan) {
|
||||
log.info("Forgetting `{}` channel (#{})", chan.getType(), chan.getID());
|
||||
channels.remove(chan.getID());
|
||||
@@ -85,11 +89,13 @@ public class ConnectionImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forget(ForwardedChannelOpener opener) {
|
||||
log.info("Forgetting opener for `{}` channels: {}", opener.getChannelType(), opener);
|
||||
openers.remove(opener.getChannelType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach(ForwardedChannelOpener opener) {
|
||||
log.info("Attaching opener for `{}` channels: {}", opener.getChannelType(), opener);
|
||||
openers.put(opener.getChannelType(), opener);
|
||||
@@ -146,26 +152,32 @@ public class ConnectionImpl
|
||||
channels.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPacketSize() {
|
||||
return maxPacketSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport() {
|
||||
return trans;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPacketSize(int maxPacketSize) {
|
||||
this.maxPacketSize = maxPacketSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWindowSize() {
|
||||
return windowSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindowSize(int windowSize) {
|
||||
this.windowSize = windowSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join()
|
||||
throws InterruptedException {
|
||||
synchronized (internalSynchronizer) {
|
||||
@@ -174,10 +186,12 @@ public class ConnectionImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextID() {
|
||||
return nextID.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<SSHPacket, ConnectionException> sendGlobalRequest(String name, boolean wantReply,
|
||||
byte[] specifics)
|
||||
throws TransportException {
|
||||
@@ -221,6 +235,7 @@ public class ConnectionImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendOpenFailure(int recipient, Reason reason, String message)
|
||||
throws TransportException {
|
||||
trans.write(new SSHPacket(Message.CHANNEL_OPEN_FAILURE)
|
||||
|
||||
@@ -125,46 +125,57 @@ public abstract class AbstractChannel
|
||||
log.info("Initialized - {}", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoExpand() {
|
||||
return autoExpand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalMaxPacketSize() {
|
||||
return lwin.getMaxPacketSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalWinSize() {
|
||||
return lwin.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemoteMaxPacketSize() {
|
||||
return rwin.getMaxPacketSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemoteWinSize() {
|
||||
return rwin.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Message msg, SSHPacket buf)
|
||||
throws ConnectionException, TransportException {
|
||||
switch (msg) {
|
||||
@@ -223,6 +234,7 @@ public abstract class AbstractChannel
|
||||
IOUtils.closeQuietly(in, out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyError(SSHException error) {
|
||||
log.debug("Channel #{} got notified of {}", getID(), error.toString());
|
||||
|
||||
@@ -235,10 +247,12 @@ public abstract class AbstractChannel
|
||||
finishOff();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoExpand(boolean autoExpand) {
|
||||
this.autoExpand = autoExpand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
throws ConnectionException, TransportException {
|
||||
lock.lock();
|
||||
@@ -267,6 +281,7 @@ public abstract class AbstractChannel
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isOpen() {
|
||||
lock.lock();
|
||||
try {
|
||||
@@ -371,6 +386,7 @@ public abstract class AbstractChannel
|
||||
in.eof();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void sendEOF()
|
||||
throws TransportException {
|
||||
try {
|
||||
|
||||
@@ -76,6 +76,7 @@ public interface Channel
|
||||
|
||||
|
||||
/** Close this channel. */
|
||||
@Override
|
||||
void close()
|
||||
throws TransportException, ConnectionException;
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ public final class ChannelInputStream
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void notifyError(SSHException error) {
|
||||
this.error = error;
|
||||
eof();
|
||||
|
||||
@@ -102,6 +102,7 @@ public final class ChannelOutputStream
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void notifyError(SSHException error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public abstract class AbstractDirectChannel
|
||||
conn.attach(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open()
|
||||
throws ConnectionException, TransportException {
|
||||
trans.write(buildOpenReq());
|
||||
|
||||
@@ -48,6 +48,7 @@ public class LocalPortForwarder {
|
||||
|
||||
final ErrorCallback closer = StreamCopier.closeOnErrorCallback(this,
|
||||
new Closeable() {
|
||||
@Override
|
||||
public void close()
|
||||
throws IOException {
|
||||
sock.close();
|
||||
|
||||
@@ -46,7 +46,7 @@ import net.schmizz.sshj.transport.TransportException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -70,22 +70,13 @@ public class
|
||||
super(conn, "session");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allocateDefaultPTY()
|
||||
throws ConnectionException, TransportException {
|
||||
// TODO FIXME (maybe?): These modes were originally copied from what SSHD was doing;
|
||||
// and then the echo modes were set to 0 to better serve the PTY example.
|
||||
// Not sure what default PTY modes should be.
|
||||
final Map<PTYMode, Integer> modes = new HashMap<PTYMode, Integer>();
|
||||
modes.put(PTYMode.ISIG, 1);
|
||||
modes.put(PTYMode.ICANON, 1);
|
||||
modes.put(PTYMode.ECHO, 0);
|
||||
modes.put(PTYMode.ECHOE, 0);
|
||||
modes.put(PTYMode.ECHOK, 0);
|
||||
modes.put(PTYMode.ECHONL, 0);
|
||||
modes.put(PTYMode.NOFLSH, 0);
|
||||
allocatePTY("vt100", 0, 0, 0, 0, modes);
|
||||
allocatePTY("vt100", 80, 24, 0, 0, Collections.<PTYMode, Integer>emptyMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allocatePTY(String term, int cols, int rows, int width, int height, Map<PTYMode, Integer> modes)
|
||||
throws ConnectionException, TransportException {
|
||||
sendChannelRequest(
|
||||
@@ -101,10 +92,12 @@ public class
|
||||
).await(conn.getTimeout(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean canDoFlowControl() {
|
||||
return canDoFlowControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeWindowDimensions(int cols, int rows, int width, int height)
|
||||
throws TransportException {
|
||||
sendChannelRequest(
|
||||
@@ -118,6 +111,7 @@ public class
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command exec(String command)
|
||||
throws ConnectionException, TransportException {
|
||||
log.info("Will request to exec `{}`", command);
|
||||
@@ -126,27 +120,33 @@ public class
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorAsString()
|
||||
throws IOException {
|
||||
return StreamCopier.copyStreamToString(err);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getErrorStream() {
|
||||
return err;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExitErrorMessage() {
|
||||
return exitErrMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signal getExitSignal() {
|
||||
return exitSignal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getExitStatus() {
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutputAsString()
|
||||
throws IOException {
|
||||
return StreamCopier.copyStreamToString(getInputStream());
|
||||
@@ -168,6 +168,7 @@ public class
|
||||
super.handleRequest(req, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reqX11Forwarding(String authProto, String authCookie, int screen)
|
||||
throws ConnectionException,
|
||||
TransportException {
|
||||
@@ -182,23 +183,27 @@ public class
|
||||
).await(conn.getTimeout(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvVar(String name, String value)
|
||||
throws ConnectionException, TransportException {
|
||||
sendChannelRequest("env", true, new Buffer.PlainBuffer().putString(name).putString(value))
|
||||
.await(conn.getTimeout(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void signal(Signal sig)
|
||||
throws TransportException {
|
||||
sendChannelRequest("signal", false, new Buffer.PlainBuffer().putString(sig.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shell startShell()
|
||||
throws ConnectionException, TransportException {
|
||||
sendChannelRequest("shell", true, null).await(conn.getTimeout(), TimeUnit.SECONDS);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subsystem startSubsystem(String name)
|
||||
throws ConnectionException, TransportException {
|
||||
log.info("Will request `{}` subsystem", name);
|
||||
@@ -207,6 +212,7 @@ public class
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getExitWasCoreDumped() {
|
||||
return wasCoreDumped;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ public abstract class AbstractForwardedChannel
|
||||
init(recipient, remoteWinSize, remoteMaxPacketSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void confirm()
|
||||
throws TransportException {
|
||||
log.info("Confirming `{}` channel #{}", getType(), getID());
|
||||
@@ -74,16 +75,19 @@ public abstract class AbstractForwardedChannel
|
||||
open.set();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(Reason reason, String message)
|
||||
throws TransportException {
|
||||
log.info("Rejecting `{}` channel: {}", getType(), message);
|
||||
conn.sendOpenFailure(getRecipient(), reason, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginatorIP() {
|
||||
return origIP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOriginatorPort() {
|
||||
return origPort;
|
||||
}
|
||||
|
||||
@@ -40,14 +40,12 @@ public abstract class AbstractForwardedChannelOpener
|
||||
this.conn = conn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChannelType() {
|
||||
return chanType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calls the listener with the new channel in a separate thread.
|
||||
*/
|
||||
|
||||
/** Calls the listener with the new channel in a separate thread. */
|
||||
protected void callListener(final ConnectListener listener, final Channel.Forwarded chan) {
|
||||
new Thread() {
|
||||
|
||||
|
||||
@@ -208,6 +208,7 @@ public class RemotePortForwarder
|
||||
* Internal API. Creates a {@link ForwardedTCPIPChannel} from the {@code CHANNEL_OPEN} request and calls associated
|
||||
* {@code ConnectListener} for that forward in a separate thread.
|
||||
*/
|
||||
@Override
|
||||
public void handleOpen(SSHPacket buf)
|
||||
throws ConnectionException, TransportException {
|
||||
final ForwardedTCPIPChannel chan = new ForwardedTCPIPChannel(conn, buf.readInt(), buf.readInt(), buf.readInt(),
|
||||
|
||||
@@ -40,6 +40,7 @@ public class SocketForwardingConnectListener
|
||||
}
|
||||
|
||||
/** On connect, confirm the channel and start forwarding. */
|
||||
@Override
|
||||
public void gotConnect(Channel.Forwarded chan)
|
||||
throws IOException {
|
||||
log.info("New connection from " + chan.getOriginatorIP() + ":" + chan.getOriginatorPort());
|
||||
@@ -54,6 +55,7 @@ public class SocketForwardingConnectListener
|
||||
chan.confirm();
|
||||
|
||||
final ErrorCallback closer = StreamCopier.closeOnErrorCallback(chan, new Closeable() {
|
||||
@Override
|
||||
public void close()
|
||||
throws IOException {
|
||||
sock.close();
|
||||
|
||||
@@ -52,10 +52,13 @@ public class X11Forwarder
|
||||
}
|
||||
|
||||
/** Internal API */
|
||||
@Override
|
||||
public void handleOpen(SSHPacket buf)
|
||||
throws ConnectionException, TransportException {
|
||||
callListener(listener, new X11Channel(conn, buf.readInt(), buf.readInt(), buf.readInt(), buf.readString(), buf
|
||||
.readInt()));
|
||||
callListener(listener, new X11Channel(conn,
|
||||
buf.readInt(),
|
||||
buf.readInt(), buf.readInt(),
|
||||
buf.readString(), buf.readInt()));
|
||||
}
|
||||
|
||||
/** Stop handling {@code x11} channel open requests. De-registers itself with connection layer. */
|
||||
|
||||
@@ -61,6 +61,7 @@ public class RandomAccessRemoteFile
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean()
|
||||
throws IOException {
|
||||
final int ch = read();
|
||||
@@ -69,6 +70,7 @@ public class RandomAccessRemoteFile
|
||||
return (ch != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte()
|
||||
throws IOException {
|
||||
final int ch = this.read();
|
||||
@@ -77,6 +79,7 @@ public class RandomAccessRemoteFile
|
||||
return (byte) (ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char readChar()
|
||||
throws IOException {
|
||||
final int ch1 = this.read();
|
||||
@@ -86,21 +89,25 @@ public class RandomAccessRemoteFile
|
||||
return (char) ((ch1 << 8) + ch2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble()
|
||||
throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat()
|
||||
throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b)
|
||||
throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
@@ -112,6 +119,7 @@ public class RandomAccessRemoteFile
|
||||
} while (n < len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt()
|
||||
throws IOException {
|
||||
final int ch1 = read();
|
||||
@@ -123,6 +131,7 @@ public class RandomAccessRemoteFile
|
||||
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readLine()
|
||||
throws IOException {
|
||||
StringBuffer input = new StringBuffer();
|
||||
@@ -151,11 +160,13 @@ public class RandomAccessRemoteFile
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong()
|
||||
throws IOException {
|
||||
return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort()
|
||||
throws IOException {
|
||||
final int ch1 = this.read();
|
||||
@@ -165,11 +176,13 @@ public class RandomAccessRemoteFile
|
||||
return (short) ((ch1 << 8) + ch2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readUTF()
|
||||
throws IOException {
|
||||
return DataInputStream.readUTF(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedByte()
|
||||
throws IOException {
|
||||
final int ch = this.read();
|
||||
@@ -178,6 +191,7 @@ public class RandomAccessRemoteFile
|
||||
return ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedShort()
|
||||
throws IOException {
|
||||
final int ch1 = this.read();
|
||||
@@ -187,6 +201,7 @@ public class RandomAccessRemoteFile
|
||||
return (ch1 << 8) + ch2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skipBytes(int n)
|
||||
throws IOException {
|
||||
if (n <= 0)
|
||||
@@ -202,45 +217,53 @@ public class RandomAccessRemoteFile
|
||||
return (int) (newpos - pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int i)
|
||||
throws IOException {
|
||||
singleByte[0] = (byte) i;
|
||||
write(singleByte);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b)
|
||||
throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
rf.write(fp, b, off, len);
|
||||
fp += (len - off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean v)
|
||||
throws IOException {
|
||||
write(v ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int v)
|
||||
throws IOException {
|
||||
write(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(String s)
|
||||
throws IOException {
|
||||
final byte[] b = s.getBytes();
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChar(int v)
|
||||
throws IOException {
|
||||
write((v >>> 8) & 0xFF);
|
||||
write(v & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChars(String s)
|
||||
throws IOException {
|
||||
final int clen = s.length();
|
||||
@@ -255,16 +278,19 @@ public class RandomAccessRemoteFile
|
||||
write(b, 0, blen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(double v)
|
||||
throws IOException {
|
||||
writeLong(Double.doubleToLongBits(v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(float v)
|
||||
throws IOException {
|
||||
writeInt(Float.floatToIntBits(v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int v)
|
||||
throws IOException {
|
||||
write((v >>> 24) & 0xFF);
|
||||
@@ -273,6 +299,7 @@ public class RandomAccessRemoteFile
|
||||
write(v & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long v)
|
||||
throws IOException {
|
||||
write((int) (v >>> 56) & 0xFF);
|
||||
@@ -285,12 +312,14 @@ public class RandomAccessRemoteFile
|
||||
write((int) v & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(int v)
|
||||
throws IOException {
|
||||
write((v >>> 8) & 0xFF);
|
||||
write(v & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeUTF(String str)
|
||||
throws IOException {
|
||||
final DataOutputStream dos = new DataOutputStream(rf.new RemoteFileOutputStream(fp));
|
||||
|
||||
@@ -45,6 +45,7 @@ abstract class RemoteResource
|
||||
return requester.newRequest(type).putString(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
throws IOException {
|
||||
log.info("Closing `{}`", this);
|
||||
|
||||
@@ -87,10 +87,12 @@ public class SFTPEngine
|
||||
return negotiatedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Request newRequest(PacketType type) {
|
||||
return new Request(type, reqID = reqID + 1 & 0xffffffffL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response doRequest(Request req)
|
||||
throws IOException {
|
||||
reader.expectResponseTo(req);
|
||||
|
||||
@@ -25,6 +25,7 @@ public class SFTPException
|
||||
|
||||
public static final ExceptionChainer<SFTPException> chainer = new ExceptionChainer<SFTPException>() {
|
||||
|
||||
@Override
|
||||
public SFTPException chain(Throwable t) {
|
||||
if (t instanceof SFTPException)
|
||||
return (SFTPException) t;
|
||||
|
||||
@@ -39,12 +39,14 @@ public class SFTPFileTransfer
|
||||
private volatile RemoteResourceFilter downloadFilter = defaultRemoteFilter;
|
||||
|
||||
private static final FileFilter defaultLocalFilter = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathName) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private static final RemoteResourceFilter defaultRemoteFilter = new RemoteResourceFilter() {
|
||||
@Override
|
||||
public boolean accept(RemoteResourceInfo resource) {
|
||||
return true;
|
||||
}
|
||||
@@ -55,11 +57,13 @@ public class SFTPFileTransfer
|
||||
this.pathHelper = new PathHelper(sftp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upload(String source, String dest)
|
||||
throws IOException {
|
||||
new Uploader().upload(new File(source), dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(String source, String dest)
|
||||
throws IOException {
|
||||
final PathComponents pathComponents = pathHelper.getComponents(source);
|
||||
|
||||
@@ -54,6 +54,7 @@ public abstract class AbstractSignature
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(PublicKey publicKey, PrivateKey privateKey) {
|
||||
try {
|
||||
signature = SecurityUtils.getSignature(algorithm);
|
||||
@@ -66,10 +67,12 @@ public abstract class AbstractSignature
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] foo) {
|
||||
update(foo, 0, foo.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] foo, int off, int len) {
|
||||
try {
|
||||
signature.update(foo, off, len);
|
||||
|
||||
@@ -48,10 +48,12 @@ public class SignatureDSA
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
||||
|
||||
@Override
|
||||
public Signature create() {
|
||||
return new SignatureDSA();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return KeyType.DSA.toString();
|
||||
}
|
||||
@@ -62,6 +64,7 @@ public class SignatureDSA
|
||||
super("SHA1withDSA");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign() {
|
||||
byte[] sig;
|
||||
try {
|
||||
@@ -102,6 +105,7 @@ public class SignatureDSA
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(byte[] sig) {
|
||||
sig = extractSig(sig);
|
||||
|
||||
|
||||
@@ -48,10 +48,12 @@ public class SignatureRSA
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
||||
|
||||
@Override
|
||||
public Signature create() {
|
||||
return new SignatureRSA();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return KeyType.RSA.toString();
|
||||
}
|
||||
@@ -62,6 +64,7 @@ public class SignatureRSA
|
||||
super("SHA1withRSA");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign() {
|
||||
try {
|
||||
return signature.sign();
|
||||
@@ -70,6 +73,7 @@ public class SignatureRSA
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(byte[] sig) {
|
||||
sig = extractSig(sig);
|
||||
try {
|
||||
|
||||
@@ -331,6 +331,7 @@ final class KeyExchanger
|
||||
transport.getDecoder().setAlgorithms(cipher_S2C, mac_S2C, compression_S2C);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Message msg, SSHPacket buf)
|
||||
throws TransportException {
|
||||
switch (expected) {
|
||||
@@ -378,6 +379,7 @@ final class KeyExchanger
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyError(SSHException error) {
|
||||
log.debug("Got notified of {}", error.toString());
|
||||
FutureUtils.alertAll(error, kexInitSent, done);
|
||||
|
||||
@@ -25,6 +25,7 @@ public class TransportException
|
||||
|
||||
/** @see ExceptionChainer */
|
||||
public static final ExceptionChainer<TransportException> chainer = new ExceptionChainer<TransportException>() {
|
||||
@Override
|
||||
public TransportException chain(Throwable t) {
|
||||
if (t instanceof TransportException)
|
||||
return (TransportException) t;
|
||||
|
||||
@@ -133,6 +133,7 @@ public final class TransportImpl
|
||||
clientID = "SSH-2.0-" + config.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(String remoteHost, int remotePort, InputStream in, OutputStream out)
|
||||
throws TransportException {
|
||||
connInfo = new ConnInfo(remoteHost, remotePort, in, out);
|
||||
@@ -214,10 +215,12 @@ public final class TransportImpl
|
||||
return ident;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHostKeyVerifier(HostKeyVerifier hkv) {
|
||||
kexer.addHostKeyVerifier(hkv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doKex()
|
||||
throws TransportException {
|
||||
kexer.startKex(true);
|
||||
@@ -227,50 +230,62 @@ public final class TransportImpl
|
||||
return kexer.isKexDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeartbeatInterval() {
|
||||
return heartbeater.getInterval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeartbeatInterval(int interval) {
|
||||
heartbeater.setInterval(interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteHost() {
|
||||
return connInfo.host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemotePort() {
|
||||
return connInfo.port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientVersion() {
|
||||
return clientID.substring(8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerVersion() {
|
||||
return serverID == null ? serverID : serverID.substring(8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSessionID() {
|
||||
return kexer.getSessionID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Service getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setService(Service service) {
|
||||
if (service == null)
|
||||
service = nullService;
|
||||
@@ -279,6 +294,7 @@ public final class TransportImpl
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reqService(Service service)
|
||||
throws TransportException {
|
||||
serviceAccept.lock();
|
||||
@@ -305,16 +321,19 @@ public final class TransportImpl
|
||||
write(new SSHPacket(Message.SERVICE_REQUEST).putString(serviceName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticated() {
|
||||
this.authed = true;
|
||||
encoder.setAuthenticated();
|
||||
decoder.setAuthenticated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticated() {
|
||||
return authed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendUnimplemented()
|
||||
throws TransportException {
|
||||
final long seq = decoder.getSequenceNumber();
|
||||
@@ -322,23 +341,28 @@ public final class TransportImpl
|
||||
return write(new SSHPacket(Message.UNIMPLEMENTED).putInt(seq));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join()
|
||||
throws TransportException {
|
||||
close.await();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return reader.isAlive() && !close.isSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
disconnect(DisconnectReason.BY_APPLICATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(DisconnectReason reason) {
|
||||
disconnect(reason, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(DisconnectReason reason, String message) {
|
||||
close.lock(); // CAS type operation on close
|
||||
try {
|
||||
@@ -357,6 +381,7 @@ public final class TransportImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long write(SSHPacket payload)
|
||||
throws TransportException {
|
||||
writeLock.lock();
|
||||
@@ -416,6 +441,7 @@ public final class TransportImpl
|
||||
*
|
||||
* @throws SSHException if an error occurs during handling (unrecoverable)
|
||||
*/
|
||||
@Override
|
||||
public void handle(Message msg, SSHPacket buf)
|
||||
throws SSHException {
|
||||
this.msg = msg;
|
||||
|
||||
@@ -42,10 +42,12 @@ public class AES128CBC
|
||||
/** Named factory for AES128CBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new AES128CBC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aes128-cbc";
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ public class AES128CTR
|
||||
/** Named factory for AES128CBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new AES128CTR();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aes128-ctr";
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ public class AES192CBC
|
||||
/** Named factory for AES192CBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new AES192CBC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aes192-cbc";
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ public class AES192CTR
|
||||
/** Named factory for AES192CTR Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new AES192CTR();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aes192-ctr";
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ public class AES256CBC
|
||||
/** Named factory for AES256CBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new AES256CBC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aes256-cbc";
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ public class AES256CTR
|
||||
/** Named factory for AES256CBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new AES256CTR();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aes256-ctr";
|
||||
}
|
||||
|
||||
@@ -70,14 +70,17 @@ public class BaseCipher
|
||||
this.transformation = transformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockSize() {
|
||||
return bsize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIVSize() {
|
||||
return ivsize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Mode mode, byte[] key, byte[] iv) {
|
||||
key = BaseCipher.resize(key, bsize);
|
||||
iv = BaseCipher.resize(iv, ivsize);
|
||||
@@ -91,6 +94,7 @@ public class BaseCipher
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] input, int inputOffset, int inputLen) {
|
||||
try {
|
||||
cipher.update(input, inputOffset, inputLen, input, inputOffset);
|
||||
|
||||
@@ -42,10 +42,12 @@ public class BlowfishCBC
|
||||
/** Named factory for BlowfishCBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new BlowfishCBC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "blowfish-cbc";
|
||||
}
|
||||
|
||||
@@ -42,26 +42,32 @@ public class NoneCipher
|
||||
/** Named factory for the no-op Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new NoneCipher();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIVSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Mode mode, byte[] bytes, byte[] bytes1) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] input, int inputOffset, int inputLen) {
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,12 @@ public class TripleDESCBC
|
||||
/** Named factory for TripleDESCBC Cipher */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Cipher> {
|
||||
@Override
|
||||
public Cipher create() {
|
||||
return new TripleDESCBC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "3des-cbc";
|
||||
}
|
||||
|
||||
@@ -46,10 +46,12 @@ public class DelayedZlibCompression
|
||||
/** Named factory for the ZLib Delayed Compression. */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Compression> {
|
||||
@Override
|
||||
public Compression create() {
|
||||
return new DelayedZlibCompression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "zlib@openssh.com";
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ public abstract class NoneCompression
|
||||
/** Named factory for the no-op <code>Compression</code> */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Compression> {
|
||||
@Override
|
||||
public Compression create() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "none";
|
||||
}
|
||||
|
||||
@@ -49,10 +49,12 @@ public class ZlibCompression
|
||||
/** Named factory for the ZLib Compression. */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Compression> {
|
||||
@Override
|
||||
public Compression create() {
|
||||
return new ZlibCompression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "zlib";
|
||||
}
|
||||
@@ -64,6 +66,7 @@ public class ZlibCompression
|
||||
|
||||
private ZStream stream;
|
||||
|
||||
@Override
|
||||
public void init(Mode mode) {
|
||||
stream = new ZStream();
|
||||
switch (mode) {
|
||||
@@ -78,10 +81,12 @@ public class ZlibCompression
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDelayed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compress(Buffer buffer) {
|
||||
stream.next_in = buffer.array();
|
||||
stream.next_in_index = buffer.rpos();
|
||||
@@ -101,6 +106,7 @@ public class ZlibCompression
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void uncompress(Buffer from, Buffer to)
|
||||
throws TransportException {
|
||||
stream.next_in = from.array();
|
||||
|
||||
@@ -61,14 +61,17 @@ public class BaseDigest
|
||||
this.bsize = bsize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] digest() {
|
||||
return md.digest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockSize() {
|
||||
return bsize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
try {
|
||||
md = SecurityUtils.getMessageDigest(algorithm);
|
||||
@@ -77,10 +80,12 @@ public class BaseDigest
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] foo) {
|
||||
update(foo, 0, foo.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] foo, int start, int len) {
|
||||
md.update(foo, start, len);
|
||||
}
|
||||
|
||||
@@ -43,10 +43,12 @@ public class MD5
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Digest> {
|
||||
|
||||
@Override
|
||||
public Digest create() {
|
||||
return new MD5();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "md5";
|
||||
}
|
||||
|
||||
@@ -43,10 +43,12 @@ public class SHA1
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Digest> {
|
||||
|
||||
@Override
|
||||
public Digest create() {
|
||||
return new SHA1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "sha1";
|
||||
}
|
||||
|
||||
@@ -78,22 +78,27 @@ public abstract class AbstractDHG
|
||||
private byte[] H;
|
||||
private PublicKey hostKey;
|
||||
|
||||
@Override
|
||||
public byte[] getH() {
|
||||
return ByteArrayUtils.copyOf(H);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getK() {
|
||||
return ByteArrayUtils.copyOf(K);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Digest getHash() {
|
||||
return sha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getHostKey() {
|
||||
return hostKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Transport trans, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
|
||||
throws GeneralSecurityException, TransportException {
|
||||
this.trans = trans;
|
||||
@@ -109,6 +114,7 @@ public abstract class AbstractDHG
|
||||
trans.write(new SSHPacket(Message.KEXDH_INIT).putMPInt(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next(Message msg, SSHPacket packet)
|
||||
throws GeneralSecurityException, TransportException {
|
||||
if (msg != Message.KEXDH_31)
|
||||
|
||||
@@ -47,10 +47,12 @@ public class DHG1
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<KeyExchange> {
|
||||
|
||||
@Override
|
||||
public KeyExchange create() {
|
||||
return new DHG1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "diffie-hellman-group1-sha1";
|
||||
}
|
||||
|
||||
@@ -48,10 +48,12 @@ public class DHG14
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<KeyExchange> {
|
||||
|
||||
@Override
|
||||
public KeyExchange create() {
|
||||
return new DHG14();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "diffie-hellman-group14-sha1";
|
||||
}
|
||||
|
||||
@@ -59,14 +59,17 @@ public class BaseMAC
|
||||
tmp = new byte[defbsize];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] doFinal() {
|
||||
return mac.doFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] doFinal(byte[] input) {
|
||||
return mac.doFinal(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFinal(byte[] buf, int offset) {
|
||||
try {
|
||||
if (bsize != defbsize) {
|
||||
@@ -79,10 +82,12 @@ public class BaseMAC
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockSize() {
|
||||
return bsize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(byte[] key) {
|
||||
if (key.length > defbsize) {
|
||||
byte[] tmp = new byte[defbsize];
|
||||
@@ -99,14 +104,17 @@ public class BaseMAC
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte foo[], int s, int l) {
|
||||
mac.update(foo, s, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] foo) {
|
||||
mac.update(foo, 0, foo.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long i) {
|
||||
tmp[0] = (byte) (i >>> 24);
|
||||
tmp[1] = (byte) (i >>> 16);
|
||||
|
||||
@@ -43,10 +43,12 @@ public class HMACMD5
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<MAC> {
|
||||
|
||||
@Override
|
||||
public MAC create() {
|
||||
return new HMACMD5();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "hmac-md5";
|
||||
}
|
||||
|
||||
@@ -43,10 +43,12 @@ public class HMACMD596
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<MAC> {
|
||||
|
||||
@Override
|
||||
public MAC create() {
|
||||
return new HMACMD596();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "hmac-md5-96";
|
||||
}
|
||||
|
||||
@@ -43,10 +43,12 @@ public class HMACSHA1
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<MAC> {
|
||||
|
||||
@Override
|
||||
public MAC create() {
|
||||
return new HMACSHA1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "hmac-sha1";
|
||||
}
|
||||
|
||||
@@ -43,10 +43,12 @@ public class HMACSHA196
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<MAC> {
|
||||
|
||||
@Override
|
||||
public MAC create() {
|
||||
return new HMACSHA196();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "hmac-sha1-96";
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ public class BouncyCastleRandom
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory<Random> {
|
||||
|
||||
@Override
|
||||
public Random create() {
|
||||
return new BouncyCastleRandom();
|
||||
}
|
||||
@@ -65,6 +66,7 @@ public class BouncyCastleRandom
|
||||
random.addSeedMaterial(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(byte[] bytes, int start, int len) {
|
||||
random.nextBytes(bytes, start, len);
|
||||
}
|
||||
|
||||
@@ -45,10 +45,12 @@ public class JCERandom
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Random> {
|
||||
|
||||
@Override
|
||||
public Random create() {
|
||||
return new JCERandom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "default";
|
||||
}
|
||||
@@ -69,6 +71,7 @@ public class JCERandom
|
||||
* @param start the offset to start at
|
||||
* @param len the number of bytes to fill
|
||||
*/
|
||||
@Override
|
||||
public synchronized void fill(byte[] foo, int start, int len) {
|
||||
if (start == 0 && len == foo.length)
|
||||
random.nextBytes(foo);
|
||||
|
||||
@@ -46,10 +46,12 @@ public class SingletonRandomFactory
|
||||
random = factory.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Random create() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(byte[] bytes, int start, int len) {
|
||||
random.fill(bytes, start, len);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ public class OpenSSHKnownHosts
|
||||
init(parts[1], parts[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(String host) {
|
||||
for (String h : hosts)
|
||||
if (host.equals(h))
|
||||
@@ -138,6 +139,7 @@ public class OpenSSHKnownHosts
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHostPart() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (String host : hosts) {
|
||||
@@ -185,6 +187,7 @@ public class OpenSSHKnownHosts
|
||||
init(parts[1], parts[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(String host)
|
||||
throws IOException {
|
||||
return hashedHost.equals(hashHost(host));
|
||||
@@ -211,6 +214,7 @@ public class OpenSSHKnownHosts
|
||||
return salt;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHostPart() {
|
||||
return hashedHost;
|
||||
}
|
||||
@@ -246,6 +250,7 @@ public class OpenSSHKnownHosts
|
||||
return khFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(final String hostname, final int port, final PublicKey key) {
|
||||
final KeyType type = KeyType.fromKey(key);
|
||||
if (type == KeyType.UNKNOWN)
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.security.PublicKey;
|
||||
public final class PromiscuousVerifier
|
||||
implements HostKeyVerifier {
|
||||
|
||||
@Override
|
||||
public boolean verify(String hostname, int port, PublicKey key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public class UserAuthException
|
||||
|
||||
public static final ExceptionChainer<UserAuthException> chainer = new ExceptionChainer<UserAuthException>() {
|
||||
|
||||
@Override
|
||||
public UserAuthException chain(Throwable t) {
|
||||
if (t instanceof UserAuthException)
|
||||
return (UserAuthException) t;
|
||||
|
||||
@@ -59,6 +59,7 @@ public class UserAuthImpl
|
||||
|
||||
// synchronized for mutual exclusion; ensure one authenticate() ever in progress
|
||||
|
||||
@Override
|
||||
public synchronized void authenticate(String username, Service nextService, Iterable<AuthMethod> methods)
|
||||
throws UserAuthException, TransportException {
|
||||
clearState();
|
||||
@@ -108,14 +109,17 @@ public class UserAuthImpl
|
||||
throw new UserAuthException("Exhausted available authentication methods", savedEx.peek());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBanner() {
|
||||
return banner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextServiceName() {
|
||||
return nextService.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getTransport() {
|
||||
return trans;
|
||||
}
|
||||
@@ -126,14 +130,17 @@ public class UserAuthImpl
|
||||
*
|
||||
* @return deque of saved exceptions
|
||||
*/
|
||||
@Override
|
||||
public Deque<UserAuthException> getSavedExceptions() {
|
||||
return savedEx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hadPartialSuccess() {
|
||||
return partialSuccess;
|
||||
}
|
||||
|
||||
@@ -37,14 +37,17 @@ public class KeyPairWrapper
|
||||
this(new KeyPair(publicKey, privateKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivate() {
|
||||
return kp.getPrivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublic() {
|
||||
return kp.getPublic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,12 @@ public class OpenSSHKeyFile
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<FileKeyProvider> {
|
||||
|
||||
@Override
|
||||
public FileKeyProvider create() {
|
||||
return new OpenSSHKeyFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OpenSSH";
|
||||
}
|
||||
|
||||
@@ -40,10 +40,12 @@ public class PKCS8KeyFile
|
||||
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<FileKeyProvider> {
|
||||
@Override
|
||||
public FileKeyProvider create() {
|
||||
return new PKCS8KeyFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PKCS8";
|
||||
}
|
||||
@@ -59,27 +61,32 @@ public class PKCS8KeyFile
|
||||
|
||||
protected char[] passphrase; // for blanking out
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivate()
|
||||
throws IOException {
|
||||
return kp != null ? kp.getPrivate() : (kp = readKeyPair()).getPrivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublic()
|
||||
throws IOException {
|
||||
return kp != null ? kp.getPublic() : (kp = readKeyPair()).getPublic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getType()
|
||||
throws IOException {
|
||||
return type != null ? type : (type = KeyType.fromKey(getPublic()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(File location) {
|
||||
assert location != null;
|
||||
this.location = location;
|
||||
resource = new PrivateKeyFileResource(location.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(File location, PasswordFinder pwdf) {
|
||||
init(location);
|
||||
this.pwdf = pwdf;
|
||||
@@ -90,6 +97,7 @@ public class PKCS8KeyFile
|
||||
return null;
|
||||
else
|
||||
return new org.bouncycastle.openssl.PasswordFinder() {
|
||||
@Override
|
||||
public char[] getPassword() {
|
||||
return passphrase = pwdf.reqPassword(resource);
|
||||
}
|
||||
|
||||
@@ -40,24 +40,29 @@ public abstract class AbstractAuthMethod
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Message msg, SSHPacket buf)
|
||||
throws UserAuthException, TransportException {
|
||||
throw new UserAuthException("Unknown packet received during " + getName() + " auth: " + msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(AuthParams params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void request()
|
||||
throws UserAuthException, TransportException {
|
||||
params.getTransport().write(buildReq());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetry() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,12 +40,14 @@ public class PasswordUtils {
|
||||
return null;
|
||||
else
|
||||
return new PasswordFinder() {
|
||||
@Override
|
||||
public char[] reqPassword(Resource<?> resource) {
|
||||
char[] cloned = password.clone();
|
||||
blankOut(password);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetry(Resource<?> resource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -20,20 +20,23 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ModeGetter} that supplies file permissions as {@code "0644"}, directory permissions
|
||||
* as {@code "0755"}, and does not supply mtime and atime.
|
||||
* as {@code "0755"}, and preserves timestamps. Note that there is no way of getting the last access time with Java file
|
||||
* API's so it is returned as the current system time.
|
||||
*/
|
||||
public class DefaultModeGetter
|
||||
implements ModeGetter {
|
||||
|
||||
@Override
|
||||
public long getLastAccessTime(File f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModifiedTime(File f) {
|
||||
// return f.lastModified() / 1000;
|
||||
return 0;
|
||||
return f.lastModified() / 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissions(File f)
|
||||
throws IOException {
|
||||
if (f.isDirectory())
|
||||
@@ -44,8 +47,9 @@ public class DefaultModeGetter
|
||||
throw new IOException("Unsupported file type: " + f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preservesTimes() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,27 +19,39 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/** Default implementation of {@link ModeSetter} that does not set any permissions or preserve mtime and atime. */
|
||||
/**
|
||||
* Default implementation of {@link ModeSetter} attempts to preserve timestamps and permissions to the extent allowed by
|
||||
* Java File API.
|
||||
*/
|
||||
public class DefaultModeSetter
|
||||
implements ModeSetter {
|
||||
|
||||
@Override
|
||||
public void setLastAccessedTime(File f, long t)
|
||||
throws IOException {
|
||||
// can't do ntn
|
||||
// Can't do anything
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastModifiedTime(File f, long t)
|
||||
throws IOException {
|
||||
// f.setLastModified(t * 1000);
|
||||
f.setLastModified(t * 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermissions(File f, int perms)
|
||||
throws IOException {
|
||||
// TODO: set user's rwx permissions; can't do anything about group and world
|
||||
f.setReadable(FilePermission.USR_R.isIn(perms),
|
||||
!(FilePermission.OTH_R.isIn(perms) || FilePermission.GRP_R.isIn(perms)));
|
||||
f.setWritable(FilePermission.USR_W.isIn(perms),
|
||||
!(FilePermission.OTH_W.isIn(perms) || FilePermission.GRP_W.isIn(perms)));
|
||||
f.setExecutable(FilePermission.USR_X.isIn(perms),
|
||||
!(FilePermission.OTH_X.isIn(perms) || FilePermission.GRP_X.isIn(perms)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preservesTimes() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,6 +67,10 @@ public enum FilePermission {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public boolean isIn(int mask) {
|
||||
return (mask & val) == mask;
|
||||
}
|
||||
|
||||
public static Set<FilePermission> fromMask(int mask) {
|
||||
List<FilePermission> perms = new LinkedList<FilePermission>();
|
||||
for (FilePermission p : FilePermission.values())
|
||||
|
||||
@@ -38,11 +38,13 @@ public class SCPFileTransfer
|
||||
return new SCPUploadClient(sessionFactory, getModeGetter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(String remotePath, String localPath)
|
||||
throws IOException {
|
||||
newSCPDownloadClient().copy(remotePath, localPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upload(String localPath, String remotePath)
|
||||
throws IOException {
|
||||
newSCPUploadClient().copy(localPath, remotePath);
|
||||
|
||||
@@ -49,6 +49,7 @@ public class OpenSSHKeyFileTest {
|
||||
final char[] incorrectPassphrase = new char[]{' '};
|
||||
|
||||
final PasswordFinder onlyGivesWhenReady = new PasswordFinder() {
|
||||
@Override
|
||||
public char[] reqPassword(Resource resource) {
|
||||
if (!readyToProvide)
|
||||
throw new AssertionError("Password requested too soon");
|
||||
@@ -56,6 +57,7 @@ public class OpenSSHKeyFileTest {
|
||||
return correctPassphrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetry(Resource resource) {
|
||||
return false;
|
||||
}
|
||||
@@ -64,6 +66,7 @@ public class OpenSSHKeyFileTest {
|
||||
int triesLeft = 3;
|
||||
|
||||
final PasswordFinder givesOn3rdTry = new PasswordFinder() {
|
||||
@Override
|
||||
public char[] reqPassword(Resource resource) {
|
||||
if (triesLeft == 0)
|
||||
return correctPassphrase;
|
||||
@@ -73,6 +76,7 @@ public class OpenSSHKeyFileTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetry(Resource resource) {
|
||||
return triesLeft >= 0;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,10 @@ import org.apache.sshd.server.PasswordAuthenticator;
|
||||
import org.apache.sshd.server.session.ServerSession;
|
||||
|
||||
/** Successfully authenticates when username == password. */
|
||||
public class BogusPasswordAuthenticator implements PasswordAuthenticator {
|
||||
public class BogusPasswordAuthenticator
|
||||
implements PasswordAuthenticator {
|
||||
|
||||
@Override
|
||||
public boolean authenticate(String username, String password, ServerSession s) {
|
||||
return username.equals(password);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user