Compare commits
No commits in common. "9b509c27768145bd97f10bd244354162770f6d56" and "1f52dedf1372d4d82c8f68a23f2cea796dd748fc" have entirely different histories.
9b509c2776
...
1f52dedf13
524 changed files with 1903 additions and 51072 deletions
|
@ -4,6 +4,7 @@ dependencies {
|
||||||
testImplementation testLibs.junit.jupiter.params
|
testImplementation testLibs.junit.jupiter.params
|
||||||
testImplementation testLibs.mockito.core
|
testImplementation testLibs.mockito.core
|
||||||
testImplementation testLibs.mockito.junit.jupiter
|
testImplementation testLibs.mockito.junit.jupiter
|
||||||
|
testImplementation testLibs.slf4j
|
||||||
testImplementation project(':files-ftp-mock')
|
testImplementation project(':files-ftp-mock')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import java.nio.file.spi.FileSystemProvider;
|
import java.nio.file.spi.FileSystemProvider;
|
||||||
import org.xbib.files.FileServiceProvider;
|
import org.xbib.files.FileServiceProvider;
|
||||||
import org.xbib.files.ftp.fs.FTPFileSystemProvider;
|
import org.xbib.files.ftp.fs.FTPFileSystemProvider;
|
||||||
import org.xbib.files.ftp.fs.FTPSFileSystemProvider;
|
|
||||||
import org.xbib.files.ftp.fs.spi.FTPFileServiceProvider;
|
import org.xbib.files.ftp.fs.spi.FTPFileServiceProvider;
|
||||||
import org.xbib.files.ftp.fs.spi.FTPSFileServiceProvider;
|
|
||||||
|
|
||||||
module org.xbib.files.ftp.fs {
|
module org.xbib.files.ftp.fs {
|
||||||
requires org.xbib.files;
|
requires org.xbib.files;
|
||||||
requires org.xbib.files.ftp;
|
requires org.xbib.files.ftp;
|
||||||
exports org.xbib.files.ftp.fs;
|
exports org.xbib.files.ftp.fs;
|
||||||
exports org.xbib.files.ftp.fs.spi;
|
exports org.xbib.files.ftp.fs.spi;
|
||||||
provides FileSystemProvider with FTPFileSystemProvider, FTPSFileSystemProvider;
|
provides FileSystemProvider with FTPFileSystemProvider;
|
||||||
provides FileServiceProvider with FTPFileServiceProvider, FTPSFileServiceProvider;
|
provides FileServiceProvider with FTPFileServiceProvider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,27 +20,24 @@ import java.util.concurrent.BlockingQueue;
|
||||||
/**
|
/**
|
||||||
* A pool of FTP clients, allowing multiple commands to be executed concurrently.
|
* A pool of FTP clients, allowing multiple commands to be executed concurrently.
|
||||||
*/
|
*/
|
||||||
class FTPClientPool {
|
final class FTPClientPool {
|
||||||
|
|
||||||
protected final String hostname;
|
private final String hostname;
|
||||||
protected final int port;
|
private final int port;
|
||||||
protected final FTPEnvironment env;
|
|
||||||
|
|
||||||
private FileSystemExceptionFactory exceptionFactory;
|
private final FTPEnvironment env;
|
||||||
|
private final FileSystemExceptionFactory exceptionFactory;
|
||||||
|
|
||||||
private BlockingQueue<Client> pool;
|
private final BlockingQueue<Client> pool;
|
||||||
|
|
||||||
FTPClientPool(String hostname, int port, FTPEnvironment env) throws IOException {
|
FTPClientPool(String hostname, int port, FTPEnvironment env) throws IOException {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.env = env.clone();
|
this.env = env.clone();
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void init() throws IOException {
|
|
||||||
this.exceptionFactory = env.getExceptionFactory();
|
this.exceptionFactory = env.getExceptionFactory();
|
||||||
final int poolSize = env.getClientConnectionCount();
|
final int poolSize = env.getClientConnectionCount();
|
||||||
this.pool = new ArrayBlockingQueue<>(poolSize);
|
this.pool = new ArrayBlockingQueue<>(poolSize);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < poolSize; i++) {
|
for (int i = 0; i < poolSize; i++) {
|
||||||
pool.add(new Client(true));
|
pool.add(new Client(true));
|
||||||
|
@ -151,23 +148,21 @@ class FTPClientPool {
|
||||||
pool.add(client);
|
pool.add(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Client implements Closeable {
|
final class Client implements Closeable {
|
||||||
|
|
||||||
|
private final FTPClient client;
|
||||||
|
private final boolean pooled;
|
||||||
|
|
||||||
protected final boolean pooled;
|
|
||||||
private FTPClient client;
|
|
||||||
private FileType fileType;
|
private FileType fileType;
|
||||||
private FileStructure fileStructure;
|
private FileStructure fileStructure;
|
||||||
private FileTransferMode fileTransferMode;
|
private FileTransferMode fileTransferMode;
|
||||||
|
|
||||||
private int refCount = 0;
|
private int refCount = 0;
|
||||||
|
|
||||||
Client(boolean pooled) throws IOException {
|
private Client(boolean pooled) throws IOException {
|
||||||
this.pooled = pooled;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void init() throws IOException {
|
|
||||||
this.client = env.createClient(hostname, port);
|
this.client = env.createClient(hostname, port);
|
||||||
|
this.pooled = pooled;
|
||||||
|
|
||||||
this.fileType = env.getDefaultFileType();
|
this.fileType = env.getDefaultFileType();
|
||||||
this.fileStructure = env.getDefaultFileStructure();
|
this.fileStructure = env.getDefaultFileStructure();
|
||||||
this.fileTransferMode = env.getDefaultFileTransferMode();
|
this.fileTransferMode = env.getDefaultFileTransferMode();
|
||||||
|
|
|
@ -4,7 +4,6 @@ import org.xbib.files.ftp.FTP;
|
||||||
import org.xbib.files.ftp.FTPClient;
|
import org.xbib.files.ftp.FTPClient;
|
||||||
import org.xbib.files.ftp.FTPClientConfig;
|
import org.xbib.files.ftp.FTPClientConfig;
|
||||||
import org.xbib.files.ftp.FTPFileEntryParser;
|
import org.xbib.files.ftp.FTPFileEntryParser;
|
||||||
import org.xbib.files.ftp.FTPSClient;
|
|
||||||
import org.xbib.files.ftp.parser.FTPFileEntryParserFactory;
|
import org.xbib.files.ftp.parser.FTPFileEntryParserFactory;
|
||||||
|
|
||||||
import javax.net.ServerSocketFactory;
|
import javax.net.ServerSocketFactory;
|
||||||
|
@ -321,6 +320,8 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FTPClient
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the timeout in milliseconds to use when reading from data connections.
|
* Stores the timeout in milliseconds to use when reading from data connections.
|
||||||
*
|
*
|
||||||
|
@ -565,10 +566,12 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStructure getDefaultFileStructure() {
|
FileStructure getDefaultFileStructure() {
|
||||||
|
// as specified by FTPClient
|
||||||
return FileStructure.FILE;
|
return FileStructure.FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTransferMode getDefaultFileTransferMode() {
|
FileTransferMode getDefaultFileTransferMode() {
|
||||||
|
// as specified by FTPClient
|
||||||
return FileTransferMode.STREAM;
|
return FileTransferMode.STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,15 +594,6 @@ public class FTPEnvironment implements Map<String, Object>, Cloneable {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPSClient createSecureClient(String hostname, int port) throws IOException {
|
|
||||||
FTPSClient client = new FTPSClient();
|
|
||||||
initializePreConnect(client);
|
|
||||||
connect(client, hostname, port);
|
|
||||||
initializePostConnect(client);
|
|
||||||
verifyConnection(client);
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializePreConnect(FTPClient client) throws IOException {
|
void initializePreConnect(FTPClient client) throws IOException {
|
||||||
client.setListHiddenFiles(true);
|
client.setListHiddenFiles(true);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.xbib.files.ftp.fs;
|
package org.xbib.files.ftp.fs;
|
||||||
|
|
||||||
import org.xbib.files.ftp.FTPFile;
|
import org.xbib.files.ftp.FTPFile;
|
||||||
|
import org.xbib.files.ftp.FTPFileFilter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
|
@ -16,9 +17,12 @@ import java.util.List;
|
||||||
abstract class FTPFileStrategy {
|
abstract class FTPFileStrategy {
|
||||||
|
|
||||||
static FTPFileStrategy getInstance(FTPClientPool.Client client) throws IOException {
|
static FTPFileStrategy getInstance(FTPClientPool.Client client) throws IOException {
|
||||||
FTPFile[] ftpFiles = client.listFiles("/", ftpFile -> {
|
FTPFile[] ftpFiles = client.listFiles("/", new FTPFileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(FTPFile ftpFile) {
|
||||||
String fileName = FTPFileSystem.getFileName(ftpFile);
|
String fileName = FTPFileSystem.getFileName(ftpFile);
|
||||||
return FTPFileSystem.CURRENT_DIR.equals(fileName);
|
return FTPFileSystem.CURRENT_DIR.equals(fileName);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return ftpFiles.length == 0 ? NonUnix.INSTANCE : Unix.INSTANCE;
|
return ftpFiles.length == 0 ? NonUnix.INSTANCE : Unix.INSTANCE;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +67,12 @@ abstract class FTPFileStrategy {
|
||||||
FTPFile getFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException {
|
FTPFile getFTPFile(FTPClientPool.Client client, FTPPath path) throws IOException {
|
||||||
final String name = path.fileName();
|
final String name = path.fileName();
|
||||||
|
|
||||||
FTPFile[] ftpFiles = client.listFiles(path.path(), ftpFile -> {
|
FTPFile[] ftpFiles = client.listFiles(path.path(), new FTPFileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(FTPFile ftpFile) {
|
||||||
String fileName = FTPFileSystem.getFileName(ftpFile);
|
String fileName = FTPFileSystem.getFileName(ftpFile);
|
||||||
return FTPFileSystem.CURRENT_DIR.equals(fileName) || (name != null && name.equals(fileName));
|
return FTPFileSystem.CURRENT_DIR.equals(fileName) || (name != null && name.equals(fileName));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
client.throwIfEmpty(path.path(), ftpFiles);
|
client.throwIfEmpty(path.path(), ftpFiles);
|
||||||
if (ftpFiles.length == 1) {
|
if (ftpFiles.length == 1) {
|
||||||
|
@ -87,13 +94,21 @@ abstract class FTPFileStrategy {
|
||||||
if (ftpFile.isDirectory() && FTPFileSystem.CURRENT_DIR.equals(FTPFileSystem.getFileName(ftpFile))) {
|
if (ftpFile.isDirectory() && FTPFileSystem.CURRENT_DIR.equals(FTPFileSystem.getFileName(ftpFile))) {
|
||||||
// The file is returned using getFTPFile, which returns the . (current directory) entry for directories.
|
// The file is returned using getFTPFile, which returns the . (current directory) entry for directories.
|
||||||
// List the parent (if any) instead.
|
// List the parent (if any) instead.
|
||||||
|
|
||||||
final String parentPath = path.toAbsolutePath().parentPath();
|
final String parentPath = path.toAbsolutePath().parentPath();
|
||||||
final String name = path.fileName();
|
final String name = path.fileName();
|
||||||
|
|
||||||
if (parentPath == null) {
|
if (parentPath == null) {
|
||||||
// path is /, there is no link
|
// path is /, there is no link
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
FTPFile[] ftpFiles = client.listFiles(parentPath, ftpFile1 -> (ftpFile1.isDirectory() || ftpFile1.isSymbolicLink()) && name.equals(FTPFileSystem.getFileName(ftpFile1)));
|
|
||||||
|
FTPFile[] ftpFiles = client.listFiles(parentPath, new FTPFileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(FTPFile ftpFile) {
|
||||||
|
return (ftpFile.isDirectory() || ftpFile.isSymbolicLink()) && name.equals(FTPFileSystem.getFileName(ftpFile));
|
||||||
|
}
|
||||||
|
});
|
||||||
client.throwIfEmpty(path.path(), ftpFiles);
|
client.throwIfEmpty(path.path(), ftpFiles);
|
||||||
return ftpFiles[0].getLink() == null ? null : ftpFiles[0];
|
return ftpFiles[0].getLink() == null ? null : ftpFiles[0];
|
||||||
}
|
}
|
||||||
|
@ -107,7 +122,9 @@ abstract class FTPFileStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
List<FTPFile> getChildren(FTPClientPool.Client client, FTPPath path) throws IOException {
|
List<FTPFile> getChildren(FTPClientPool.Client client, FTPPath path) throws IOException {
|
||||||
|
|
||||||
FTPFile[] ftpFiles = client.listFiles(path.path());
|
FTPFile[] ftpFiles = client.listFiles(path.path());
|
||||||
|
|
||||||
boolean isDirectory = false;
|
boolean isDirectory = false;
|
||||||
List<FTPFile> children = new ArrayList<>(ftpFiles.length);
|
List<FTPFile> children = new ArrayList<>(ftpFiles.length);
|
||||||
for (FTPFile ftpFile : ftpFiles) {
|
for (FTPFile ftpFile : ftpFiles) {
|
||||||
|
@ -118,6 +135,7 @@ abstract class FTPFileStrategy {
|
||||||
children.add(ftpFile);
|
children.add(ftpFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isDirectory && children.size() <= 1) {
|
if (!isDirectory && children.size() <= 1) {
|
||||||
// either zero or one, check the parent to see if the path exists and is a directory
|
// either zero or one, check the parent to see if the path exists and is a directory
|
||||||
FTPPath currentPath = path;
|
FTPPath currentPath = path;
|
||||||
|
@ -130,6 +148,7 @@ abstract class FTPFileStrategy {
|
||||||
throw new NotDirectoryException(path.path());
|
throw new NotDirectoryException(path.path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,51 +53,43 @@ public class FTPFileSystem extends FileSystem {
|
||||||
static final String CURRENT_DIR = ".";
|
static final String CURRENT_DIR = ".";
|
||||||
static final String PARENT_DIR = "..";
|
static final String PARENT_DIR = "..";
|
||||||
|
|
||||||
protected static final Set<String> SUPPORTED_FILE_ATTRIBUTE_VIEWS = Collections
|
private static final Set<String> SUPPORTED_FILE_ATTRIBUTE_VIEWS = Collections
|
||||||
.unmodifiableSet(new HashSet<>(Arrays.asList("basic", "owner", "posix")));
|
.unmodifiableSet(new HashSet<>(Arrays.asList("basic", "owner", "posix")));
|
||||||
protected static final Set<String> BASIC_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
private static final Set<String> BASIC_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||||
"basic:lastModifiedTime", "basic:lastAccessTime", "basic:creationTime", "basic:size",
|
"basic:lastModifiedTime", "basic:lastAccessTime", "basic:creationTime", "basic:size",
|
||||||
"basic:isRegularFile", "basic:isDirectory", "basic:isSymbolicLink", "basic:isOther", "basic:fileKey")));
|
"basic:isRegularFile", "basic:isDirectory", "basic:isSymbolicLink", "basic:isOther", "basic:fileKey")));
|
||||||
protected static final Set<String> OWNER_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Collections.singletonList(
|
private static final Set<String> OWNER_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Collections.singletonList(
|
||||||
"owner:owner")));
|
"owner:owner")));
|
||||||
protected static final Set<String> POSIX_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
private static final Set<String> POSIX_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||||
"posix:lastModifiedTime", "posix:lastAccessTime", "posix:creationTime", "posix:size",
|
"posix:lastModifiedTime", "posix:lastAccessTime", "posix:creationTime", "posix:size",
|
||||||
"posix:isRegularFile", "posix:isDirectory", "posix:isSymbolicLink", "posix:isOther", "posix:fileKey",
|
"posix:isRegularFile", "posix:isDirectory", "posix:isSymbolicLink", "posix:isOther", "posix:fileKey",
|
||||||
"posix:owner", "posix:group", "posix:permissions")));
|
"posix:owner", "posix:group", "posix:permissions")));
|
||||||
|
private final FTPFileSystemProvider provider;
|
||||||
protected final FTPFileSystemProvider provider;
|
private final Iterable<Path> rootDirectories;
|
||||||
protected final URI uri;
|
private final FileStore fileStore;
|
||||||
protected final FTPEnvironment env;
|
private final Iterable<FileStore> fileStores;
|
||||||
protected Iterable<Path> rootDirectories;
|
private final FTPClientPool clientPool;
|
||||||
protected FileStore fileStore;
|
private final URI uri;
|
||||||
protected Iterable<FileStore> fileStores;
|
private final String defaultDirectory;
|
||||||
private FTPClientPool clientPool;
|
private final FTPFileStrategy ftpFileStrategy;
|
||||||
protected String defaultDirectory;
|
|
||||||
FTPFileStrategy ftpFileStrategy;
|
|
||||||
private final AtomicBoolean open = new AtomicBoolean(true);
|
private final AtomicBoolean open = new AtomicBoolean(true);
|
||||||
|
|
||||||
public FTPFileSystem(FTPFileSystemProvider provider, URI uri, FTPEnvironment env) throws IOException {
|
public FTPFileSystem(FTPFileSystemProvider provider, URI uri, FTPEnvironment env) throws IOException {
|
||||||
this.provider = Objects.requireNonNull(provider);
|
this.provider = Objects.requireNonNull(provider);
|
||||||
this.uri = Objects.requireNonNull(uri);
|
|
||||||
this.env = Objects.requireNonNull(env);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void init() throws IOException {
|
|
||||||
this.rootDirectories = Collections.<Path>singleton(new FTPPath(this, "/"));
|
this.rootDirectories = Collections.<Path>singleton(new FTPPath(this, "/"));
|
||||||
this.fileStore = new FTPFileStore(this);
|
this.fileStore = new FTPFileStore(this);
|
||||||
this.fileStores = Collections.<FileStore>singleton(fileStore);
|
this.fileStores = Collections.<FileStore>singleton(fileStore);
|
||||||
|
|
||||||
this.clientPool = new FTPClientPool(uri.getHost(), uri.getPort(), env);
|
this.clientPool = new FTPClientPool(uri.getHost(), uri.getPort(), env);
|
||||||
|
this.uri = Objects.requireNonNull(uri);
|
||||||
|
|
||||||
try (FTPClientPool.Client client = clientPool.get()) {
|
try (FTPClientPool.Client client = clientPool.get()) {
|
||||||
this.defaultDirectory = client.pwd();
|
this.defaultDirectory = client.pwd();
|
||||||
|
|
||||||
this.ftpFileStrategy = FTPFileStrategy.getInstance(client);
|
this.ftpFileStrategy = FTPFileStrategy.getInstance(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPClientPool getClientPool() {
|
|
||||||
return clientPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFileName(FTPFile ftpFile) {
|
public static String getFileName(FTPFile ftpFile) {
|
||||||
String fileName = ftpFile.getName();
|
String fileName = ftpFile.getName();
|
||||||
if (fileName == null) {
|
if (fileName == null) {
|
||||||
|
@ -477,8 +469,7 @@ public class FTPFileSystem extends FileSystem {
|
||||||
getFTPFile(client, path);
|
getFTPFile(client, path);
|
||||||
}
|
}
|
||||||
String fileName = path.fileName();
|
String fileName = path.fileName();
|
||||||
return !CURRENT_DIR.equals(fileName) && !PARENT_DIR.equals(fileName) &&
|
return !CURRENT_DIR.equals(fileName) && !PARENT_DIR.equals(fileName) && fileName.startsWith(".");
|
||||||
fileName != null && fileName.startsWith(".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileStore getFileStore(FTPPath path) throws IOException {
|
public FileStore getFileStore(FTPPath path) throws IOException {
|
||||||
|
@ -501,11 +492,16 @@ public class FTPFileSystem extends FileSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasAccess(FTPFile ftpFile, AccessMode mode) {
|
private boolean hasAccess(FTPFile ftpFile, AccessMode mode) {
|
||||||
return switch (mode) {
|
switch (mode) {
|
||||||
case READ -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
|
case READ:
|
||||||
case WRITE -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION);
|
return ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
|
||||||
case EXECUTE -> ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PosixFileAttributes readAttributes(FTPPath path, LinkOption... options) throws IOException {
|
public PosixFileAttributes readAttributes(FTPPath path, LinkOption... options) throws IOException {
|
||||||
|
|
|
@ -1,442 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,653 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,512 +0,0 @@
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,476 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
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,7 +2,6 @@ package org.xbib.files.ftp.fs.spi;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface WithContext<T> {
|
interface WithContext<T> {
|
||||||
T perform(FTPContext ctx) throws IOException;
|
T perform(FTPContext ctx) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.xbib.files.ftp.fs.spi;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface WithSecureContext<T> {
|
|
||||||
T perform(FTPSContext ctx) throws IOException;
|
|
||||||
}
|
|
|
@ -1,2 +1 @@
|
||||||
org.xbib.files.ftp.fs.FTPFileSystemProvider
|
org.xbib.files.ftp.fs.FTPFileSystemProvider
|
||||||
org.xbib.files.ftp.fs.FTPSFileSystemProvider
|
|
|
@ -1,2 +1 @@
|
||||||
org.xbib.files.ftp.fs.spi.FTPFileServiceProvider
|
org.xbib.files.ftp.fs.spi.FTPFileServiceProvider
|
||||||
org.xbib.files.ftp.fs.spi.FTPSFileServiceProvider
|
|
|
@ -3,6 +3,7 @@ module org.xbib.files.ftp.fs.test {
|
||||||
requires org.junit.jupiter.api;
|
requires org.junit.jupiter.api;
|
||||||
requires org.junit.jupiter.params;
|
requires org.junit.jupiter.params;
|
||||||
requires org.mockito;
|
requires org.mockito;
|
||||||
|
requires org.slf4j;
|
||||||
requires org.xbib.files.ftp;
|
requires org.xbib.files.ftp;
|
||||||
requires org.xbib.files.ftp.fs;
|
requires org.xbib.files.ftp.fs;
|
||||||
requires org.xbib.files.ftp.mock;
|
requires org.xbib.files.ftp.mock;
|
||||||
|
|
|
@ -65,6 +65,9 @@ import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
|
public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
|
||||||
|
|
||||||
|
//@Rule
|
||||||
|
//public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetPath() {
|
public void testGetPath() {
|
||||||
testGetPath("/", "/");
|
testGetPath("/", "/");
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
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,16 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package org.xbib.files.jadaptive.sftp;
|
|
||||||
|
|
||||||
import com.sshtools.common.files.nio.AbstractFileNIOProvider;
|
|
||||||
|
|
||||||
public class SftpFileSystemProvider extends AbstractFileNIOProvider {
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.xbib.files.jadaptive.sftp;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface WithContext<T> {
|
|
||||||
T perform(SftpContext ctx) throws IOException;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
org.xbib.files.jadaptive.sftp.SftpFileSystemProvider
|
|
|
@ -1,8 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
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
|
|
|
@ -1,30 +0,0 @@
|
||||||
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.
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
This work is based on
|
|
||||||
|
|
||||||
https://github.com/mwiede/jsch
|
|
||||||
|
|
||||||
forked as of 23 July 2024 (Version 0.2.18)
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
dependencies {
|
|
||||||
testImplementation testLibs.testcontainers
|
|
||||||
testImplementation testLibs.testcontainers.junit.jupiter
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* 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() {}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,246 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,303 +0,0 @@
|
||||||
/*
|
|
||||||
* 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(""); }
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,842 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,334 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,265 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
* provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
||||||
* and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
||||||
* conditions and the following disclaimer in the documentation and/or other materials provided with
|
|
||||||
* the distribution.
|
|
||||||
*
|
|
||||||
* 3. The names of the authors may not be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
||||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.jcraft.jsch;
|
|
||||||
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
class ChannelSession extends Channel {
|
|
||||||
private static byte[] _session = Util.str2byte("session");
|
|
||||||
|
|
||||||
protected boolean agent_forwarding = false;
|
|
||||||
protected boolean xforwading = false;
|
|
||||||
protected Hashtable<byte[], byte[]> env = null;
|
|
||||||
|
|
||||||
protected boolean pty = false;
|
|
||||||
|
|
||||||
protected String ttype = "vt100";
|
|
||||||
protected int tcol = 80;
|
|
||||||
protected int trow = 24;
|
|
||||||
protected int twp = 640;
|
|
||||||
protected int thp = 480;
|
|
||||||
protected byte[] terminal_mode = null;
|
|
||||||
|
|
||||||
ChannelSession() {
|
|
||||||
super();
|
|
||||||
type = _session;
|
|
||||||
io = new IO();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable the agent forwarding.
|
|
||||||
*
|
|
||||||
* @param enable
|
|
||||||
*/
|
|
||||||
public void setAgentForwarding(boolean enable) {
|
|
||||||
agent_forwarding = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable the X11 forwarding. Refer to RFC4254 6.3.1. Requesting X11 Forwarding.
|
|
||||||
*
|
|
||||||
* @param enable
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setXForwarding(boolean enable) {
|
|
||||||
xforwading = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead.
|
|
||||||
* @see #setEnv(String, String)
|
|
||||||
* @see #setEnv(byte[], byte[])
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void setEnv(Hashtable<byte[], byte[]> env) {
|
|
||||||
synchronized (this) {
|
|
||||||
this.env = env;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the environment variable. If <code>name</code> and <code>value</code> are needed to be
|
|
||||||
* passed to the remote in your favorite encoding, use {@link #setEnv(byte[], byte[])}. Refer to
|
|
||||||
* RFC4254 6.4 Environment Variable Passing.
|
|
||||||
*
|
|
||||||
* @param name A name for environment variable.
|
|
||||||
* @param value A value for environment variable.
|
|
||||||
*/
|
|
||||||
public void setEnv(String name, String value) {
|
|
||||||
setEnv(Util.str2byte(name), Util.str2byte(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the environment variable. Refer to RFC4254 6.4 Environment Variable Passing.
|
|
||||||
*
|
|
||||||
* @param name A name of environment variable.
|
|
||||||
* @param value A value of environment variable.
|
|
||||||
* @see #setEnv(String, String)
|
|
||||||
*/
|
|
||||||
public void setEnv(byte[] name, byte[] value) {
|
|
||||||
synchronized (this) {
|
|
||||||
getEnv().put(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hashtable<byte[], byte[]> getEnv() {
|
|
||||||
if (env == null)
|
|
||||||
env = new Hashtable<>();
|
|
||||||
return env;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a Pseudo-Terminal. Refer to RFC4254 6.2. Requesting a Pseudo-Terminal.
|
|
||||||
*
|
|
||||||
* @param enable
|
|
||||||
*/
|
|
||||||
public void setPty(boolean enable) {
|
|
||||||
pty = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the terminal mode.
|
|
||||||
*
|
|
||||||
* @param terminal_mode
|
|
||||||
*/
|
|
||||||
public void setTerminalMode(byte[] terminal_mode) {
|
|
||||||
this.terminal_mode = terminal_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the window dimension interactively. Refer to RFC4254 6.7. Window Dimension Change
|
|
||||||
* Message.
|
|
||||||
*
|
|
||||||
* @param col terminal width, columns
|
|
||||||
* @param row terminal height, rows
|
|
||||||
* @param wp terminal width, pixels
|
|
||||||
* @param hp terminal height, pixels
|
|
||||||
*/
|
|
||||||
public void setPtySize(int col, int row, int wp, int hp) {
|
|
||||||
setPtyType(this.ttype, col, row, wp, hp);
|
|
||||||
if (!pty || !isConnected()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
RequestWindowChange request = new RequestWindowChange();
|
|
||||||
request.setSize(col, row, wp, hp);
|
|
||||||
request.request(getSession(), this);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// System.err.println("ChannelSessio.setPtySize: "+e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the terminal type. This method is not effective after Channel#connect().
|
|
||||||
*
|
|
||||||
* @param ttype terminal type(for example, "vt100")
|
|
||||||
* @see #setPtyType(String, int, int, int, int)
|
|
||||||
*/
|
|
||||||
public void setPtyType(String ttype) {
|
|
||||||
setPtyType(ttype, 80, 24, 640, 480);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the terminal type. This method is not effective after Channel#connect().
|
|
||||||
*
|
|
||||||
* @param ttype terminal type(for example, "vt100")
|
|
||||||
* @param col terminal width, columns
|
|
||||||
* @param row terminal height, rows
|
|
||||||
* @param wp terminal width, pixels
|
|
||||||
* @param hp terminal height, pixels
|
|
||||||
*/
|
|
||||||
public void setPtyType(String ttype, int col, int row, int wp, int hp) {
|
|
||||||
this.ttype = ttype;
|
|
||||||
this.tcol = col;
|
|
||||||
this.trow = row;
|
|
||||||
this.twp = wp;
|
|
||||||
this.thp = hp;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void sendRequests() throws Exception {
|
|
||||||
Session _session = getSession();
|
|
||||||
Request request;
|
|
||||||
if (agent_forwarding) {
|
|
||||||
request = new RequestAgentForwarding();
|
|
||||||
request.request(_session, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xforwading) {
|
|
||||||
request = new RequestX11();
|
|
||||||
request.request(_session, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pty) {
|
|
||||||
request = new RequestPtyReq();
|
|
||||||
((RequestPtyReq) request).setTType(ttype);
|
|
||||||
((RequestPtyReq) request).setTSize(tcol, trow, twp, thp);
|
|
||||||
if (terminal_mode != null) {
|
|
||||||
((RequestPtyReq) request).setTerminalMode(terminal_mode);
|
|
||||||
}
|
|
||||||
request.request(_session, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env != null) {
|
|
||||||
for (Enumeration<byte[]> _env = env.keys(); _env.hasMoreElements();) {
|
|
||||||
byte[] name = _env.nextElement();
|
|
||||||
byte[] value = env.get(name);
|
|
||||||
request = new RequestEnv();
|
|
||||||
((RequestEnv) request).setEnv(toByteArray(name), toByteArray(value));
|
|
||||||
request.request(_session, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] toByteArray(Object o) {
|
|
||||||
if (o instanceof String) {
|
|
||||||
return Util.str2byte((String) o);
|
|
||||||
}
|
|
||||||
return (byte[]) o;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void run() {
|
|
||||||
// System.err.println(this+":run >");
|
|
||||||
|
|
||||||
Buffer buf = new Buffer(rmpsize);
|
|
||||||
Packet packet = new Packet(buf);
|
|
||||||
int i = -1;
|
|
||||||
try {
|
|
||||||
Session _session = getSession();
|
|
||||||
while (isConnected() && thread != null && io != null && io.in != null) {
|
|
||||||
i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin());
|
|
||||||
if (i == 0)
|
|
||||||
continue;
|
|
||||||
if (i == -1) {
|
|
||||||
eof();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (close)
|
|
||||||
break;
|
|
||||||
// System.out.println("write: "+i);
|
|
||||||
packet.reset();
|
|
||||||
buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
|
|
||||||
buf.putInt(recipient);
|
|
||||||
buf.putInt(i);
|
|
||||||
buf.skip(i);
|
|
||||||
_session.write(packet, this, i);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// System.err.println("# ChannelExec.run");
|
|
||||||
// e.printStackTrace();
|
|
||||||
}
|
|
||||||
Thread _thread = thread;
|
|
||||||
if (_thread != null) {
|
|
||||||
synchronized (_thread) {
|
|
||||||
_thread.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thread = null;
|
|
||||||
// System.err.println(this+":run <");
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,262 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,187 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,194 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,246 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,186 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,229 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 "";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* 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){} }
|
|
||||||
*/
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
|
@ -1,141 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,694 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
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 "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 JSchAuthCancelException extends JSchException {
|
|
||||||
private static final long serialVersionUID = -1L;
|
|
||||||
String method;
|
|
||||||
|
|
||||||
JSchAuthCancelException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
JSchAuthCancelException(String s) {
|
|
||||||
super(s);
|
|
||||||
this.method = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethod() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 JSchChangedHostKeyException extends JSchHostKeyException {
|
|
||||||
private static final long serialVersionUID = -1L;
|
|
||||||
|
|
||||||
JSchChangedHostKeyException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
JSchChangedHostKeyException(String s) {
|
|
||||||
super(s);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 JSchException extends Exception {
|
|
||||||
private static final long serialVersionUID = -1L;
|
|
||||||
|
|
||||||
public JSchException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSchException(String s) {
|
|
||||||
super(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSchException(String s, Throwable e) {
|
|
||||||
super(s, e);
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue