Compare commits
10 commits
1f52dedf13
...
9b509c2776
Author | SHA1 | Date | |
---|---|---|---|
9b509c2776 | |||
b8c0048cd4 | |||
f9c77330f6 | |||
a905b0559a | |||
4c66383a05 | |||
bac77bbd0f | |||
9af09a4176 | |||
5cf088bd12 | |||
be26f3e231 | |||
5c18f0704f |
524 changed files with 51073 additions and 1904 deletions
|
@ -4,7 +4,6 @@ dependencies {
|
|||
testImplementation testLibs.junit.jupiter.params
|
||||
testImplementation testLibs.mockito.core
|
||||
testImplementation testLibs.mockito.junit.jupiter
|
||||
testImplementation testLibs.slf4j
|
||||
testImplementation project(':files-ftp-mock')
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import java.nio.file.spi.FileSystemProvider;
|
||||
import org.xbib.files.FileServiceProvider;
|
||||
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.FTPSFileServiceProvider;
|
||||
|
||||
module org.xbib.files.ftp.fs {
|
||||
requires org.xbib.files;
|
||||
requires org.xbib.files.ftp;
|
||||
exports org.xbib.files.ftp.fs;
|
||||
exports org.xbib.files.ftp.fs.spi;
|
||||
provides FileSystemProvider with FTPFileSystemProvider;
|
||||
provides FileServiceProvider with FTPFileServiceProvider;
|
||||
provides FileSystemProvider with FTPFileSystemProvider, FTPSFileSystemProvider;
|
||||
provides FileServiceProvider with FTPFileServiceProvider, FTPSFileServiceProvider;
|
||||
}
|
||||
|
|
|
@ -20,24 +20,27 @@ import java.util.concurrent.BlockingQueue;
|
|||
/**
|
||||
* A pool of FTP clients, allowing multiple commands to be executed concurrently.
|
||||
*/
|
||||
final class FTPClientPool {
|
||||
class FTPClientPool {
|
||||
|
||||
private final String hostname;
|
||||
private final int port;
|
||||
protected final String hostname;
|
||||
protected final int port;
|
||||
protected final FTPEnvironment env;
|
||||
|
||||
private final FTPEnvironment env;
|
||||
private final FileSystemExceptionFactory exceptionFactory;
|
||||
private FileSystemExceptionFactory exceptionFactory;
|
||||
|
||||
private final BlockingQueue<Client> pool;
|
||||
private BlockingQueue<Client> pool;
|
||||
|
||||
FTPClientPool(String hostname, int port, FTPEnvironment env) throws IOException {
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.env = env.clone();
|
||||
init();
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -148,21 +151,23 @@ final class FTPClientPool {
|
|||
pool.add(client);
|
||||
}
|
||||
|
||||
final class Client implements Closeable {
|
||||
|
||||
private final FTPClient client;
|
||||
private final boolean pooled;
|
||||
class Client implements Closeable {
|
||||
|
||||
protected final boolean pooled;
|
||||
private FTPClient client;
|
||||
private FileType fileType;
|
||||
private FileStructure fileStructure;
|
||||
private FileTransferMode fileTransferMode;
|
||||
|
||||
private int refCount = 0;
|
||||
|
||||
private Client(boolean pooled) throws IOException {
|
||||
this.client = env.createClient(hostname, port);
|
||||
Client(boolean pooled) throws IOException {
|
||||
this.pooled = pooled;
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() throws IOException {
|
||||
this.client = env.createClient(hostname, port);
|
||||
this.fileType = env.getDefaultFileType();
|
||||
this.fileStructure = env.getDefaultFileStructure();
|
||||
this.fileTransferMode = env.getDefaultFileTransferMode();
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.xbib.files.ftp.FTP;
|
|||
import org.xbib.files.ftp.FTPClient;
|
||||
import org.xbib.files.ftp.FTPClientConfig;
|
||||
import org.xbib.files.ftp.FTPFileEntryParser;
|
||||
import org.xbib.files.ftp.FTPSClient;
|
||||
import org.xbib.files.ftp.parser.FTPFileEntryParserFactory;
|
||||
|
||||
import javax.net.ServerSocketFactory;
|
||||
|
@ -320,8 +321,6 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
// FTPClient
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
// as specified by FTPClient
|
||||
return FileStructure.FILE;
|
||||
}
|
||||
|
||||
FileTransferMode getDefaultFileTransferMode() {
|
||||
// as specified by FTPClient
|
||||
return FileTransferMode.STREAM;
|
||||
}
|
||||
|
||||
|
@ -594,6 +591,15 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
|
|||
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 {
|
||||
client.setListHiddenFiles(true);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.xbib.files.ftp.fs;
|
||||
|
||||
import org.xbib.files.ftp.FTPFile;
|
||||
import org.xbib.files.ftp.FTPFileFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
|
@ -17,12 +16,9 @@ import java.util.List;
|
|||
abstract class FTPFileStrategy {
|
||||
|
||||
static FTPFileStrategy getInstance(FTPClientPool.Client client) throws IOException {
|
||||
FTPFile[] ftpFiles = client.listFiles("/", new FTPFileFilter() {
|
||||
@Override
|
||||
public boolean accept(FTPFile ftpFile) {
|
||||
String fileName = FTPFileSystem.getFileName(ftpFile);
|
||||
return FTPFileSystem.CURRENT_DIR.equals(fileName);
|
||||
}
|
||||
FTPFile[] ftpFiles = client.listFiles("/", ftpFile -> {
|
||||
String fileName = FTPFileSystem.getFileName(ftpFile);
|
||||
return FTPFileSystem.CURRENT_DIR.equals(fileName);
|
||||
});
|
||||
return ftpFiles.length == 0 ? NonUnix.INSTANCE : Unix.INSTANCE;
|
||||
}
|
||||
|
@ -67,12 +63,9 @@ abstract class FTPFileStrategy {
|
|||
FTPFile getFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException {
|
||||
final String name = path.fileName();
|
||||
|
||||
FTPFile[] ftpFiles = client.listFiles(path.path(), new FTPFileFilter() {
|
||||
@Override
|
||||
public boolean accept(FTPFile ftpFile) {
|
||||
String fileName = FTPFileSystem.getFileName(ftpFile);
|
||||
return FTPFileSystem.CURRENT_DIR.equals(fileName) || (name != null && name.equals(fileName));
|
||||
}
|
||||
FTPFile[] ftpFiles = client.listFiles(path.path(), ftpFile -> {
|
||||
String fileName = FTPFileSystem.getFileName(ftpFile);
|
||||
return FTPFileSystem.CURRENT_DIR.equals(fileName) || (name != null && name.equals(fileName));
|
||||
});
|
||||
client.throwIfEmpty(path.path(), ftpFiles);
|
||||
if (ftpFiles.length == 1) {
|
||||
|
@ -94,21 +87,13 @@ abstract class FTPFileStrategy {
|
|||
if (ftpFile.isDirectory() && FTPFileSystem.CURRENT_DIR.equals(FTPFileSystem.getFileName(ftpFile))) {
|
||||
// The file is returned using getFTPFile, which returns the . (current directory) entry for directories.
|
||||
// List the parent (if any) instead.
|
||||
|
||||
final String parentPath = path.toAbsolutePath().parentPath();
|
||||
final String name = path.fileName();
|
||||
|
||||
if (parentPath == null) {
|
||||
// path is /, there is no link
|
||||
return null;
|
||||
}
|
||||
|
||||
FTPFile[] ftpFiles = client.listFiles(parentPath, new FTPFileFilter() {
|
||||
@Override
|
||||
public boolean accept(FTPFile ftpFile) {
|
||||
return (ftpFile.isDirectory() || ftpFile.isSymbolicLink()) && name.equals(FTPFileSystem.getFileName(ftpFile));
|
||||
}
|
||||
});
|
||||
FTPFile[] ftpFiles = client.listFiles(parentPath, ftpFile1 -> (ftpFile1.isDirectory() || ftpFile1.isSymbolicLink()) && name.equals(FTPFileSystem.getFileName(ftpFile1)));
|
||||
client.throwIfEmpty(path.path(), ftpFiles);
|
||||
return ftpFiles[0].getLink() == null ? null : ftpFiles[0];
|
||||
}
|
||||
|
@ -122,9 +107,7 @@ abstract class FTPFileStrategy {
|
|||
|
||||
@Override
|
||||
List<FTPFile> getChildren(FTPClientPool.Client client, FTPPath path) throws IOException {
|
||||
|
||||
FTPFile[] ftpFiles = client.listFiles(path.path());
|
||||
|
||||
boolean isDirectory = false;
|
||||
List<FTPFile> children = new ArrayList<>(ftpFiles.length);
|
||||
for (FTPFile ftpFile : ftpFiles) {
|
||||
|
@ -135,7 +118,6 @@ abstract class FTPFileStrategy {
|
|||
children.add(ftpFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDirectory && children.size() <= 1) {
|
||||
// either zero or one, check the parent to see if the path exists and is a directory
|
||||
FTPPath currentPath = path;
|
||||
|
@ -148,7 +130,6 @@ abstract class FTPFileStrategy {
|
|||
throw new NotDirectoryException(path.path());
|
||||
}
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,43 +53,51 @@ public class FTPFileSystem extends FileSystem {
|
|||
static final String CURRENT_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")));
|
||||
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: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")));
|
||||
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:isRegularFile", "posix:isDirectory", "posix:isSymbolicLink", "posix:isOther", "posix:fileKey",
|
||||
"posix:owner", "posix:group", "posix:permissions")));
|
||||
private final FTPFileSystemProvider provider;
|
||||
private final Iterable<Path> rootDirectories;
|
||||
private final FileStore fileStore;
|
||||
private final Iterable<FileStore> fileStores;
|
||||
private final FTPClientPool clientPool;
|
||||
private final URI uri;
|
||||
private final String defaultDirectory;
|
||||
private final FTPFileStrategy ftpFileStrategy;
|
||||
|
||||
protected final FTPFileSystemProvider provider;
|
||||
protected final URI uri;
|
||||
protected final FTPEnvironment env;
|
||||
protected Iterable<Path> rootDirectories;
|
||||
protected FileStore fileStore;
|
||||
protected Iterable<FileStore> fileStores;
|
||||
private FTPClientPool clientPool;
|
||||
protected String defaultDirectory;
|
||||
FTPFileStrategy ftpFileStrategy;
|
||||
private final AtomicBoolean open = new AtomicBoolean(true);
|
||||
|
||||
public FTPFileSystem(FTPFileSystemProvider provider, URI uri, FTPEnvironment env) throws IOException {
|
||||
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.fileStore = new FTPFileStore(this);
|
||||
this.fileStores = Collections.<FileStore>singleton(fileStore);
|
||||
|
||||
this.clientPool = new FTPClientPool(uri.getHost(), uri.getPort(), env);
|
||||
this.uri = Objects.requireNonNull(uri);
|
||||
|
||||
try (FTPClientPool.Client client = clientPool.get()) {
|
||||
this.defaultDirectory = client.pwd();
|
||||
|
||||
this.ftpFileStrategy = FTPFileStrategy.getInstance(client);
|
||||
}
|
||||
}
|
||||
|
||||
FTPClientPool getClientPool() {
|
||||
return clientPool;
|
||||
}
|
||||
|
||||
public static String getFileName(FTPFile ftpFile) {
|
||||
String fileName = ftpFile.getName();
|
||||
if (fileName == null) {
|
||||
|
@ -469,7 +477,8 @@ public class FTPFileSystem extends FileSystem {
|
|||
getFTPFile(client, path);
|
||||
}
|
||||
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 {
|
||||
|
@ -492,16 +501,11 @@ public class FTPFileSystem extends FileSystem {
|
|||
}
|
||||
|
||||
private boolean hasAccess(FTPFile ftpFile, AccessMode mode) {
|
||||
switch (mode) {
|
||||
case READ:
|
||||
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
|
||||
case WRITE:
|
||||
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION);
|
||||
case EXECUTE:
|
||||
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package org.xbib.files.ftp.fs.spi;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
@FunctionalInterface
|
||||
interface WithContext<T> {
|
||||
T perform(FTPContext ctx) throws IOException;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
org.xbib.files.ftp.fs.FTPFileSystemProvider
|
||||
org.xbib.files.ftp.fs.FTPSFileSystemProvider
|
|
@ -1 +1,2 @@
|
|||
org.xbib.files.ftp.fs.spi.FTPFileServiceProvider
|
||||
org.xbib.files.ftp.fs.spi.FTPFileServiceProvider
|
||||
org.xbib.files.ftp.fs.spi.FTPSFileServiceProvider
|
|
@ -3,7 +3,6 @@ module org.xbib.files.ftp.fs.test {
|
|||
requires org.junit.jupiter.api;
|
||||
requires org.junit.jupiter.params;
|
||||
requires org.mockito;
|
||||
requires org.slf4j;
|
||||
requires org.xbib.files.ftp;
|
||||
requires org.xbib.files.ftp.fs;
|
||||
requires org.xbib.files.ftp.mock;
|
||||
|
|
|
@ -65,9 +65,6 @@ import static org.mockito.Mockito.verify;
|
|||
|
||||
public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
|
||||
|
||||
//@Rule
|
||||
//public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testGetPath() {
|
||||
testGetPath("/", "/");
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
dependencies {
|
||||
api project(':files-api')
|
||||
api libs.maverick.synergy.client
|
||||
testImplementation libs.net.security
|
||||
}
|
12
files-jadaptive-sftp/src/main/java/module-info.java
Normal file
12
files-jadaptive-sftp/src/main/java/module-info.java
Normal 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;
|
||||
}
|
|
@ -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 {
|
||||
}
|
||||
}
|
|
@ -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.FileWalker;
|
||||
|
@ -33,7 +33,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SFTPFileService implements FileService {
|
||||
public class SftpFileService implements FileService {
|
||||
|
||||
private static final int BUFFER_SIZE = 128 * 1024;
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class SFTPFileService implements FileService {
|
|||
|
||||
private final Map<String, ?> env;
|
||||
|
||||
public SFTPFileService(URI uri, Map<String, ?> env) {
|
||||
public SftpFileService(URI uri, Map<String, ?> env) {
|
||||
this.uri = uri;
|
||||
this.env = env;
|
||||
}
|
||||
|
@ -303,31 +303,31 @@ public class SFTPFileService implements FileService {
|
|||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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))));
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,7 @@ public class SFTPFileService implements FileService {
|
|||
});
|
||||
}
|
||||
|
||||
private void doUpload(SFTPContext ctx,
|
||||
private void doUpload(SftpContext ctx,
|
||||
ReadableByteChannel source,
|
||||
Path target,
|
||||
Set<PosixFilePermission> dirPerms,
|
||||
|
@ -367,19 +367,19 @@ public class SFTPFileService implements FileService {
|
|||
transfer(source, ctx.provider.newByteChannel(target, prepareWriteOptions(copyOptions)));
|
||||
}
|
||||
|
||||
private void download(SFTPContext ctx,
|
||||
private void download(SftpContext ctx,
|
||||
Path source,
|
||||
OutputStream outputStream) throws IOException {
|
||||
download(ctx, source, Channels.newChannel(outputStream));
|
||||
}
|
||||
|
||||
private void download(SFTPContext ctx,
|
||||
private void download(SftpContext ctx,
|
||||
Path source,
|
||||
WritableByteChannel writableByteChannel) throws IOException {
|
||||
transfer(ctx.provider.newByteChannel(source, prepareReadOptions()), writableByteChannel);
|
||||
}
|
||||
|
||||
private void download(SFTPContext ctx,
|
||||
private void download(SftpContext ctx,
|
||||
Path source,
|
||||
Path target,
|
||||
CopyOption... copyOptions) throws IOException {
|
||||
|
@ -459,10 +459,10 @@ public class SFTPFileService implements FileService {
|
|||
}
|
||||
|
||||
private <T> T performWithContext(WithContext<T> action) throws IOException {
|
||||
SFTPContext ctx = null;
|
||||
SftpContext ctx = null;
|
||||
try {
|
||||
if (uri != null) {
|
||||
ctx = new SFTPContext(uri, env);
|
||||
ctx = new SftpContext(uri, env);
|
||||
return action.perform(ctx);
|
||||
} else {
|
||||
return null;
|
|
@ -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.FileServiceProvider;
|
||||
|
@ -6,10 +6,10 @@ import org.xbib.files.FileServiceProvider;
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
public class SFTPFileServiceProvider implements FileServiceProvider {
|
||||
public class SftpFileServiceProvider implements FileServiceProvider {
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.xbib.files.jadaptive.sftp;
|
||||
|
||||
import com.sshtools.common.files.nio.AbstractFileNIOProvider;
|
||||
|
||||
public class SftpFileSystemProvider extends AbstractFileNIOProvider {
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.xbib.files.jadaptive.sftp;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@FunctionalInterface
|
||||
interface WithContext<T> {
|
||||
T perform(SftpContext ctx) throws IOException;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.xbib.files.jadaptive.sftp.SftpFileSystemProvider
|
8
files-jadaptive-sftp/src/test/java/module-info.java
Normal file
8
files-jadaptive-sftp/src/test/java/module-info.java
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
30
files-jsch/LICENSE.txt
Normal 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
7
files-jsch/NOTICE.txt
Normal 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
4
files-jsch/build.gradle
Normal file
|
@ -0,0 +1,4 @@
|
|||
dependencies {
|
||||
testImplementation testLibs.testcontainers
|
||||
testImplementation testLibs.testcontainers.junit.jupiter
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/AgentConnector.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/AgentConnector.java
Normal 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;
|
||||
}
|
80
files-jsch/src/main/java/com/jcraft/jsch/AgentIdentity.java
Normal file
80
files-jsch/src/main/java/com/jcraft/jsch/AgentIdentity.java
Normal 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() {}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
246
files-jsch/src/main/java/com/jcraft/jsch/AgentProxy.java
Normal file
246
files-jsch/src/main/java/com/jcraft/jsch/AgentProxy.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
38
files-jsch/src/main/java/com/jcraft/jsch/Argon2.java
Normal file
38
files-jsch/src/main/java/com/jcraft/jsch/Argon2.java
Normal 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;
|
||||
}
|
31
files-jsch/src/main/java/com/jcraft/jsch/BCrypt.java
Normal file
31
files-jsch/src/main/java/com/jcraft/jsch/BCrypt.java
Normal 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;
|
||||
}
|
303
files-jsch/src/main/java/com/jcraft/jsch/Buffer.java
Normal file
303
files-jsch/src/main/java/com/jcraft/jsch/Buffer.java
Normal 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(""); }
|
||||
*/
|
||||
|
||||
}
|
842
files-jsch/src/main/java/com/jcraft/jsch/Channel.java
Normal file
842
files-jsch/src/main/java/com/jcraft/jsch/Channel.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
175
files-jsch/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java
Normal file
175
files-jsch/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java
Normal 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;
|
||||
}
|
||||
}
|
88
files-jsch/src/main/java/com/jcraft/jsch/ChannelExec.java
Normal file
88
files-jsch/src/main/java/com/jcraft/jsch/ChannelExec.java
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
265
files-jsch/src/main/java/com/jcraft/jsch/ChannelSession.java
Normal file
265
files-jsch/src/main/java/com/jcraft/jsch/ChannelSession.java
Normal 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 <");
|
||||
}
|
||||
}
|
3039
files-jsch/src/main/java/com/jcraft/jsch/ChannelSftp.java
Normal file
3039
files-jsch/src/main/java/com/jcraft/jsch/ChannelSftp.java
Normal file
File diff suppressed because it is too large
Load diff
65
files-jsch/src/main/java/com/jcraft/jsch/ChannelShell.java
Normal file
65
files-jsch/src/main/java/com/jcraft/jsch/ChannelShell.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
262
files-jsch/src/main/java/com/jcraft/jsch/ChannelX11.java
Normal file
262
files-jsch/src/main/java/com/jcraft/jsch/ChannelX11.java
Normal 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;
|
||||
}
|
||||
}
|
60
files-jsch/src/main/java/com/jcraft/jsch/Cipher.java
Normal file
60
files-jsch/src/main/java/com/jcraft/jsch/Cipher.java
Normal 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;
|
||||
}
|
||||
}
|
53
files-jsch/src/main/java/com/jcraft/jsch/CipherNone.java
Normal file
53
files-jsch/src/main/java/com/jcraft/jsch/CipherNone.java
Normal 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;
|
||||
}
|
||||
}
|
44
files-jsch/src/main/java/com/jcraft/jsch/Compression.java
Normal file
44
files-jsch/src/main/java/com/jcraft/jsch/Compression.java
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
45
files-jsch/src/main/java/com/jcraft/jsch/DH.java
Normal file
45
files-jsch/src/main/java/com/jcraft/jsch/DH.java
Normal 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;
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DH25519.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DH25519.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DH448.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DH448.java
Normal 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;
|
||||
}
|
||||
}
|
34
files-jsch/src/main/java/com/jcraft/jsch/DHEC256.java
Normal file
34
files-jsch/src/main/java/com/jcraft/jsch/DHEC256.java
Normal 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;
|
||||
}
|
||||
}
|
34
files-jsch/src/main/java/com/jcraft/jsch/DHEC384.java
Normal file
34
files-jsch/src/main/java/com/jcraft/jsch/DHEC384.java
Normal 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;
|
||||
}
|
||||
}
|
34
files-jsch/src/main/java/com/jcraft/jsch/DHEC521.java
Normal file
34
files-jsch/src/main/java/com/jcraft/jsch/DHEC521.java
Normal 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;
|
||||
}
|
||||
}
|
187
files-jsch/src/main/java/com/jcraft/jsch/DHECN.java
Normal file
187
files-jsch/src/main/java/com/jcraft/jsch/DHECN.java
Normal 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;
|
||||
}
|
||||
}
|
66
files-jsch/src/main/java/com/jcraft/jsch/DHG1.java
Normal file
66
files-jsch/src/main/java/com/jcraft/jsch/DHG1.java
Normal 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";
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG14.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG14.java
Normal 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";
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG14224.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG14224.java
Normal 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";
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG14256.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG14256.java
Normal 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";
|
||||
}
|
||||
}
|
79
files-jsch/src/main/java/com/jcraft/jsch/DHG14N.java
Normal file
79
files-jsch/src/main/java/com/jcraft/jsch/DHG14N.java
Normal 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;
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG15.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG15.java
Normal 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";
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG15256.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG15256.java
Normal 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";
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG15384.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG15384.java
Normal 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";
|
||||
}
|
||||
}
|
98
files-jsch/src/main/java/com/jcraft/jsch/DHG15N.java
Normal file
98
files-jsch/src/main/java/com/jcraft/jsch/DHG15N.java
Normal 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;
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG16.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG16.java
Normal 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";
|
||||
}
|
||||
}
|
35
files-jsch/src/main/java/com/jcraft/jsch/DHG16384.java
Normal file
35
files-jsch/src/main/java/com/jcraft/jsch/DHG16384.java
Normal 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";
|
||||
}
|
||||
}
|
116
files-jsch/src/main/java/com/jcraft/jsch/DHG16N.java
Normal file
116
files-jsch/src/main/java/com/jcraft/jsch/DHG16N.java
Normal 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;
|
||||
}
|
||||
}
|
158
files-jsch/src/main/java/com/jcraft/jsch/DHG17.java
Normal file
158
files-jsch/src/main/java/com/jcraft/jsch/DHG17.java
Normal 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";
|
||||
}
|
||||
}
|
194
files-jsch/src/main/java/com/jcraft/jsch/DHG18.java
Normal file
194
files-jsch/src/main/java/com/jcraft/jsch/DHG18.java
Normal 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";
|
||||
}
|
||||
}
|
246
files-jsch/src/main/java/com/jcraft/jsch/DHGEX.java
Normal file
246
files-jsch/src/main/java/com/jcraft/jsch/DHGEX.java
Normal 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;
|
||||
}
|
||||
}
|
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX1.java
Normal file
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX1.java
Normal 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";
|
||||
}
|
||||
}
|
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX224.java
Normal file
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX224.java
Normal 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";
|
||||
}
|
||||
}
|
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX256.java
Normal file
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX256.java
Normal 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";
|
||||
}
|
||||
}
|
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX384.java
Normal file
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX384.java
Normal 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";
|
||||
}
|
||||
}
|
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX512.java
Normal file
33
files-jsch/src/main/java/com/jcraft/jsch/DHGEX512.java
Normal 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";
|
||||
}
|
||||
}
|
186
files-jsch/src/main/java/com/jcraft/jsch/DHGN.java
Normal file
186
files-jsch/src/main/java/com/jcraft/jsch/DHGN.java
Normal 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;
|
||||
}
|
||||
}
|
199
files-jsch/src/main/java/com/jcraft/jsch/DHXEC.java
Normal file
199
files-jsch/src/main/java/com/jcraft/jsch/DHXEC.java
Normal 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;
|
||||
}
|
||||
}
|
229
files-jsch/src/main/java/com/jcraft/jsch/DHXECKEM.java
Normal file
229
files-jsch/src/main/java/com/jcraft/jsch/DHXECKEM.java
Normal 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;
|
||||
}
|
||||
}
|
37
files-jsch/src/main/java/com/jcraft/jsch/ECDH.java
Normal file
37
files-jsch/src/main/java/com/jcraft/jsch/ECDH.java
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
39
files-jsch/src/main/java/com/jcraft/jsch/GSSContext.java
Normal file
39
files-jsch/src/main/java/com/jcraft/jsch/GSSContext.java
Normal 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();
|
||||
}
|
41
files-jsch/src/main/java/com/jcraft/jsch/HASH.java
Normal file
41
files-jsch/src/main/java/com/jcraft/jsch/HASH.java
Normal 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 "";
|
||||
}
|
||||
}
|
167
files-jsch/src/main/java/com/jcraft/jsch/HostKey.java
Normal file
167
files-jsch/src/main/java/com/jcraft/jsch/HostKey.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
136
files-jsch/src/main/java/com/jcraft/jsch/IO.java
Normal file
136
files-jsch/src/main/java/com/jcraft/jsch/IO.java
Normal 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){} }
|
||||
*/
|
||||
}
|
122
files-jsch/src/main/java/com/jcraft/jsch/Identity.java
Normal file
122
files-jsch/src/main/java/com/jcraft/jsch/Identity.java
Normal 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();
|
||||
}
|
141
files-jsch/src/main/java/com/jcraft/jsch/IdentityFile.java
Normal file
141
files-jsch/src/main/java/com/jcraft/jsch/IdentityFile.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
694
files-jsch/src/main/java/com/jcraft/jsch/JSch.java
Normal file
694
files-jsch/src/main/java/com/jcraft/jsch/JSch.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
Loading…
Reference in a new issue