Compare commits

...

10 commits

524 changed files with 51073 additions and 1904 deletions

View file

@ -4,7 +4,6 @@ dependencies {
testImplementation testLibs.junit.jupiter.params testImplementation testLibs.junit.jupiter.params
testImplementation testLibs.mockito.core testImplementation testLibs.mockito.core
testImplementation testLibs.mockito.junit.jupiter testImplementation testLibs.mockito.junit.jupiter
testImplementation testLibs.slf4j
testImplementation project(':files-ftp-mock') testImplementation project(':files-ftp-mock')
} }

View file

@ -1,13 +1,15 @@
import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileSystemProvider;
import org.xbib.files.FileServiceProvider; import org.xbib.files.FileServiceProvider;
import org.xbib.files.ftp.fs.FTPFileSystemProvider; import org.xbib.files.ftp.fs.FTPFileSystemProvider;
import org.xbib.files.ftp.fs.FTPSFileSystemProvider;
import org.xbib.files.ftp.fs.spi.FTPFileServiceProvider; import org.xbib.files.ftp.fs.spi.FTPFileServiceProvider;
import org.xbib.files.ftp.fs.spi.FTPSFileServiceProvider;
module org.xbib.files.ftp.fs { module org.xbib.files.ftp.fs {
requires org.xbib.files; requires org.xbib.files;
requires org.xbib.files.ftp; requires org.xbib.files.ftp;
exports org.xbib.files.ftp.fs; exports org.xbib.files.ftp.fs;
exports org.xbib.files.ftp.fs.spi; exports org.xbib.files.ftp.fs.spi;
provides FileSystemProvider with FTPFileSystemProvider; provides FileSystemProvider with FTPFileSystemProvider, FTPSFileSystemProvider;
provides FileServiceProvider with FTPFileServiceProvider; provides FileServiceProvider with FTPFileServiceProvider, FTPSFileServiceProvider;
} }

View file

@ -20,24 +20,27 @@ import java.util.concurrent.BlockingQueue;
/** /**
* A pool of FTP clients, allowing multiple commands to be executed concurrently. * A pool of FTP clients, allowing multiple commands to be executed concurrently.
*/ */
final class FTPClientPool { class FTPClientPool {
private final String hostname; protected final String hostname;
private final int port; protected final int port;
protected final FTPEnvironment env;
private final FTPEnvironment env; private FileSystemExceptionFactory exceptionFactory;
private final FileSystemExceptionFactory exceptionFactory;
private final BlockingQueue<Client> pool; private BlockingQueue<Client> pool;
FTPClientPool(String hostname, int port, FTPEnvironment env) throws IOException { FTPClientPool(String hostname, int port, FTPEnvironment env) throws IOException {
this.hostname = hostname; this.hostname = hostname;
this.port = port; this.port = port;
this.env = env.clone(); this.env = env.clone();
init();
}
protected void init() throws IOException {
this.exceptionFactory = env.getExceptionFactory(); this.exceptionFactory = env.getExceptionFactory();
final int poolSize = env.getClientConnectionCount(); final int poolSize = env.getClientConnectionCount();
this.pool = new ArrayBlockingQueue<>(poolSize); this.pool = new ArrayBlockingQueue<>(poolSize);
try { try {
for (int i = 0; i < poolSize; i++) { for (int i = 0; i < poolSize; i++) {
pool.add(new Client(true)); pool.add(new Client(true));
@ -148,21 +151,23 @@ final class FTPClientPool {
pool.add(client); pool.add(client);
} }
final class Client implements Closeable { class Client implements Closeable {
private final FTPClient client;
private final boolean pooled;
protected final boolean pooled;
private FTPClient client;
private FileType fileType; private FileType fileType;
private FileStructure fileStructure; private FileStructure fileStructure;
private FileTransferMode fileTransferMode; private FileTransferMode fileTransferMode;
private int refCount = 0; private int refCount = 0;
private Client(boolean pooled) throws IOException { Client(boolean pooled) throws IOException {
this.client = env.createClient(hostname, port);
this.pooled = pooled; this.pooled = pooled;
init();
}
protected void init() throws IOException {
this.client = env.createClient(hostname, port);
this.fileType = env.getDefaultFileType(); this.fileType = env.getDefaultFileType();
this.fileStructure = env.getDefaultFileStructure(); this.fileStructure = env.getDefaultFileStructure();
this.fileTransferMode = env.getDefaultFileTransferMode(); this.fileTransferMode = env.getDefaultFileTransferMode();

View file

@ -4,6 +4,7 @@ import org.xbib.files.ftp.FTP;
import org.xbib.files.ftp.FTPClient; import org.xbib.files.ftp.FTPClient;
import org.xbib.files.ftp.FTPClientConfig; import org.xbib.files.ftp.FTPClientConfig;
import org.xbib.files.ftp.FTPFileEntryParser; import org.xbib.files.ftp.FTPFileEntryParser;
import org.xbib.files.ftp.FTPSClient;
import org.xbib.files.ftp.parser.FTPFileEntryParserFactory; import org.xbib.files.ftp.parser.FTPFileEntryParserFactory;
import javax.net.ServerSocketFactory; import javax.net.ServerSocketFactory;
@ -320,8 +321,6 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
return this; return this;
} }
// FTPClient
/** /**
* Stores the timeout in milliseconds to use when reading from data connections. * Stores the timeout in milliseconds to use when reading from data connections.
* *
@ -566,12 +565,10 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
} }
FileStructure getDefaultFileStructure() { FileStructure getDefaultFileStructure() {
// as specified by FTPClient
return FileStructure.FILE; return FileStructure.FILE;
} }
FileTransferMode getDefaultFileTransferMode() { FileTransferMode getDefaultFileTransferMode() {
// as specified by FTPClient
return FileTransferMode.STREAM; return FileTransferMode.STREAM;
} }
@ -594,6 +591,15 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
return client; return client;
} }
FTPSClient createSecureClient(String hostname, int port) throws IOException {
FTPSClient client = new FTPSClient();
initializePreConnect(client);
connect(client, hostname, port);
initializePostConnect(client);
verifyConnection(client);
return client;
}
void initializePreConnect(FTPClient client) throws IOException { void initializePreConnect(FTPClient client) throws IOException {
client.setListHiddenFiles(true); client.setListHiddenFiles(true);

View file

@ -1,7 +1,6 @@
package org.xbib.files.ftp.fs; package org.xbib.files.ftp.fs;
import org.xbib.files.ftp.FTPFile; import org.xbib.files.ftp.FTPFile;
import org.xbib.files.ftp.FTPFileFilter;
import java.io.IOException; import java.io.IOException;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
@ -17,12 +16,9 @@ import java.util.List;
abstract class FTPFileStrategy { abstract class FTPFileStrategy {
static FTPFileStrategy getInstance(FTPClientPool.Client client) throws IOException { static FTPFileStrategy getInstance(FTPClientPool.Client client) throws IOException {
FTPFile[] ftpFiles = client.listFiles("/", new FTPFileFilter() { FTPFile[] ftpFiles = client.listFiles("/", ftpFile -> {
@Override String fileName = FTPFileSystem.getFileName(ftpFile);
public boolean accept(FTPFile ftpFile) { return FTPFileSystem.CURRENT_DIR.equals(fileName);
String fileName = FTPFileSystem.getFileName(ftpFile);
return FTPFileSystem.CURRENT_DIR.equals(fileName);
}
}); });
return ftpFiles.length == 0 ? NonUnix.INSTANCE : Unix.INSTANCE; return ftpFiles.length == 0 ? NonUnix.INSTANCE : Unix.INSTANCE;
} }
@ -67,12 +63,9 @@ abstract class FTPFileStrategy {
FTPFile getFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException { FTPFile getFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException {
final String name = path.fileName(); final String name = path.fileName();
FTPFile[] ftpFiles = client.listFiles(path.path(), new FTPFileFilter() { FTPFile[] ftpFiles = client.listFiles(path.path(), ftpFile -> {
@Override String fileName = FTPFileSystem.getFileName(ftpFile);
public boolean accept(FTPFile ftpFile) { return FTPFileSystem.CURRENT_DIR.equals(fileName) || (name != null && name.equals(fileName));
String fileName = FTPFileSystem.getFileName(ftpFile);
return FTPFileSystem.CURRENT_DIR.equals(fileName) || (name != null && name.equals(fileName));
}
}); });
client.throwIfEmpty(path.path(), ftpFiles); client.throwIfEmpty(path.path(), ftpFiles);
if (ftpFiles.length == 1) { if (ftpFiles.length == 1) {
@ -94,21 +87,13 @@ abstract class FTPFileStrategy {
if (ftpFile.isDirectory() && FTPFileSystem.CURRENT_DIR.equals(FTPFileSystem.getFileName(ftpFile))) { if (ftpFile.isDirectory() && FTPFileSystem.CURRENT_DIR.equals(FTPFileSystem.getFileName(ftpFile))) {
// The file is returned using getFTPFile, which returns the . (current directory) entry for directories. // The file is returned using getFTPFile, which returns the . (current directory) entry for directories.
// List the parent (if any) instead. // List the parent (if any) instead.
final String parentPath = path.toAbsolutePath().parentPath(); final String parentPath = path.toAbsolutePath().parentPath();
final String name = path.fileName(); final String name = path.fileName();
if (parentPath == null) { if (parentPath == null) {
// path is /, there is no link // path is /, there is no link
return null; return null;
} }
FTPFile[] ftpFiles = client.listFiles(parentPath, ftpFile1 -> (ftpFile1.isDirectory() || ftpFile1.isSymbolicLink()) && name.equals(FTPFileSystem.getFileName(ftpFile1)));
FTPFile[] ftpFiles = client.listFiles(parentPath, new FTPFileFilter() {
@Override
public boolean accept(FTPFile ftpFile) {
return (ftpFile.isDirectory() || ftpFile.isSymbolicLink()) && name.equals(FTPFileSystem.getFileName(ftpFile));
}
});
client.throwIfEmpty(path.path(), ftpFiles); client.throwIfEmpty(path.path(), ftpFiles);
return ftpFiles[0].getLink() == null ? null : ftpFiles[0]; return ftpFiles[0].getLink() == null ? null : ftpFiles[0];
} }
@ -122,9 +107,7 @@ abstract class FTPFileStrategy {
@Override @Override
List<FTPFile> getChildren(FTPClientPool.Client client, FTPPath path) throws IOException { List<FTPFile> getChildren(FTPClientPool.Client client, FTPPath path) throws IOException {
FTPFile[] ftpFiles = client.listFiles(path.path()); FTPFile[] ftpFiles = client.listFiles(path.path());
boolean isDirectory = false; boolean isDirectory = false;
List<FTPFile> children = new ArrayList<>(ftpFiles.length); List<FTPFile> children = new ArrayList<>(ftpFiles.length);
for (FTPFile ftpFile : ftpFiles) { for (FTPFile ftpFile : ftpFiles) {
@ -135,7 +118,6 @@ abstract class FTPFileStrategy {
children.add(ftpFile); children.add(ftpFile);
} }
} }
if (!isDirectory && children.size() <= 1) { if (!isDirectory && children.size() <= 1) {
// either zero or one, check the parent to see if the path exists and is a directory // either zero or one, check the parent to see if the path exists and is a directory
FTPPath currentPath = path; FTPPath currentPath = path;
@ -148,7 +130,6 @@ abstract class FTPFileStrategy {
throw new NotDirectoryException(path.path()); throw new NotDirectoryException(path.path());
} }
} }
return children; return children;
} }

View file

@ -53,43 +53,51 @@ public class FTPFileSystem extends FileSystem {
static final String CURRENT_DIR = "."; static final String CURRENT_DIR = ".";
static final String PARENT_DIR = ".."; static final String PARENT_DIR = "..";
private static final Set<String> SUPPORTED_FILE_ATTRIBUTE_VIEWS = Collections protected static final Set<String> SUPPORTED_FILE_ATTRIBUTE_VIEWS = Collections
.unmodifiableSet(new HashSet<>(Arrays.asList("basic", "owner", "posix"))); .unmodifiableSet(new HashSet<>(Arrays.asList("basic", "owner", "posix")));
private static final Set<String> BASIC_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( protected static final Set<String> BASIC_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
"basic:lastModifiedTime", "basic:lastAccessTime", "basic:creationTime", "basic:size", "basic:lastModifiedTime", "basic:lastAccessTime", "basic:creationTime", "basic:size",
"basic:isRegularFile", "basic:isDirectory", "basic:isSymbolicLink", "basic:isOther", "basic:fileKey"))); "basic:isRegularFile", "basic:isDirectory", "basic:isSymbolicLink", "basic:isOther", "basic:fileKey")));
private static final Set<String> OWNER_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Collections.singletonList( protected static final Set<String> OWNER_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Collections.singletonList(
"owner:owner"))); "owner:owner")));
private static final Set<String> POSIX_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( protected static final Set<String> POSIX_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
"posix:lastModifiedTime", "posix:lastAccessTime", "posix:creationTime", "posix:size", "posix:lastModifiedTime", "posix:lastAccessTime", "posix:creationTime", "posix:size",
"posix:isRegularFile", "posix:isDirectory", "posix:isSymbolicLink", "posix:isOther", "posix:fileKey", "posix:isRegularFile", "posix:isDirectory", "posix:isSymbolicLink", "posix:isOther", "posix:fileKey",
"posix:owner", "posix:group", "posix:permissions"))); "posix:owner", "posix:group", "posix:permissions")));
private final FTPFileSystemProvider provider;
private final Iterable<Path> rootDirectories; protected final FTPFileSystemProvider provider;
private final FileStore fileStore; protected final URI uri;
private final Iterable<FileStore> fileStores; protected final FTPEnvironment env;
private final FTPClientPool clientPool; protected Iterable<Path> rootDirectories;
private final URI uri; protected FileStore fileStore;
private final String defaultDirectory; protected Iterable<FileStore> fileStores;
private final FTPFileStrategy ftpFileStrategy; private FTPClientPool clientPool;
protected String defaultDirectory;
FTPFileStrategy ftpFileStrategy;
private final AtomicBoolean open = new AtomicBoolean(true); private final AtomicBoolean open = new AtomicBoolean(true);
public FTPFileSystem(FTPFileSystemProvider provider, URI uri, FTPEnvironment env) throws IOException { public FTPFileSystem(FTPFileSystemProvider provider, URI uri, FTPEnvironment env) throws IOException {
this.provider = Objects.requireNonNull(provider); this.provider = Objects.requireNonNull(provider);
this.uri = Objects.requireNonNull(uri);
this.env = Objects.requireNonNull(env);
init();
}
protected void init() throws IOException {
this.rootDirectories = Collections.<Path>singleton(new FTPPath(this, "/")); this.rootDirectories = Collections.<Path>singleton(new FTPPath(this, "/"));
this.fileStore = new FTPFileStore(this); this.fileStore = new FTPFileStore(this);
this.fileStores = Collections.<FileStore>singleton(fileStore); this.fileStores = Collections.<FileStore>singleton(fileStore);
this.clientPool = new FTPClientPool(uri.getHost(), uri.getPort(), env); this.clientPool = new FTPClientPool(uri.getHost(), uri.getPort(), env);
this.uri = Objects.requireNonNull(uri);
try (FTPClientPool.Client client = clientPool.get()) { try (FTPClientPool.Client client = clientPool.get()) {
this.defaultDirectory = client.pwd(); this.defaultDirectory = client.pwd();
this.ftpFileStrategy = FTPFileStrategy.getInstance(client); this.ftpFileStrategy = FTPFileStrategy.getInstance(client);
} }
} }
FTPClientPool getClientPool() {
return clientPool;
}
public static String getFileName(FTPFile ftpFile) { public static String getFileName(FTPFile ftpFile) {
String fileName = ftpFile.getName(); String fileName = ftpFile.getName();
if (fileName == null) { if (fileName == null) {
@ -469,7 +477,8 @@ public class FTPFileSystem extends FileSystem {
getFTPFile(client, path); getFTPFile(client, path);
} }
String fileName = path.fileName(); String fileName = path.fileName();
return !CURRENT_DIR.equals(fileName) && !PARENT_DIR.equals(fileName) && fileName.startsWith("."); return !CURRENT_DIR.equals(fileName) && !PARENT_DIR.equals(fileName) &&
fileName != null && fileName.startsWith(".");
} }
public FileStore getFileStore(FTPPath path) throws IOException { public FileStore getFileStore(FTPPath path) throws IOException {
@ -492,16 +501,11 @@ public class FTPFileSystem extends FileSystem {
} }
private boolean hasAccess(FTPFile ftpFile, AccessMode mode) { private boolean hasAccess(FTPFile ftpFile, AccessMode mode) {
switch (mode) { return switch (mode) {
case READ: case READ -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION); case WRITE -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION);
case WRITE: case EXECUTE -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION);
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION); };
case EXECUTE:
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION);
default:
return false;
}
} }
public PosixFileAttributes readAttributes(FTPPath path, LinkOption... options) throws IOException { public PosixFileAttributes readAttributes(FTPPath path, LinkOption... options) throws IOException {

View file

@ -0,0 +1,442 @@
package org.xbib.files.ftp.fs;
import org.xbib.files.ftp.FTPSClient;
import org.xbib.files.ftp.FTPFile;
import org.xbib.files.ftp.FTPFileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.nio.file.OpenOption;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* A pool of FTPS clients, allowing multiple commands to be executed concurrently.
*/
class FTPSClientPool extends FTPClientPool {
private FileSystemExceptionFactory exceptionFactory;
private BlockingQueue<Client> pool;
FTPSClientPool(String hostname, int port, FTPEnvironment env) throws IOException {
super(hostname, port, env);
}
@Override
protected void init() throws IOException {
this.exceptionFactory = env.getExceptionFactory();
final int poolSize = env.getClientConnectionCount();
this.pool = new ArrayBlockingQueue<>(poolSize);
try {
for (int i = 0; i < poolSize; i++) {
pool.add(new Client(true));
}
} catch (IOException e) {
// creating the pool failed, disconnect all clients
for (Client client : pool) {
try {
client.disconnect();
} catch (IOException e2) {
e.addSuppressed(e2);
}
}
throw e;
}
}
Client get() throws IOException {
try {
Client client = pool.take();
try {
if (!client.isConnected()) {
client = new Client(true);
}
} catch (final Exception e) {
// could not create a new client; re-add the broken client to the pool to prevent pool starvation
pool.add(client);
throw e;
}
client.increaseRefCount();
return client;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
InterruptedIOException iioe = new InterruptedIOException(e.getMessage());
iioe.initCause(e);
throw iioe;
}
}
Client getOrCreate() throws IOException {
Client client = pool.poll();
if (client == null) {
// nothing was taken from the pool, so no risk of pool starvation if creating the client fails
return new Client(false);
}
try {
if (!client.isConnected()) {
client = new Client(true);
}
} catch (final Exception e) {
// could not create a new client; re-add the broken client to the pool to prevent pool starvation
pool.add(client);
throw e;
}
client.increaseRefCount();
return client;
}
void keepAlive() throws IOException {
List<Client> clients = new ArrayList<>();
pool.drainTo(clients);
IOException exception = null;
for (Client client : clients) {
try {
client.keepAlive();
} catch (IOException e) {
exception = add(exception, e);
} finally {
returnToPool(client);
}
}
if (exception != null) {
throw exception;
}
}
void close() throws IOException {
List<Client> clients = new ArrayList<>();
pool.drainTo(clients);
IOException exception = null;
for (Client client : clients) {
try {
client.disconnect();
} catch (IOException e) {
exception = add(exception, e);
}
}
if (exception != null) {
throw exception;
}
}
private IOException add(IOException existing, IOException e) {
if (existing == null) {
return e;
}
existing.addSuppressed(e);
return existing;
}
private void returnToPool(Client client) {
assert client.refCount == 0;
pool.add(client);
}
class Client extends FTPClientPool.Client {
private FTPSClient client;
private FileType fileType;
private FileStructure fileStructure;
private FileTransferMode fileTransferMode;
private int refCount = 0;
private Client(boolean pooled) throws IOException {
super(pooled);
}
@Override
protected void init() throws IOException {
this.client = env.createSecureClient(hostname, port);
this.fileType = env.getDefaultFileType();
this.fileStructure = env.getDefaultFileStructure();
this.fileTransferMode = env.getDefaultFileTransferMode();
}
private void increaseRefCount() {
refCount++;
}
private int decreaseRefCount() {
if (refCount > 0) {
refCount--;
}
return refCount;
}
private void keepAlive() throws IOException {
client.sendNoOp();
}
private boolean isConnected() {
if (client.isConnected()) {
try {
keepAlive();
return true;
} catch (IOException e) {
// the keep alive failed - treat as not connected, and actually disconnect quietly
disconnectQuietly();
}
}
return false;
}
private void disconnect() throws IOException {
client.disconnect();
}
private void disconnectQuietly() {
try {
client.disconnect();
} catch (IOException e) {
// ignore
}
}
@Override
public void close() throws IOException {
if (decreaseRefCount() == 0) {
if (pooled) {
returnToPool(this);
} else {
disconnect();
}
}
}
String pwd() throws IOException {
String pwd = client.printWorkingDirectory();
if (pwd == null) {
throw new FTPFileSystemException(client.getReplyCode(), client.getReplyString());
}
return pwd;
}
private void applyTransferOptions(TransferOptions options) throws IOException {
if (options.fileType != null && options.fileType != fileType) {
options.fileType.apply(client);
fileType = options.fileType;
}
if (options.fileStructure != null && options.fileStructure != fileStructure) {
options.fileStructure.apply(client);
fileStructure = options.fileStructure;
}
if (options.fileTransferMode != null && options.fileTransferMode != fileTransferMode) {
options.fileTransferMode.apply(client);
fileTransferMode = options.fileTransferMode;
}
}
InputStream newInputStream(String path, OpenOptions options) throws IOException {
assert options.read;
applyTransferOptions(options);
InputStream in = client.retrieveFileStream(path);
if (in == null) {
throw exceptionFactory.createNewInputStreamException(path, client.getReplyCode(), client.getReplyString());
}
refCount++;
return new FTPInputStream(path, in, options.deleteOnClose);
}
OutputStream newOutputStream(String path, OpenOptions options) throws IOException {
assert options.write;
applyTransferOptions(options);
OutputStream out = options.append ? client.appendFileStream(path) : client.storeFileStream(path);
if (out == null) {
throw exceptionFactory.createNewOutputStreamException(path, client.getReplyCode(), client.getReplyString(), options.options);
}
refCount++;
return new FTPOutputStream(path, out, options.deleteOnClose);
}
private void finalizeStream() throws IOException {
assert refCount > 0;
if (!client.completePendingCommand()) {
throw new FTPFileSystemException(client.getReplyCode(), client.getReplyString());
}
if (decreaseRefCount() == 0) {
if (pooled) {
returnToPool(Client.this);
} else {
disconnect();
}
}
}
void storeFile(String path, InputStream local, TransferOptions options, Collection<? extends OpenOption> openOptions) throws IOException {
applyTransferOptions(options);
if (!client.storeFile(path, local)) {
throw exceptionFactory.createNewOutputStreamException(path, client.getReplyCode(), client.getReplyString(), openOptions);
}
}
FTPFile[] listFiles(String path) throws IOException {
return client.listFiles(path);
}
FTPFile[] listFiles(String path, FTPFileFilter filter) throws IOException {
return client.listFiles(path, filter);
}
void throwIfEmpty(String path, FTPFile[] ftpFiles) throws IOException {
if (ftpFiles.length == 0) {
throw exceptionFactory.createGetFileException(path, client.getReplyCode(), client.getReplyString());
}
}
void mkdir(String path) throws IOException {
if (!client.makeDirectory(path)) {
throw exceptionFactory.createCreateDirectoryException(path, client.getReplyCode(), client.getReplyString());
}
}
void delete(String path, boolean isDirectory) throws IOException {
boolean success = isDirectory ? client.removeDirectory(path) : client.deleteFile(path);
if (!success) {
throw exceptionFactory.createDeleteException(path, client.getReplyCode(), client.getReplyString(), isDirectory);
}
}
void rename(String source, String target) throws IOException {
if (!client.rename(source, target)) {
throw exceptionFactory.createMoveException(source, target, client.getReplyCode(), client.getReplyString());
}
}
ZonedDateTime mdtm(String path) throws IOException {
FTPFile file = client.mdtmFile(path);
return file == null ? null : file.getTimestamp();
}
private final class FTPInputStream extends InputStream {
private final String path;
private final InputStream in;
private final boolean deleteOnClose;
private boolean open = true;
private FTPInputStream(String path, InputStream in, boolean deleteOnClose) {
this.path = path;
this.in = in;
this.deleteOnClose = deleteOnClose;
}
@Override
public int read() throws IOException {
return in.read();
}
@Override
public int read(byte[] b) throws IOException {
return in.read(b);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return in.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
return in.skip(n);
}
@Override
public int available() throws IOException {
return in.available();
}
@Override
public void close() throws IOException {
if (open) {
in.close();
open = false;
finalizeStream();
if (deleteOnClose) {
delete(path, false);
}
}
}
@Override
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
in.reset();
}
@Override
public boolean markSupported() {
return in.markSupported();
}
}
private final class FTPOutputStream extends OutputStream {
private final String path;
private final OutputStream out;
private final boolean deleteOnClose;
private boolean open = true;
private FTPOutputStream(String path, OutputStream out, boolean deleteOnClose) {
this.path = path;
this.out = out;
this.deleteOnClose = deleteOnClose;
}
@Override
public void write(int b) throws IOException {
out.write(b);
}
@Override
public void write(byte[] b) throws IOException {
out.write(b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
}
@Override
public void flush() throws IOException {
out.flush();
}
@Override
public void close() throws IOException {
if (open) {
out.close();
open = false;
finalizeStream();
if (deleteOnClose) {
delete(path, false);
}
}
}
}
}
}

View file

@ -0,0 +1,653 @@
package org.xbib.files.ftp.fs;
import org.xbib.files.ftp.FTPFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessDeniedException;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileStore;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.NotLinkException;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* An FTPS file system.
*/
public class FTPSFileSystem extends FTPFileSystem {
private FTPSClientPool clientPool;
public FTPSFileSystem(FTPSFileSystemProvider provider, URI uri, FTPEnvironment env) throws IOException {
super(provider, uri, env);
}
protected void init() throws IOException {
this.rootDirectories = Collections.<Path>singleton(new FTPPath(this, "/"));
this.fileStore = new FTPFileStore(this);
this.fileStores = Collections.<FileStore>singleton(fileStore);
this.clientPool = new FTPSClientPool(uri.getHost(), uri.getPort(), env);
try (FTPSClientPool.Client client = clientPool.get()) {
this.defaultDirectory = client.pwd();
this.ftpFileStrategy = FTPFileStrategy.getInstance(client);
}
}
public static String getFileName(FTPFile ftpFile) {
String fileName = ftpFile.getName();
if (fileName == null) {
return null;
}
int index = fileName.lastIndexOf('/');
return index == -1 || index == fileName.length() - 1 ? fileName : fileName.substring(index + 1);
}
@Override
public void keepAlive() throws IOException {
clientPool.keepAlive();
}
@Override
public FTPPath toRealPath(FTPPath path, LinkOption... options) throws IOException {
boolean followLinks = LinkOptionSupport.followLinks(options);
try (FTPClientPool.Client client = clientPool.get()) {
return toRealPath(client, path, followLinks).ftpPath;
}
}
private FTPPathAndFilePair toRealPath(FTPClientPool.Client client, FTPPath path, boolean followLinks) throws IOException {
FTPPath absPath = toAbsolutePath(path).normalize();
// call getFTPFile to verify the file exists
FTPFile ftpFile = getFTPFile(client, absPath);
if (followLinks && isPossibleSymbolicLink(ftpFile)) {
FTPFile link = getLink(client, ftpFile, absPath);
if (link != null) {
return toRealPath(client, new FTPPath(this, link.getLink()), followLinks);
}
}
return new FTPPathAndFilePair(absPath, ftpFile);
}
private boolean isPossibleSymbolicLink(FTPFile ftpFile) {
return ftpFile.isSymbolicLink() || (ftpFile.isDirectory() && CURRENT_DIR.equals(getFileName(ftpFile)));
}
public InputStream newInputStream(FTPPath path, OpenOption... options) throws IOException {
OpenOptions openOptions = OpenOptions.forNewInputStream(options);
try (FTPClientPool.Client client = clientPool.get()) {
return newInputStream(client, path, openOptions);
}
}
private InputStream newInputStream(FTPClientPool.Client client, FTPPath path, OpenOptions options) throws IOException {
assert options.read;
return client.newInputStream(path.path(), options);
}
public OutputStream newOutputStream(FTPPath path, OpenOption... options) throws IOException {
OpenOptions openOptions = OpenOptions.forNewOutputStream(options);
try (FTPClientPool.Client client = clientPool.get()) {
return newOutputStream(client, path, false, openOptions).out;
}
}
private FTPFileAndOutputStreamPair newOutputStream(FTPClientPool.Client client, FTPPath path, boolean requireFTPFile, OpenOptions options) throws IOException {
// retrieve the file unless create is true and createNew is false, because then the file can be created
FTPFile ftpFile = null;
if (!options.create || options.createNew) {
ftpFile = findFTPFile(client, path);
if (ftpFile != null && ftpFile.isDirectory()) {
throw Messages.fileSystemProvider().isDirectory(path.path());
}
if (!options.createNew && ftpFile == null) {
throw new NoSuchFileException(path.path());
} else if (options.createNew && ftpFile != null) {
throw new FileAlreadyExistsException(path.path());
}
}
// else the file can be created if necessary
if (ftpFile == null && requireFTPFile) {
ftpFile = findFTPFile(client, path);
}
OutputStream out = client.newOutputStream(path.path(), options);
return new FTPFileAndOutputStreamPair(ftpFile, out);
}
public SeekableByteChannel newByteChannel(FTPPath path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
if (attrs.length > 0) {
throw Messages.fileSystemProvider().unsupportedCreateFileAttribute(attrs[0].name());
}
OpenOptions openOptions = OpenOptions.forNewByteChannel(options);
try (FTPClientPool.Client client = clientPool.get()) {
if (openOptions.read) {
// use findFTPFile instead of getFTPFile, to let the opening of the stream provide the correct error message
FTPFile ftpFile = findFTPFile(client, path);
InputStream in = newInputStream(client, path, openOptions);
long size = ftpFile == null ? 0 : ftpFile.getSize();
return FileSystemProviderSupport.createSeekableByteChannel(in, size);
}
// if append then we need the FTP file, to find the initial position of the channel
boolean requireFTPFile = openOptions.append;
FTPFileAndOutputStreamPair outPair = newOutputStream(client, path, requireFTPFile, openOptions);
long initialPosition = outPair.ftpFile == null ? 0 : outPair.ftpFile.getSize();
return FileSystemProviderSupport.createSeekableByteChannel(outPair.out, initialPosition);
}
}
public DirectoryStream<Path> newDirectoryStream(final FTPPath path, Filter<? super Path> filter) throws IOException {
List<FTPFile> children;
try (FTPClientPool.Client client = clientPool.get()) {
children = ftpFileStrategy.getChildren(client, path);
}
return new FTPPathDirectoryStream(path, children, filter);
}
public void createDirectory(FTPPath path, FileAttribute<?>... attrs) throws IOException {
if (attrs.length > 0) {
throw Messages.fileSystemProvider().unsupportedCreateFileAttribute(attrs[0].name());
}
try (FTPClientPool.Client client = clientPool.get()) {
client.mkdir(path.path());
}
}
public void delete(FTPPath path) throws IOException {
try (FTPClientPool.Client client = clientPool.get()) {
FTPFile ftpFile = getFTPFile(client, path);
boolean isDirectory = ftpFile.isDirectory();
client.delete(path.path(), isDirectory);
}
}
public FTPPath readSymbolicLink(FTPPath path) throws IOException {
try (FTPClientPool.Client client = clientPool.get()) {
FTPFile ftpFile = getFTPFile(client, path);
FTPFile link = getLink(client, ftpFile, path);
if (link == null) {
throw new NotLinkException(path.path());
}
return path.resolveSibling(link.getLink());
}
}
public void copy(FTPPath source, FTPPath target, CopyOption... options) throws IOException {
boolean sameFileSystem = source.getFileSystem() == target.getFileSystem();
CopyOptions copyOptions = CopyOptions.forCopy(options);
try (FTPClientPool.Client client = clientPool.get()) {
// get the FTP file to determine whether a directory needs to be created or a file needs to be copied
// Files.copy specifies that for links, the final target must be copied
FTPPathAndFilePair sourcePair = toRealPath(client, source, true);
if (!sameFileSystem) {
copyAcrossFileSystems(client, source, sourcePair.ftpFile, target, copyOptions);
return;
}
try {
if (sourcePair.ftpPath.path().equals(toRealPath(client, target, true).ftpPath.path())) {
// non-op, don't do a thing as specified by Files.copy
return;
}
} catch (NoSuchFileException e) {
// the target does not exist or either path is an invalid link, ignore the error and continue
}
FTPFile targetFtpFile = findFTPFile(client, target);
if (targetFtpFile != null) {
if (copyOptions.replaceExisting) {
client.delete(target.path(), targetFtpFile.isDirectory());
} else {
throw new FileAlreadyExistsException(target.path());
}
}
if (sourcePair.ftpFile.isDirectory()) {
client.mkdir(target.path());
} else {
try (FTPClientPool.Client client2 = clientPool.getOrCreate()) {
copyFile(client, source, client2, target, copyOptions);
}
}
}
}
private void copyAcrossFileSystems(FTPClientPool.Client sourceClient, FTPPath source, FTPFile sourceFtpFile, FTPPath target, CopyOptions options)
throws IOException {
try (FTPClientPool.Client targetClient = target.getFileSystem().getClientPool().getOrCreate()) {
FTPFile targetFtpFile = findFTPFile(targetClient, target);
if (targetFtpFile != null) {
if (options.replaceExisting) {
targetClient.delete(target.path(), targetFtpFile.isDirectory());
} else {
throw new FileAlreadyExistsException(target.path());
}
}
if (sourceFtpFile.isDirectory()) {
sourceClient.mkdir(target.path());
} else {
copyFile(sourceClient, source, targetClient, target, options);
}
}
}
private void copyFile(FTPClientPool.Client sourceClient, FTPPath source, FTPClientPool.Client targetClient, FTPPath target, CopyOptions options) throws IOException {
OpenOptions inOptions = OpenOptions.forNewInputStream(options.toOpenOptions(StandardOpenOption.READ));
OpenOptions outOptions = OpenOptions
.forNewOutputStream(options.toOpenOptions(StandardOpenOption.WRITE, StandardOpenOption.CREATE));
try (InputStream in = sourceClient.newInputStream(source.path(), inOptions)) {
targetClient.storeFile(target.path(), in, outOptions, outOptions.options);
}
}
public void move(FTPPath source, FTPPath target, CopyOption... options) throws IOException {
boolean sameFileSystem = source.getFileSystem() == target.getFileSystem();
CopyOptions copyOptions = CopyOptions.forMove(sameFileSystem, options);
try (FTPClientPool.Client client = clientPool.get()) {
if (!sameFileSystem) {
FTPFile ftpFile = getFTPFile(client, source);
if (getLink(client, ftpFile, source) != null) {
throw new IOException(FTPMessages.copyOfSymbolicLinksAcrossFileSystemsNotSupported());
}
copyAcrossFileSystems(client, source, ftpFile, target, copyOptions);
client.delete(source.path(), ftpFile.isDirectory());
return;
}
try {
if (isSameFile(client, source, target)) {
// non-op, don't do a thing as specified by Files.move
return;
}
} catch (NoSuchFileException e) {
// the source or target does not exist or either path is an invalid link
// call getFTPFile to ensure the source file exists
// ignore any error to target or if the source link is invalid
getFTPFile(client, source);
}
if (toAbsolutePath(source).parentPath() == null) {
// cannot move or rename the root
throw new DirectoryNotEmptyException(source.path());
}
FTPFile targetFTPFile = findFTPFile(client, target);
if (copyOptions.replaceExisting && targetFTPFile != null) {
client.delete(target.path(), targetFTPFile.isDirectory());
}
client.rename(source.path(), target.path());
}
}
public boolean isSameFile(FTPPath path, FTPPath path2) throws IOException {
if (path.getFileSystem() != path2.getFileSystem()) {
return false;
}
if (path.equals(path2)) {
return true;
}
try (FTPClientPool.Client client = clientPool.get()) {
return isSameFile(client, path, path2);
}
}
private boolean isSameFile(FTPClientPool.Client client, FTPPath path, FTPPath path2) throws IOException {
if (path.equals(path2)) {
return true;
}
return toRealPath(client, path, true).ftpPath.path().equals(toRealPath(client, path2, true).ftpPath.path());
}
public boolean isHidden(FTPPath path) throws IOException {
// call getFTPFile to check for existence
try (FTPClientPool.Client client = clientPool.get()) {
getFTPFile(client, path);
}
String fileName = path.fileName();
return !CURRENT_DIR.equals(fileName) && !PARENT_DIR.equals(fileName) &&
fileName != null && fileName.startsWith(".");
}
public FileStore getFileStore(FTPPath path) throws IOException {
// call getFTPFile to check existence of the path
try (FTPClientPool.Client client = clientPool.get()) {
getFTPFile(client, path);
}
return fileStore;
}
public void checkAccess(FTPPath path, AccessMode... modes) throws IOException {
try (FTPClientPool.Client client = clientPool.get()) {
FTPFile ftpFile = getFTPFile(client, path);
for (AccessMode mode : modes) {
if (!hasAccess(ftpFile, mode)) {
throw new AccessDeniedException(path.path());
}
}
}
}
private boolean hasAccess(FTPFile ftpFile, AccessMode mode) {
return switch (mode) {
case READ -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
case WRITE -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION);
case EXECUTE -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION);
};
}
public PosixFileAttributes readAttributes(FTPPath path, LinkOption... options) throws IOException {
boolean followLinks = LinkOptionSupport.followLinks(options);
try (FTPClientPool.Client client = clientPool.get()) {
FTPPathAndFilePair pair = toRealPath(client, path, followLinks);
ZonedDateTime lastModified = client.mdtm(pair.ftpPath.path());
FTPFile link = followLinks ? null : getLink(client, pair.ftpFile, path);
FTPFile ftpFile = link == null ? pair.ftpFile : link;
return new FTPPathFileAttributes(ftpFile, lastModified);
}
}
public Map<String, Object> readAttributes(FTPPath path, String attributes, LinkOption... options) throws IOException {
String view;
int pos = attributes.indexOf(':');
if (pos == -1) {
view = "basic";
attributes = "basic:" + attributes;
} else {
view = attributes.substring(0, pos);
}
if (!SUPPORTED_FILE_ATTRIBUTE_VIEWS.contains(view)) {
throw Messages.fileSystemProvider().unsupportedFileAttributeView(view);
}
Set<String> allowedAttributes;
if (attributes.startsWith("basic:")) {
allowedAttributes = BASIC_ATTRIBUTES;
} else if (attributes.startsWith("owner:")) {
allowedAttributes = OWNER_ATTRIBUTES;
} else if (attributes.startsWith("posix:")) {
allowedAttributes = POSIX_ATTRIBUTES;
} else {
// should not occur
throw Messages.fileSystemProvider().unsupportedFileAttributeView(attributes.substring(0, attributes.indexOf(':')));
}
Map<String, Object> result = getAttributeMap(attributes, allowedAttributes);
PosixFileAttributes posixAttributes = readAttributes(path, options);
for (Map.Entry<String, Object> entry : result.entrySet()) {
switch (entry.getKey()) {
case "basic:lastModifiedTime":
case "posix:lastModifiedTime":
entry.setValue(posixAttributes.lastModifiedTime());
break;
case "basic:lastAccessTime":
case "posix:lastAccessTime":
entry.setValue(posixAttributes.lastAccessTime());
break;
case "basic:creationTime":
case "posix:creationTime":
entry.setValue(posixAttributes.creationTime());
break;
case "basic:size":
case "posix:size":
entry.setValue(posixAttributes.size());
break;
case "basic:isRegularFile":
case "posix:isRegularFile":
entry.setValue(posixAttributes.isRegularFile());
break;
case "basic:isDirectory":
case "posix:isDirectory":
entry.setValue(posixAttributes.isDirectory());
break;
case "basic:isSymbolicLink":
case "posix:isSymbolicLink":
entry.setValue(posixAttributes.isSymbolicLink());
break;
case "basic:isOther":
case "posix:isOther":
entry.setValue(posixAttributes.isOther());
break;
case "basic:fileKey":
case "posix:fileKey":
entry.setValue(posixAttributes.fileKey());
break;
case "owner:owner":
case "posix:owner":
entry.setValue(posixAttributes.owner());
break;
case "posix:group":
entry.setValue(posixAttributes.group());
break;
case "posix:permissions":
entry.setValue(posixAttributes.permissions());
break;
default:
// should not occur
throw new IllegalStateException("unexpected attribute name: " + entry.getKey());
}
}
return result;
}
private Map<String, Object> getAttributeMap(String attributes, Set<String> allowedAttributes) {
int indexOfColon = attributes.indexOf(':');
String prefix = attributes.substring(0, indexOfColon + 1);
attributes = attributes.substring(indexOfColon + 1);
String[] attributeList = attributes.split(",");
Map<String, Object> result = new HashMap<>(allowedAttributes.size());
for (String attribute : attributeList) {
String prefixedAttribute = prefix + attribute;
if (allowedAttributes.contains(prefixedAttribute)) {
result.put(prefixedAttribute, null);
} else if ("*".equals(attribute)) {
for (String s : allowedAttributes) {
result.put(s, null);
}
} else {
throw Messages.fileSystemProvider().unsupportedFileAttribute(attribute);
}
}
return result;
}
public FTPFile getFTPFile(FTPPath path) throws IOException {
try (FTPClientPool.Client client = clientPool.get()) {
return getFTPFile(client, path);
}
}
private FTPFile getFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException {
return ftpFileStrategy.getFTPFile(client, path);
}
private FTPFile findFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException {
try {
return getFTPFile(client, path);
} catch (NoSuchFileException e) {
return null;
}
}
private FTPFile getLink(FTPClientPool.Client client, FTPFile ftpFile, FTPPath path) throws IOException {
return ftpFileStrategy.getLink(client, ftpFile, path);
}
private static final class FTPPathAndFilePair {
private final FTPPath ftpPath;
private final FTPFile ftpFile;
private FTPPathAndFilePair(FTPPath ftpPath, FTPFile ftpFile) {
this.ftpPath = ftpPath;
this.ftpFile = ftpFile;
}
}
private static final class FTPFileAndOutputStreamPair {
private final FTPFile ftpFile;
private final OutputStream out;
private FTPFileAndOutputStreamPair(FTPFile ftpFile, OutputStream out) {
this.ftpFile = ftpFile;
this.out = out;
}
}
private static final class FTPPathDirectoryStream extends AbstractDirectoryStream<Path> {
private final FTPPath path;
private final List<FTPFile> files;
private Iterator<FTPFile> iterator;
private FTPPathDirectoryStream(FTPPath path, List<FTPFile> files, Filter<? super Path> filter) {
super(filter);
this.path = path;
this.files = files;
}
@Override
protected void setupIteration() {
iterator = files.iterator();
}
@Override
protected Path getNext() throws IOException {
return iterator.hasNext() ? path.resolve(getFileName(iterator.next())) : null;
}
}
private static final class FTPPathFileAttributes implements PosixFileAttributes {
private static final FileTime EPOCH = FileTime.fromMillis(0L);
private final FTPFile ftpFile;
private final FileTime lastModified;
private FTPPathFileAttributes(FTPFile ftpFile, ZonedDateTime lastModified) {
this.ftpFile = ftpFile;
if (lastModified == null) {
ZonedDateTime timestamp = ftpFile.getTimestamp();
this.lastModified = timestamp == null ? EPOCH : FileTime.from(timestamp.toInstant());
} else {
this.lastModified = FileTime.from(lastModified.toInstant());
}
}
@Override
public UserPrincipal owner() {
String user = ftpFile.getUser();
return user == null ? null : new SimpleUserPrincipal(user);
}
@Override
public GroupPrincipal group() {
String group = ftpFile.getGroup();
return group == null ? null : new SimpleGroupPrincipal(group);
}
@Override
public Set<PosixFilePermission> permissions() {
Set<PosixFilePermission> permissions = EnumSet.noneOf(PosixFilePermission.class);
addPermissionIfSet(ftpFile, FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION, PosixFilePermission.OWNER_READ, permissions);
addPermissionIfSet(ftpFile, FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, PosixFilePermission.OWNER_WRITE, permissions);
addPermissionIfSet(ftpFile, FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION, PosixFilePermission.OWNER_EXECUTE, permissions);
addPermissionIfSet(ftpFile, FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION, PosixFilePermission.GROUP_READ, permissions);
addPermissionIfSet(ftpFile, FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION, PosixFilePermission.GROUP_WRITE, permissions);
addPermissionIfSet(ftpFile, FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION, PosixFilePermission.GROUP_EXECUTE, permissions);
addPermissionIfSet(ftpFile, FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION, PosixFilePermission.OTHERS_READ, permissions);
addPermissionIfSet(ftpFile, FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION, PosixFilePermission.OTHERS_WRITE, permissions);
addPermissionIfSet(ftpFile, FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION, PosixFilePermission.OTHERS_EXECUTE, permissions);
return permissions;
}
private void addPermissionIfSet(FTPFile ftpFile, int access, int permission, PosixFilePermission value,
Set<PosixFilePermission> permissions) {
if (ftpFile.hasPermission(access, permission)) {
permissions.add(value);
}
}
@Override
public FileTime lastModifiedTime() {
return lastModified;
}
@Override
public FileTime lastAccessTime() {
return lastModifiedTime();
}
@Override
public FileTime creationTime() {
return lastModifiedTime();
}
@Override
public boolean isRegularFile() {
return ftpFile.isFile();
}
@Override
public boolean isDirectory() {
return ftpFile.isDirectory();
}
@Override
public boolean isSymbolicLink() {
return ftpFile.isSymbolicLink();
}
@Override
public boolean isOther() {
return false;
}
@Override
public long size() {
return ftpFile.getSize();
}
@Override
public Object fileKey() {
return null;
}
}
}

View file

@ -0,0 +1,512 @@
package org.xbib.files.ftp.fs;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.ProviderMismatchException;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* A provider for FTPS file systems.
*/
public class FTPSFileSystemProvider extends FTPFileSystemProvider {
private final Map<URI, FTPSFileSystem> fileSystems = new HashMap<>();
private static FTPPath toFTPPath(Path path) {
Objects.requireNonNull(path);
if (path instanceof FTPPath) {
return (FTPPath) path;
}
throw new ProviderMismatchException();
}
/**
* Send a keep-alive signal for an FTP file system.
*
* @param fs The FTP file system to send a keep-alive signal for.
* @throws ProviderMismatchException If the given file system is not an FTP file system
* (not created by an {@code FTPFileSystemProvider}).
* @throws IOException If an I/O error occurred.
*/
public static void keepAlive(FileSystem fs) throws IOException {
if (fs instanceof FTPSFileSystem) {
((FTPSFileSystem) fs).keepAlive();
}
throw new ProviderMismatchException();
}
/**
* Returns the URI scheme that identifies this provider: {@code ftps}.
*/
@Override
public String getScheme() {
return "ftps";
}
/**
* Constructs a new {@code FileSystem} object identified by a URI.
* <p>
* The URI must have a {@link URI#getScheme() scheme} equal to {@link #getScheme()},
* and no {@link URI#getUserInfo() user information},
* {@link URI#getPath() path}, {@link URI#getQuery() query} or {@link URI#getFragment() fragment}.
* Authentication credentials must be set through
* the given environment map, preferably through {@link FTPEnvironment}.
* <p>
* This provider allows multiple file systems per host, but only one file system per user on a host.
* Once a file system is {@link FileSystem#close() closed}, this provider allows a new file system
* to be created with the same URI and credentials
* as the closed file system.
*/
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
// user info must come from the environment map
checkURI(uri, false, false);
FTPEnvironment environment = wrapEnvironment(env);
String username = environment.getUsername();
URI normalizedURI = normalizeWithUsername(uri, username);
synchronized (fileSystems) {
if (fileSystems.containsKey(normalizedURI)) {
throw new FileSystemAlreadyExistsException(normalizedURI.toString());
}
FTPSFileSystem fs = new FTPSFileSystem(this, normalizedURI, environment);
fileSystems.put(normalizedURI, fs);
return fs;
}
}
FTPEnvironment wrapEnvironment(Map<String, ?> env) {
return FTPEnvironment.wrap(env);
}
/**
* Returns an existing {@code FileSystem} created by this provider.
* The URI must have a {@link URI#getScheme() scheme} equal to {@link #getScheme()},
* and no {@link URI#getPath() path},
* {@link URI#getQuery() query} or {@link URI#getFragment() fragment}.
* Because the original credentials were provided through an environment map,
* the URI can contain {@link URI#getUserInfo() user information}, although this should not
* contain a password for security reasons.
* Once a file system is {@link FileSystem#close() closed},
* this provided will throw a {@link FileSystemNotFoundException}.
*/
@Override
public FileSystem getFileSystem(URI uri) {
checkURI(uri, true, false);
return getExistingFileSystem(uri);
}
/**
* Return a {@code Path} object by converting the given {@link URI}. The resulting {@code Path}
* is associated with a {@link FileSystem} that
* already exists. This method does not support constructing {@code FileSystem}s automatically.
* <p>
* The URI must have a {@link URI#getScheme() scheme} equal to {@link #getScheme()},
* and no {@link URI#getQuery() query} or
* {@link URI#getFragment() fragment}. Because the original credentials were provided through an environment map,
* the URI can contain {@link URI#getUserInfo() user information},
* although this should not contain a password for security reasons.
*/
@Override
public Path getPath(URI uri) {
checkURI(uri, true, true);
FTPSFileSystem fs = getExistingFileSystem(uri);
return fs.getPath(uri.getPath());
}
private FTPSFileSystem getExistingFileSystem(URI uri) {
URI normalizedURI = normalizeWithoutPassword(uri);
synchronized (fileSystems) {
FTPSFileSystem fs = fileSystems.get(normalizedURI);
if (fs == null) {
throw new FileSystemNotFoundException(uri.toString());
}
return fs;
}
}
private void checkURI(URI uri, boolean allowUserInfo, boolean allowPath) {
if (!uri.isAbsolute()) {
throw Messages.uri().notAbsolute(uri);
}
if (!getScheme().equalsIgnoreCase(uri.getScheme())) {
throw Messages.uri().invalidScheme(uri, getScheme());
}
if (!allowUserInfo && uri.getUserInfo() != null && !uri.getUserInfo().isEmpty()) {
throw Messages.uri().hasUserInfo(uri);
}
if (uri.isOpaque()) {
throw Messages.uri().notHierarchical(uri);
}
if (!allowPath && uri.getPath() != null && !uri.getPath().isEmpty()) {
throw Messages.uri().hasPath(uri);
}
if (uri.getQuery() != null && !uri.getQuery().isEmpty()) {
throw Messages.uri().hasQuery(uri);
}
if (uri.getFragment() != null && !uri.getFragment().isEmpty()) {
throw Messages.uri().hasFragment(uri);
}
}
void removeFileSystem(URI uri) {
URI normalizedURI = normalizeWithoutPassword(uri);
synchronized (fileSystems) {
fileSystems.remove(normalizedURI);
}
}
private URI normalizeWithoutPassword(URI uri) {
String userInfo = uri.getUserInfo();
if (userInfo == null && uri.getPath() == null && uri.getQuery() == null && uri.getFragment() == null) {
// nothing to normalize, return the URI
return uri;
}
String username = null;
if (userInfo != null) {
int index = userInfo.indexOf(':');
username = index == -1 ? userInfo : userInfo.substring(0, index);
}
// no path, query or fragment
return URISupport.create(uri.getScheme(), username, uri.getHost(), uri.getPort(), null, null, null);
}
private URI normalizeWithUsername(URI uri, String username) {
if (username == null && uri.getUserInfo() == null && uri.getPath() == null && uri.getQuery() == null && uri.getFragment() == null) {
// nothing to normalize or add, return the URI
return uri;
}
// no path, query or fragment
return URISupport.create(uri.getScheme(), username, uri.getHost(), uri.getPort(), null, null, null);
}
/**
* Opens a file, returning an input stream to read from the file.
* This method works in exactly the manner specified by the {@link Files#newInputStream(Path, OpenOption...)} method.
* <p>
* In addition to the standard open options, this method also supports single occurrences of each of
* {@link FileType}, {@link FileStructure} and
* {@link FileTransferMode}. These three option types, with defaults of {@link FileType#binary()},
* {@link FileStructure#FILE} and
* {@link FileTransferMode#STREAM}, persist for all calls that support file transfers:
* <ul>
* <li>{@link #newInputStream(Path, OpenOption...)}</li>
* <li>{@link #newOutputStream(Path, OpenOption...)}</li>
* <li>{@link #newByteChannel(Path, Set, FileAttribute...)}</li>
* <li>{@link #copy(Path, Path, CopyOption...)}</li>
* <li>{@link #move(Path, Path, CopyOption...)}</li>
* </ul>
* <p>
* Note: while the returned input stream is not closed, the path's file system will have
* one available connection fewer.
* It is therefore essential that the input stream is closed as soon as possible.
*/
@Override
public InputStream newInputStream(Path path, OpenOption... options) throws IOException {
return toFTPPath(path).newInputStream(options);
}
/**
* Opens or creates a file, returning an output stream that may be used to write bytes to the file.
* This method works in exactly the manner specified by the {@link Files#newOutputStream(Path, OpenOption...)} method.
* <p>
* In addition to the standard open options, this method also supports single occurrences of each of
* {@link FileType}, {@link FileStructure} and
* {@link FileTransferMode}. These three option types, with defaults of {@link FileType#binary()},
* {@link FileStructure#FILE} and
* {@link FileTransferMode#STREAM}, persist for all calls that support file transfers:
* <ul>
* <li>{@link #newInputStream(Path, OpenOption...)}</li>
* <li>{@link #newOutputStream(Path, OpenOption...)}</li>
* <li>{@link #newByteChannel(Path, Set, FileAttribute...)}</li>
* <li>{@link #copy(Path, Path, CopyOption...)}</li>
* <li>{@link #move(Path, Path, CopyOption...)}</li>
* </ul>
* <p>
* Note: while the returned output stream is not closed, the path's file system will have one available
* connection fewer.
* It is therefore essential that the output stream is closed as soon as possible.
*/
@Override
public OutputStream newOutputStream(Path path, OpenOption... options) throws IOException {
return toFTPPath(path).newOutputStream(options);
}
/**
* Opens or creates a file, returning a seekable byte channel to access the file.
* This method works in exactly the manner specified by the
* {@link Files#newByteChannel(Path, Set, FileAttribute...)} method.
* <p>
* In addition to the standard open options, this method also supports single occurrences of
* each of {@link FileType}, {@link FileStructure} and
* {@link FileTransferMode}. These three option types, with defaults of {@link FileType#binary()},
* {@link FileStructure#FILE} and
* {@link FileTransferMode#STREAM}, persist for all calls that support file transfers:
* <ul>
* <li>{@link #newInputStream(Path, OpenOption...)}</li>
* <li>{@link #newOutputStream(Path, OpenOption...)}</li>
* <li>{@link #newByteChannel(Path, Set, FileAttribute...)}</li>
* <li>{@link #copy(Path, Path, CopyOption...)}</li>
* <li>{@link #move(Path, Path, CopyOption...)}</li>
* </ul>
* <p>
* This method does not support any file attributes to be set. If any file attributes are given,
* an {@link UnsupportedOperationException} will be
* thrown.
* <p>
* Note: while the returned channel is not closed, the path's file system will have one available connection fewer.
* It is therefore essential that the channel is closed as soon as possible.
*/
@Override
public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options,
FileAttribute<?>... attrs) throws IOException {
return toFTPPath(path).newByteChannel(options, attrs);
}
@Override
public DirectoryStream<Path> newDirectoryStream(Path dir, Filter<? super Path> filter) throws IOException {
return toFTPPath(dir).newDirectoryStream(filter);
}
/**
* Creates a new directory.
* This method works in exactly the manner specified by the
* {@link Files#createDirectory(Path, FileAttribute...)} method.
* <p>
* This method does not support any file attributes to be set.
* If any file attributes are given, an {@link UnsupportedOperationException} will be
* thrown.
*/
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
toFTPPath(dir).createDirectory(attrs);
}
@Override
public void delete(Path path) throws IOException {
toFTPPath(path).delete();
}
@Override
public Path readSymbolicLink(Path link) throws IOException {
return toFTPPath(link).readSymbolicLink();
}
/**
* Copy a file to a target file.
* This method works in exactly the manner specified by the {@link Files#copy(Path, Path, CopyOption...)}
* method except that both the source and
* target paths must be associated with this provider.
* <p>
* In addition to the standard copy options, this method also supports single occurrences of each of
* {@link FileType}, {@link FileStructure} and
* {@link FileTransferMode}. These three option types, with defaults of {@link FileType#binary()},
* {@link FileStructure#FILE} and
* {@link FileTransferMode#STREAM}, persist for all calls that support file transfers:
* <ul>
* <li>{@link #newInputStream(Path, OpenOption...)}</li>
* <li>{@link #newOutputStream(Path, OpenOption...)}</li>
* <li>{@link #newByteChannel(Path, Set, FileAttribute...)}</li>
* <li>{@link #copy(Path, Path, CopyOption...)}</li>
* <li>{@link #move(Path, Path, CopyOption...)}</li>
* </ul>
* <p>
* {@link StandardCopyOption#COPY_ATTRIBUTES} and {@link StandardCopyOption#ATOMIC_MOVE} are not supported though.
*/
@Override
public void copy(Path source, Path target, CopyOption... options) throws IOException {
toFTPPath(source).copy(toFTPPath(target), options);
}
/**
* Move or rename a file to a target file.
* This method works in exactly the manner specified by the {@link Files#move(Path, Path, CopyOption...)}
* method except that both the source and
* target paths must be associated with this provider.
* <p>
* In addition to the standard copy options, this method also supports single occurrences of each of
* {@link FileType}, {@link FileStructure} and
* {@link FileTransferMode}. These three option types, with defaults of {@link FileType#binary()},
* {@link FileStructure#FILE} and
* {@link FileTransferMode#STREAM}, persist for all calls that support file transfers:
* <ul>
* <li>{@link #newInputStream(Path, OpenOption...)}</li>
* <li>{@link #newOutputStream(Path, OpenOption...)}</li>
* <li>{@link #newByteChannel(Path, Set, FileAttribute...)}</li>
* <li>{@link #copy(Path, Path, CopyOption...)}</li>
* <li>{@link #move(Path, Path, CopyOption...)}</li>
* </ul>
* <p>
* {@link StandardCopyOption#COPY_ATTRIBUTES} is not supported though.
* {@link StandardCopyOption#ATOMIC_MOVE} is only supported if the paths have
* the same file system.
*/
@Override
public void move(Path source, Path target, CopyOption... options) throws IOException {
toFTPPath(source).move(toFTPPath(target), options);
}
@Override
public boolean isSameFile(Path path, Path path2) throws IOException {
return toFTPPath(path).isSameFile(path2);
}
@Override
public boolean isHidden(Path path) throws IOException {
return toFTPPath(path).isHidden();
}
@Override
public FileStore getFileStore(Path path) throws IOException {
return toFTPPath(path).getFileStore();
}
@Override
public void checkAccess(Path path, AccessMode... modes) throws IOException {
toFTPPath(path).checkAccess(modes);
}
/**
* Returns a file attribute view of a given type.
* This method works in exactly the manner specified by the
* {@link Files#getFileAttributeView(Path, Class, LinkOption...)} method.
* <p>
* This provider supports {@link BasicFileAttributeView}, {@link FileOwnerAttributeView} and
* {@link PosixFileAttributeView}.
* All other classes will result in a {@code null} return value.
* <p>
* Note that the returned {@link FileAttributeView} is read-only; any attempt to change any attributes
* through the view will result in an
* {@link UnsupportedOperationException} to be thrown.
*/
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
Objects.requireNonNull(type);
if (type == BasicFileAttributeView.class) {
return type.cast(new AttributeView("basic", toFTPPath(path)));
}
if (type == FileOwnerAttributeView.class) {
return type.cast(new AttributeView("owner", toFTPPath(path)));
}
if (type == PosixFileAttributeView.class) {
return type.cast(new AttributeView("posix", toFTPPath(path)));
}
return null;
}
/**
* Reads a file's attributes as a bulk operation.
* This method works in exactly the manner specified by the
* {@link Files#readAttributes(Path, Class, LinkOption...)} method.
* This provider supports {@link BasicFileAttributes} and {@link PosixFileAttributes}
* (there is no {@code FileOwnerFileAttributes}).
* All other classes will result in an {@link UnsupportedOperationException} to be thrown.
*/
@Override
public <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options)
throws IOException {
if (type == BasicFileAttributes.class || type == PosixFileAttributes.class) {
return type.cast(toFTPPath(path).readAttributes(options));
}
throw Messages.fileSystemProvider().unsupportedFileAttributesType(type);
}
/**
* Reads a set of file attributes as a bulk operation.
* This method works in exactly the manner specified by the {@link Files#readAttributes(Path, String, LinkOption...)} method.
* <p>
* This provider supports views {@code basic}, {@code owner} and {code posix}, where {@code basic} will be used if no view is given.
* All other views will result in an {@link UnsupportedOperationException} to be thrown.
*/
@Override
public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) throws IOException {
return toFTPPath(path).readAttributes(attributes, options);
}
/**
* Sets the value of a file attribute.
* This method works in exactly the manner specified by the {@link Files#setAttribute(Path, String, Object, LinkOption...)} method.
* <p>
* This provider does not support attributes for paths to be set. This method will always throw an {@link UnsupportedOperationException}.
*/
@Override
public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException {
throw Messages.unsupportedOperation(FileSystemProvider.class, "setAttribute");
}
private static final class AttributeView implements PosixFileAttributeView {
private final String name;
private final FTPPath path;
private AttributeView(String name, FTPPath path) {
this.name = Objects.requireNonNull(name);
this.path = Objects.requireNonNull(path);
}
@Override
public String name() {
return name;
}
@Override
public UserPrincipal getOwner() throws IOException {
return readAttributes().owner();
}
@Override
public void setOwner(UserPrincipal owner) throws IOException {
throw Messages.unsupportedOperation(FileOwnerAttributeView.class, "setOwner");
}
@Override
public PosixFileAttributes readAttributes() throws IOException {
return path.readAttributes();
}
@Override
public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException {
throw Messages.unsupportedOperation(BasicFileAttributeView.class, "setTimes");
}
@Override
public void setGroup(GroupPrincipal group) throws IOException {
throw Messages.unsupportedOperation(PosixFileAttributeView.class, "setGroup");
}
@Override
public void setPermissions(Set<PosixFilePermission> perms) throws IOException {
throw Messages.unsupportedOperation(PosixFileAttributeView.class, "setPermissions");
}
}
}

View file

@ -0,0 +1,27 @@
package org.xbib.files.ftp.fs.spi;
import org.xbib.files.ftp.fs.FTPEnvironment;
import org.xbib.files.ftp.fs.FTPSFileSystemProvider;
import java.io.Closeable;
import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.util.Map;
class FTPSContext implements Closeable {
final FTPSFileSystemProvider provider;
final FileSystem fileSystem;
FTPSContext(URI uri, Map<String, ?> env) throws IOException {
this.provider = new FTPSFileSystemProvider();
this.fileSystem = provider.newFileSystem(uri, env != null ? env : new FTPEnvironment());
}
@Override
public void close() throws IOException {
fileSystem.close();
}
}

View file

@ -0,0 +1,476 @@
package org.xbib.files.ftp.fs.spi;
import org.xbib.files.FileService;
import org.xbib.files.FileWalker;
import org.xbib.files.WrappedDirectoryStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.time.Instant;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
public class FTPSFileService implements FileService {
private static final int BUFFER_SIZE = 128 * 1024;
private static final Set<PosixFilePermission> DEFAULT_DIR_PERMISSIONS =
PosixFilePermissions.fromString("rwxr-xr-x");
private static final Set<PosixFilePermission> DEFAULT_FILE_PERMISSIONS =
PosixFilePermissions.fromString("rw-r--r--");
private final URI uri;
private final Map<String, ?> env;
public FTPSFileService(URI uri, Map<String, ?> env) {
this.uri = uri;
this.env = env;
}
@Override
public Boolean exists(String path) throws IOException {
return performWithContext(ctx -> Files.exists(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isExecutable(String path) throws IOException {
return performWithContext(ctx -> Files.isExecutable(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isDirectory(String path) throws IOException {
return performWithContext(ctx -> Files.isDirectory(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isRegularFile(String path) throws IOException {
return performWithContext(ctx -> Files.isRegularFile(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isHidden(String path) throws IOException {
return performWithContext(ctx -> Files.isHidden(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isSameFile(String path1, String path2) throws IOException {
return performWithContext(ctx -> Files.isSameFile(ctx.fileSystem.getPath(path1), ctx.fileSystem.getPath(path2)));
}
@Override
public Boolean isSymbolicLink(String path) throws IOException {
return performWithContext(ctx -> Files.isSymbolicLink(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isReadable(String path) throws IOException {
return performWithContext(ctx -> Files.isReadable(ctx.fileSystem.getPath(path)));
}
@Override
public Boolean isWritable(String path) throws IOException {
return performWithContext(ctx -> Files.isWritable(ctx.fileSystem.getPath(path)));
}
@Override
public void createFile(String path, FileAttribute<?>... attributes) throws IOException {
performWithContext(ctx -> Files.createFile(ctx.fileSystem.getPath(path), attributes));
}
@Override
public void createDirectory(String path, FileAttribute<?>... attributes) throws IOException {
performWithContext(ctx -> Files.createDirectory(ctx.fileSystem.getPath(path), attributes));
}
@Override
public void createDirectories(String path, FileAttribute<?>... attributes) throws IOException {
performWithContext(ctx -> Files.createDirectories(ctx.fileSystem.getPath(path), attributes));
}
@Override
public void setAttribute(String path, String attribute, Object value) throws IOException {
performWithContext(ctx -> Files.setAttribute(ctx.fileSystem.getPath(path), attribute, value));
}
@Override
public Object getAttribute(String path, String attribute) throws IOException {
return performWithContext(ctx -> Files.getAttribute(ctx.fileSystem.getPath(path), attribute));
}
@Override
public void setPermissions(String path, Set<PosixFilePermission> permissions) throws IOException {
performWithContext(ctx -> Files.setPosixFilePermissions(ctx.fileSystem.getPath(path), permissions));
}
@Override
public Set<PosixFilePermission> getPermissions(String path) throws IOException {
return performWithContext(ctx -> Files.getPosixFilePermissions(ctx.fileSystem.getPath(path)));
}
@Override
public void setLastModifiedTime(String path, Instant lastModified) throws IOException {
performWithContext(ctx -> Files.setLastModifiedTime(ctx.fileSystem.getPath(path), FileTime.from(lastModified)));
}
@Override
public Instant getLastModifiedTime(String path) throws IOException{
return performWithContext(ctx -> Files.getLastModifiedTime(ctx.fileSystem.getPath(path)).toInstant());
}
@Override
public void setPosixFileAttributes(String path,
String owner,
String group,
Instant lastModifiedTime,
Instant lastAccessTime,
Instant createTime) throws IOException {
performWithContext(ctx -> {
PosixFileAttributeView view = Files.getFileAttributeView(ctx.fileSystem.getPath(path),
PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
view.setOwner(ctx.fileSystem.getUserPrincipalLookupService().lookupPrincipalByName(owner));
view.setGroup(ctx.fileSystem.getUserPrincipalLookupService().lookupPrincipalByGroupName(group));
view.setTimes(FileTime.from(lastModifiedTime),
FileTime.from(lastAccessTime),
FileTime.from(createTime));
return null;
});
}
@Override
public PosixFileAttributes getPosixFileAttributes(String path) throws IOException {
return performWithContext(ctx -> Files.getFileAttributeView(ctx.fileSystem.getPath(path),
PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS).readAttributes());
}
@Override
public void setOwner(String path, String owner) throws IOException {
performWithContext(ctx -> Files.setOwner(ctx.fileSystem.getPath(path),
ctx.fileSystem.getUserPrincipalLookupService().lookupPrincipalByName(owner)));
}
@Override
public String getOwner(String path) throws IOException {
return performWithContext(ctx -> Files.getOwner(ctx.fileSystem.getPath(path)).getName());
}
@Override
public void setGroup(String path, String group) throws IOException {
performWithContext(ctx -> {
PosixFileAttributeView view = Files.getFileAttributeView(ctx.fileSystem.getPath(path),
PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
view.setGroup(ctx.fileSystem.getUserPrincipalLookupService().lookupPrincipalByGroupName(group));
return null;
});
}
@Override
public String getGroup(String path) throws IOException {
return performWithContext(ctx -> Files.getFileAttributeView(ctx.fileSystem.getPath(path),
PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS).readAttributes().group().getName());
}
@Override
public void upload(Path source,
Path target,
CopyOption... copyOptions) throws IOException {
upload(source, target, DEFAULT_DIR_PERMISSIONS, DEFAULT_FILE_PERMISSIONS, copyOptions);
}
@Override
public void upload(Path source,
Path target,
Set<PosixFilePermission> dirPerms,
Set<PosixFilePermission> filePerms,
CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
upload(ctx, Files.newByteChannel(source), target, dirPerms, filePerms, copyOptions);
return null;
});
}
@Override
public void upload(Path source,
String target,
CopyOption... copyOptions) throws IOException {
upload(source, target, DEFAULT_DIR_PERMISSIONS, DEFAULT_FILE_PERMISSIONS, copyOptions);
}
@Override
public void upload(Path source, String target,
Set<PosixFilePermission> dirPerms,
Set<PosixFilePermission> filePerms,
CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
upload(ctx, Files.newByteChannel(source), ctx.fileSystem.getPath(target),
dirPerms, filePerms, copyOptions);
return null;
});
}
@Override
public void upload(InputStream source,
Path target,
CopyOption... copyOptions) throws IOException {
upload(source, target, DEFAULT_DIR_PERMISSIONS, DEFAULT_FILE_PERMISSIONS, copyOptions);
}
@Override
public void upload(InputStream source,
Path target,
Set<PosixFilePermission> dirPerms,
Set<PosixFilePermission> filePerms,
CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
upload(ctx, Channels.newChannel(source), target, dirPerms, filePerms, copyOptions);
return null;
});
}
@Override
public void upload(InputStream source,
String target,
CopyOption... copyOptions) throws IOException {
upload(source, target, DEFAULT_DIR_PERMISSIONS, DEFAULT_FILE_PERMISSIONS, copyOptions);
}
@Override
public void upload(InputStream source, String target,
Set<PosixFilePermission> dirPerms,
Set<PosixFilePermission> filePerms,
CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
upload(ctx, Channels.newChannel(source), ctx.fileSystem.getPath(target),
dirPerms, filePerms, copyOptions);
return null;
});
}
@Override
public void download(Path source, Path target, CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
download(ctx, source, target, copyOptions);
return null;
});
}
@Override
public void download(String source, Path target, CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
download(ctx, ctx.fileSystem.getPath(source), target, copyOptions);
return null;
});
}
@Override
public void download(Path source, OutputStream target) throws IOException {
performWithContext(ctx -> {
download(ctx, source, target);
return null;
});
}
@Override
public void download(String source, OutputStream target) throws IOException {
performWithContext(ctx -> {
Files.copy(ctx.fileSystem.getPath(source), target);
return null;
});
}
@Override
public DirectoryStream<Path> stream(String path, String glob) throws IOException {
FTPSContext ctx = new FTPSContext(uri, env);
return new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path), glob));
}
@Override
public DirectoryStream<Path> stream(String path, DirectoryStream.Filter<Path> filter) throws IOException {
FTPSContext ctx = new FTPSContext(uri, env);
return new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path), filter));
}
@Override
public Stream<Path> list(String path) throws IOException {
FTPSContext ctx = new FTPSContext(uri, env);
return FileWalker.list(new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path))));
}
@Override
public Stream<Path> walk(String path, FileVisitOption... options) throws IOException {
FTPSContext ctx = new FTPSContext(uri, env);
return FileWalker.walk(ctx, ctx.fileSystem.getPath(path), Integer.MAX_VALUE, options);
}
@Override
public Stream<Path> walk(String path, int maxdepth, FileVisitOption... options) throws IOException {
FTPSContext ctx = new FTPSContext(uri, env);
return FileWalker.walk(ctx, ctx.fileSystem.getPath(path), maxdepth, options);
}
@Override
public void copy(String source, String target, CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
Files.copy(ctx.fileSystem.getPath(source), ctx.fileSystem.getPath(target), copyOptions);
return null;
});
}
@Override
public void rename(String source, String target, CopyOption... copyOptions) throws IOException {
performWithContext(ctx -> {
Files.move(ctx.fileSystem.getPath(source), ctx.fileSystem.getPath(target), copyOptions);
return null;
});
}
@Override
public void remove(String source) throws IOException {
performWithContext(ctx -> {
Files.deleteIfExists(ctx.fileSystem.getPath(source));
return null;
});
}
private void upload(FTPSContext ctx,
ReadableByteChannel source,
Path target,
Set<PosixFilePermission> dirPerms,
Set<PosixFilePermission> filePerms,
CopyOption... copyOptions) throws IOException {
prepareForWrite(target, dirPerms, filePerms);
transfer(source, ctx.provider.newByteChannel(target, prepareWriteOptions(copyOptions)));
}
private void download(FTPSContext ctx,
Path source,
OutputStream outputStream) throws IOException {
download(ctx, source, Channels.newChannel(outputStream));
}
private void download(FTPSContext ctx,
Path source,
WritableByteChannel writableByteChannel) throws IOException {
transfer(ctx.provider.newByteChannel(source, prepareReadOptions()), writableByteChannel);
}
private void download(FTPSContext ctx,
Path source,
Path target,
CopyOption... copyOptions) throws IOException {
prepareForWrite(target);
transfer(ctx.provider.newByteChannel(source, prepareReadOptions(copyOptions)),
Files.newByteChannel(target, prepareWriteOptions(copyOptions)));
}
private void prepareForWrite(Path path) throws IOException {
if (path == null) {
return;
}
Path parent = path.getParent();
if (parent != null) {
if (!Files.exists(parent)) {
Files.createDirectories(parent);
}
}
if (!Files.exists(path)) {
Files.createFile(path);
}
}
private void prepareForWrite(Path path,
Set<PosixFilePermission> dirPerms,
Set<PosixFilePermission> filePerms) throws IOException {
if (path == null) {
return;
}
Path parent = path.getParent();
if (parent != null) {
if (!Files.exists(parent)) {
Files.createDirectories(parent);
}
PosixFileAttributeView posixFileAttributeView =
Files.getFileAttributeView(parent, PosixFileAttributeView.class);
posixFileAttributeView.setPermissions(dirPerms);
}
if (!Files.exists(path)) {
Files.createFile(path);
}
PosixFileAttributeView posixFileAttributeView =
Files.getFileAttributeView(path, PosixFileAttributeView.class);
posixFileAttributeView.setPermissions(filePerms);
}
private Set<? extends OpenOption> prepareReadOptions(CopyOption... copyOptions) {
// ignore user copy options
return EnumSet.of(StandardOpenOption.READ);
}
private Set<? extends OpenOption> prepareWriteOptions(CopyOption... copyOptions) {
Set<? extends OpenOption> options = null;
for (CopyOption copyOption : copyOptions) {
if (copyOption == StandardCopyOption.REPLACE_EXISTING) {
options = EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
}
}
if (options == null) {
// we can not use CREATE_NEW, file is already there because of prepareForWrite() -> Files.createFile()
options = EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE);
}
return options;
}
private void transfer(ReadableByteChannel readableByteChannel,
WritableByteChannel writableByteChannel) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
int read;
while ((read = readableByteChannel.read(buffer)) > 0) {
buffer.flip();
while (read > 0) {
read -= writableByteChannel.write(buffer);
}
buffer.clear();
}
}
private <T> T performWithContext(WithSecureContext<T> action) throws IOException {
FTPSContext ctx = null;
try {
if (uri != null) {
ctx = new FTPSContext(uri, env);
return action.perform(ctx);
} else {
return null;
}
} finally {
if (ctx != null) {
ctx.close();
}
}
}
}

View file

@ -0,0 +1,15 @@
package org.xbib.files.ftp.fs.spi;
import org.xbib.files.FileService;
import org.xbib.files.FileServiceProvider;
import java.net.URI;
import java.util.Map;
public class FTPSFileServiceProvider implements FileServiceProvider {
@Override
public FileService provide(URI uri, Map<String, ?> env) {
return uri.isAbsolute() && uri.getScheme().equals("ftps") ? new FTPSFileService(uri, env) : null;
}
}

View file

@ -2,6 +2,7 @@ package org.xbib.files.ftp.fs.spi;
import java.io.IOException; import java.io.IOException;
@FunctionalInterface
interface WithContext<T> { interface WithContext<T> {
T perform(FTPContext ctx) throws IOException; T perform(FTPContext ctx) throws IOException;
} }

View file

@ -0,0 +1,8 @@
package org.xbib.files.ftp.fs.spi;
import java.io.IOException;
@FunctionalInterface
interface WithSecureContext<T> {
T perform(FTPSContext ctx) throws IOException;
}

View file

@ -1 +1,2 @@
org.xbib.files.ftp.fs.FTPFileSystemProvider org.xbib.files.ftp.fs.FTPFileSystemProvider
org.xbib.files.ftp.fs.FTPSFileSystemProvider

View file

@ -1 +1,2 @@
org.xbib.files.ftp.fs.spi.FTPFileServiceProvider org.xbib.files.ftp.fs.spi.FTPFileServiceProvider
org.xbib.files.ftp.fs.spi.FTPSFileServiceProvider

View file

@ -3,7 +3,6 @@ module org.xbib.files.ftp.fs.test {
requires org.junit.jupiter.api; requires org.junit.jupiter.api;
requires org.junit.jupiter.params; requires org.junit.jupiter.params;
requires org.mockito; requires org.mockito;
requires org.slf4j;
requires org.xbib.files.ftp; requires org.xbib.files.ftp;
requires org.xbib.files.ftp.fs; requires org.xbib.files.ftp.fs;
requires org.xbib.files.ftp.mock; requires org.xbib.files.ftp.mock;

View file

@ -65,9 +65,6 @@ import static org.mockito.Mockito.verify;
public class FTPFileSystemTest extends AbstractFTPFileSystemTest { public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
//@Rule
//public ExpectedException thrown = ExpectedException.none();
@Test @Test
public void testGetPath() { public void testGetPath() {
testGetPath("/", "/"); testGetPath("/", "/");

View file

@ -1,5 +1,4 @@
dependencies { dependencies {
api project(':files-api') api project(':files-api')
api libs.maverick.synergy.client api libs.maverick.synergy.client
testImplementation libs.net.security
} }

View file

@ -0,0 +1,12 @@
import org.xbib.files.jadaptive.sftp.SftpFileSystemProvider;
import java.nio.file.spi.FileSystemProvider;
module org.xbib.files.jadaptive.sftp {
requires java.logging;
requires org.xbib.files;
requires com.sshtools.maverick.base;
requires com.sshtools.synergy.common;
requires com.sshtools.synergy.client;
provides FileSystemProvider with SftpFileSystemProvider;
}

View file

@ -0,0 +1,20 @@
package org.xbib.files.jadaptive.sftp;
import java.io.Closeable;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
public class SftpContext implements Closeable {
SftpFileSystemProvider provider;
SftpFileSystem fileSystem;
public SftpContext(URI uri, Map<String, ?> env) throws IOException {
}
@Override
public void close() throws IOException {
}
}

View file

@ -1,4 +1,4 @@
package org.xbib.files.sftp.jadaptive.fs.spi; package org.xbib.files.jadaptive.sftp;
import org.xbib.files.FileService; import org.xbib.files.FileService;
import org.xbib.files.FileWalker; import org.xbib.files.FileWalker;
@ -33,7 +33,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
public class SFTPFileService implements FileService { public class SftpFileService implements FileService {
private static final int BUFFER_SIZE = 128 * 1024; private static final int BUFFER_SIZE = 128 * 1024;
@ -47,7 +47,7 @@ public class SFTPFileService implements FileService {
private final Map<String, ?> env; private final Map<String, ?> env;
public SFTPFileService(URI uri, Map<String, ?> env) { public SftpFileService(URI uri, Map<String, ?> env) {
this.uri = uri; this.uri = uri;
this.env = env; this.env = env;
} }
@ -303,31 +303,31 @@ public class SFTPFileService implements FileService {
@Override @Override
public DirectoryStream<Path> stream(String path, String glob) throws IOException { public DirectoryStream<Path> stream(String path, String glob) throws IOException {
SFTPContext ctx = new SFTPContext(uri, env); SftpContext ctx = new SftpContext(uri, env);
return new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path), glob)); return new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path), glob));
} }
@Override @Override
public DirectoryStream<Path> stream(String path, DirectoryStream.Filter<Path> filter) throws IOException { public DirectoryStream<Path> stream(String path, DirectoryStream.Filter<Path> filter) throws IOException {
SFTPContext ctx = new SFTPContext(uri, env); SftpContext ctx = new SftpContext(uri, env);
return new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path), filter)); return new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path), filter));
} }
@Override @Override
public Stream<Path> list(String path) throws IOException { public Stream<Path> list(String path) throws IOException {
SFTPContext ctx = new SFTPContext(uri, env); SftpContext ctx = new SftpContext(uri, env);
return FileWalker.list(new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path)))); return FileWalker.list(new WrappedDirectoryStream<>(ctx, Files.newDirectoryStream(ctx.fileSystem.getPath(path))));
} }
@Override @Override
public Stream<Path> walk(String path, FileVisitOption... options) throws IOException { public Stream<Path> walk(String path, FileVisitOption... options) throws IOException {
SFTPContext ctx = new SFTPContext(uri, env); SftpContext ctx = new SftpContext(uri, env);
return FileWalker.walk(ctx, ctx.fileSystem.getPath(path), Integer.MAX_VALUE, options); return FileWalker.walk(ctx, ctx.fileSystem.getPath(path), Integer.MAX_VALUE, options);
} }
@Override @Override
public Stream<Path> walk(String path, int maxdepth, FileVisitOption... options) throws IOException { public Stream<Path> walk(String path, int maxdepth, FileVisitOption... options) throws IOException {
SFTPContext ctx = new SFTPContext(uri, env); SftpContext ctx = new SftpContext(uri, env);
return FileWalker.walk(ctx, ctx.fileSystem.getPath(path), maxdepth, options); return FileWalker.walk(ctx, ctx.fileSystem.getPath(path), maxdepth, options);
} }
@ -357,7 +357,7 @@ public class SFTPFileService implements FileService {
}); });
} }
private void doUpload(SFTPContext ctx, private void doUpload(SftpContext ctx,
ReadableByteChannel source, ReadableByteChannel source,
Path target, Path target,
Set<PosixFilePermission> dirPerms, Set<PosixFilePermission> dirPerms,
@ -367,19 +367,19 @@ public class SFTPFileService implements FileService {
transfer(source, ctx.provider.newByteChannel(target, prepareWriteOptions(copyOptions))); transfer(source, ctx.provider.newByteChannel(target, prepareWriteOptions(copyOptions)));
} }
private void download(SFTPContext ctx, private void download(SftpContext ctx,
Path source, Path source,
OutputStream outputStream) throws IOException { OutputStream outputStream) throws IOException {
download(ctx, source, Channels.newChannel(outputStream)); download(ctx, source, Channels.newChannel(outputStream));
} }
private void download(SFTPContext ctx, private void download(SftpContext ctx,
Path source, Path source,
WritableByteChannel writableByteChannel) throws IOException { WritableByteChannel writableByteChannel) throws IOException {
transfer(ctx.provider.newByteChannel(source, prepareReadOptions()), writableByteChannel); transfer(ctx.provider.newByteChannel(source, prepareReadOptions()), writableByteChannel);
} }
private void download(SFTPContext ctx, private void download(SftpContext ctx,
Path source, Path source,
Path target, Path target,
CopyOption... copyOptions) throws IOException { CopyOption... copyOptions) throws IOException {
@ -459,10 +459,10 @@ public class SFTPFileService implements FileService {
} }
private <T> T performWithContext(WithContext<T> action) throws IOException { private <T> T performWithContext(WithContext<T> action) throws IOException {
SFTPContext ctx = null; SftpContext ctx = null;
try { try {
if (uri != null) { if (uri != null) {
ctx = new SFTPContext(uri, env); ctx = new SftpContext(uri, env);
return action.perform(ctx); return action.perform(ctx);
} else { } else {
return null; return null;

View file

@ -1,4 +1,4 @@
package org.xbib.files.sftp.jadaptive.fs.spi; package org.xbib.files.jadaptive.sftp;
import org.xbib.files.FileService; import org.xbib.files.FileService;
import org.xbib.files.FileServiceProvider; import org.xbib.files.FileServiceProvider;
@ -6,10 +6,10 @@ import org.xbib.files.FileServiceProvider;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
public class SFTPFileServiceProvider implements FileServiceProvider { public class SftpFileServiceProvider implements FileServiceProvider {
@Override @Override
public FileService provide(URI uri, Map<String, ?> env) { public FileService provide(URI uri, Map<String, ?> env) {
return uri.isAbsolute() && uri.getScheme().equals("sftp") ? new SFTPFileService(uri, env) : null; return uri.isAbsolute() && uri.getScheme().equals("sftp") ? new SftpFileService(uri, env) : null;
} }
} }

View file

@ -0,0 +1,16 @@
package org.xbib.files.jadaptive.sftp;
import com.sshtools.common.files.nio.AbstractFileNIOFileSystem;
import com.sshtools.common.files.nio.AbstractFileNIOProvider;
import com.sshtools.common.ssh.SshConnection;
import java.net.URI;
public class SftpFileSystem extends AbstractFileNIOFileSystem {
public SftpFileSystem(SshConnection con,
URI uri,
AbstractFileNIOProvider provider) {
super(con, uri, provider);
}
}

View file

@ -0,0 +1,6 @@
package org.xbib.files.jadaptive.sftp;
import com.sshtools.common.files.nio.AbstractFileNIOProvider;
public class SftpFileSystemProvider extends AbstractFileNIOProvider {
}

View file

@ -0,0 +1,8 @@
package org.xbib.files.jadaptive.sftp;
import java.io.IOException;
@FunctionalInterface
interface WithContext<T> {
T perform(SftpContext ctx) throws IOException;
}

View file

@ -0,0 +1 @@
org.xbib.files.jadaptive.sftp.SftpFileSystemProvider

View file

@ -0,0 +1,8 @@
module org.xbib.files.jadaptive.sftp.test {
requires java.logging;
requires transitive org.junit.jupiter.api;
requires org.xbib.files;
requires org.xbib.files.jadaptive.sftp;
exports org.xbib.files.jadaptive.sftp.test;
opens org.xbib.files.jadaptive.sftp.test to org.junit.platform.commons;
}

View file

@ -0,0 +1,32 @@
package org.xbib.files.jadaptive.sftp.test;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SftpFileSystemTest {
private static final Logger logger = Logger.getLogger(SftpFileSystemTest.class.getName());
public SftpFileSystemTest() {
}
@Disabled("missing connection object")
@Test
public void testFileSystem() throws IOException {
Map<String, ?> env = Map.of("username", "joerg");
try (FileSystem fileSystem = FileSystems.newFileSystem(URI.create("abfs://xbib.org:22"), env)) {
for (Path path : fileSystem.getRootDirectories()) {
logger.log(Level.INFO, "root dir = " + path);
}
}
}
}

View file

@ -0,0 +1,5 @@
handlers=java.util.logging.ConsoleHandler
.level=ALL
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] %5$s %6$s%n
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

30
files-jsch/LICENSE.txt Normal file
View file

@ -0,0 +1,30 @@
JSch 0.0.* was released under the GNU LGPL license. Later, we have switched
over to a BSD-style license.
------------------------------------------------------------------------------
Copyright (c) 2002-2015 Atsuhiko Yamanaka, JCraft,Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7
files-jsch/NOTICE.txt Normal file
View file

@ -0,0 +1,7 @@
This work is based on
https://github.com/mwiede/jsch
forked as of 23 July 2024 (Version 0.2.18)

4
files-jsch/build.gradle Normal file
View file

@ -0,0 +1,4 @@
dependencies {
testImplementation testLibs.testcontainers
testImplementation testLibs.testcontainers.junit.jupiter
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface AgentConnector {
String getName();
boolean isAvailable();
void query(Buffer buffer) throws AgentProxyException;
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class AgentIdentity implements Identity {
private AgentProxy agent;
private byte[] blob;
private String comment;
private String algname;
AgentIdentity(AgentProxy agent, byte[] blob, String comment) {
this.agent = agent;
this.blob = blob;
this.comment = comment;
algname = Util.byte2str((new Buffer(blob)).getString());
}
@Override
public boolean setPassphrase(byte[] passphrase) throws JSchException {
return true;
}
@Override
public byte[] getPublicKeyBlob() {
return blob;
}
@Override
public byte[] getSignature(byte[] data) {
return agent.sign(blob, data, null);
}
@Override
public byte[] getSignature(byte[] data, String alg) {
return agent.sign(blob, data, alg);
}
@Override
public String getAlgName() {
return algname;
}
@Override
public String getName() {
return comment;
}
@Override
public boolean isEncrypted() {
return false;
}
@Override
public void clear() {}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
public class AgentIdentityRepository implements IdentityRepository {
private AgentProxy agent;
public AgentIdentityRepository(AgentConnector connector) {
this.agent = new AgentProxy(connector);
}
@Override
public Vector<Identity> getIdentities() {
return agent.getIdentities();
}
@Override
public boolean add(byte[] identity) {
return agent.addIdentity(identity);
}
@Override
public boolean remove(byte[] blob) {
return agent.removeIdentity(blob);
}
@Override
public void removeAll() {
agent.removeAllIdentities();
}
@Override
public String getName() {
return agent.getConnector().getName();
}
@Override
public int getStatus() {
if (agent.getConnector().isAvailable()) {
return RUNNING;
} else {
return NOTRUNNING;
}
}
}

View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
class AgentProxy {
private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
private static final byte SSH_AGENTC_RSA_CHALLENGE = 3;
private static final byte SSH_AGENT_RSA_RESPONSE = 4;
private static final byte SSH_AGENT_FAILURE = 5;
private static final byte SSH_AGENT_SUCCESS = 6;
private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11;
private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12;
private static final byte SSH2_AGENTC_SIGN_REQUEST = 13;
private static final byte SSH2_AGENT_SIGN_RESPONSE = 14;
private static final byte SSH2_AGENTC_ADD_IDENTITY = 17;
private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18;
private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20;
private static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21;
private static final byte SSH_AGENTC_LOCK = 22;
private static final byte SSH_AGENTC_UNLOCK = 23;
private static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24;
private static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25;
private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26;
private static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1;
private static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2;
private static final byte SSH2_AGENT_FAILURE = 30;
private static final byte SSH_COM_AGENT2_FAILURE = 102;
// private static final byte SSH_AGENT_OLD_SIGNATURE = 0x1;
private static final int SSH_AGENT_RSA_SHA2_256 = 0x2;
private static final int SSH_AGENT_RSA_SHA2_512 = 0x4;
private static final int MAX_AGENT_IDENTITIES = 2048;
private final byte[] buf = new byte[1024];
private final Buffer buffer = new Buffer(buf);
private AgentConnector connector;
AgentProxy(AgentConnector connector) {
this.connector = connector;
}
synchronized Vector<Identity> getIdentities() {
Vector<Identity> identities = new Vector<>();
int required_size = 1 + 4;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES);
try {
connector.query(buffer);
} catch (AgentProxyException e) {
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
return identities;
}
int rcode = buffer.getByte();
// System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER);
if (rcode != SSH2_AGENT_IDENTITIES_ANSWER) {
return identities;
}
int count = buffer.getInt();
// System.out.println(count);
if (count <= 0 || count > MAX_AGENT_IDENTITIES) {
return identities;
}
for (int i = 0; i < count; i++) {
byte[] blob = buffer.getString();
String comment = Util.byte2str(buffer.getString());
identities.add(new AgentIdentity(this, blob, comment));
}
return identities;
}
synchronized byte[] sign(byte[] blob, byte[] data, String alg) {
int flags = 0x0;
if (alg != null) {
if (alg.equals("rsa-sha2-256")) {
flags = SSH_AGENT_RSA_SHA2_256;
} else if (alg.equals("rsa-sha2-512")) {
flags = SSH_AGENT_RSA_SHA2_512;
}
}
int required_size = 1 + 4 * 4 + blob.length + data.length;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_SIGN_REQUEST);
buffer.putString(blob);
buffer.putString(data);
buffer.putInt(flags);
try {
connector.query(buffer);
} catch (AgentProxyException e) {
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
int rcode = buffer.getByte();
// System.out.println(rcode == SSH2_AGENT_SIGN_RESPONSE);
if (rcode != SSH2_AGENT_SIGN_RESPONSE) {
return null;
}
return buffer.getString();
}
synchronized boolean removeIdentity(byte[] blob) {
int required_size = 1 + 4 * 2 + blob.length;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REMOVE_IDENTITY);
buffer.putString(blob);
try {
connector.query(buffer);
} catch (AgentProxyException e) {
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
int rcode = buffer.getByte();
// System.out.println(rcode == SSH_AGENT_SUCCESS);
return rcode == SSH_AGENT_SUCCESS;
}
synchronized void removeAllIdentities() {
int required_size = 1 + 4;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
try {
connector.query(buffer);
} catch (AgentProxyException e) {
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
// int rcode = buffer.getByte();
// System.out.println(rcode == SSH_AGENT_SUCCESS);
}
synchronized boolean addIdentity(byte[] identity) {
int required_size = 1 + 4 + identity.length;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_ADD_IDENTITY);
buffer.putByte(identity);
try {
connector.query(buffer);
} catch (AgentProxyException e) {
buffer.rewind();
buffer.putByte(SSH_AGENT_FAILURE);
}
int rcode = buffer.getByte();
// System.out.println(rcode == SSH_AGENT_SUCCESS);
return rcode == SSH_AGENT_SUCCESS;
}
synchronized boolean isRunning() {
int required_size = 1 + 4;
buffer.reset();
buffer.checkFreeSize(required_size);
buffer.putInt(required_size - 4);
buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES);
try {
connector.query(buffer);
} catch (AgentProxyException e) {
return false;
}
int rcode = buffer.getByte();
// System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER);
return rcode == SSH2_AGENT_IDENTITIES_ANSWER;
}
synchronized AgentConnector getConnector() {
return connector;
}
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class AgentProxyException extends Exception {
private static final long serialVersionUID = -1L;
public AgentProxyException(String message) {
super(message);
}
public AgentProxyException(String message, Throwable e) {
super(message, e);
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Argon2 extends KDF {
public static final int ARGON2D = 0;
public static final int ARGON2I = 1;
public static final int ARGON2ID = 2;
public static final int V10 = 0x10;
public static final int V13 = 0x13;
void init(byte[] salt, int iteration, int type, byte[] additional, byte[] secret, int memory,
int parallelism, int version) throws Exception;
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface BCrypt extends KDF {
void init(byte[] salt, int iteration) throws Exception;
}

View file

@ -0,0 +1,303 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class Buffer {
final byte[] tmp = new byte[4];
byte[] buffer;
int index;
int s;
public Buffer(int size) {
buffer = new byte[size];
index = 0;
s = 0;
}
public Buffer(byte[] buffer) {
this.buffer = buffer;
index = 0;
s = 0;
}
public Buffer() {
this(1024 * 10 * 2);
}
public void putByte(byte foo) {
buffer[index++] = foo;
}
public void putByte(byte[] foo) {
putByte(foo, 0, foo.length);
}
public void putByte(byte[] foo, int begin, int length) {
System.arraycopy(foo, begin, buffer, index, length);
index += length;
}
public void putString(byte[] foo) {
putString(foo, 0, foo.length);
}
public void putString(byte[] foo, int begin, int length) {
putInt(length);
putByte(foo, begin, length);
}
public void putInt(int val) {
tmp[0] = (byte) (val >>> 24);
tmp[1] = (byte) (val >>> 16);
tmp[2] = (byte) (val >>> 8);
tmp[3] = (byte) (val);
System.arraycopy(tmp, 0, buffer, index, 4);
index += 4;
}
public void putLong(long val) {
tmp[0] = (byte) (val >>> 56);
tmp[1] = (byte) (val >>> 48);
tmp[2] = (byte) (val >>> 40);
tmp[3] = (byte) (val >>> 32);
System.arraycopy(tmp, 0, buffer, index, 4);
tmp[0] = (byte) (val >>> 24);
tmp[1] = (byte) (val >>> 16);
tmp[2] = (byte) (val >>> 8);
tmp[3] = (byte) (val);
System.arraycopy(tmp, 0, buffer, index + 4, 4);
index += 8;
}
void skip(int n) {
index += n;
}
void putPad(int n) {
while (n > 0) {
buffer[index++] = (byte) 0;
n--;
}
}
public void putMPInt(byte[] foo) {
int i = foo.length;
if ((foo[0] & 0x80) != 0) {
i++;
putInt(i);
putByte((byte) 0);
} else {
putInt(i);
}
putByte(foo);
}
public int getLength() {
return index - s;
}
public int getOffSet() {
return s;
}
public void setOffSet(int s) {
this.s = s;
}
public long getLong() {
long foo = getInt() & 0xffffffffL;
foo = ((foo << 32)) | (getInt() & 0xffffffffL);
return foo;
}
public int getInt() {
int foo = getShort();
foo = ((foo << 16) & 0xffff0000) | (getShort() & 0xffff);
return foo;
}
public long getUInt() {
long foo = 0L;
long bar = 0L;
foo = getByte();
foo = ((foo << 8) & 0xff00) | (getByte() & 0xff);
bar = getByte();
bar = ((bar << 8) & 0xff00) | (getByte() & 0xff);
foo = ((foo << 16) & 0xffff0000) | (bar & 0xffff);
return foo;
}
int getShort() {
int foo = getByte();
foo = ((foo << 8) & 0xff00) | (getByte() & 0xff);
return foo;
}
public int getByte() {
return (buffer[s++] & 0xff);
}
public void getByte(byte[] foo) {
getByte(foo, 0, foo.length);
}
void getByte(byte[] foo, int start, int len) {
System.arraycopy(buffer, s, foo, start, len);
s += len;
}
public int getByte(int len) {
int foo = s;
s += len;
return foo;
}
public byte[] getMPInt() {
int i = getInt(); // uint32
if (i < 0 || // bigger than 0x7fffffff
i > 8 * 1024) {
// TODO: an exception should be thrown.
i = 8 * 1024; // the session will be broken, but working around OOME.
}
byte[] foo = new byte[i];
getByte(foo, 0, i);
return foo;
}
public byte[] getMPIntBits() {
int bits = getInt();
int bytes = (bits + 7) / 8;
byte[] foo = new byte[bytes];
getByte(foo, 0, bytes);
if ((foo[0] & 0x80) != 0) {
byte[] bar = new byte[foo.length + 1];
bar[0] = 0; // ??
System.arraycopy(foo, 0, bar, 1, foo.length);
foo = bar;
}
return foo;
}
public byte[] getString() {
int i = getInt(); // uint32
if (i < 0 || // bigger than 0x7fffffff
i > 256 * 1024) {
// TODO: an exception should be thrown.
i = 256 * 1024; // the session will be broken, but working around OOME.
}
byte[] foo = new byte[i];
getByte(foo, 0, i);
return foo;
}
byte[] getString(int[] start, int[] len) {
int i = getInt();
start[0] = getByte(i);
len[0] = i;
return buffer;
}
public void reset() {
index = 0;
s = 0;
}
public void shift() {
if (s == 0)
return;
System.arraycopy(buffer, s, buffer, 0, index - s);
index = index - s;
s = 0;
}
void rewind() {
s = 0;
}
byte getCommand() {
return buffer[5];
}
// Hardcode this since we can't use dynamic Session value
private static final int buffer_margin = 32 + // maximum padding length
64 + // maximum mac length
32; // margin for deflater; deflater may inflate data
void checkFreeSize(int n) {
int size = index + n + buffer_margin;
if (buffer.length < size) {
int i = buffer.length * 2;
if (i < size)
i = size;
byte[] tmp = new byte[i];
System.arraycopy(buffer, 0, tmp, 0, index);
buffer = tmp;
}
}
byte[][] getBytes(int n, String msg) throws JSchException {
byte[][] tmp = new byte[n][];
for (int i = 0; i < n; i++) {
int j = getInt();
if (getLength() < j) {
throw new JSchException(msg);
}
tmp[i] = new byte[j];
getByte(tmp[i]);
}
return tmp;
}
/*
* static Buffer fromBytes(byte[]... args){ int length = args.length*4; for(int i = 0; i <
* args.length; i++){ length += args[i].length; } Buffer buf = new Buffer(length); for(int i = 0;
* i < args.length; i++){ buf.putString(args[i]); } return buf; }
*/
static Buffer fromBytes(byte[][] args) {
int length = args.length * 4;
for (int i = 0; i < args.length; i++) {
length += args[i].length;
}
Buffer buf = new Buffer(length);
for (int i = 0; i < args.length; i++) {
buf.putString(args[i]);
}
return buf;
}
/*
* static String[] chars={ "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f" };
* static void dump_buffer(){ int foo; for(int i=0; i<tmp_buffer_index; i++){
* foo=tmp_buffer[i]&0xff; System.err.print(chars[(foo>>>4)&0xf]);
* System.err.print(chars[foo&0xf]); if(i%16==15){ System.err.println(""); continue; } if(i>0 &&
* i%2==1){ System.err.print(" "); } } System.err.println(""); } static void dump(byte[] b){
* dump(b, 0, b.length); } static void dump(byte[] b, int s, int l){ for(int i=s; i<s+l; i++){
* System.err.print(Integer.toHexString(b[i]&0xff)+":"); } System.err.println(""); }
*/
}

View file

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

View file

@ -0,0 +1,268 @@
/*
* Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.util.Vector;
class ChannelAgentForwarding extends Channel {
private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
private static final byte SSH_AGENTC_RSA_CHALLENGE = 3;
private static final byte SSH_AGENT_RSA_RESPONSE = 4;
private static final byte SSH_AGENT_FAILURE = 5;
private static final byte SSH_AGENT_SUCCESS = 6;
private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11;
private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12;
private static final byte SSH2_AGENTC_SIGN_REQUEST = 13;
private static final byte SSH2_AGENT_SIGN_RESPONSE = 14;
private static final byte SSH2_AGENTC_ADD_IDENTITY = 17;
private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18;
private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
private static final byte SSH2_AGENT_FAILURE = 30;
// static private final int SSH_AGENT_OLD_SIGNATURE=0x1;
private static final int SSH_AGENT_RSA_SHA2_256 = 0x2;
private static final int SSH_AGENT_RSA_SHA2_512 = 0x4;
private Buffer rbuf = null;
private Buffer wbuf = null;
private Packet packet = null;
private Buffer mbuf = null;
ChannelAgentForwarding() {
super();
lwsize_max = LOCAL_WINDOW_SIZE_MAX;
lwsize = LOCAL_WINDOW_SIZE_MAX;
lmpsize = LOCAL_MAXIMUM_PACKET_SIZE;
type = Util.str2byte("auth-agent@openssh.com");
rbuf = new Buffer();
rbuf.reset();
// wbuf=new Buffer(rmpsize);
// packet=new Packet(wbuf);
mbuf = new Buffer();
connected = true;
}
@Override
void run() {
try {
sendOpenConfirmation();
} catch (Exception e) {
close = true;
disconnect();
}
}
@Override
void write(byte[] foo, int s, int l) throws IOException {
if (packet == null) {
wbuf = new Buffer(rmpsize);
packet = new Packet(wbuf);
}
rbuf.shift();
if (rbuf.buffer.length < rbuf.index + l) {
byte[] newbuf = new byte[rbuf.s + l];
System.arraycopy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.length);
rbuf.buffer = newbuf;
}
rbuf.putByte(foo, s, l);
int mlen = rbuf.getInt();
if (mlen > rbuf.getLength()) {
rbuf.s -= 4;
return;
}
int typ = rbuf.getByte();
Session _session = null;
try {
_session = getSession();
} catch (JSchException e) {
throw new IOException(e.toString(), e);
}
IdentityRepository irepo = _session.getIdentityRepository();
UserInfo userinfo = _session.getUserInfo();
mbuf.reset();
if (typ == SSH2_AGENTC_REQUEST_IDENTITIES) {
mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
Vector<Identity> identities = irepo.getIdentities();
synchronized (identities) {
int count = 0;
for (int i = 0; i < identities.size(); i++) {
Identity identity = identities.elementAt(i);
if (identity.getPublicKeyBlob() != null)
count++;
}
mbuf.putInt(count);
for (int i = 0; i < identities.size(); i++) {
Identity identity = identities.elementAt(i);
byte[] pubkeyblob = identity.getPublicKeyBlob();
if (pubkeyblob == null)
continue;
mbuf.putString(pubkeyblob);
mbuf.putString(Util.empty);
}
}
} else if (typ == SSH_AGENTC_REQUEST_RSA_IDENTITIES) {
mbuf.putByte(SSH_AGENT_RSA_IDENTITIES_ANSWER);
mbuf.putInt(0);
} else if (typ == SSH2_AGENTC_SIGN_REQUEST) {
byte[] blob = rbuf.getString();
byte[] data = rbuf.getString();
int flags = rbuf.getInt();
// if((flags & SSH_AGENT_OLD_SIGNATURE)!=0){ // old OpenSSH 2.0, 2.1
// datafellows = SSH_BUG_SIGBLOB;
// }
Vector<Identity> identities = irepo.getIdentities();
Identity identity = null;
synchronized (identities) {
for (int i = 0; i < identities.size(); i++) {
Identity _identity = identities.elementAt(i);
if (_identity.getPublicKeyBlob() == null)
continue;
if (!Util.array_equals(blob, _identity.getPublicKeyBlob())) {
continue;
}
if (_identity.isEncrypted()) {
if (userinfo == null)
continue;
while (_identity.isEncrypted()) {
if (!userinfo.promptPassphrase("Passphrase for " + _identity.getName())) {
break;
}
String _passphrase = userinfo.getPassphrase();
if (_passphrase == null) {
break;
}
byte[] passphrase = Util.str2byte(_passphrase);
try {
if (_identity.setPassphrase(passphrase)) {
break;
}
} catch (JSchException e) {
break;
}
}
}
if (!_identity.isEncrypted()) {
identity = _identity;
break;
}
}
}
byte[] signature = null;
if (identity != null) {
Buffer kbuf = new Buffer(blob);
String keytype = Util.byte2str(kbuf.getString());
if (keytype.equals("ssh-rsa")) {
if ((flags & SSH_AGENT_RSA_SHA2_256) != 0) {
signature = identity.getSignature(data, "rsa-sha2-256");
} else if ((flags & SSH_AGENT_RSA_SHA2_512) != 0) {
signature = identity.getSignature(data, "rsa-sha2-512");
} else {
signature = identity.getSignature(data, "ssh-rsa");
}
} else {
signature = identity.getSignature(data);
}
}
if (signature == null) {
mbuf.putByte(SSH2_AGENT_FAILURE);
} else {
mbuf.putByte(SSH2_AGENT_SIGN_RESPONSE);
mbuf.putString(signature);
}
} else if (typ == SSH2_AGENTC_REMOVE_IDENTITY) {
byte[] blob = rbuf.getString();
irepo.remove(blob);
mbuf.putByte(SSH_AGENT_SUCCESS);
} else if (typ == SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES) {
mbuf.putByte(SSH_AGENT_SUCCESS);
} else if (typ == SSH2_AGENTC_REMOVE_ALL_IDENTITIES) {
irepo.removeAll();
mbuf.putByte(SSH_AGENT_SUCCESS);
} else if (typ == SSH2_AGENTC_ADD_IDENTITY) {
int fooo = rbuf.getLength();
byte[] tmp = new byte[fooo];
rbuf.getByte(tmp);
boolean result = irepo.add(tmp);
mbuf.putByte(result ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
} else {
rbuf.skip(rbuf.getLength() - 1);
mbuf.putByte(SSH_AGENT_FAILURE);
}
byte[] response = new byte[mbuf.getLength()];
mbuf.getByte(response);
send(response);
}
private void send(byte[] message) {
packet.reset();
wbuf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
wbuf.putInt(recipient);
wbuf.putInt(4 + message.length);
wbuf.putString(message);
try {
getSession().write(packet, this, 4 + message.length);
} catch (Exception e) {
}
}
@Override
void eof_remote() {
super.eof_remote();
eof();
}
}

View file

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

View file

@ -0,0 +1,175 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.InputStream;
import java.io.OutputStream;
public class ChannelDirectTCPIP extends Channel {
private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
private static final byte[] _type = Util.str2byte("direct-tcpip");
String host;
int port;
String originator_IP_address = "127.0.0.1";
int originator_port = 0;
ChannelDirectTCPIP() {
super();
type = _type;
lwsize_max = LOCAL_WINDOW_SIZE_MAX;
lwsize = LOCAL_WINDOW_SIZE_MAX;
lmpsize = LOCAL_MAXIMUM_PACKET_SIZE;
}
@Override
void init() {
io = new IO();
}
@Override
public void connect(int connectTimeout) throws JSchException {
this.connectTimeout = connectTimeout;
try {
Session _session = getSession();
if (!_session.isConnected()) {
throw new JSchException("session is down");
}
if (io.in != null) {
thread = new Thread(this::run);
thread.setName("DirectTCPIP thread " + _session.getHost());
if (_session.daemon_thread) {
thread.setDaemon(_session.daemon_thread);
}
thread.start();
} else {
sendChannelOpen();
}
} catch (Exception e) {
io.close();
io = null;
Channel.del(this);
if (e instanceof JSchException) {
throw (JSchException) e;
}
}
}
@Override
void run() {
try {
sendChannelOpen();
Buffer buf = new Buffer(rmpsize);
Packet packet = new Packet(buf);
Session _session = getSession();
int i = 0;
while (isConnected() && thread != null && io != null && io.in != null) {
i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin());
if (i <= 0) {
eof();
break;
}
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
synchronized (this) {
if (close)
break;
_session.write(packet, this, i);
}
}
} catch (Exception e) {
// Whenever an exception is thrown by sendChannelOpen(),
// 'connected' is false.
if (!connected) {
connected = true;
}
disconnect();
return;
}
eof();
disconnect();
}
@Override
public void setInputStream(InputStream in) {
io.setInputStream(in);
}
@Override
public void setOutputStream(OutputStream out) {
io.setOutputStream(out);
}
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
public void setOrgIPAddress(String foo) {
this.originator_IP_address = foo;
}
public void setOrgPort(int foo) {
this.originator_port = foo;
}
@Override
protected Packet genChannelOpenPacket() {
Buffer buf = new Buffer(50 + // 6 + 4*8 + 12
host.length() + originator_IP_address.length() + session.getBufferMargin());
Packet packet = new Packet(buf);
// byte SSH_MSG_CHANNEL_OPEN(90)
// string channel type //
// uint32 sender channel // 0
// uint32 initial window size // 0x100000(65536)
// uint32 maxmum packet size // 0x4000(16384)
packet.reset();
buf.putByte((byte) 90);
buf.putString(this.type);
buf.putInt(id);
buf.putInt(lwsize);
buf.putInt(lmpsize);
buf.putString(Util.str2byte(host));
buf.putInt(port);
buf.putString(Util.str2byte(originator_IP_address));
buf.putInt(originator_port);
return packet;
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class ChannelExec extends ChannelSession {
byte[] command = new byte[0];
public ChannelExec() {
}
@Override
public void start() throws JSchException {
Session _session = getSession();
try {
sendRequests();
Request request = new RequestExec(command);
request.request(_session, this);
} catch (Exception e) {
if (e instanceof JSchException)
throw (JSchException) e;
throw new JSchException("ChannelExec", e);
}
if (io.in != null) {
thread = new Thread(this::run);
thread.setName("Exec thread " + _session.getHost());
if (_session.daemon_thread) {
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
public void setCommand(String command) {
this.command = Util.str2byte(command);
}
public void setCommand(byte[] command) {
this.command = command;
}
@Override
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
public void setErrStream(OutputStream out) {
setExtOutputStream(out);
}
public void setErrStream(OutputStream out, boolean dontclose) {
setExtOutputStream(out, dontclose);
}
public InputStream getErrStream() throws IOException {
return getExtInputStream();
}
}

View file

@ -0,0 +1,334 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.PipedOutputStream;
import java.net.Socket;
import java.util.Vector;
public class ChannelForwardedTCPIP extends Channel {
private static Vector<Config> pool = new Vector<>();
private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
// static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
private static final int TIMEOUT = 10 * 1000;
private Socket socket = null;
private ForwardedTCPIPDaemon daemon = null;
private Config config = null;
ChannelForwardedTCPIP() {
super();
lwsize_max = LOCAL_WINDOW_SIZE_MAX;
lwsize = LOCAL_WINDOW_SIZE_MAX;
lmpsize = LOCAL_MAXIMUM_PACKET_SIZE;
io = new IO();
connected = true;
}
@Override
public void run() {
try {
if (config instanceof ConfigDaemon) {
ConfigDaemon _config = (ConfigDaemon) config;
Class<? extends ForwardedTCPIPDaemon> c =
Class.forName(_config.target).asSubclass(ForwardedTCPIPDaemon.class);
daemon = c.getDeclaredConstructor().newInstance();
PipedOutputStream out = new PipedOutputStream();
io.setInputStream(new PassiveInputStream(out, 32 * 1024), false);
daemon.setChannel(this, getInputStream(), out);
daemon.setArg(_config.arg);
new Thread(daemon).start();
} else {
ConfigLHost _config = (ConfigLHost) config;
socket =
(_config.factory == null) ? Util.createSocket(_config.target, _config.lport, TIMEOUT)
: _config.factory.createSocket(_config.target, _config.lport);
socket.setTcpNoDelay(true);
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
}
sendOpenConfirmation();
} catch (Exception e) {
sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
close = true;
disconnect();
return;
}
thread = Thread.currentThread();
Buffer buf = new Buffer(rmpsize);
Packet packet = new Packet(buf);
int i = 0;
try {
Session _session = getSession();
while (thread != null && io != null && io.in != null) {
i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin());
if (i <= 0) {
eof();
break;
}
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
synchronized (this) {
if (close)
break;
_session.write(packet, this, i);
}
}
} catch (Exception e) {
// System.err.println(e);
}
// thread=null;
// eof();
disconnect();
}
@Override
void getData(Buffer buf) {
setRecipient(buf.getInt());
setRemoteWindowSize(buf.getUInt());
setRemotePacketSize(buf.getInt());
byte[] addr = buf.getString();
int port = buf.getInt();
byte[] orgaddr = buf.getString();
int orgport = buf.getInt();
/*
* System.err.println("addr: "+Util.byte2str(addr)); System.err.println("port: "+port);
* System.err.println("orgaddr: "+Util.byte2str(orgaddr));
* System.err.println("orgport: "+orgport);
*/
Session _session = null;
try {
_session = getSession();
} catch (JSchException e) {
// session has been already down.
}
this.config = getPort(_session, Util.byte2str(addr), port);
if (this.config == null)
this.config = getPort(_session, null, port);
if (this.config == null) {
if (_session.getLogger().isEnabled(Logger.ERROR)) {
_session.getLogger().log(Logger.ERROR,
"ChannelForwardedTCPIP: " + Util.byte2str(addr) + ":" + port + " is not registered.");
}
}
}
private static Config getPort(Session session, String address_to_bind, int rport) {
synchronized (pool) {
for (int i = 0; i < pool.size(); i++) {
Config bar = pool.elementAt(i);
if (bar.session != session)
continue;
if (bar.rport != rport) {
if (bar.rport != 0 || bar.allocated_rport != rport)
continue;
}
if (address_to_bind != null && !bar.address_to_bind.equals(address_to_bind))
continue;
return bar;
}
return null;
}
}
static String[] getPortForwarding(Session session) {
Vector<String> foo = new Vector<>();
synchronized (pool) {
for (int i = 0; i < pool.size(); i++) {
Config config = pool.elementAt(i);
if (config.session == session) {
if (config instanceof ConfigDaemon)
foo.addElement(config.allocated_rport + ":" + config.target + ":");
else
foo.addElement(
config.allocated_rport + ":" + config.target + ":" + ((ConfigLHost) config).lport);
}
}
}
String[] bar = new String[foo.size()];
for (int i = 0; i < foo.size(); i++) {
bar[i] = foo.elementAt(i);
}
return bar;
}
static String normalize(String address) {
if (address == null) {
return "localhost";
} else if (address.length() == 0 || address.equals("*")) {
return "";
} else {
return address;
}
}
static void addPort(Session session, String _address_to_bind, int port, int allocated_port,
String target, int lport, SocketFactory factory) throws JSchException {
String address_to_bind = normalize(_address_to_bind);
synchronized (pool) {
if (getPort(session, address_to_bind, port) != null) {
throw new JSchException("PortForwardingR: remote port " + port + " is already registered.");
}
ConfigLHost config = new ConfigLHost();
config.session = session;
config.rport = port;
config.allocated_rport = allocated_port;
config.target = target;
config.lport = lport;
config.address_to_bind = address_to_bind;
config.factory = factory;
pool.addElement(config);
}
}
static void addPort(Session session, String _address_to_bind, int port, int allocated_port,
String daemon, Object[] arg) throws JSchException {
String address_to_bind = normalize(_address_to_bind);
synchronized (pool) {
if (getPort(session, address_to_bind, port) != null) {
throw new JSchException("PortForwardingR: remote port " + port + " is already registered.");
}
ConfigDaemon config = new ConfigDaemon();
config.session = session;
config.rport = port;
config.allocated_rport = port;
config.target = daemon;
config.arg = arg;
config.address_to_bind = address_to_bind;
pool.addElement(config);
}
}
static void delPort(ChannelForwardedTCPIP c) {
Session _session = null;
try {
_session = c.getSession();
} catch (JSchException e) {
// session has been already down.
}
if (_session != null && c.config != null)
delPort(_session, c.config.rport);
}
static void delPort(Session session, int rport) {
delPort(session, null, rport);
}
static void delPort(Session session, String address_to_bind, int rport) {
synchronized (pool) {
Config foo = getPort(session, normalize(address_to_bind), rport);
if (foo == null)
foo = getPort(session, null, rport);
if (foo == null)
return;
pool.removeElement(foo);
if (address_to_bind == null) {
address_to_bind = foo.address_to_bind;
}
if (address_to_bind == null) {
address_to_bind = "0.0.0.0";
}
}
Buffer buf = new Buffer(200); // ??
Packet packet = new Packet(buf);
try {
// byte SSH_MSG_GLOBAL_REQUEST 80
// string "cancel-tcpip-forward"
// boolean want_reply
// string address_to_bind (e.g. "127.0.0.1")
// uint32 port number to bind
packet.reset();
buf.putByte((byte) 80 /* SSH_MSG_GLOBAL_REQUEST */);
buf.putString(Util.str2byte("cancel-tcpip-forward"));
buf.putByte((byte) 0);
buf.putString(Util.str2byte(address_to_bind));
buf.putInt(rport);
session.write(packet);
} catch (Exception e) {
// throw new JSchException(e.toString(), e);
}
}
static void delPort(Session session) {
int[] rport = null;
int count = 0;
synchronized (pool) {
rport = new int[pool.size()];
for (int i = 0; i < pool.size(); i++) {
Config config = pool.elementAt(i);
if (config.session == session) {
rport[count++] = config.rport; // ((Integer)bar[1]).intValue();
}
}
}
for (int i = 0; i < count; i++) {
delPort(session, rport[i]);
}
}
public int getRemotePort() {
return (config != null ? config.rport : 0);
}
private void setSocketFactory(SocketFactory factory) {
if (config != null && (config instanceof ConfigLHost))
((ConfigLHost) config).factory = factory;
}
abstract static class Config {
Session session;
int rport;
int allocated_rport;
String address_to_bind;
String target;
}
static class ConfigDaemon extends Config {
Object[] arg;
}
static class ConfigLHost extends Config {
int lport;
SocketFactory factory;
}
}

View file

@ -0,0 +1,265 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Enumeration;
import java.util.Hashtable;
class ChannelSession extends Channel {
private static byte[] _session = Util.str2byte("session");
protected boolean agent_forwarding = false;
protected boolean xforwading = false;
protected Hashtable<byte[], byte[]> env = null;
protected boolean pty = false;
protected String ttype = "vt100";
protected int tcol = 80;
protected int trow = 24;
protected int twp = 640;
protected int thp = 480;
protected byte[] terminal_mode = null;
ChannelSession() {
super();
type = _session;
io = new IO();
}
/**
* Enable the agent forwarding.
*
* @param enable
*/
public void setAgentForwarding(boolean enable) {
agent_forwarding = enable;
}
/**
* Enable the X11 forwarding. Refer to RFC4254 6.3.1. Requesting X11 Forwarding.
*
* @param enable
*/
@Override
public void setXForwarding(boolean enable) {
xforwading = enable;
}
/**
* @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead.
* @see #setEnv(String, String)
* @see #setEnv(byte[], byte[])
*/
@Deprecated
public void setEnv(Hashtable<byte[], byte[]> env) {
synchronized (this) {
this.env = env;
}
}
/**
* Set the environment variable. If <code>name</code> and <code>value</code> are needed to be
* passed to the remote in your favorite encoding, use {@link #setEnv(byte[], byte[])}. Refer to
* RFC4254 6.4 Environment Variable Passing.
*
* @param name A name for environment variable.
* @param value A value for environment variable.
*/
public void setEnv(String name, String value) {
setEnv(Util.str2byte(name), Util.str2byte(value));
}
/**
* Set the environment variable. Refer to RFC4254 6.4 Environment Variable Passing.
*
* @param name A name of environment variable.
* @param value A value of environment variable.
* @see #setEnv(String, String)
*/
public void setEnv(byte[] name, byte[] value) {
synchronized (this) {
getEnv().put(name, value);
}
}
private Hashtable<byte[], byte[]> getEnv() {
if (env == null)
env = new Hashtable<>();
return env;
}
/**
* Allocate a Pseudo-Terminal. Refer to RFC4254 6.2. Requesting a Pseudo-Terminal.
*
* @param enable
*/
public void setPty(boolean enable) {
pty = enable;
}
/**
* Set the terminal mode.
*
* @param terminal_mode
*/
public void setTerminalMode(byte[] terminal_mode) {
this.terminal_mode = terminal_mode;
}
/**
* Change the window dimension interactively. Refer to RFC4254 6.7. Window Dimension Change
* Message.
*
* @param col terminal width, columns
* @param row terminal height, rows
* @param wp terminal width, pixels
* @param hp terminal height, pixels
*/
public void setPtySize(int col, int row, int wp, int hp) {
setPtyType(this.ttype, col, row, wp, hp);
if (!pty || !isConnected()) {
return;
}
try {
RequestWindowChange request = new RequestWindowChange();
request.setSize(col, row, wp, hp);
request.request(getSession(), this);
} catch (Exception e) {
// System.err.println("ChannelSessio.setPtySize: "+e);
}
}
/**
* Set the terminal type. This method is not effective after Channel#connect().
*
* @param ttype terminal type(for example, "vt100")
* @see #setPtyType(String, int, int, int, int)
*/
public void setPtyType(String ttype) {
setPtyType(ttype, 80, 24, 640, 480);
}
/**
* Set the terminal type. This method is not effective after Channel#connect().
*
* @param ttype terminal type(for example, "vt100")
* @param col terminal width, columns
* @param row terminal height, rows
* @param wp terminal width, pixels
* @param hp terminal height, pixels
*/
public void setPtyType(String ttype, int col, int row, int wp, int hp) {
this.ttype = ttype;
this.tcol = col;
this.trow = row;
this.twp = wp;
this.thp = hp;
}
protected void sendRequests() throws Exception {
Session _session = getSession();
Request request;
if (agent_forwarding) {
request = new RequestAgentForwarding();
request.request(_session, this);
}
if (xforwading) {
request = new RequestX11();
request.request(_session, this);
}
if (pty) {
request = new RequestPtyReq();
((RequestPtyReq) request).setTType(ttype);
((RequestPtyReq) request).setTSize(tcol, trow, twp, thp);
if (terminal_mode != null) {
((RequestPtyReq) request).setTerminalMode(terminal_mode);
}
request.request(_session, this);
}
if (env != null) {
for (Enumeration<byte[]> _env = env.keys(); _env.hasMoreElements();) {
byte[] name = _env.nextElement();
byte[] value = env.get(name);
request = new RequestEnv();
((RequestEnv) request).setEnv(toByteArray(name), toByteArray(value));
request.request(_session, this);
}
}
}
private byte[] toByteArray(Object o) {
if (o instanceof String) {
return Util.str2byte((String) o);
}
return (byte[]) o;
}
@Override
void run() {
// System.err.println(this+":run >");
Buffer buf = new Buffer(rmpsize);
Packet packet = new Packet(buf);
int i = -1;
try {
Session _session = getSession();
while (isConnected() && thread != null && io != null && io.in != null) {
i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin());
if (i == 0)
continue;
if (i == -1) {
eof();
break;
}
if (close)
break;
// System.out.println("write: "+i);
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
_session.write(packet, this, i);
}
} catch (Exception e) {
// System.err.println("# ChannelExec.run");
// e.printStackTrace();
}
Thread _thread = thread;
if (_thread != null) {
synchronized (_thread) {
_thread.notifyAll();
}
}
thread = null;
// System.err.println(this+":run <");
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public class ChannelShell extends ChannelSession {
ChannelShell() {
super();
pty = true;
}
@Override
public void start() throws JSchException {
Session _session = getSession();
try {
sendRequests();
Request request = new RequestShell();
request.request(_session, this);
} catch (Exception e) {
if (e instanceof JSchException)
throw (JSchException) e;
throw new JSchException("ChannelShell", e);
}
if (io.in != null) {
thread = new Thread(this::run);
thread.setName("Shell for " + _session.host);
if (_session.daemon_thread) {
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
@Override
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class ChannelSubsystem extends ChannelSession {
boolean want_reply = true;
String subsystem = "";
public ChannelSubsystem() {
}
public void setWantReply(boolean foo) {
want_reply = foo;
}
public void setSubsystem(String foo) {
subsystem = foo;
}
@Override
public void start() throws JSchException {
Session _session = getSession();
try {
Request request;
if (xforwading) {
request = new RequestX11();
request.request(_session, this);
}
if (pty) {
request = new RequestPtyReq();
request.request(_session, this);
}
request = new RequestSubsystem();
((RequestSubsystem) request).request(_session, this, subsystem, want_reply);
} catch (Exception e) {
if (e instanceof JSchException) {
throw (JSchException) e;
}
throw new JSchException("ChannelSubsystem", e);
}
if (io.in != null) {
thread = new Thread(this::run);
thread.setName("Subsystem for " + _session.host);
if (_session.daemon_thread) {
thread.setDaemon(_session.daemon_thread);
}
thread.start();
}
}
@Override
void init() throws JSchException {
io.setInputStream(getSession().in);
io.setOutputStream(getSession().out);
}
public void setErrStream(OutputStream out) {
setExtOutputStream(out);
}
public InputStream getErrStream() throws IOException {
return getExtInputStream();
}
}

View file

@ -0,0 +1,262 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.net.Socket;
import java.util.Hashtable;
class ChannelX11 extends Channel {
private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
private static final int TIMEOUT = 10 * 1000;
private static String host = "127.0.0.1";
private static int port = 6000;
private boolean init = true;
static byte[] cookie = null;
private static byte[] cookie_hex = null;
private static Hashtable<Session, byte[]> faked_cookie_pool = new Hashtable<>();
private static Hashtable<Session, byte[]> faked_cookie_hex_pool = new Hashtable<>();
private static byte[] table = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66};
private Socket socket = null;
static int revtable(byte foo) {
for (int i = 0; i < table.length; i++) {
if (table[i] == foo)
return i;
}
return 0;
}
static void setCookie(String foo) {
cookie_hex = Util.str2byte(foo);
cookie = new byte[16];
for (int i = 0; i < 16; i++) {
cookie[i] = (byte) (((revtable(cookie_hex[i * 2]) << 4) & 0xf0)
| ((revtable(cookie_hex[i * 2 + 1])) & 0xf));
}
}
static void setHost(String foo) {
host = foo;
}
static void setPort(int foo) {
port = foo;
}
static byte[] getFakedCookie(Session session) {
synchronized (faked_cookie_hex_pool) {
byte[] foo = faked_cookie_hex_pool.get(session);
if (foo == null) {
Random random = Session.random;
foo = new byte[16];
synchronized (random) {
random.fill(foo, 0, 16);
}
/*
* System.err.print("faked_cookie: "); for(int i=0; i<foo.length; i++){
* System.err.print(Integer.toHexString(foo[i]&0xff)+":"); } System.err.println("");
*/
faked_cookie_pool.put(session, foo);
byte[] bar = new byte[32];
for (int i = 0; i < 16; i++) {
bar[2 * i] = table[(foo[i] >>> 4) & 0xf];
bar[2 * i + 1] = table[(foo[i]) & 0xf];
}
faked_cookie_hex_pool.put(session, bar);
foo = bar;
}
return foo;
}
}
static void removeFakedCookie(Session session) {
synchronized (faked_cookie_hex_pool) {
faked_cookie_hex_pool.remove(session);
faked_cookie_pool.remove(session);
}
}
ChannelX11() {
super();
lwsize_max = LOCAL_WINDOW_SIZE_MAX;
lwsize = LOCAL_WINDOW_SIZE_MAX;
lmpsize = LOCAL_MAXIMUM_PACKET_SIZE;
type = Util.str2byte("x11");
connected = true;
/*
* try{ socket=Util.createSocket(host, port, TIMEOUT); socket.setTcpNoDelay(true); io=new IO();
* io.setInputStream(socket.getInputStream()); io.setOutputStream(socket.getOutputStream()); }
* catch(Exception e){ //System.err.println(e); }
*/
}
@Override
void run() {
try {
socket = Util.createSocket(host, port, TIMEOUT);
socket.setTcpNoDelay(true);
io = new IO();
io.setInputStream(socket.getInputStream());
io.setOutputStream(socket.getOutputStream());
sendOpenConfirmation();
} catch (Exception e) {
sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
close = true;
disconnect();
return;
}
thread = Thread.currentThread();
Buffer buf = new Buffer(rmpsize);
Packet packet = new Packet(buf);
int i = 0;
try {
Session _session = getSession();
while (thread != null && io != null && io.in != null) {
i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin());
if (i <= 0) {
eof();
break;
}
if (close)
break;
packet.reset();
buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
buf.putInt(recipient);
buf.putInt(i);
buf.skip(i);
_session.write(packet, this, i);
}
} catch (Exception e) {
// System.err.println(e);
}
disconnect();
}
private byte[] cache = new byte[0];
private byte[] addCache(byte[] foo, int s, int l) {
byte[] bar = new byte[cache.length + l];
System.arraycopy(foo, s, bar, cache.length, l);
if (cache.length > 0)
System.arraycopy(cache, 0, bar, 0, cache.length);
cache = bar;
return cache;
}
@Override
void write(byte[] foo, int s, int l) throws IOException {
// if(eof_local)return;
if (init) {
Session _session = null;
try {
_session = getSession();
} catch (JSchException e) {
throw new IOException(e.toString(), e);
}
foo = addCache(foo, s, l);
s = 0;
l = foo.length;
if (l < 9)
return;
int plen = (foo[s + 6] & 0xff) * 256 + (foo[s + 7] & 0xff);
int dlen = (foo[s + 8] & 0xff) * 256 + (foo[s + 9] & 0xff);
if ((foo[s] & 0xff) == 0x42) {
} else if ((foo[s] & 0xff) == 0x6c) {
plen = ((plen >>> 8) & 0xff) | ((plen << 8) & 0xff00);
dlen = ((dlen >>> 8) & 0xff) | ((dlen << 8) & 0xff00);
} else {
// ??
}
if (l < 12 + plen + ((-plen) & 3) + dlen)
return;
byte[] bar = new byte[dlen];
System.arraycopy(foo, s + 12 + plen + ((-plen) & 3), bar, 0, dlen);
byte[] faked_cookie = null;
synchronized (faked_cookie_pool) {
faked_cookie = faked_cookie_pool.get(_session);
}
/*
* System.err.print("faked_cookie: "); for(int i=0; i<faked_cookie.length; i++){
* System.err.print(Integer.toHexString(faked_cookie[i]&0xff)+":"); } System.err.println("");
* System.err.print("bar: "); for(int i=0; i<bar.length; i++){
* System.err.print(Integer.toHexString(bar[i]&0xff)+":"); } System.err.println("");
*/
if (equals(bar, faked_cookie)) {
if (cookie != null)
System.arraycopy(cookie, 0, foo, s + 12 + plen + ((-plen) & 3), dlen);
} else {
// System.err.println("wrong cookie");
thread = null;
eof();
io.close();
disconnect();
}
init = false;
io.put(foo, s, l);
cache = null;
return;
}
io.put(foo, s, l);
}
private static boolean equals(byte[] foo, byte[] bar) {
if (foo.length != bar.length)
return false;
for (int i = 0; i < foo.length; i++) {
if (foo[i] != bar[i])
return false;
}
return true;
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Cipher {
static int ENCRYPT_MODE = 0;
static int DECRYPT_MODE = 1;
int getIVSize();
int getBlockSize();
default int getTagSize() {
return 0;
}
void init(int mode, byte[] key, byte[] iv) throws Exception;
default void update(int foo) throws Exception {}
void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception;
default void updateAAD(byte[] foo, int s1, int len) throws Exception {}
default void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception {}
boolean isCBC();
default boolean isAEAD() {
return false;
}
default boolean isChaCha20() {
return false;
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class CipherNone implements Cipher {
private static final int ivsize = 8;
private static final int bsize = 16;
@Override
public int getIVSize() {
return ivsize;
}
@Override
public int getBlockSize() {
return bsize;
}
@Override
public void init(int mode, byte[] key, byte[] iv) throws Exception {}
@Override
public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception {}
@Override
public boolean isCBC() {
return false;
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Compression {
public static final int INFLATER = 0;
public static final int DEFLATER = 1;
default void init(int type, int level, Session session) {
init(type, level);
}
default void end() {}
void init(int type, int level);
byte[] compress(byte[] buf, int start, int[] len);
byte[] uncompress(byte[] buf, int start, int[] len);
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface ConfigRepository {
public Config getConfig(String host);
public interface Config {
public String getHostname();
public String getUser();
public int getPort();
public String getValue(String key);
public String[] getValues(String key);
}
static final Config defaultConfig = new Config() {
@Override
public String getHostname() {
return null;
}
@Override
public String getUser() {
return null;
}
@Override
public int getPort() {
return -1;
}
@Override
public String getValue(String key) {
return null;
}
@Override
public String[] getValues(String key) {
return null;
}
};
static final ConfigRepository nullConfig = new ConfigRepository() {
@Override
public Config getConfig(String host) {
return defaultConfig;
}
};
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface DH {
void init() throws Exception;
void setP(byte[] p);
void setG(byte[] g);
byte[] getE() throws Exception;
void setF(byte[] f);
byte[] getK() throws Exception;
// checkRange() will check if e and f are in [1,p-1]
// as defined at https://tools.ietf.org/html/rfc4253#section-8
void checkRange() throws Exception;
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DH25519 extends DHXEC {
public DH25519() {
sha_name = "sha-256";
curve_name = "X25519";
key_len = 32;
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DH25519SNTRUP761 extends DHXECKEM {
public DH25519SNTRUP761() {
kem_name = "sntrup761";
sha_name = "sha-512";
curve_name = "X25519";
kem_pubkey_len = 1158;
kem_encap_len = 1039;
xec_key_len = 32;
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DH448 extends DHXEC {
public DH448() {
sha_name = "sha-512";
curve_name = "X448";
key_len = 56;
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHEC256 extends DHECN {
public DHEC256() {
sha_name = "sha-256";
key_size = 256;
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHEC384 extends DHECN {
public DHEC384() {
sha_name = "sha-384";
key_size = 384;
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHEC521 extends DHECN {
public DHEC521() {
sha_name = "sha-512";
key_size = 521;
}
}

View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHECN extends KeyExchange {
private static final int SSH_MSG_KEX_ECDH_INIT = 30;
private static final int SSH_MSG_KEX_ECDH_REPLY = 31;
private int state;
byte[] Q_C;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
private ECDH ecdh;
protected String sha_name;
protected int key_size;
@Override
public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws Exception {
this.V_S = V_S;
this.V_C = V_C;
this.I_S = I_S;
this.I_C = I_C;
try {
Class<? extends HASH> c = Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
sha = c.getDeclaredConstructor().newInstance();
sha.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
buf = new Buffer();
packet = new Packet(buf);
packet.reset();
buf.putByte((byte) SSH_MSG_KEX_ECDH_INIT);
try {
Class<? extends ECDH> c =
Class.forName(session.getConfig("ecdh-sha2-nistp")).asSubclass(ECDH.class);
ecdh = c.getDeclaredConstructor().newInstance();
ecdh.init(key_size);
Q_C = ecdh.getQ();
buf.putString(Q_C);
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if (session.getLogger().isEnabled(Logger.INFO)) {
session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent");
session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY");
}
state = SSH_MSG_KEX_ECDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception {
int i, j;
switch (state) {
case SSH_MSG_KEX_ECDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_ECDH_REPLY
// string K_S, server's public host key
// string Q_S, server's ephemeral public key octet string
// string the signature on the exchange hash
j = _buf.getInt();
j = _buf.getByte();
j = _buf.getByte();
if (j != SSH_MSG_KEX_ECDH_REPLY) {
if (session.getLogger().isEnabled(Logger.ERROR)) {
session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_ECDH_REPLY " + j);
}
return false;
}
K_S = _buf.getString();
byte[] Q_S = _buf.getString();
byte[][] r_s = KeyPairECDSA.fromPoint(Q_S);
// RFC 5656,
// 4. ECDH Key Exchange
// All elliptic curve public keys MUST be validated after they are
// received. An example of a validation algorithm can be found in
// Section 3.2.2 of [SEC1]. If a key fails validation,
// the key exchange MUST fail.
if (!ecdh.validate(r_s[0], r_s[1])) {
return false;
}
K = encodeAsMPInt(normalize(ecdh.getSecret(r_s[0], r_s[1])));
byte[] sig_of_H = _buf.getString();
// The hash H is computed as the HASH hash of the concatenation of the
// following:
// string V_C, client's identification string (CR and LF excluded)
// string V_S, server's identification string (CR and LF excluded)
// string I_C, payload of the client's SSH_MSG_KEXINIT
// string I_S, payload of the server's SSH_MSG_KEXINIT
// string K_S, server's public host key
// string Q_C, client's ephemeral public key octet string
// string Q_S, server's ephemeral public key octet string
// mpint K, shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C);
buf.putString(V_S);
buf.putString(I_C);
buf.putString(I_S);
buf.putString(K_S);
buf.putString(Q_C);
buf.putString(Q_S);
byte[] foo = new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
sha.update(K, 0, K.length);
H = sha.digest();
i = 0;
j = 0;
j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000)
| ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff);
String alg = Util.byte2str(K_S, i, j);
i += j;
boolean result = verify(alg, K_S, i, sig_of_H);
state = STATE_END;
return result;
}
return false;
}
@Override
public int getState() {
return state;
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG1 extends DHGN {
static final byte[] g = {2};
static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA,
(byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6,
(byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29,
(byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74,
(byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34,
(byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD,
(byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D,
(byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35,
(byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
(byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4,
(byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B,
(byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89,
(byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
(byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51,
(byte) 0xEC, (byte) 0xE6, (byte) 0x53, (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
@Override
byte[] G() {
return g;
}
@Override
byte[] P() {
return p;
}
@Override
String sha_name() {
return "sha-1";
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG14 extends DHG14N {
@Override
String sha_name() {
return "sha-1";
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG14224 extends DHG14N {
@Override
String sha_name() {
return "sha-224";
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG14256 extends DHG14N {
@Override
String sha_name() {
return "sha-256";
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHG14N extends DHGN {
static final byte[] g = {2};
static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA,
(byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6,
(byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29,
(byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74,
(byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34,
(byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD,
(byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D,
(byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35,
(byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
(byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4,
(byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B,
(byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89,
(byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
(byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51,
(byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C,
(byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA,
(byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69,
(byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F,
(byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD,
(byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85,
(byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70,
(byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E,
(byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C,
(byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90,
(byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3,
(byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03,
(byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2,
(byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C,
(byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95,
(byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C,
(byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26,
(byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72,
(byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAC, (byte) 0xAA, (byte) 0x68, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
@Override
byte[] G() {
return g;
}
@Override
byte[] P() {
return p;
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG15 extends DHG15N {
@Override
String sha_name() {
return "sha-512";
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG15256 extends DHG15N {
@Override
String sha_name() {
return "sha-256";
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG15384 extends DHG15N {
@Override
String sha_name() {
return "sha-384";
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHG15N extends DHGN {
static final byte[] g = {2};
static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA,
(byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6,
(byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29,
(byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74,
(byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34,
(byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD,
(byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D,
(byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35,
(byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
(byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4,
(byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B,
(byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89,
(byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
(byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51,
(byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C,
(byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA,
(byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69,
(byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F,
(byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD,
(byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85,
(byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70,
(byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E,
(byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C,
(byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90,
(byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3,
(byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03,
(byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2,
(byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C,
(byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95,
(byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C,
(byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26,
(byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72,
(byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD,
(byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33,
(byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA,
(byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB,
(byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D,
(byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85,
(byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE,
(byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C,
(byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE,
(byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B,
(byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08,
(byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8,
(byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17,
(byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57,
(byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88,
(byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2,
(byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43,
(byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E,
(byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x3A, (byte) 0xD2,
(byte) 0xCA, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF};
@Override
byte[] G() {
return g;
}
@Override
byte[] P() {
return p;
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG16 extends DHG16N {
@Override
String sha_name() {
return "sha-512";
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG16384 extends DHG16N {
@Override
String sha_name() {
return "sha-384";
}
}

View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHG16N extends DHGN {
static final byte[] g = {2};
static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA,
(byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6,
(byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29,
(byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74,
(byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34,
(byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD,
(byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D,
(byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35,
(byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
(byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4,
(byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B,
(byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89,
(byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
(byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51,
(byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C,
(byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA,
(byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69,
(byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F,
(byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD,
(byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85,
(byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70,
(byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E,
(byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C,
(byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90,
(byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3,
(byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03,
(byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2,
(byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C,
(byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95,
(byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C,
(byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26,
(byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72,
(byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD,
(byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33,
(byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA,
(byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB,
(byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D,
(byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85,
(byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE,
(byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C,
(byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE,
(byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B,
(byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08,
(byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8,
(byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17,
(byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57,
(byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88,
(byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2,
(byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43,
(byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E,
(byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x21, (byte) 0x08,
(byte) 0x01, (byte) 0x1A, (byte) 0x72, (byte) 0x3C, (byte) 0x12, (byte) 0xA7, (byte) 0x87,
(byte) 0xE6, (byte) 0xD7, (byte) 0x88, (byte) 0x71, (byte) 0x9A, (byte) 0x10, (byte) 0xBD,
(byte) 0xBA, (byte) 0x5B, (byte) 0x26, (byte) 0x99, (byte) 0xC3, (byte) 0x27, (byte) 0x18,
(byte) 0x6A, (byte) 0xF4, (byte) 0xE2, (byte) 0x3C, (byte) 0x1A, (byte) 0x94, (byte) 0x68,
(byte) 0x34, (byte) 0xB6, (byte) 0x15, (byte) 0x0B, (byte) 0xDA, (byte) 0x25, (byte) 0x83,
(byte) 0xE9, (byte) 0xCA, (byte) 0x2A, (byte) 0xD4, (byte) 0x4C, (byte) 0xE8, (byte) 0xDB,
(byte) 0xBB, (byte) 0xC2, (byte) 0xDB, (byte) 0x04, (byte) 0xDE, (byte) 0x8E, (byte) 0xF9,
(byte) 0x2E, (byte) 0x8E, (byte) 0xFC, (byte) 0x14, (byte) 0x1F, (byte) 0xBE, (byte) 0xCA,
(byte) 0xA6, (byte) 0x28, (byte) 0x7C, (byte) 0x59, (byte) 0x47, (byte) 0x4E, (byte) 0x6B,
(byte) 0xC0, (byte) 0x5D, (byte) 0x99, (byte) 0xB2, (byte) 0x96, (byte) 0x4F, (byte) 0xA0,
(byte) 0x90, (byte) 0xC3, (byte) 0xA2, (byte) 0x23, (byte) 0x3B, (byte) 0xA1, (byte) 0x86,
(byte) 0x51, (byte) 0x5B, (byte) 0xE7, (byte) 0xED, (byte) 0x1F, (byte) 0x61, (byte) 0x29,
(byte) 0x70, (byte) 0xCE, (byte) 0xE2, (byte) 0xD7, (byte) 0xAF, (byte) 0xB8, (byte) 0x1B,
(byte) 0xDD, (byte) 0x76, (byte) 0x21, (byte) 0x70, (byte) 0x48, (byte) 0x1C, (byte) 0xD0,
(byte) 0x06, (byte) 0x91, (byte) 0x27, (byte) 0xD5, (byte) 0xB0, (byte) 0x5A, (byte) 0xA9,
(byte) 0x93, (byte) 0xB4, (byte) 0xEA, (byte) 0x98, (byte) 0x8D, (byte) 0x8F, (byte) 0xDD,
(byte) 0xC1, (byte) 0x86, (byte) 0xFF, (byte) 0xB7, (byte) 0xDC, (byte) 0x90, (byte) 0xA6,
(byte) 0xC0, (byte) 0x8F, (byte) 0x4D, (byte) 0xF4, (byte) 0x35, (byte) 0xC9, (byte) 0x34,
(byte) 0x06, (byte) 0x31, (byte) 0x99, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
@Override
byte[] G() {
return g;
}
@Override
byte[] P() {
return p;
}
}

View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG17 extends DHGN {
static final byte[] g = {2};
static final byte[] p =
{(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21,
(byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B,
(byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E,
(byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B,
(byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51,
(byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD,
(byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43,
(byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F,
(byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D,
(byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76,
(byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42,
(byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF,
(byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE,
(byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5,
(byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F,
(byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4,
(byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1,
(byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36,
(byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F,
(byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F, (byte) 0x83, (byte) 0x65,
(byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD, (byte) 0x96, (byte) 0x1C,
(byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52, (byte) 0xBB,
(byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96,
(byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC,
(byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA,
(byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46,
(byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77,
(byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03, (byte) 0x9B, (byte) 0x27,
(byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2, (byte) 0x8F, (byte) 0xB5,
(byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52, (byte) 0xC9,
(byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17,
(byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95,
(byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98,
(byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A,
(byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD, (byte) 0x33, (byte) 0x17,
(byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33, (byte) 0xA8, (byte) 0x55,
(byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA, (byte) 0x64, (byte) 0xEC,
(byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB, (byte) 0xEF, (byte) 0x0A,
(byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D, (byte) 0x06, (byte) 0x0C,
(byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85, (byte) 0xA6, (byte) 0xE1,
(byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE, (byte) 0x8C, (byte) 0xDB,
(byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C, (byte) 0x94, (byte) 0xE0,
(byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE, (byte) 0xE3, (byte) 0xD2,
(byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B, (byte) 0xF1, (byte) 0x2F,
(byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08, (byte) 0x64, (byte) 0xD8,
(byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8, (byte) 0x6A, (byte) 0x64,
(byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17, (byte) 0x7B, (byte) 0x20,
(byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57, (byte) 0x7A, (byte) 0x61,
(byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88, (byte) 0xC0, (byte) 0xBA,
(byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2, (byte) 0x4F, (byte) 0xA0,
(byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43, (byte) 0xDB, (byte) 0x5B,
(byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E, (byte) 0x4B, (byte) 0x82,
(byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x21, (byte) 0x08, (byte) 0x01, (byte) 0x1A,
(byte) 0x72, (byte) 0x3C, (byte) 0x12, (byte) 0xA7, (byte) 0x87, (byte) 0xE6, (byte) 0xD7,
(byte) 0x88, (byte) 0x71, (byte) 0x9A, (byte) 0x10, (byte) 0xBD, (byte) 0xBA, (byte) 0x5B,
(byte) 0x26, (byte) 0x99, (byte) 0xC3, (byte) 0x27, (byte) 0x18, (byte) 0x6A, (byte) 0xF4,
(byte) 0xE2, (byte) 0x3C, (byte) 0x1A, (byte) 0x94, (byte) 0x68, (byte) 0x34, (byte) 0xB6,
(byte) 0x15, (byte) 0x0B, (byte) 0xDA, (byte) 0x25, (byte) 0x83, (byte) 0xE9, (byte) 0xCA,
(byte) 0x2A, (byte) 0xD4, (byte) 0x4C, (byte) 0xE8, (byte) 0xDB, (byte) 0xBB, (byte) 0xC2,
(byte) 0xDB, (byte) 0x04, (byte) 0xDE, (byte) 0x8E, (byte) 0xF9, (byte) 0x2E, (byte) 0x8E,
(byte) 0xFC, (byte) 0x14, (byte) 0x1F, (byte) 0xBE, (byte) 0xCA, (byte) 0xA6, (byte) 0x28,
(byte) 0x7C, (byte) 0x59, (byte) 0x47, (byte) 0x4E, (byte) 0x6B, (byte) 0xC0, (byte) 0x5D,
(byte) 0x99, (byte) 0xB2, (byte) 0x96, (byte) 0x4F, (byte) 0xA0, (byte) 0x90, (byte) 0xC3,
(byte) 0xA2, (byte) 0x23, (byte) 0x3B, (byte) 0xA1, (byte) 0x86, (byte) 0x51, (byte) 0x5B,
(byte) 0xE7, (byte) 0xED, (byte) 0x1F, (byte) 0x61, (byte) 0x29, (byte) 0x70, (byte) 0xCE,
(byte) 0xE2, (byte) 0xD7, (byte) 0xAF, (byte) 0xB8, (byte) 0x1B, (byte) 0xDD, (byte) 0x76,
(byte) 0x21, (byte) 0x70, (byte) 0x48, (byte) 0x1C, (byte) 0xD0, (byte) 0x06, (byte) 0x91,
(byte) 0x27, (byte) 0xD5, (byte) 0xB0, (byte) 0x5A, (byte) 0xA9, (byte) 0x93, (byte) 0xB4,
(byte) 0xEA, (byte) 0x98, (byte) 0x8D, (byte) 0x8F, (byte) 0xDD, (byte) 0xC1, (byte) 0x86,
(byte) 0xFF, (byte) 0xB7, (byte) 0xDC, (byte) 0x90, (byte) 0xA6, (byte) 0xC0, (byte) 0x8F,
(byte) 0x4D, (byte) 0xF4, (byte) 0x35, (byte) 0xC9, (byte) 0x34, (byte) 0x02, (byte) 0x84,
(byte) 0x92, (byte) 0x36, (byte) 0xC3, (byte) 0xFA, (byte) 0xB4, (byte) 0xD2, (byte) 0x7C,
(byte) 0x70, (byte) 0x26, (byte) 0xC1, (byte) 0xD4, (byte) 0xDC, (byte) 0xB2, (byte) 0x60,
(byte) 0x26, (byte) 0x46, (byte) 0xDE, (byte) 0xC9, (byte) 0x75, (byte) 0x1E, (byte) 0x76,
(byte) 0x3D, (byte) 0xBA, (byte) 0x37, (byte) 0xBD, (byte) 0xF8, (byte) 0xFF, (byte) 0x94,
(byte) 0x06, (byte) 0xAD, (byte) 0x9E, (byte) 0x53, (byte) 0x0E, (byte) 0xE5, (byte) 0xDB,
(byte) 0x38, (byte) 0x2F, (byte) 0x41, (byte) 0x30, (byte) 0x01, (byte) 0xAE, (byte) 0xB0,
(byte) 0x6A, (byte) 0x53, (byte) 0xED, (byte) 0x90, (byte) 0x27, (byte) 0xD8, (byte) 0x31,
(byte) 0x17, (byte) 0x97, (byte) 0x27, (byte) 0xB0, (byte) 0x86, (byte) 0x5A, (byte) 0x89,
(byte) 0x18, (byte) 0xDA, (byte) 0x3E, (byte) 0xDB, (byte) 0xEB, (byte) 0xCF, (byte) 0x9B,
(byte) 0x14, (byte) 0xED, (byte) 0x44, (byte) 0xCE, (byte) 0x6C, (byte) 0xBA, (byte) 0xCE,
(byte) 0xD4, (byte) 0xBB, (byte) 0x1B, (byte) 0xDB, (byte) 0x7F, (byte) 0x14, (byte) 0x47,
(byte) 0xE6, (byte) 0xCC, (byte) 0x25, (byte) 0x4B, (byte) 0x33, (byte) 0x20, (byte) 0x51,
(byte) 0x51, (byte) 0x2B, (byte) 0xD7, (byte) 0xAF, (byte) 0x42, (byte) 0x6F, (byte) 0xB8,
(byte) 0xF4, (byte) 0x01, (byte) 0x37, (byte) 0x8C, (byte) 0xD2, (byte) 0xBF, (byte) 0x59,
(byte) 0x83, (byte) 0xCA, (byte) 0x01, (byte) 0xC6, (byte) 0x4B, (byte) 0x92, (byte) 0xEC,
(byte) 0xF0, (byte) 0x32, (byte) 0xEA, (byte) 0x15, (byte) 0xD1, (byte) 0x72, (byte) 0x1D,
(byte) 0x03, (byte) 0xF4, (byte) 0x82, (byte) 0xD7, (byte) 0xCE, (byte) 0x6E, (byte) 0x74,
(byte) 0xFE, (byte) 0xF6, (byte) 0xD5, (byte) 0x5E, (byte) 0x70, (byte) 0x2F, (byte) 0x46,
(byte) 0x98, (byte) 0x0C, (byte) 0x82, (byte) 0xB5, (byte) 0xA8, (byte) 0x40, (byte) 0x31,
(byte) 0x90, (byte) 0x0B, (byte) 0x1C, (byte) 0x9E, (byte) 0x59, (byte) 0xE7, (byte) 0xC9,
(byte) 0x7F, (byte) 0xBE, (byte) 0xC7, (byte) 0xE8, (byte) 0xF3, (byte) 0x23, (byte) 0xA9,
(byte) 0x7A, (byte) 0x7E, (byte) 0x36, (byte) 0xCC, (byte) 0x88, (byte) 0xBE, (byte) 0x0F,
(byte) 0x1D, (byte) 0x45, (byte) 0xB7, (byte) 0xFF, (byte) 0x58, (byte) 0x5A, (byte) 0xC5,
(byte) 0x4B, (byte) 0xD4, (byte) 0x07, (byte) 0xB2, (byte) 0x2B, (byte) 0x41, (byte) 0x54,
(byte) 0xAA, (byte) 0xCC, (byte) 0x8F, (byte) 0x6D, (byte) 0x7E, (byte) 0xBF, (byte) 0x48,
(byte) 0xE1, (byte) 0xD8, (byte) 0x14, (byte) 0xCC, (byte) 0x5E, (byte) 0xD2, (byte) 0x0F,
(byte) 0x80, (byte) 0x37, (byte) 0xE0, (byte) 0xA7, (byte) 0x97, (byte) 0x15, (byte) 0xEE,
(byte) 0xF2, (byte) 0x9B, (byte) 0xE3, (byte) 0x28, (byte) 0x06, (byte) 0xA1, (byte) 0xD5,
(byte) 0x8B, (byte) 0xB7, (byte) 0xC5, (byte) 0xDA, (byte) 0x76, (byte) 0xF5, (byte) 0x50,
(byte) 0xAA, (byte) 0x3D, (byte) 0x8A, (byte) 0x1F, (byte) 0xBF, (byte) 0xF0, (byte) 0xEB,
(byte) 0x19, (byte) 0xCC, (byte) 0xB1, (byte) 0xA3, (byte) 0x13, (byte) 0xD5, (byte) 0x5C,
(byte) 0xDA, (byte) 0x56, (byte) 0xC9, (byte) 0xEC, (byte) 0x2E, (byte) 0xF2, (byte) 0x96,
(byte) 0x32, (byte) 0x38, (byte) 0x7F, (byte) 0xE8, (byte) 0xD7, (byte) 0x6E, (byte) 0x3C,
(byte) 0x04, (byte) 0x68, (byte) 0x04, (byte) 0x3E, (byte) 0x8F, (byte) 0x66, (byte) 0x3F,
(byte) 0x48, (byte) 0x60, (byte) 0xEE, (byte) 0x12, (byte) 0xBF, (byte) 0x2D, (byte) 0x5B,
(byte) 0x0B, (byte) 0x74, (byte) 0x74, (byte) 0xD6, (byte) 0xE6, (byte) 0x94, (byte) 0xF9,
(byte) 0x1E, (byte) 0x6D, (byte) 0xCC, (byte) 0x40, (byte) 0x24, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,};
@Override
byte[] G() {
return g;
}
@Override
byte[] P() {
return p;
}
@Override
String sha_name() {
return "sha-512";
}
}

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHG18 extends DHGN {
static final byte[] g = {2};
static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA,
(byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6,
(byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29,
(byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74,
(byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34,
(byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD,
(byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D,
(byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35,
(byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
(byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4,
(byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B,
(byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89,
(byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
(byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51,
(byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C,
(byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA,
(byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69,
(byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F,
(byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD,
(byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85,
(byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70,
(byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E,
(byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C,
(byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90,
(byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3,
(byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03,
(byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2,
(byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C,
(byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95,
(byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C,
(byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26,
(byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72,
(byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD,
(byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33,
(byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA,
(byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB,
(byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D,
(byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85,
(byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE,
(byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C,
(byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE,
(byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B,
(byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08,
(byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8,
(byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17,
(byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57,
(byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88,
(byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2,
(byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43,
(byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E,
(byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x21, (byte) 0x08,
(byte) 0x01, (byte) 0x1A, (byte) 0x72, (byte) 0x3C, (byte) 0x12, (byte) 0xA7, (byte) 0x87,
(byte) 0xE6, (byte) 0xD7, (byte) 0x88, (byte) 0x71, (byte) 0x9A, (byte) 0x10, (byte) 0xBD,
(byte) 0xBA, (byte) 0x5B, (byte) 0x26, (byte) 0x99, (byte) 0xC3, (byte) 0x27, (byte) 0x18,
(byte) 0x6A, (byte) 0xF4, (byte) 0xE2, (byte) 0x3C, (byte) 0x1A, (byte) 0x94, (byte) 0x68,
(byte) 0x34, (byte) 0xB6, (byte) 0x15, (byte) 0x0B, (byte) 0xDA, (byte) 0x25, (byte) 0x83,
(byte) 0xE9, (byte) 0xCA, (byte) 0x2A, (byte) 0xD4, (byte) 0x4C, (byte) 0xE8, (byte) 0xDB,
(byte) 0xBB, (byte) 0xC2, (byte) 0xDB, (byte) 0x04, (byte) 0xDE, (byte) 0x8E, (byte) 0xF9,
(byte) 0x2E, (byte) 0x8E, (byte) 0xFC, (byte) 0x14, (byte) 0x1F, (byte) 0xBE, (byte) 0xCA,
(byte) 0xA6, (byte) 0x28, (byte) 0x7C, (byte) 0x59, (byte) 0x47, (byte) 0x4E, (byte) 0x6B,
(byte) 0xC0, (byte) 0x5D, (byte) 0x99, (byte) 0xB2, (byte) 0x96, (byte) 0x4F, (byte) 0xA0,
(byte) 0x90, (byte) 0xC3, (byte) 0xA2, (byte) 0x23, (byte) 0x3B, (byte) 0xA1, (byte) 0x86,
(byte) 0x51, (byte) 0x5B, (byte) 0xE7, (byte) 0xED, (byte) 0x1F, (byte) 0x61, (byte) 0x29,
(byte) 0x70, (byte) 0xCE, (byte) 0xE2, (byte) 0xD7, (byte) 0xAF, (byte) 0xB8, (byte) 0x1B,
(byte) 0xDD, (byte) 0x76, (byte) 0x21, (byte) 0x70, (byte) 0x48, (byte) 0x1C, (byte) 0xD0,
(byte) 0x06, (byte) 0x91, (byte) 0x27, (byte) 0xD5, (byte) 0xB0, (byte) 0x5A, (byte) 0xA9,
(byte) 0x93, (byte) 0xB4, (byte) 0xEA, (byte) 0x98, (byte) 0x8D, (byte) 0x8F, (byte) 0xDD,
(byte) 0xC1, (byte) 0x86, (byte) 0xFF, (byte) 0xB7, (byte) 0xDC, (byte) 0x90, (byte) 0xA6,
(byte) 0xC0, (byte) 0x8F, (byte) 0x4D, (byte) 0xF4, (byte) 0x35, (byte) 0xC9, (byte) 0x34,
(byte) 0x02, (byte) 0x84, (byte) 0x92, (byte) 0x36, (byte) 0xC3, (byte) 0xFA, (byte) 0xB4,
(byte) 0xD2, (byte) 0x7C, (byte) 0x70, (byte) 0x26, (byte) 0xC1, (byte) 0xD4, (byte) 0xDC,
(byte) 0xB2, (byte) 0x60, (byte) 0x26, (byte) 0x46, (byte) 0xDE, (byte) 0xC9, (byte) 0x75,
(byte) 0x1E, (byte) 0x76, (byte) 0x3D, (byte) 0xBA, (byte) 0x37, (byte) 0xBD, (byte) 0xF8,
(byte) 0xFF, (byte) 0x94, (byte) 0x06, (byte) 0xAD, (byte) 0x9E, (byte) 0x53, (byte) 0x0E,
(byte) 0xE5, (byte) 0xDB, (byte) 0x38, (byte) 0x2F, (byte) 0x41, (byte) 0x30, (byte) 0x01,
(byte) 0xAE, (byte) 0xB0, (byte) 0x6A, (byte) 0x53, (byte) 0xED, (byte) 0x90, (byte) 0x27,
(byte) 0xD8, (byte) 0x31, (byte) 0x17, (byte) 0x97, (byte) 0x27, (byte) 0xB0, (byte) 0x86,
(byte) 0x5A, (byte) 0x89, (byte) 0x18, (byte) 0xDA, (byte) 0x3E, (byte) 0xDB, (byte) 0xEB,
(byte) 0xCF, (byte) 0x9B, (byte) 0x14, (byte) 0xED, (byte) 0x44, (byte) 0xCE, (byte) 0x6C,
(byte) 0xBA, (byte) 0xCE, (byte) 0xD4, (byte) 0xBB, (byte) 0x1B, (byte) 0xDB, (byte) 0x7F,
(byte) 0x14, (byte) 0x47, (byte) 0xE6, (byte) 0xCC, (byte) 0x25, (byte) 0x4B, (byte) 0x33,
(byte) 0x20, (byte) 0x51, (byte) 0x51, (byte) 0x2B, (byte) 0xD7, (byte) 0xAF, (byte) 0x42,
(byte) 0x6F, (byte) 0xB8, (byte) 0xF4, (byte) 0x01, (byte) 0x37, (byte) 0x8C, (byte) 0xD2,
(byte) 0xBF, (byte) 0x59, (byte) 0x83, (byte) 0xCA, (byte) 0x01, (byte) 0xC6, (byte) 0x4B,
(byte) 0x92, (byte) 0xEC, (byte) 0xF0, (byte) 0x32, (byte) 0xEA, (byte) 0x15, (byte) 0xD1,
(byte) 0x72, (byte) 0x1D, (byte) 0x03, (byte) 0xF4, (byte) 0x82, (byte) 0xD7, (byte) 0xCE,
(byte) 0x6E, (byte) 0x74, (byte) 0xFE, (byte) 0xF6, (byte) 0xD5, (byte) 0x5E, (byte) 0x70,
(byte) 0x2F, (byte) 0x46, (byte) 0x98, (byte) 0x0C, (byte) 0x82, (byte) 0xB5, (byte) 0xA8,
(byte) 0x40, (byte) 0x31, (byte) 0x90, (byte) 0x0B, (byte) 0x1C, (byte) 0x9E, (byte) 0x59,
(byte) 0xE7, (byte) 0xC9, (byte) 0x7F, (byte) 0xBE, (byte) 0xC7, (byte) 0xE8, (byte) 0xF3,
(byte) 0x23, (byte) 0xA9, (byte) 0x7A, (byte) 0x7E, (byte) 0x36, (byte) 0xCC, (byte) 0x88,
(byte) 0xBE, (byte) 0x0F, (byte) 0x1D, (byte) 0x45, (byte) 0xB7, (byte) 0xFF, (byte) 0x58,
(byte) 0x5A, (byte) 0xC5, (byte) 0x4B, (byte) 0xD4, (byte) 0x07, (byte) 0xB2, (byte) 0x2B,
(byte) 0x41, (byte) 0x54, (byte) 0xAA, (byte) 0xCC, (byte) 0x8F, (byte) 0x6D, (byte) 0x7E,
(byte) 0xBF, (byte) 0x48, (byte) 0xE1, (byte) 0xD8, (byte) 0x14, (byte) 0xCC, (byte) 0x5E,
(byte) 0xD2, (byte) 0x0F, (byte) 0x80, (byte) 0x37, (byte) 0xE0, (byte) 0xA7, (byte) 0x97,
(byte) 0x15, (byte) 0xEE, (byte) 0xF2, (byte) 0x9B, (byte) 0xE3, (byte) 0x28, (byte) 0x06,
(byte) 0xA1, (byte) 0xD5, (byte) 0x8B, (byte) 0xB7, (byte) 0xC5, (byte) 0xDA, (byte) 0x76,
(byte) 0xF5, (byte) 0x50, (byte) 0xAA, (byte) 0x3D, (byte) 0x8A, (byte) 0x1F, (byte) 0xBF,
(byte) 0xF0, (byte) 0xEB, (byte) 0x19, (byte) 0xCC, (byte) 0xB1, (byte) 0xA3, (byte) 0x13,
(byte) 0xD5, (byte) 0x5C, (byte) 0xDA, (byte) 0x56, (byte) 0xC9, (byte) 0xEC, (byte) 0x2E,
(byte) 0xF2, (byte) 0x96, (byte) 0x32, (byte) 0x38, (byte) 0x7F, (byte) 0xE8, (byte) 0xD7,
(byte) 0x6E, (byte) 0x3C, (byte) 0x04, (byte) 0x68, (byte) 0x04, (byte) 0x3E, (byte) 0x8F,
(byte) 0x66, (byte) 0x3F, (byte) 0x48, (byte) 0x60, (byte) 0xEE, (byte) 0x12, (byte) 0xBF,
(byte) 0x2D, (byte) 0x5B, (byte) 0x0B, (byte) 0x74, (byte) 0x74, (byte) 0xD6, (byte) 0xE6,
(byte) 0x94, (byte) 0xF9, (byte) 0x1E, (byte) 0x6D, (byte) 0xBE, (byte) 0x11, (byte) 0x59,
(byte) 0x74, (byte) 0xA3, (byte) 0x92, (byte) 0x6F, (byte) 0x12, (byte) 0xFE, (byte) 0xE5,
(byte) 0xE4, (byte) 0x38, (byte) 0x77, (byte) 0x7C, (byte) 0xB6, (byte) 0xA9, (byte) 0x32,
(byte) 0xDF, (byte) 0x8C, (byte) 0xD8, (byte) 0xBE, (byte) 0xC4, (byte) 0xD0, (byte) 0x73,
(byte) 0xB9, (byte) 0x31, (byte) 0xBA, (byte) 0x3B, (byte) 0xC8, (byte) 0x32, (byte) 0xB6,
(byte) 0x8D, (byte) 0x9D, (byte) 0xD3, (byte) 0x00, (byte) 0x74, (byte) 0x1F, (byte) 0xA7,
(byte) 0xBF, (byte) 0x8A, (byte) 0xFC, (byte) 0x47, (byte) 0xED, (byte) 0x25, (byte) 0x76,
(byte) 0xF6, (byte) 0x93, (byte) 0x6B, (byte) 0xA4, (byte) 0x24, (byte) 0x66, (byte) 0x3A,
(byte) 0xAB, (byte) 0x63, (byte) 0x9C, (byte) 0x5A, (byte) 0xE4, (byte) 0xF5, (byte) 0x68,
(byte) 0x34, (byte) 0x23, (byte) 0xB4, (byte) 0x74, (byte) 0x2B, (byte) 0xF1, (byte) 0xC9,
(byte) 0x78, (byte) 0x23, (byte) 0x8F, (byte) 0x16, (byte) 0xCB, (byte) 0xE3, (byte) 0x9D,
(byte) 0x65, (byte) 0x2D, (byte) 0xE3, (byte) 0xFD, (byte) 0xB8, (byte) 0xBE, (byte) 0xFC,
(byte) 0x84, (byte) 0x8A, (byte) 0xD9, (byte) 0x22, (byte) 0x22, (byte) 0x2E, (byte) 0x04,
(byte) 0xA4, (byte) 0x03, (byte) 0x7C, (byte) 0x07, (byte) 0x13, (byte) 0xEB, (byte) 0x57,
(byte) 0xA8, (byte) 0x1A, (byte) 0x23, (byte) 0xF0, (byte) 0xC7, (byte) 0x34, (byte) 0x73,
(byte) 0xFC, (byte) 0x64, (byte) 0x6C, (byte) 0xEA, (byte) 0x30, (byte) 0x6B, (byte) 0x4B,
(byte) 0xCB, (byte) 0xC8, (byte) 0x86, (byte) 0x2F, (byte) 0x83, (byte) 0x85, (byte) 0xDD,
(byte) 0xFA, (byte) 0x9D, (byte) 0x4B, (byte) 0x7F, (byte) 0xA2, (byte) 0xC0, (byte) 0x87,
(byte) 0xE8, (byte) 0x79, (byte) 0x68, (byte) 0x33, (byte) 0x03, (byte) 0xED, (byte) 0x5B,
(byte) 0xDD, (byte) 0x3A, (byte) 0x06, (byte) 0x2B, (byte) 0x3C, (byte) 0xF5, (byte) 0xB3,
(byte) 0xA2, (byte) 0x78, (byte) 0xA6, (byte) 0x6D, (byte) 0x2A, (byte) 0x13, (byte) 0xF8,
(byte) 0x3F, (byte) 0x44, (byte) 0xF8, (byte) 0x2D, (byte) 0xDF, (byte) 0x31, (byte) 0x0E,
(byte) 0xE0, (byte) 0x74, (byte) 0xAB, (byte) 0x6A, (byte) 0x36, (byte) 0x45, (byte) 0x97,
(byte) 0xE8, (byte) 0x99, (byte) 0xA0, (byte) 0x25, (byte) 0x5D, (byte) 0xC1, (byte) 0x64,
(byte) 0xF3, (byte) 0x1C, (byte) 0xC5, (byte) 0x08, (byte) 0x46, (byte) 0x85, (byte) 0x1D,
(byte) 0xF9, (byte) 0xAB, (byte) 0x48, (byte) 0x19, (byte) 0x5D, (byte) 0xED, (byte) 0x7E,
(byte) 0xA1, (byte) 0xB1, (byte) 0xD5, (byte) 0x10, (byte) 0xBD, (byte) 0x7E, (byte) 0xE7,
(byte) 0x4D, (byte) 0x73, (byte) 0xFA, (byte) 0xF3, (byte) 0x6B, (byte) 0xC3, (byte) 0x1E,
(byte) 0xCF, (byte) 0xA2, (byte) 0x68, (byte) 0x35, (byte) 0x90, (byte) 0x46, (byte) 0xF4,
(byte) 0xEB, (byte) 0x87, (byte) 0x9F, (byte) 0x92, (byte) 0x40, (byte) 0x09, (byte) 0x43,
(byte) 0x8B, (byte) 0x48, (byte) 0x1C, (byte) 0x6C, (byte) 0xD7, (byte) 0x88, (byte) 0x9A,
(byte) 0x00, (byte) 0x2E, (byte) 0xD5, (byte) 0xEE, (byte) 0x38, (byte) 0x2B, (byte) 0xC9,
(byte) 0x19, (byte) 0x0D, (byte) 0xA6, (byte) 0xFC, (byte) 0x02, (byte) 0x6E, (byte) 0x47,
(byte) 0x95, (byte) 0x58, (byte) 0xE4, (byte) 0x47, (byte) 0x56, (byte) 0x77, (byte) 0xE9,
(byte) 0xAA, (byte) 0x9E, (byte) 0x30, (byte) 0x50, (byte) 0xE2, (byte) 0x76, (byte) 0x56,
(byte) 0x94, (byte) 0xDF, (byte) 0xC8, (byte) 0x1F, (byte) 0x56, (byte) 0xE8, (byte) 0x80,
(byte) 0xB9, (byte) 0x6E, (byte) 0x71, (byte) 0x60, (byte) 0xC9, (byte) 0x80, (byte) 0xDD,
(byte) 0x98, (byte) 0xED, (byte) 0xD3, (byte) 0xDF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
@Override
byte[] G() {
return g;
}
@Override
byte[] P() {
return p;
}
@Override
String sha_name() {
return "sha-512";
}
}

View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.math.BigInteger;
abstract class DHGEX extends KeyExchange {
private static final int SSH_MSG_KEX_DH_GEX_GROUP = 31;
private static final int SSH_MSG_KEX_DH_GEX_INIT = 32;
private static final int SSH_MSG_KEX_DH_GEX_REPLY = 33;
private static final int SSH_MSG_KEX_DH_GEX_REQUEST = 34;
int min;
int preferred;
int max;
private int state;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
private Buffer buf;
private Packet packet;
private byte[] p;
private byte[] g;
private byte[] e;
protected String hash;
@Override
public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws Exception {
this.V_S = V_S;
this.V_C = V_C;
this.I_S = I_S;
this.I_C = I_C;
try {
Class<? extends HASH> c = Class.forName(session.getConfig(hash)).asSubclass(HASH.class);
sha = c.getDeclaredConstructor().newInstance();
sha.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
buf = new Buffer();
packet = new Packet(buf);
try {
Class<? extends DH> c = Class.forName(session.getConfig("dh")).asSubclass(DH.class);
min = Integer.parseInt(session.getConfig("dhgex_min"));
max = Integer.parseInt(session.getConfig("dhgex_max"));
preferred = Integer.parseInt(session.getConfig("dhgex_preferred"));
if (min <= 0 || max <= 0 || preferred <= 0 || preferred < min || preferred > max) {
throw new JSchException(
"Invalid DHGEX sizes: min=" + min + " max=" + max + " preferred=" + preferred);
}
dh = c.getDeclaredConstructor().newInstance();
dh.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
packet.reset();
buf.putByte((byte) SSH_MSG_KEX_DH_GEX_REQUEST);
buf.putInt(min);
buf.putInt(preferred);
buf.putInt(max);
session.write(packet);
if (session.getLogger().isEnabled(Logger.INFO)) {
session.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_REQUEST(" + min + "<" + preferred + "<" + max + ") sent");
session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_GROUP");
}
state = SSH_MSG_KEX_DH_GEX_GROUP;
}
@Override
public boolean next(Buffer _buf) throws Exception {
int i, j;
switch (state) {
case SSH_MSG_KEX_DH_GEX_GROUP:
// byte SSH_MSG_KEX_DH_GEX_GROUP(31)
// mpint p, safe prime
// mpint g, generator for subgroup in GF (p)
_buf.getInt();
_buf.getByte();
j = _buf.getByte();
if (j != SSH_MSG_KEX_DH_GEX_GROUP) {
if (session.getLogger().isEnabled(Logger.ERROR)) {
session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_DH_GEX_GROUP " + j);
}
return false;
}
p = _buf.getMPInt();
g = _buf.getMPInt();
int bits = new BigInteger(1, p).bitLength();
if (bits < min || bits > max) {
return false;
}
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEX_DH_GEX_INIT(32)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e = dh.getE();
packet.reset();
buf.putByte((byte) SSH_MSG_KEX_DH_GEX_INIT);
buf.putMPInt(e);
session.write(packet);
if (session.getLogger().isEnabled(Logger.INFO)) {
session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_DH_GEX_INIT sent");
session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_REPLY");
}
state = SSH_MSG_KEX_DH_GEX_REPLY;
return true;
// break;
case SSH_MSG_KEX_DH_GEX_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_DH_GEX_REPLY(33)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j = _buf.getInt();
j = _buf.getByte();
j = _buf.getByte();
if (j != SSH_MSG_KEX_DH_GEX_REPLY) {
if (session.getLogger().isEnabled(Logger.ERROR)) {
session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_DH_GEX_REPLY " + j);
}
return false;
}
K_S = _buf.getString();
byte[] f = _buf.getMPInt();
byte[] sig_of_H = _buf.getString();
dh.setF(f);
dh.checkRange();
K = encodeAsMPInt(normalize(dh.getK()));
// The hash H is computed as the HASH hash of the concatenation of the
// following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// uint32 min, minimal size in bits of an acceptable group
// uint32 n, preferred size in bits of the group the server should send
// uint32 max, maximal size in bits of an acceptable group
// mpint p, safe prime
// mpint g, generator for subgroup
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C);
buf.putString(V_S);
buf.putString(I_C);
buf.putString(I_S);
buf.putString(K_S);
buf.putInt(min);
buf.putInt(preferred);
buf.putInt(max);
buf.putMPInt(p);
buf.putMPInt(g);
buf.putMPInt(e);
buf.putMPInt(f);
byte[] foo = new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
sha.update(K, 0, K.length);
H = sha.digest();
// System.err.print("H -> "); dump(H, 0, H.length);
i = 0;
j = 0;
j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000)
| ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff);
String alg = Util.byte2str(K_S, i, j);
i += j;
boolean result = verify(alg, K_S, i, sig_of_H);
state = STATE_END;
return result;
}
return false;
}
@Override
public int getState() {
return state;
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHGEX1 extends DHGEX {
DHGEX1() {
hash = "sha-1";
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHGEX224 extends DHGEX {
DHGEX224() {
hash = "sha-224";
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHGEX256 extends DHGEX {
DHGEX256() {
hash = "sha-256";
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHGEX384 extends DHGEX {
DHGEX384() {
hash = "sha-384";
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class DHGEX512 extends DHGEX {
DHGEX512() {
hash = "sha-512";
}
}

View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHGN extends KeyExchange {
private static final int SSH_MSG_KEXDH_INIT = 30;
private static final int SSH_MSG_KEXDH_REPLY = 31;
private int state;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
abstract byte[] G();
abstract byte[] P();
abstract String sha_name();
@Override
public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws Exception {
this.V_S = V_S;
this.V_C = V_C;
this.I_S = I_S;
this.I_C = I_C;
try {
Class<? extends HASH> c = Class.forName(session.getConfig(sha_name())).asSubclass(HASH.class);
sha = c.getDeclaredConstructor().newInstance();
sha.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
buf = new Buffer();
packet = new Packet(buf);
try {
Class<? extends DH> c = Class.forName(session.getConfig("dh")).asSubclass(DH.class);
dh = c.getDeclaredConstructor().newInstance();
dh.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
dh.setP(P());
dh.setG(G());
// The client responds with:
// byte SSH_MSG_KEXDH_INIT(30)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e = dh.getE();
packet.reset();
buf.putByte((byte) SSH_MSG_KEXDH_INIT);
buf.putMPInt(e);
if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if (session.getLogger().isEnabled(Logger.INFO)) {
session.getLogger().log(Logger.INFO, "SSH_MSG_KEXDH_INIT sent");
session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEXDH_REPLY");
}
state = SSH_MSG_KEXDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception {
int i, j;
switch (state) {
case SSH_MSG_KEXDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEXDH_REPLY(31)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j = _buf.getInt();
j = _buf.getByte();
j = _buf.getByte();
if (j != SSH_MSG_KEXDH_REPLY) {
if (session.getLogger().isEnabled(Logger.ERROR)) {
session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEXDH_REPLY " + j);
}
return false;
}
K_S = _buf.getString();
byte[] f = _buf.getMPInt();
byte[] sig_of_H = _buf.getString();
dh.setF(f);
dh.checkRange();
K = encodeAsMPInt(normalize(dh.getK()));
// The hash H is computed as the HASH hash of the concatenation of the
// following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C);
buf.putString(V_S);
buf.putString(I_C);
buf.putString(I_S);
buf.putString(K_S);
buf.putMPInt(e);
buf.putMPInt(f);
byte[] foo = new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
sha.update(K, 0, K.length);
H = sha.digest();
// System.err.print("H -> "); //dump(H, 0, H.length);
i = 0;
j = 0;
j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000)
| ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff);
String alg = Util.byte2str(K_S, i, j);
i += j;
boolean result = verify(alg, K_S, i, sig_of_H);
state = STATE_END;
return result;
}
return false;
}
@Override
public int getState() {
return state;
}
}

View file

@ -0,0 +1,199 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHXEC extends KeyExchange {
private static final int SSH_MSG_KEX_ECDH_INIT = 30;
private static final int SSH_MSG_KEX_ECDH_REPLY = 31;
private int state;
byte[] Q_C;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
private XDH xdh;
protected String sha_name;
protected String curve_name;
protected int key_len;
@Override
public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws Exception {
this.V_S = V_S;
this.V_C = V_C;
this.I_S = I_S;
this.I_C = I_C;
try {
Class<? extends HASH> c = Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
sha = c.getDeclaredConstructor().newInstance();
sha.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
buf = new Buffer();
packet = new Packet(buf);
packet.reset();
buf.putByte((byte) SSH_MSG_KEX_ECDH_INIT);
try {
Class<? extends XDH> c = Class.forName(session.getConfig("xdh")).asSubclass(XDH.class);
xdh = c.getDeclaredConstructor().newInstance();
xdh.init(curve_name, key_len);
Q_C = xdh.getQ();
buf.putString(Q_C);
} catch (Exception | NoClassDefFoundError e) {
throw new JSchException(e.toString(), e);
}
if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if (session.getLogger().isEnabled(Logger.INFO)) {
session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent");
session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY");
}
state = SSH_MSG_KEX_ECDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception {
int i, j;
switch (state) {
case SSH_MSG_KEX_ECDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_ECDH_REPLY
// string K_S, server's public host key
// string Q_S, server's ephemeral public key octet string
// string the signature on the exchange hash
j = _buf.getInt();
j = _buf.getByte();
j = _buf.getByte();
if (j != SSH_MSG_KEX_ECDH_REPLY) {
if (session.getLogger().isEnabled(Logger.ERROR)) {
session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_ECDH_REPLY " + j);
}
return false;
}
K_S = _buf.getString();
byte[] Q_S = _buf.getString();
// RFC 5656,
// 4. ECDH Key Exchange
// All elliptic curve public keys MUST be validated after they are
// received. An example of a validation algorithm can be found in
// Section 3.2.2 of [SEC1]. If a key fails validation,
// the key exchange MUST fail.
if (!xdh.validate(Q_S)) {
return false;
}
K = encodeAsMPInt(normalize(xdh.getSecret(Q_S)));
byte[] sig_of_H = _buf.getString();
// The hash H is computed as the HASH hash of the concatenation of the
// following:
// string V_C, client's identification string (CR and LF excluded)
// string V_S, server's identification string (CR and LF excluded)
// string I_C, payload of the client's SSH_MSG_KEXINIT
// string I_S, payload of the server's SSH_MSG_KEXINIT
// string K_S, server's public host key
// string Q_C, client's ephemeral public key octet string
// string Q_S, server's ephemeral public key octet string
// mpint K, shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
// RFC 8731,
// 3.1. Shared Secret Encoding
// The shared secret, K, is defined in [RFC4253] and [RFC5656] as an
// integer encoded as a multiple precision integer (mpint).
// Curve25519/448 outputs a binary string X, which is the 32- or 56-byte
// point obtained by scalar multiplication of the other side's public
// key and the local private key scalar. The 32 or 56 bytes of X are
// converted into K by interpreting the octets as an unsigned fixed-
// length integer encoded in network byte order.
//
// The mpint K is then encoded using the process described in Section 5
// of [RFC4251], and the resulting bytes are fed as described in
// [RFC4253] to the key exchange method's hash function to generate
// encryption keys.
buf.reset();
buf.putString(V_C);
buf.putString(V_S);
buf.putString(I_C);
buf.putString(I_S);
buf.putString(K_S);
buf.putString(Q_C);
buf.putString(Q_S);
byte[] foo = new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
sha.update(K, 0, K.length);
H = sha.digest();
i = 0;
j = 0;
j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000)
| ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff);
String alg = Util.byte2str(K_S, i, j);
i += j;
boolean result = verify(alg, K_S, i, sig_of_H);
state = STATE_END;
return result;
}
return false;
}
@Override
public int getState() {
return state;
}
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
abstract class DHXECKEM extends KeyExchange {
private static final int SSH_MSG_KEX_ECDH_INIT = 30;
private static final int SSH_MSG_KEX_ECDH_REPLY = 31;
private int state;
byte[] Q_C;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
private KEM kem;
private XDH xdh;
protected String kem_name;
protected String sha_name;
protected String curve_name;
protected int kem_pubkey_len;
protected int kem_encap_len;
protected int xec_key_len;
@Override
public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws Exception {
this.V_S = V_S;
this.V_C = V_C;
this.I_S = I_S;
this.I_C = I_C;
try {
Class<? extends HASH> c = Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
sha = c.getDeclaredConstructor().newInstance();
sha.init();
} catch (Exception e) {
throw new JSchException(e.toString(), e);
}
buf = new Buffer();
packet = new Packet(buf);
packet.reset();
// command + string len + Q_C len
buf.checkFreeSize(1 + 4 + kem_pubkey_len + xec_key_len);
buf.putByte((byte) SSH_MSG_KEX_ECDH_INIT);
try {
Class<? extends KEM> k = Class.forName(session.getConfig(kem_name)).asSubclass(KEM.class);
kem = k.getDeclaredConstructor().newInstance();
kem.init();
Class<? extends XDH> c = Class.forName(session.getConfig("xdh")).asSubclass(XDH.class);
xdh = c.getDeclaredConstructor().newInstance();
xdh.init(curve_name, xec_key_len);
byte[] kem_public_key_C = kem.getPublicKey();
byte[] xec_public_key_C = xdh.getQ();
Q_C = new byte[kem_pubkey_len + xec_key_len];
System.arraycopy(kem_public_key_C, 0, Q_C, 0, kem_pubkey_len);
System.arraycopy(xec_public_key_C, 0, Q_C, kem_pubkey_len, xec_key_len);
buf.putString(Q_C);
} catch (Exception | NoClassDefFoundError e) {
throw new JSchException(e.toString(), e);
}
if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if (session.getLogger().isEnabled(Logger.INFO)) {
session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent");
session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY");
}
state = SSH_MSG_KEX_ECDH_REPLY;
}
@Override
public boolean next(Buffer _buf) throws Exception {
int i, j;
switch (state) {
case SSH_MSG_KEX_ECDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_ECDH_REPLY
// string K_S, server's public host key
// string Q_S, server's ephemeral public key octet string
// string the signature on the exchange hash
j = _buf.getInt();
j = _buf.getByte();
j = _buf.getByte();
if (j != SSH_MSG_KEX_ECDH_REPLY) {
if (session.getLogger().isEnabled(Logger.ERROR)) {
session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_ECDH_REPLY " + j);
}
return false;
}
K_S = _buf.getString();
byte[] Q_S = _buf.getString();
if (Q_S.length != kem_encap_len + xec_key_len) {
return false;
}
byte[] encapsulation = new byte[kem_encap_len];
byte[] xec_public_key_S = new byte[xec_key_len];
System.arraycopy(Q_S, 0, encapsulation, 0, kem_encap_len);
System.arraycopy(Q_S, kem_encap_len, xec_public_key_S, 0, xec_key_len);
// RFC 5656,
// 4. ECDH Key Exchange
// All elliptic curve public keys MUST be validated after they are
// received. An example of a validation algorithm can be found in
// Section 3.2.2 of [SEC1]. If a key fails validation,
// the key exchange MUST fail.
if (!xdh.validate(xec_public_key_S)) {
return false;
}
byte[] tmp = null;
try {
tmp = kem.decapsulate(encapsulation);
sha.update(tmp, 0, tmp.length);
} finally {
Util.bzero(tmp);
}
try {
tmp = normalize(xdh.getSecret(xec_public_key_S));
sha.update(tmp, 0, tmp.length);
} finally {
Util.bzero(tmp);
}
K = encodeAsString(sha.digest());
byte[] sig_of_H = _buf.getString();
// The hash H is computed as the HASH hash of the concatenation of the
// following:
// string V_C, client's identification string (CR and LF excluded)
// string V_S, server's identification string (CR and LF excluded)
// string I_C, payload of the client's SSH_MSG_KEXINIT
// string I_S, payload of the server's SSH_MSG_KEXINIT
// string K_S, server's public host key
// string Q_C, client's ephemeral public key octet string
// string Q_S, server's ephemeral public key octet string
// string K, shared secret
// draft-josefsson-ntruprime-ssh-02,
// 3. Key Exchange Method: sntrup761x25519-sha512
// ...
// The SSH_MSG_KEX_ECDH_REPLY's signature value is computed as described
// in [RFC5656] with the following changes. Instead of encoding the
// shared secret K as 'mpint', it MUST be encoded as 'string'. The
// shared secret K value MUST be the 64-byte output octet string of the
// SHA-512 hash computed with the input as the 32-byte octet string key
// output from the key encapsulation mechanism of sntrup761 concatenated
// with the 32-byte octet string of X25519(a, X25519(b, 9)) = X25519(b,
// X25519(a, 9)).
buf.reset();
buf.putString(V_C);
buf.putString(V_S);
buf.putString(I_C);
buf.putString(I_S);
buf.putString(K_S);
buf.putString(Q_C);
buf.putString(Q_S);
byte[] foo = new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
sha.update(K, 0, K.length);
H = sha.digest();
i = 0;
j = 0;
j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000)
| ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff);
String alg = Util.byte2str(K_S, i, j);
i += j;
boolean result = verify(alg, K_S, i, sig_of_H);
state = STATE_END;
return result;
}
return false;
}
@Override
public int getState() {
return state;
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface ECDH {
void init(int size) throws Exception;
byte[] getSecret(byte[] r, byte[] s) throws Exception;
byte[] getQ() throws Exception;
boolean validate(byte[] r, byte[] s) throws Exception;
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.InputStream;
import java.io.OutputStream;
public interface ForwardedTCPIPDaemon extends Runnable {
void setChannel(ChannelForwardedTCPIP channel, InputStream in, OutputStream out);
void setArg(Object[] arg);
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface GSSContext {
public void create(String user, String host) throws JSchException;
public boolean isEstablished();
public byte[] init(byte[] token, int s, int l) throws JSchException;
public byte[] getMIC(byte[] message, int s, int l);
public void dispose();
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface HASH {
void init() throws Exception;
int getBlockSize();
void update(byte[] foo, int start, int len) throws Exception;
byte[] digest() throws Exception;
default String name() {
return "";
}
}

View file

@ -0,0 +1,167 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Locale;
public class HostKey {
private static final byte[][] names =
{Util.str2byte("ssh-dss"), Util.str2byte("ssh-rsa"), Util.str2byte("ecdsa-sha2-nistp256"),
Util.str2byte("ecdsa-sha2-nistp384"), Util.str2byte("ecdsa-sha2-nistp521"),
Util.str2byte("ssh-ed25519"), Util.str2byte("ssh-ed448")};
public static final int UNKNOWN = -1;
public static final int GUESS = 0;
public static final int SSHDSS = 1;
public static final int SSHRSA = 2;
public static final int ECDSA256 = 3;
public static final int ECDSA384 = 4;
public static final int ECDSA521 = 5;
public static final int ED25519 = 6;
public static final int ED448 = 7;
protected String marker;
protected String host;
protected int type;
protected byte[] key;
protected String comment;
public HostKey(String host, byte[] key) throws JSchException {
this(host, GUESS, key);
}
public HostKey(String host, int type, byte[] key) throws JSchException {
this(host, type, key, null);
}
public HostKey(String host, int type, byte[] key, String comment) throws JSchException {
this("", host, type, key, comment);
}
public HostKey(String marker, String host, int type, byte[] key, String comment)
throws JSchException {
this.marker = marker;
this.host = host;
if (type == GUESS) {
if (key[8] == 'd') {
this.type = SSHDSS;
} else if (key[8] == 'r') {
this.type = SSHRSA;
} else if (key[8] == 'e' && key[10] == '2') {
this.type = ED25519;
} else if (key[8] == 'e' && key[10] == '4') {
this.type = ED448;
} else if (key[8] == 'a' && key[20] == '2') {
this.type = ECDSA256;
} else if (key[8] == 'a' && key[20] == '3') {
this.type = ECDSA384;
} else if (key[8] == 'a' && key[20] == '5') {
this.type = ECDSA521;
} else {
throw new JSchException("invalid key type");
}
} else {
this.type = type;
}
this.key = key;
this.comment = comment;
}
public String getHost() {
return host;
}
public String getType() {
if (type == SSHDSS || type == SSHRSA || type == ED25519 || type == ED448 || type == ECDSA256
|| type == ECDSA384 || type == ECDSA521) {
return Util.byte2str(names[type - 1]);
}
return "UNKNOWN";
}
protected static int name2type(String name) {
for (int i = 0; i < names.length; i++) {
if (Util.byte2str(names[i]).equals(name)) {
return i + 1;
}
}
return UNKNOWN;
}
public String getKey() {
return Util.byte2str(Util.toBase64(key, 0, key.length, true));
}
public String getFingerPrint(JSch jsch) {
HASH hash = null;
try {
String _c = JSch.getConfig("FingerprintHash").toLowerCase(Locale.ROOT);
Class<? extends HASH> c = Class.forName(JSch.getConfig(_c)).asSubclass(HASH.class);
hash = c.getDeclaredConstructor().newInstance();
} catch (Exception e) {
if (jsch.getInstanceLogger().isEnabled(Logger.ERROR)) {
jsch.getInstanceLogger().log(Logger.ERROR, "getFingerPrint: " + e.getMessage(), e);
}
}
return Util.getFingerPrint(hash, key, false, true);
}
public String getComment() {
return comment;
}
public String getMarker() {
return marker;
}
boolean isMatched(String _host) {
return isIncluded(_host);
}
private boolean isIncluded(String _host) {
int i = 0;
String hosts = this.host;
int hostslen = hosts.length();
int hostlen = _host.length();
int j;
while (i < hostslen) {
j = hosts.indexOf(',', i);
if (j == -1) {
if (hostlen != hostslen - i)
return false;
return hosts.regionMatches(true, i, _host, 0, hostlen);
}
if (hostlen == (j - i)) {
if (hosts.regionMatches(true, i, _host, 0, hostlen))
return true;
}
i = j + 1;
}
return false;
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface HostKeyRepository {
final int OK = 0;
final int NOT_INCLUDED = 1;
final int CHANGED = 2;
/**
* Checks if <code>host</code> is included with the <code>key</code>.
*
* @return #NOT_INCLUDED, #OK or #CHANGED
* @see #NOT_INCLUDED
* @see #OK
* @see #CHANGED
*/
int check(String host, byte[] key);
/**
* Adds a host key <code>hostkey</code>
*
* @param hostkey a host key to be added
* @param ui a user interface for showing messages or promping inputs.
* @see UserInfo
*/
void add(HostKey hostkey, UserInfo ui);
/**
* Removes a host key if there exists mached key with <code>host</code>, <code>type</code>.
*
* @see #remove(String host, String type, byte[] key)
*/
void remove(String host, String type);
/**
* Removes a host key if there exists a matched key with <code>host</code>, <code>type</code> and
* <code>key</code>.
*/
void remove(String host, String type, byte[] key);
/**
* Returns id of this repository.
*
* @return identity in String
*/
String getKnownHostsRepositoryID();
/**
* Retuns a list for host keys managed in this repository.
*
* @see #getHostKey(String host, String type)
*/
HostKey[] getHostKey();
/**
* Retuns a list for host keys managed in this repository.
*
* @param host a hostname used in searching host keys. If <code>null</code> is given, every host
* key will be listed.
* @param type a key type used in searching host keys, and it should be "ssh-dss" or "ssh-rsa". If
* <code>null</code> is given, a key type type will not be ignored.
*/
HostKey[] getHostKey(String host, String type);
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
class IO {
InputStream in;
OutputStream out;
OutputStream out_ext;
private boolean in_dontclose = false;
private boolean out_dontclose = false;
private boolean out_ext_dontclose = false;
void setOutputStream(OutputStream out) {
this.out = out;
}
void setOutputStream(OutputStream out, boolean dontclose) {
this.out_dontclose = dontclose;
setOutputStream(out);
}
void setExtOutputStream(OutputStream out) {
this.out_ext = out;
}
void setExtOutputStream(OutputStream out, boolean dontclose) {
this.out_ext_dontclose = dontclose;
setExtOutputStream(out);
}
void setInputStream(InputStream in) {
this.in = in;
}
void setInputStream(InputStream in, boolean dontclose) {
this.in_dontclose = dontclose;
setInputStream(in);
}
void put(Packet p) throws IOException, SocketException {
out.write(p.buffer.buffer, 0, p.buffer.index);
out.flush();
}
void put(byte[] array, int begin, int length) throws IOException {
out.write(array, begin, length);
out.flush();
}
void put_ext(byte[] array, int begin, int length) throws IOException {
out_ext.write(array, begin, length);
out_ext.flush();
}
int getByte() throws IOException {
return in.read();
}
void getByte(byte[] array) throws IOException {
getByte(array, 0, array.length);
}
void getByte(byte[] array, int begin, int length) throws IOException {
do {
int completed = in.read(array, begin, length);
if (completed < 0) {
throw new IOException("End of IO Stream Read");
}
begin += completed;
length -= completed;
} while (length > 0);
}
void out_close() {
try {
if (out != null && !out_dontclose)
out.close();
out = null;
} catch (Exception ee) {
}
}
void close() {
try {
if (in != null && !in_dontclose)
in.close();
in = null;
} catch (Exception ee) {
}
out_close();
try {
if (out_ext != null && !out_ext_dontclose)
out_ext.close();
out_ext = null;
} catch (Exception ee) {
}
}
/*
* void finalize() throws Throwable{ try{ if(in!=null) in.close(); } catch(Exception ee){} try{
* if(out!=null) out.close(); } catch(Exception ee){} try{ if(out_ext!=null) out_ext.close(); }
* catch(Exception ee){} }
*/
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
public interface Identity {
/**
* Decrypts this identity with the specified pass-phrase.
*
* @param passphrase the pass-phrase for this identity.
* @return <code>true</code> if the decryption is succeeded or this identity is not cyphered.
*/
public boolean setPassphrase(byte[] passphrase) throws JSchException;
/**
* Returns the public-key blob.
*
* @return the public-key blob
*/
public byte[] getPublicKeyBlob();
/**
* Signs on data with this identity, and returns the result.
*
* <p>
* <em>IMPORTANT NOTE:</em> <br>
* The {@link #getSignature(byte[], String)} method should be overridden to ensure {@code ssh-rsa}
* type public keys function with the {@code rsa-sha2-256} or {@code rsa-sha2-512} signature
* algorithms.
*
* @param data data to be signed
* @return the signature
* @see #getSignature(byte[], String)
*/
public byte[] getSignature(byte[] data);
/**
* Signs on data with this identity, and returns the result.
*
* <p>
* <em>IMPORTANT NOTE:</em> <br>
* The default implementation of this method simply calls {@link #getSignature(byte[])}, which
* will fail with {@code ssh-rsa} type public keys when utilized with the {@code rsa-sha2-256} or
* {@code rsa-sha2-512} signature algorithms: <br>
* it exists only to maintain backwards compatibility of this interface.
*
* <p>
* This default method should be overridden by implementations to ensure the {@code rsa-sha2-256}
* and {@code rsa-sha2-512} signature algorithms function correctly.
*
* @param data data to be signed
* @param alg signature algorithm to use
* @return the signature
* @since 0.1.57
* @see #getSignature(byte[])
*/
public default byte[] getSignature(byte[] data, String alg) {
return getSignature(data);
}
/**
* This method is deprecated and the default implmentation of this method will throw an
* {@link UnsupportedOperationException}.
*
* @deprecated The decryption should be done automatically in {@link #setPassphrase(byte[])}
* @return <code>true</code> if the decryption is succeeded or this identity is not cyphered.
* @see #setPassphrase(byte[])
*/
@Deprecated
public default boolean decrypt() {
throw new UnsupportedOperationException("not implemented");
}
/**
* Returns the name of the key algorithm.
*
* @return the name of the key algorithm
*/
public String getAlgName();
/**
* Returns the name of this identity. It will be useful to identify this object in the
* {@link IdentityRepository}.
*
* @return the name of this identity
*/
public String getName();
/**
* Returns <code>true</code> if this identity is cyphered.
*
* @return <code>true</code> if this identity is cyphered.
*/
public boolean isEncrypted();
/** Disposes internally allocated data, like byte array for the private key. */
public void clear();
}

View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
class IdentityFile implements Identity {
private KeyPair kpair;
private String identity;
static IdentityFile newInstance(String prvfile, String pubfile, JSch.InstanceLogger instLogger)
throws JSchException {
KeyPair kpair = KeyPair.load(instLogger, prvfile, pubfile);
return new IdentityFile(prvfile, kpair);
}
static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey,
JSch.InstanceLogger instLogger) throws JSchException {
KeyPair kpair = KeyPair.load(instLogger, prvkey, pubkey);
return new IdentityFile(name, kpair);
}
private IdentityFile(String name, KeyPair kpair) {
this.identity = name;
this.kpair = kpair;
}
/**
* Decrypts this identity with the specified pass-phrase.
*
* @param passphrase the pass-phrase for this identity.
* @return <code>true</code> if the decryption is succeeded or this identity is not cyphered.
*/
@Override
public boolean setPassphrase(byte[] passphrase) throws JSchException {
return kpair.decrypt(passphrase);
}
/**
* Returns the public-key blob.
*
* @return the public-key blob
*/
@Override
public byte[] getPublicKeyBlob() {
return kpair.getPublicKeyBlob();
}
/**
* Signs on data with this identity, and returns the result.
*
* @param data data to be signed
* @return the signature
*/
@Override
public byte[] getSignature(byte[] data) {
return kpair.getSignature(data);
}
/**
* Signs on data with this identity, and returns the result.
*
* @param data data to be signed
* @param alg signature algorithm to use
* @return the signature
*/
@Override
public byte[] getSignature(byte[] data, String alg) {
return kpair.getSignature(data, alg);
}
/**
* Returns the name of the key algorithm.
*
* @return the name of the key algorithm
*/
@Override
public String getAlgName() {
return kpair.getKeyTypeString();
}
/**
* Returns the name of this identity. It will be useful to identify this object in the
* {@link IdentityRepository}.
*
* @return the name of this identity
*/
@Override
public String getName() {
return identity;
}
/**
* Returns <code>true</code> if this identity is cyphered.
*
* @return <code>true</code> if this identity is cyphered.
*/
@Override
public boolean isEncrypted() {
return kpair.isEncrypted();
}
/** Disposes internally allocated data, like byte array for the private key. */
@Override
public void clear() {
kpair.dispose();
kpair = null;
}
/**
* Returns an instance of {@link KeyPair} used in this {@link Identity}.
*
* @return an instance of {@link KeyPair} used in this {@link Identity}.
*/
public KeyPair getKeyPair() {
return kpair;
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
public interface IdentityRepository {
public static final int UNAVAILABLE = 0;
public static final int NOTRUNNING = 1;
public static final int RUNNING = 2;
public String getName();
public int getStatus();
public Vector<Identity> getIdentities();
public boolean add(byte[] identity);
public boolean remove(byte[] blob);
public void removeAll();
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.util.Vector;
/**
* JSch will accept ciphered keys, but some implementations of IdentityRepository can not. For
* example, IdentityRepository for ssh-agent and pageant only accept plain keys. The following class
* has been introduced to cache ciphered keys for them, and pass them whenever they are de-ciphered.
*/
class IdentityRepositoryWrapper implements IdentityRepository {
private IdentityRepository ir;
private Vector<Identity> cache = new Vector<>();
private boolean keep_in_cache = false;
IdentityRepositoryWrapper(IdentityRepository ir) {
this(ir, false);
}
IdentityRepositoryWrapper(IdentityRepository ir, boolean keep_in_cache) {
this.ir = ir;
this.keep_in_cache = keep_in_cache;
}
@Override
public String getName() {
return ir.getName();
}
@Override
public int getStatus() {
return ir.getStatus();
}
@Override
public boolean add(byte[] identity) {
return ir.add(identity);
}
@Override
public boolean remove(byte[] blob) {
return ir.remove(blob);
}
@Override
public void removeAll() {
cache.removeAllElements();
ir.removeAll();
}
@Override
public Vector<Identity> getIdentities() {
Vector<Identity> result = new Vector<>();
for (int i = 0; i < cache.size(); i++) {
Identity identity = cache.elementAt(i);
result.add(identity);
}
Vector<Identity> tmp = ir.getIdentities();
for (int i = 0; i < tmp.size(); i++) {
result.add(tmp.elementAt(i));
}
return result;
}
void add(Identity identity) {
if (!keep_in_cache && !identity.isEncrypted() && (identity instanceof IdentityFile)) {
try {
ir.add(((IdentityFile) identity).getKeyPair().forSSHAgent());
} catch (JSchException e) {
// an exception will not be thrown.
}
} else
cache.addElement(identity);
}
void check() {
if (cache.size() > 0) {
Object[] identities = cache.toArray();
for (int i = 0; i < identities.length; i++) {
Identity identity = (Identity) (identities[i]);
cache.removeElement(identity);
add(identity);
}
}
}
}

View file

@ -0,0 +1,694 @@
/*
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided with
* the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcraft.jsch;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
public class JSch {
/** The version number. */
public static final String VERSION = Version.getVersion();
static Hashtable<String, String> config = new Hashtable<>();
static {
config.put("kex", Util.getSystemProperty("jsch.kex",
"curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256"));
config.put("server_host_key", Util.getSystemProperty("jsch.server_host_key",
"ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256"));
config.put("prefer_known_host_key_types",
Util.getSystemProperty("jsch.prefer_known_host_key_types", "yes"));
config.put("enable_strict_kex", Util.getSystemProperty("jsch.enable_strict_kex", "yes"));
config.put("require_strict_kex", Util.getSystemProperty("jsch.require_strict_kex", "no"));
config.put("enable_server_sig_algs",
Util.getSystemProperty("jsch.enable_server_sig_algs", "yes"));
config.put("enable_ext_info_in_auth",
Util.getSystemProperty("jsch.enable_ext_info_in_auth", "yes"));
config.put("cipher.s2c", Util.getSystemProperty("jsch.cipher",
"aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com"));
config.put("cipher.c2s", Util.getSystemProperty("jsch.cipher",
"aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com"));
config.put("mac.s2c", Util.getSystemProperty("jsch.mac",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1"));
config.put("mac.c2s", Util.getSystemProperty("jsch.mac",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1"));
config.put("compression.s2c", Util.getSystemProperty("jsch.compression", "none"));
config.put("compression.c2s", Util.getSystemProperty("jsch.compression", "none"));
config.put("lang.s2c", Util.getSystemProperty("jsch.lang", ""));
config.put("lang.c2s", Util.getSystemProperty("jsch.lang", ""));
config.put("dhgex_min", Util.getSystemProperty("jsch.dhgex_min", "2048"));
config.put("dhgex_max", Util.getSystemProperty("jsch.dhgex_max", "8192"));
config.put("dhgex_preferred", Util.getSystemProperty("jsch.dhgex_preferred", "3072"));
config.put("compression_level", Util.getSystemProperty("jsch.compression_level", "6"));
config.put("diffie-hellman-group-exchange-sha1", "com.jcraft.jsch.DHGEX1");
config.put("diffie-hellman-group1-sha1", "com.jcraft.jsch.DHG1");
config.put("diffie-hellman-group14-sha1", "com.jcraft.jsch.DHG14");
config.put("diffie-hellman-group-exchange-sha256", "com.jcraft.jsch.DHGEX256");
config.put("diffie-hellman-group-exchange-sha224@ssh.com", "com.jcraft.jsch.DHGEX224");
config.put("diffie-hellman-group-exchange-sha384@ssh.com", "com.jcraft.jsch.DHGEX384");
config.put("diffie-hellman-group-exchange-sha512@ssh.com", "com.jcraft.jsch.DHGEX512");
config.put("diffie-hellman-group14-sha256", "com.jcraft.jsch.DHG14256");
config.put("diffie-hellman-group15-sha512", "com.jcraft.jsch.DHG15");
config.put("diffie-hellman-group16-sha512", "com.jcraft.jsch.DHG16");
config.put("diffie-hellman-group17-sha512", "com.jcraft.jsch.DHG17");
config.put("diffie-hellman-group18-sha512", "com.jcraft.jsch.DHG18");
config.put("diffie-hellman-group14-sha256@ssh.com", "com.jcraft.jsch.DHG14256");
config.put("diffie-hellman-group14-sha224@ssh.com", "com.jcraft.jsch.DHG14224");
config.put("diffie-hellman-group15-sha256@ssh.com", "com.jcraft.jsch.DHG15256");
config.put("diffie-hellman-group15-sha384@ssh.com", "com.jcraft.jsch.DHG15384");
config.put("diffie-hellman-group16-sha512@ssh.com", "com.jcraft.jsch.DHG16");
config.put("diffie-hellman-group16-sha384@ssh.com", "com.jcraft.jsch.DHG16384");
config.put("diffie-hellman-group18-sha512@ssh.com", "com.jcraft.jsch.DHG18");
config.put("ecdsa-sha2-nistp256", "com.jcraft.jsch.jce.SignatureECDSA256");
config.put("ecdsa-sha2-nistp384", "com.jcraft.jsch.jce.SignatureECDSA384");
config.put("ecdsa-sha2-nistp521", "com.jcraft.jsch.jce.SignatureECDSA521");
config.put("ecdh-sha2-nistp256", "com.jcraft.jsch.DHEC256");
config.put("ecdh-sha2-nistp384", "com.jcraft.jsch.DHEC384");
config.put("ecdh-sha2-nistp521", "com.jcraft.jsch.DHEC521");
config.put("ecdh-sha2-nistp", "com.jcraft.jsch.jce.ECDHN");
config.put("curve25519-sha256", "com.jcraft.jsch.DH25519");
config.put("curve25519-sha256@libssh.org", "com.jcraft.jsch.DH25519");
config.put("curve448-sha512", "com.jcraft.jsch.DH448");
config.put("sntrup761x25519-sha512@openssh.com", "com.jcraft.jsch.DH25519SNTRUP761");
config.put("sntrup761", "com.jcraft.jsch.bc.SNTRUP761");
config.put("dh", "com.jcraft.jsch.jce.DH");
config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC");
config.put("blowfish-cbc", "com.jcraft.jsch.jce.BlowfishCBC");
config.put("hmac-sha1", "com.jcraft.jsch.jce.HMACSHA1");
config.put("hmac-sha1-96", "com.jcraft.jsch.jce.HMACSHA196");
config.put("hmac-sha2-256", "com.jcraft.jsch.jce.HMACSHA256");
config.put("hmac-sha2-512", "com.jcraft.jsch.jce.HMACSHA512");
config.put("hmac-md5", "com.jcraft.jsch.jce.HMACMD5");
config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596");
config.put("hmac-sha1-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA1ETM");
config.put("hmac-sha1-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA196ETM");
config.put("hmac-sha2-256-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA256ETM");
config.put("hmac-sha2-512-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA512ETM");
config.put("hmac-md5-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD5ETM");
config.put("hmac-md5-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD596ETM");
config.put("hmac-sha256-2@ssh.com", "com.jcraft.jsch.jce.HMACSHA2562SSHCOM");
config.put("hmac-sha224@ssh.com", "com.jcraft.jsch.jce.HMACSHA224SSHCOM");
config.put("hmac-sha256@ssh.com", "com.jcraft.jsch.jce.HMACSHA256SSHCOM");
config.put("hmac-sha384@ssh.com", "com.jcraft.jsch.jce.HMACSHA384SSHCOM");
config.put("hmac-sha512@ssh.com", "com.jcraft.jsch.jce.HMACSHA512SSHCOM");
config.put("sha-1", "com.jcraft.jsch.jce.SHA1");
config.put("sha-224", "com.jcraft.jsch.jce.SHA224");
config.put("sha-256", "com.jcraft.jsch.jce.SHA256");
config.put("sha-384", "com.jcraft.jsch.jce.SHA384");
config.put("sha-512", "com.jcraft.jsch.jce.SHA512");
config.put("md5", "com.jcraft.jsch.jce.MD5");
config.put("sha1", "com.jcraft.jsch.jce.SHA1");
config.put("sha224", "com.jcraft.jsch.jce.SHA224");
config.put("sha256", "com.jcraft.jsch.jce.SHA256");
config.put("sha384", "com.jcraft.jsch.jce.SHA384");
config.put("sha512", "com.jcraft.jsch.jce.SHA512");
config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA");
config.put("ssh-rsa", "com.jcraft.jsch.jce.SignatureRSA");
config.put("rsa-sha2-256", "com.jcraft.jsch.jce.SignatureRSASHA256");
config.put("rsa-sha2-512", "com.jcraft.jsch.jce.SignatureRSASHA512");
config.put("ssh-rsa-sha224@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA224SSHCOM");
config.put("ssh-rsa-sha256@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA256SSHCOM");
config.put("ssh-rsa-sha384@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA384SSHCOM");
config.put("ssh-rsa-sha512@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA512SSHCOM");
config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA");
config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA");
config.put("keypairgen.ecdsa", "com.jcraft.jsch.jce.KeyPairGenECDSA");
config.put("random", "com.jcraft.jsch.jce.Random");
config.put("hmac-ripemd160", "com.jcraft.jsch.bc.HMACRIPEMD160");
config.put("hmac-ripemd160@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160OpenSSH");
config.put("hmac-ripemd160-etm@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160ETM");
config.put("none", "com.jcraft.jsch.CipherNone");
config.put("aes128-gcm@openssh.com", "com.jcraft.jsch.jce.AES128GCM");
config.put("aes256-gcm@openssh.com", "com.jcraft.jsch.jce.AES256GCM");
config.put("aes128-cbc", "com.jcraft.jsch.jce.AES128CBC");
config.put("aes192-cbc", "com.jcraft.jsch.jce.AES192CBC");
config.put("aes256-cbc", "com.jcraft.jsch.jce.AES256CBC");
config.put("rijndael-cbc@lysator.liu.se", "com.jcraft.jsch.jce.AES256CBC");
config.put("chacha20-poly1305@openssh.com", "com.jcraft.jsch.bc.ChaCha20Poly1305");
config.put("cast128-cbc", "com.jcraft.jsch.bc.CAST128CBC");
config.put("cast128-ctr", "com.jcraft.jsch.bc.CAST128CTR");
config.put("twofish128-cbc", "com.jcraft.jsch.bc.Twofish128CBC");
config.put("twofish192-cbc", "com.jcraft.jsch.bc.Twofish192CBC");
config.put("twofish256-cbc", "com.jcraft.jsch.bc.Twofish256CBC");
config.put("twofish-cbc", "com.jcraft.jsch.bc.Twofish256CBC");
config.put("twofish128-ctr", "com.jcraft.jsch.bc.Twofish128CTR");
config.put("twofish192-ctr", "com.jcraft.jsch.bc.Twofish192CTR");
config.put("twofish256-ctr", "com.jcraft.jsch.bc.Twofish256CTR");
config.put("seed-cbc@ssh.com", "com.jcraft.jsch.bc.SEEDCBC");
config.put("aes128-ctr", "com.jcraft.jsch.jce.AES128CTR");
config.put("aes192-ctr", "com.jcraft.jsch.jce.AES192CTR");
config.put("aes256-ctr", "com.jcraft.jsch.jce.AES256CTR");
config.put("3des-ctr", "com.jcraft.jsch.jce.TripleDESCTR");
config.put("blowfish-ctr", "com.jcraft.jsch.jce.BlowfishCTR");
config.put("arcfour", "com.jcraft.jsch.jce.ARCFOUR");
config.put("arcfour128", "com.jcraft.jsch.jce.ARCFOUR128");
config.put("arcfour256", "com.jcraft.jsch.jce.ARCFOUR256");
config.put("userauth.none", "com.jcraft.jsch.UserAuthNone");
config.put("userauth.password", "com.jcraft.jsch.UserAuthPassword");
config.put("userauth.keyboard-interactive", "com.jcraft.jsch.UserAuthKeyboardInteractive");
config.put("userauth.publickey", "com.jcraft.jsch.UserAuthPublicKey");
config.put("userauth.gssapi-with-mic", "com.jcraft.jsch.UserAuthGSSAPIWithMIC");
config.put("gssapi-with-mic.krb5", "com.jcraft.jsch.jgss.GSSContextKrb5");
config.put("zlib", "com.jcraft.jsch.jzlib.Compression");
config.put("zlib@openssh.com", "com.jcraft.jsch.jzlib.Compression");
config.put("pbkdf", "com.jcraft.jsch.jce.PBKDF");
config.put("pbkdf2-hmac-sha1", "com.jcraft.jsch.jce.PBKDF2HMACSHA1");
config.put("pbkdf2-hmac-sha224", "com.jcraft.jsch.jce.PBKDF2HMACSHA224");
config.put("pbkdf2-hmac-sha256", "com.jcraft.jsch.jce.PBKDF2HMACSHA256");
config.put("pbkdf2-hmac-sha384", "com.jcraft.jsch.jce.PBKDF2HMACSHA384");
config.put("pbkdf2-hmac-sha512", "com.jcraft.jsch.jce.PBKDF2HMACSHA512");
config.put("pbkdf2-hmac-sha512-224", "com.jcraft.jsch.jce.PBKDF2HMACSHA512224");
config.put("pbkdf2-hmac-sha512-256", "com.jcraft.jsch.jce.PBKDF2HMACSHA512256");
config.put("bcrypt", "com.jcraft.jsch.jbcrypt.JBCrypt");
config.put("argon2", "com.jcraft.jsch.bc.Argon2");
config.put("scrypt", "com.jcraft.jsch.bc.SCrypt");
if (JavaVersion.getVersion() >= 11) {
config.put("xdh", "com.jcraft.jsch.jce.XDH");
} else {
config.put("xdh", "com.jcraft.jsch.bc.XDH");
}
if (JavaVersion.getVersion() >= 15) {
config.put("keypairgen.eddsa", "com.jcraft.jsch.jce.KeyPairGenEdDSA");
config.put("ssh-ed25519", "com.jcraft.jsch.jce.SignatureEd25519");
config.put("ssh-ed448", "com.jcraft.jsch.jce.SignatureEd448");
} else {
config.put("keypairgen.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA");
config.put("ssh-ed25519", "com.jcraft.jsch.bc.SignatureEd25519");
config.put("ssh-ed448", "com.jcraft.jsch.bc.SignatureEd448");
}
config.put("keypairgen_fromprivate.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA");
config.put("StrictHostKeyChecking", "ask");
config.put("HashKnownHosts", "no");
config.put("PreferredAuthentications", Util.getSystemProperty("jsch.preferred_authentications",
"gssapi-with-mic,publickey,keyboard-interactive,password"));
config.put("PubkeyAcceptedAlgorithms", Util.getSystemProperty("jsch.client_pubkey",
"ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256"));
config.put("enable_pubkey_auth_query",
Util.getSystemProperty("jsch.enable_pubkey_auth_query", "yes"));
config.put("try_additional_pubkey_algorithms",
Util.getSystemProperty("jsch.try_additional_pubkey_algorithms", "yes"));
config.put("enable_auth_none", Util.getSystemProperty("jsch.enable_auth_none", "yes"));
config.put("use_sftp_write_flush_workaround",
Util.getSystemProperty("jsch.use_sftp_write_flush_workaround", "yes"));
config.put("CheckCiphers",
Util.getSystemProperty("jsch.check_ciphers", "chacha20-poly1305@openssh.com"));
config.put("CheckMacs", Util.getSystemProperty("jsch.check_macs", ""));
config.put("CheckKexes", Util.getSystemProperty("jsch.check_kexes",
"sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,curve448-sha512"));
config.put("CheckSignatures",
Util.getSystemProperty("jsch.check_signatures", "ssh-ed25519,ssh-ed448"));
config.put("FingerprintHash", Util.getSystemProperty("jsch.fingerprint_hash", "sha256"));
config.put("MaxAuthTries", Util.getSystemProperty("jsch.max_auth_tries", "6"));
config.put("ClearAllForwardings", "no");
}
final InstanceLogger instLogger = new InstanceLogger();
private Vector<Session> sessionPool = new Vector<>();
private IdentityRepository defaultIdentityRepository = new LocalIdentityRepository(instLogger);
private IdentityRepository identityRepository = defaultIdentityRepository;
private ConfigRepository configRepository = null;
/**
* Sets the <code>identityRepository</code>, which will be referred in the public key
* authentication.
*
* @param identityRepository if <code>null</code> is given, the default repository, which usually
* refers to ~/.ssh/, will be used.
* @see #getIdentityRepository()
*/
public synchronized void setIdentityRepository(IdentityRepository identityRepository) {
if (identityRepository == null) {
this.identityRepository = defaultIdentityRepository;
} else {
this.identityRepository = identityRepository;
}
}
public synchronized IdentityRepository getIdentityRepository() {
return this.identityRepository;
}
public ConfigRepository getConfigRepository() {
return this.configRepository;
}
public void setConfigRepository(ConfigRepository configRepository) {
this.configRepository = configRepository;
}
private HostKeyRepository known_hosts = null;
static final Logger DEVNULL = new Logger() {
@Override
public boolean isEnabled(int level) {
return false;
}
@Override
public void log(int level, String message) {}
};
static Logger logger = DEVNULL;
public JSch() {}
/**
* Instantiates the <code>Session</code> object with <code>host</code>. The user name and port
* number will be retrieved from ConfigRepository. If user name is not given, the system property
* "user.name" will be referred.
*
* @param host hostname
* @throws JSchException if <code>username</code> or <code>host</code> are invalid.
* @return the instance of <code>Session</code> class.
* @see #getSession(String username, String host, int port)
* @see Session
* @see ConfigRepository
*/
public Session getSession(String host) throws JSchException {
return getSession(null, host, 22);
}
/**
* Instantiates the <code>Session</code> object with <code>username</code> and <code>host</code>.
* The TCP port 22 will be used in making the connection. Note that the TCP connection must not be
* established until Session#connect().
*
* @param username user name
* @param host hostname
* @throws JSchException if <code>username</code> or <code>host</code> are invalid.
* @return the instance of <code>Session</code> class.
* @see #getSession(String username, String host, int port)
* @see Session
*/
public Session getSession(String username, String host) throws JSchException {
return getSession(username, host, 22);
}
/**
* Instantiates the <code>Session</code> object with given <code>username</code>,
* <code>host</code> and <code>port</code>. Note that the TCP connection must not be established
* until Session#connect().
*
* @param username user name
* @param host hostname
* @param port port number
* @throws JSchException if <code>username</code> or <code>host</code> are invalid.
* @return the instance of <code>Session</code> class.
* @see #getSession(String username, String host, int port)
* @see Session
*/
public Session getSession(String username, String host, int port) throws JSchException {
if (host == null) {
throw new JSchException("host must not be null.");
}
Session s = new Session(this, username, host, port);
return s;
}
protected void addSession(Session session) {
synchronized (sessionPool) {
sessionPool.addElement(session);
}
}
protected boolean removeSession(Session session) {
synchronized (sessionPool) {
return sessionPool.remove(session);
}
}
/**
* Sets the hostkey repository.
*
* @param hkrepo
* @see HostKeyRepository
* @see KnownHosts
*/
public void setHostKeyRepository(HostKeyRepository hkrepo) {
known_hosts = hkrepo;
}
/**
* Sets the instance of <code>KnownHosts</code>, which refers to <code>filename</code>.
*
* @param filename filename of known_hosts file.
* @throws JSchException if the given filename is invalid.
* @see KnownHosts
*/
public void setKnownHosts(String filename) throws JSchException {
if (known_hosts == null)
known_hosts = new KnownHosts(this);
if (known_hosts instanceof KnownHosts) {
synchronized (known_hosts) {
((KnownHosts) known_hosts).setKnownHosts(filename);
}
}
}
/**
* Sets the instance of <code>KnownHosts</code> generated with <code>stream</code>.
*
* @param stream the instance of InputStream from known_hosts file.
* @throws JSchException if an I/O error occurs.
* @see KnownHosts
*/
public void setKnownHosts(InputStream stream) throws JSchException {
if (known_hosts == null)
known_hosts = new KnownHosts(this);
if (known_hosts instanceof KnownHosts) {
synchronized (known_hosts) {
((KnownHosts) known_hosts).setKnownHosts(stream);
}
}
}
/**
* Returns the current hostkey repository. By the default, this method will the instance of
* <code>KnownHosts</code>.
*
* @return current hostkey repository.
* @see HostKeyRepository
* @see KnownHosts
*/
public HostKeyRepository getHostKeyRepository() {
if (known_hosts == null)
known_hosts = new KnownHosts(this);
return known_hosts;
}
/**
* Sets the private key, which will be referred in the public key authentication.
*
* @param prvkey filename of the private key.
* @throws JSchException if <code>prvkey</code> is invalid.
* @see #addIdentity(String prvkey, String passphrase)
*/
public void addIdentity(String prvkey) throws JSchException {
addIdentity(prvkey, (byte[]) null);
}
/**
* Sets the private key, which will be referred in the public key authentication. Before
* registering it into identityRepository, it will be deciphered with <code>passphrase</code>.
*
* @param prvkey filename of the private key.
* @param passphrase passphrase for <code>prvkey</code>.
* @throws JSchException if <code>passphrase</code> is not right.
* @see #addIdentity(String prvkey, byte[] passphrase)
*/
public void addIdentity(String prvkey, String passphrase) throws JSchException {
byte[] _passphrase = null;
if (passphrase != null) {
_passphrase = Util.str2byte(passphrase);
}
addIdentity(prvkey, _passphrase);
if (_passphrase != null)
Util.bzero(_passphrase);
}
/**
* Sets the private key, which will be referred in the public key authentication. Before
* registering it into identityRepository, it will be deciphered with <code>passphrase</code>.
*
* @param prvkey filename of the private key.
* @param passphrase passphrase for <code>prvkey</code>.
* @throws JSchException if <code>passphrase</code> is not right.
* @see #addIdentity(String prvkey, String pubkey, byte[] passphrase)
*/
public void addIdentity(String prvkey, byte[] passphrase) throws JSchException {
Identity identity = IdentityFile.newInstance(prvkey, null, instLogger);
addIdentity(identity, passphrase);
}
/**
* Sets the private key, which will be referred in the public key authentication. Before
* registering it into identityRepository, it will be deciphered with <code>passphrase</code>.
*
* @param prvkey filename of the private key.
* @param pubkey filename of the public key.
* @param passphrase passphrase for <code>prvkey</code>.
* @throws JSchException if <code>passphrase</code> is not right.
*/
public void addIdentity(String prvkey, String pubkey, byte[] passphrase) throws JSchException {
Identity identity = IdentityFile.newInstance(prvkey, pubkey, instLogger);
addIdentity(identity, passphrase);
}
/**
* Sets the private key, which will be referred in the public key authentication. Before
* registering it into identityRepository, it will be deciphered with <code>passphrase</code>.
*
* @param name name of the identity to be used to retrieve it in the identityRepository.
* @param prvkey private key in byte array.
* @param pubkey public key in byte array.
* @param passphrase passphrase for <code>prvkey</code>.
*/
public void addIdentity(String name, byte[] prvkey, byte[] pubkey, byte[] passphrase)
throws JSchException {
Identity identity = IdentityFile.newInstance(name, prvkey, pubkey, instLogger);
addIdentity(identity, passphrase);
}
/**
* Sets the private key, which will be referred in the public key authentication. Before
* registering it into identityRepository, it will be deciphered with <code>passphrase</code>.
*
* @param identity private key.
* @param passphrase passphrase for <code>identity</code>.
* @throws JSchException if <code>passphrase</code> is not right.
*/
public void addIdentity(Identity identity, byte[] passphrase) throws JSchException {
if (passphrase != null) {
try {
byte[] goo = new byte[passphrase.length];
System.arraycopy(passphrase, 0, goo, 0, passphrase.length);
passphrase = goo;
identity.setPassphrase(passphrase);
} finally {
Util.bzero(passphrase);
}
}
if (identityRepository instanceof LocalIdentityRepository) {
((LocalIdentityRepository) identityRepository).add(identity);
} else if (identity instanceof IdentityFile && !identity.isEncrypted()) {
identityRepository.add(((IdentityFile) identity).getKeyPair().forSSHAgent());
} else {
synchronized (this) {
if (!(identityRepository instanceof IdentityRepositoryWrapper)) {
setIdentityRepository(new IdentityRepositoryWrapper(identityRepository));
}
}
((IdentityRepositoryWrapper) identityRepository).add(identity);
}
}
/**
* @deprecated use #removeIdentity(Identity identity)
*/
@Deprecated
public void removeIdentity(String name) throws JSchException {
Vector<Identity> identities = identityRepository.getIdentities();
for (int i = 0; i < identities.size(); i++) {
Identity identity = identities.elementAt(i);
if (!identity.getName().equals(name))
continue;
if (identityRepository instanceof LocalIdentityRepository) {
((LocalIdentityRepository) identityRepository).remove(identity);
} else
identityRepository.remove(identity.getPublicKeyBlob());
}
}
/**
* Removes the identity from identityRepository.
*
* @param identity the indentity to be removed.
* @throws JSchException if <code>identity</code> is invalid.
*/
public void removeIdentity(Identity identity) throws JSchException {
identityRepository.remove(identity.getPublicKeyBlob());
}
/**
* Lists names of identities included in the identityRepository.
*
* @return names of identities
* @throws JSchException if identityReposory has problems.
*/
public Vector<String> getIdentityNames() throws JSchException {
Vector<String> foo = new Vector<>();
Vector<Identity> identities = identityRepository.getIdentities();
for (int i = 0; i < identities.size(); i++) {
Identity identity = identities.elementAt(i);
foo.addElement(identity.getName());
}
return foo;
}
/**
* Removes all identities from identityRepository.
*
* @throws JSchException if identityReposory has problems.
*/
public void removeAllIdentity() throws JSchException {
identityRepository.removeAll();
}
/**
* Returns the config value for the specified key.
*
* @param key key for the configuration.
* @return config value
*/
public static String getConfig(String key) {
synchronized (config) {
if (key.equals("PubkeyAcceptedKeyTypes")) {
key = "PubkeyAcceptedAlgorithms";
}
return config.get(key);
}
}
/**
* Sets or Overrides the configuration.
*
* @param newconf configurations
*/
public static void setConfig(Hashtable<String, String> newconf) {
synchronized (config) {
for (Enumeration<String> e = newconf.keys(); e.hasMoreElements();) {
String newkey = e.nextElement();
String key =
(newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey);
config.put(key, newconf.get(newkey));
}
}
}
/**
* Sets or Overrides the configuration.
*
* @param key key for the configuration
* @param value value for the configuration
*/
public static void setConfig(String key, String value) {
if (key.equals("PubkeyAcceptedKeyTypes")) {
config.put("PubkeyAcceptedAlgorithms", value);
} else {
config.put(key, value);
}
}
/**
* Sets the logger
*
* @param logger logger or <code>null</code> if no logging should take place
* @see Logger
*/
public static void setLogger(Logger logger) {
if (logger == null)
logger = DEVNULL;
JSch.logger = logger;
}
/**
* Returns a logger to be used for this particular instance of JSch
*
* @return The logger that is used by this instance. If no particular logger has been set, the
* statically set logger is returned.
*/
public Logger getInstanceLogger() {
return instLogger.getLogger();
}
/**
* Sets a logger to be used for this particular instance of JSch
*
* @param logger The logger to be used or <code>null</code> if the statically set logger should be
* used
*/
public void setInstanceLogger(Logger logger) {
instLogger.setLogger(logger);
}
/**
* Returns the statically set logger, i.e. the logger being used by all JSch instances without
* explicitly set logger.
*
* @return The logger
*/
public static Logger getLogger() {
return logger;
}
static class InstanceLogger {
private Logger logger;
private InstanceLogger() {}
Logger getLogger() {
if (logger == null) {
return JSch.logger;
}
return logger;
}
void setLogger(Logger logger) {
this.logger = logger;
}
}
}

View file

@ -0,0 +1,71 @@
package com.jcraft.jsch;
import java.util.Locale;
/**
* Extension of {@link JSchException} to indicate when a connection fails during algorithm
* negotiation.
*/
public class JSchAlgoNegoFailException extends JSchException {
private static final long serialVersionUID = -1L;
private final String algorithmName;
private final String jschProposal;
private final String serverProposal;
JSchAlgoNegoFailException(int algorithmIndex, String jschProposal, String serverProposal) {
super(failString(algorithmIndex, jschProposal, serverProposal));
algorithmName = algorithmNameFromIndex(algorithmIndex);
this.jschProposal = jschProposal;
this.serverProposal = serverProposal;
}
/** Get the algorithm name. */
public String getAlgorithmName() {
return algorithmName;
}
/** Get the JSch algorithm proposal. */
public String getJSchProposal() {
return jschProposal;
}
/** Get the server algorithm proposal. */
public String getServerProposal() {
return serverProposal;
}
private static String failString(int algorithmIndex, String jschProposal, String serverProposal) {
return String.format(Locale.ROOT,
"Algorithm negotiation fail: algorithmName=\"%s\" jschProposal=\"%s\" serverProposal=\"%s\"",
algorithmNameFromIndex(algorithmIndex), jschProposal, serverProposal);
}
private static String algorithmNameFromIndex(int algorithmIndex) {
switch (algorithmIndex) {
case KeyExchange.PROPOSAL_KEX_ALGS:
return "kex";
case KeyExchange.PROPOSAL_SERVER_HOST_KEY_ALGS:
return "server_host_key";
case KeyExchange.PROPOSAL_ENC_ALGS_CTOS:
return "cipher.c2s";
case KeyExchange.PROPOSAL_ENC_ALGS_STOC:
return "cipher.s2c";
case KeyExchange.PROPOSAL_MAC_ALGS_CTOS:
return "mac.c2s";
case KeyExchange.PROPOSAL_MAC_ALGS_STOC:
return "mac.s2c";
case KeyExchange.PROPOSAL_COMP_ALGS_CTOS:
return "compression.c2s";
case KeyExchange.PROPOSAL_COMP_ALGS_STOC:
return "compression.s2c";
case KeyExchange.PROPOSAL_LANG_CTOS:
return "lang.c2s";
case KeyExchange.PROPOSAL_LANG_STOC:
return "lang.s2c";
default:
return "";
}
}
}

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