com.sshtools.synergy.ssh.SshContext Maven / Gradle / Ivy
package com.sshtools.synergy.ssh;
/*-
* #%L
* Common API
* %%
* Copyright (C) 2002 - 2024 JADAPTIVE Limited
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import com.sshtools.common.forwarding.ForwardingPolicy;
import com.sshtools.common.logger.Log;
import com.sshtools.common.ssh.Context;
import com.sshtools.common.ssh.ExecutorOperationListener;
import com.sshtools.common.ssh.ExecutorServiceProvider;
import com.sshtools.common.ssh.SecurityLevel;
import com.sshtools.common.ssh.SshException;
import com.sshtools.common.ssh.components.ComponentFactory;
import com.sshtools.common.ssh.components.ComponentManager;
import com.sshtools.common.ssh.components.SshCipher;
import com.sshtools.common.ssh.components.SshHmac;
import com.sshtools.common.ssh.components.SshPublicKey;
import com.sshtools.common.ssh.components.jce.JCEComponentManager;
import com.sshtools.common.ssh.compression.NoneCompression.NoneCompressionFactory;
import com.sshtools.common.ssh.compression.SshCompression;
import com.sshtools.common.ssh.compression.SshCompressionFactory;
import com.sshtools.common.util.ByteBufferPool;
import com.sshtools.synergy.nio.ConnectRequestFuture;
import com.sshtools.synergy.nio.DefaultSocketConnectionFactory;
import com.sshtools.synergy.nio.ProtocolContext;
import com.sshtools.synergy.nio.ProtocolEngine;
import com.sshtools.synergy.nio.SocketConnectionFactory;
import com.sshtools.synergy.nio.SshEngine;
import com.sshtools.synergy.nio.SshEngineContext;
import com.sshtools.synergy.ssh.components.SshKeyExchange;
/**
* This class defines an SSH context for listening interfaces on the
* {@link com.sshtools.synergy.nio.SshEngine}.
*/
public abstract class SshContext extends ProtocolContext implements
ExecutorServiceProvider, Context {
public static final String CIPHER_TRIPLEDES_CBC = "3des-cbc";
public static final String CIPHER_TRIPLEDES_CTR = "3des-ctr";
public static final String CIPHER_BLOWFISH_CBC = "blowfish-cbc";
public static final String CIPHER_AES128_CBC = "aes128-cbc";
public static final String CIPHER_AES192_CBC = "aes192-cbc";
public static final String CIPHER_AES256_CBC = "aes256-cbc";
public static final String CIPHER_AES128_CTR = "aes128-ctr";
public static final String CIPHER_AES192_CTR = "aes192-ctr";
public static final String CIPHER_AES256_CTR = "aes256-ctr";
public static final String CIPHER_ARCFOUR = "arcfour";
public static final String CIPHER_ARCFOUR_128 = "arcfour128";
public static final String CIPHER_ARCFOUR_256 = "arcfour256";
public static final String CIPHER_AES_GCM_128 = "[email protected]";
public static final String CIPHER_AES_GCM_256 = "[email protected]";
/** SHA1 message authentication **/
public static final String HMAC_SHA1 = "hmac-sha1";
public static final String HMAC_SHA1_ETM = "[email protected]";
/** SHA1 96 bit message authentication **/
public static final String HMAC_SHA1_96 = "hmac-sha1-96";
/** MD5 message authentication **/
public static final String HMAC_MD5 = "hmac-md5";
public static final String HMAC_MD5_ETM = "[email protected]";
/** MD5 96 bit message authentication **/
public static final String HMAC_MD5_96 = "hmac-md5-96";
public static final String HMAC_SHA256 = "hmac-sha2-256";
public static final String HMAC_SHA256_ETM = "[email protected]";
public static final String HMAC_SHA256_96 = "hmac-sha2-256-96";
public static final String HMAC_SHA512 = "hmac-sha2-512";
public static final String HMAC_SHA512_ETM = "[email protected]";
public static final String HMAC_SHA512_96 = "hmac-sha2-512-96";
public static final String HMAC_RIPEMD160 = "hmac-ripemd160";
public static final String HMAC_RIPEMD160_ETM = "[email protected]";
/** Compression off **/
public static final String COMPRESSION_NONE = "none";
/** ZLIB compression **/
public static final String COMPRESSION_ZLIB = "zlib";
/**
* Constant for the algorithm name "diffie-hellman-group1-sha1".
*/
public static final String KEX_DIFFIE_HELLMAN_GROUP1_SHA1 = "diffie-hellman-group1-sha1";
/**
* Constant for the algorithm name "diffie-hellman-group-exchange-sha1".
*/
public static final String KEX_DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA1 = "diffie-hellman-group-exchange-sha1";
public static final String KEX_DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA256 = "diffie-hellman-group-exchange-sha256";
/** Constant for the algorithm name "diffie-hellman-group14-sha1". */
public static final String KEX_DIFFIE_HELLMAN_GROUP14_SHA1 = "diffie-hellman-group14-sha1";
/** Constant for the algorithm name "diffie-hellman-group14-sha256". */
public static final String KEX_DIFFIE_HELLMAN_GROUP14_SHA256 = "diffie-hellman-group14-sha256";
/** Constant for the algorithm name "diffie-hellman-group15-sha512". */
public static final String KEX_DIFFIE_HELLMAN_GROUP15_SHA512 = "diffie-hellman-group15-sha512";
/** Constant for the algorithm name "diffie-hellman-group16-sha512". */
public static final String KEX_DIFFIE_HELLMAN_GROUP16_SHA512 = "diffie-hellman-group16-sha512";
/** Constant for the algorithm name "diffie-hellman-group17-sha512". */
public static final String KEX_DIFFIE_HELLMAN_GROUP17_SHA512 = "diffie-hellman-group17-sha512";
/** Constant for the algorithm name "diffie-hellman-group18-sha512". */
public static final String KEX_DIFFIE_HELLMAN_GROUP18_SHA512 = "diffie-hellman-group18-sha512";
public static final String KEX_DIFFIE_HELLMAN_ECDH_NISTP_256 = "ecdh-sha2-nistp256";
public static final String KEX_DIFFIE_HELLMAN_ECDH_NISTP_384 = "ecdh-sha2-nistp384";
public static final String KEX_DIFFIE_HELLMAN_ECDH_NISTP_521 = "ecdh-sha2-nistp521";
/** SSH2 DSA Public Key **/
@Deprecated
public static final String PUBLIC_KEY_SSHDSS = "ssh-dss";
/** ED25519 Public key */
public static final String PUBLIC_KEY_ED25519 = "ssh-ed25519";
/** ED25519 Public key */
public static final String PUBLIC_KEY_ED448 = "ssh-ed448";
/** SSH2 RSA Public Key **/
public static final String PUBLIC_KEY_SSHRSA = "ssh-rsa";
/** ECDSA 256 bit Public Key **/
public static final String PUBLIC_KEY_ECDSA_SHA2_NISPTP_256 = "ecdsa-sha2-nistp256";
/** ECDSA 384 bit Public Key **/
public static final String PUBLIC_KEY_ECDSA_SHA2_NISPTP_384 = "ecdsa-sha2-nistp384";
/** ECDSA 521 bit Public Key **/
public static final String PUBLIC_KEY_ECDSA_SHA2_NISPTP_521 = "ecdsa-sha2-nistp521";
/**
* RSA key with SHA256 signature
*/
public static final String PUBLIC_KEY_RSA_SHA256 = "rsa-sha2-256";
/**
* RSA key with SHA512 signature
*/
public static final String PUBLIC_KEY_RSA_SHA512 = "rsa-sha2-512";
/** Identifier for password authentication **/
public static final String PASSWORD_AUTHENTICATION = "password";
/** Identifier for public key authentication **/
public static final String PUBLICKEY_AUTHENTICATION = "publickey";
public static final String KEYBOARD_INTERACTIVE_AUTHENTICATION = "keyboard-interactive";
protected int maximumSocketsBacklogPerRemotelyForwardedConnection = 50;
protected SocketConnectionFactory socketConnectionFactory = new DefaultSocketConnectionFactory();
protected ComponentFactory compressionsCS;
protected ComponentFactory compressionsSC;
protected ComponentFactory ciphersCS;
protected ComponentFactory ciphersSC;
protected ComponentFactory> keyExchanges;
protected ComponentFactory macCS;
protected ComponentFactory macSC;
protected ComponentFactory publicKeys;
protected ComponentFactory signatures;
protected String prefCipherCS = CIPHER_AES256_CTR;
protected String prefCipherSC = CIPHER_AES256_CTR;
protected String prefMacCS = HMAC_SHA256;
protected String prefMacSC = HMAC_SHA256;
protected String prefCompressionCS = COMPRESSION_NONE;
protected String prefCompressionSC = COMPRESSION_NONE;
protected String prefKeyExchange = KEX_DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA256;
protected String prefPublicKey = PUBLIC_KEY_ED25519;
protected int maxChannels = 100;
protected int compressionLevel = 6;
protected int maximumPacketLength = 131072 + 256; // Add overhead to support clients
// using 128k file blocks
protected long MAX_NUM_PACKETS_BEFORE_REKEY = 2147483647;
protected long MAX_NUM_BYTES_BEFORE_REKEY = 1073741824;
protected SshEngine daemon;
protected String softwareVersionComments = "MaverickSynergy";
protected boolean extendedIdentificationSanitization = true;
protected boolean killTunnelsOnRemoteForwardingCancel = false;
protected boolean sendIgnorePacketOnIdle = false;
protected int idleConnectionTimeout = 600;
protected int idleAuthenticationTimeoutSeconds = 30;
protected int keepAliveInterval = 30;
protected int keepAliveDataMaxLength = 128;
protected static ExecutorService executor;
protected Locale locale = Locale.getDefault();
protected ByteBufferPool byteBufferPool = null;
protected int minDHGroupExchangeKeySize = 2048;
protected int preferredDHGroupExchangeKeySize = 2048;
protected int maxDHGroupExchangeKeySize = 8192;
List listeners = new ArrayList();
protected ComponentManager componentManager;
boolean httpRedirect;
String httpRedirectUrl;
Map,Object> policies = new HashMap<>();
private boolean sha1SignaturesSupported = true;
/** Constructs a default context but does not set the daemon
* @param componentManager
* @throws SshException */
public SshContext(ComponentManager componentManager, SecurityLevel securityLevel) throws IOException, SshException {
this.componentManager = componentManager;
keyExchanges = new ComponentFactory>(componentManager);
configureKeyExchanges();
keyExchanges.configureSecurityLevel(securityLevel);
ciphersCS = ComponentManager.getDefaultInstance().supportedSsh2CiphersCS();
ciphersCS.configureSecurityLevel(securityLevel);
ciphersSC = ComponentManager.getDefaultInstance().supportedSsh2CiphersSC();
ciphersSC.configureSecurityLevel(securityLevel);
macCS = ComponentManager.getDefaultInstance().supportedHMacsCS();
macCS.configureSecurityLevel(securityLevel);
macSC = ComponentManager.getDefaultInstance().supportedHMacsSC();
macSC.configureSecurityLevel(securityLevel);
publicKeys = ComponentManager.getDefaultInstance().supportedPublicKeys();
publicKeys.configureSecurityLevel(securityLevel);
signatures = ComponentManager.getDefaultInstance().supportedPublicKeys();
signatures.configureSecurityLevel(securityLevel);
try {
compressionsCS = new ComponentFactory(componentManager);
compressionsSC = new ComponentFactory(componentManager);
compressionsCS.add(new NoneCompressionFactory());
compressionsSC.add(new NoneCompressionFactory());
for(var compress : ServiceLoader.load(SshCompressionFactory.class,
JCEComponentManager.getDefaultInstance().getClassLoader())) {
compressionsCS.add(compress);
compressionsSC.add(compress);
}
} catch (Throwable t) {
throw new IOException(t.getMessage() != null ? t.getMessage() : t
.getClass().getName());
}
this.keepAlive = true;
this.tcpNoDelay = true;
}
/** Initialise the SshContext by setting the daemon */
public void init(SshEngine daemon) {
this.daemon = daemon;
}
/**
* Constructs a default context
* @param componentManager
*
* @throws IOException
* @throws SshException
*/
public SshContext(SshEngine daemon, ComponentManager componentManager, SecurityLevel securityLevel) throws IOException, SshException {
this(componentManager, securityLevel);
init(daemon);
}
public abstract ConnectionManager extends SshContext> getConnectionManager();
public abstract ProtocolEngine createEngine(ConnectRequestFuture connectFuture) throws IOException;
public abstract String getSupportedPublicKeys();
protected abstract void configureKeyExchanges();
public abstract String getPreferredPublicKey();
public abstract ChannelFactory extends SshContext> getChannelFactory();
@SuppressWarnings("unchecked")
public P getPolicy(Class
clz) {
try {
if(!policies.containsKey(clz)) {
policies.put(clz, clz.getConstructor().newInstance());
}
return (P) policies.get(clz);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new IllegalArgumentException(e);
}
}
@SuppressWarnings("unchecked")
public
P getPolicy(Class
clz, P defaultValue) {
if(!policies.containsKey(clz)) {
policies.put(clz, defaultValue);
}
return (P) policies.get(clz);
}
@Override
public void setPolicy(Class> clz, Object policy) {
policies.put(clz, policy);
}
@Override
public boolean hasPolicy(Class> clz) {
return policies.containsKey(clz);
}
public ComponentManager getComponentManager() {
return componentManager;
}
public synchronized void addOperationListener(ExecutorOperationListener listener) {
listeners.add(listener);
}
public synchronized void removeOperationListener(ExecutorOperationListener listener) {
listeners.remove(listener);
}
@Override
public synchronized List getExecutorListeners() {
return new ArrayList(listeners);
}
public void setSocketConnectionFactory(SocketConnectionFactory socketConnectionFactory) {
this.socketConnectionFactory = socketConnectionFactory;
}
public SocketConnectionFactory getSocketConnectionFactory() {
return socketConnectionFactory;
}
public abstract GlobalRequestHandler extends SshContext> getGlobalRequestHandler(String requestname);
/**
* Get the instance of the SSHD for this context.
*
* @return Daemon
*/
public SshEngine getEngine() {
return daemon;
}
/**
* Set the maximum number of open channels allowed by each client (defaults
* to 100).
*
* @param maxChannels
*/
public void setChannelLimit(int maxChannels) {
this.maxChannels = maxChannels;
}
/**
* Get the maximum number of open channels allowed by each client.
*
* @return int
*/
public int getChannelLimit() {
return maxChannels;
}
public ComponentFactory getSupportedSignatures() {
return signatures;
}
/**
*
* Returns a factory implementation that enables configuration of the
* available ciphers.
*
*
*
* The standard default ciphers installed are 3DES and Blowfish, however the
* J2SSH Maverick API on which this server is based also supports a number
* of optional ciphers AES, CAST and Twofish. These can be installed by
* adding the sshtools-cipher.jar to your class path and using the
* following code within your SSHD
* {@link SshDaemon#configure(ConfigurationContext)} method.
*
*
* // import the cipher package
* import com.sshtools.cipher.*;
*
* // Add AES
* context.supportedCiphers().add(AES128Cbc.AES128_CBC, AES128Cbc.class);
* context.supportedCiphers().add(AES192Cbc.AES192_CBC, AES192Cbc.class);
* context.supportedCiphers().add(AES256Cbc.AES256_CBC, AES256Cbc.class);
*
* // Add Twofish - note the 256 bit cipher has two different entries to maintain backwards compatibility
* context.supportedCiphers().add(Twofish128Cbc.TWOFISH128_CBC, Twofish128Cbc.class);
* context.supportedCiphers().add(Twofish192Cbc.TWOFISH192_CBC, Twofish192Cbc.class);
* context.supportedCiphers().add(Twofish256Cbc.TWOFISH256_CBC, Twofish256Cbc.class);
* context.supportedCiphers().add(Twofish256Cbc.TWOFISH_CBC, Twofish256Cbc.class);
*
* // Add CAST
* context.supportedCiphers().add(CAST128Cbc.CAST128_CBC, CAST128Cbc.class);
*
*
*
*
* @return the component factory
*/
public ComponentFactory supportedCiphersCS() {
return ciphersCS;
}
public ComponentFactory supportedCiphersSC() {
return ciphersSC;
}
/**
* Get the currently preferred cipher for the Client->Server stream.
*
* @return the preferred Client-Server cipher
*/
public String getPreferredCipherCS() {
return prefCipherCS;
}
/**
*
* Set the preferred cipher for the Client->Server stream.
*
*
*
* Use the static fields available within this class (or the
* com.sshtools.cipher classes) to identify the correct cipher.
*
*
*
* context.setPreferredCipherCS(ConfigurationContext.CIPHER_BLOWFISH_CBC);
*
*
*
* * The default cipher is 3DES * * * @param name * @throws IOException * if the cipher is not supported * @throws SshException */ public void setPreferredCipherCS(String name) throws IOException, SshException { if (ciphersCS.contains(name)) { prefCipherCS = name; setCipherPreferredPositionCS(name, 0); } else { throw new IOException(name + " is not supported"); } } /** * Get the currently preferred cipher for the Server->Client stream. * * @return the preferred Server-Client cipher */ public String getPreferredCipherSC() { return prefCipherSC; } /** * Get the software/version/comments field that is to be used in the SSH * protocols negotiation procedure. * * @return String */ public String getSoftwareVersionComments() { if(extendedIdentificationSanitization) { return softwareVersionComments.replace(' ', '_').replace('-', '_'); } else { return softwareVersionComments; } } /** * Set the current implementations software/version/comments field that is * used during the SSH protocols negotiation procedure. This value MUST * consist of printable US-ASCII characters with the exception of whitespace * and the minus sign (-) and be no longer than 200 characters. * * @param softwareVersionComments */ public void setSoftwareVersionComments(String softwareVersionComments) { this.softwareVersionComments = softwareVersionComments; } /** *
* Set the preferred cipher for the Server->Client stream. *
* ** Use the static fields available within this class (or the * com.sshtools.cipher classes) to identify the correct cipher.
* * * * context.setPreferredCipherSC(ConfigurationContext.CIPHER_BLOWFISH_CBC); * * * *
* The default cipher is 3DES * * * @param name * @throws IOException * @throws SshException */ public void setPreferredCipherSC(String name) throws IOException, SshException { if (ciphersSC.contains(name)) { prefCipherSC = name; setCipherPreferredPositionSC(name, 0); } else { throw new IOException(name + " is not supported"); } } /** *
* Get the supported message authentication algorithms. *
* ** There are no optional MAC algorithms currently available and this method is * supplied in preperation for future enhancements. *
* * @return the component factory */ public ComponentFactory* Set the preferred MAC for the Client->Server stream. *
* ** Use the static fields available within this class to identify the correct * MAC.
* * * * context.setPreferredMacCS(ConfigurationContext.HMAC_MD5); * * * *
* The default MAC is HMAC_SHA1 * * * @param name * @throws IOException * @throws SshException */ public void setPreferredMacCS(String name) throws IOException, SshException { if (macCS.contains(name)) { prefMacCS = name; setMacPreferredPositionCS(name, 0); } else { throw new IOException(name + " is not supported"); } } /** * Get the currently supported mac for the Server-Client stream. * * @return the preferred Server-Client mac */ public String getPreferredMacSC() { return prefMacSC; } /** * When the user cancels a remote forwarding should active tunnels be * dropped? * * @param killTunnelsOnRemoteForwardingCancel * boolean */ public void setRemoteForwardingCancelKillsTunnels( boolean killTunnelsOnRemoteForwardingCancel) { this.killTunnelsOnRemoteForwardingCancel = killTunnelsOnRemoteForwardingCancel; } /** * Determines whether the cancellation of a remote forwarding drops * currently active tunnels * * @return boolean */ public boolean getRemoteForwardingCancelKillsTunnels() { return killTunnelsOnRemoteForwardingCancel; } public boolean isExtendedIdentificationSanitization() { return extendedIdentificationSanitization; } public void setExtendedIdentificationSanitization(boolean extendedIdentificationSanitization) { this.extendedIdentificationSanitization = extendedIdentificationSanitization; } /** *
* Set the preferred mac for the Server->Client stream. *
* ** Use the static fields available within this class to identify the correct * MAC.
* * * * context.setPreferredMacCS(ConfigurationContext.HMAC_MD5); * * * *
* The default MAC is HMAC_SHA1 * * * @param name * @throws IOException * @throws SshException */ public void setPreferredMacSC(String name) throws IOException, SshException { if (macSC.contains(name)) { prefMacSC = name; setMacPreferredPositionSC(name, 0); } else { throw new IOException(name + " is not supported"); } } /** *
* Get the supported compression algorithms. *
* ** There are * no optional compression algorithms currently available and this method is * supplied in preperation for future enhancements. *
* * @return the component factory */ public ComponentFactory* Set the preferred compression for the Client->Server stream. *
* ** It is recommended that you do not set the preferred compression * so that the client has control over the compression selection. *
* * @param name * @throws IOException */ public void setPreferredCompressionCS(String name) throws IOException { if (compressionsCS.contains(name)) { prefCompressionCS = name; } else { throw new IOException(name + " is not supported"); } } /** * Get the currently preferred compression for the Server->Client stream. * * @return the preferred Server->Client compression */ public String getPreferredCompressionSC() { return prefCompressionSC; } /** ** Set the preferred compression for the Server->Client stream. *
* ** It is recommended that you do not set the preferred compression * so that the client has control over the compression selection. *
* * @param name * @throws IOException */ public void setPreferredCompressionSC(String name) throws IOException { if (compressionsSC.contains(name)) { prefCompressionSC = name; } else { throw new IOException(name + " is not supported"); } } /** ** Get the supported key exchange methods. *
* ** There are * no optional key exchange algorithms currently available and this method is * supplied in preperation for future enhancements. *
* * @return the component factory */ public ComponentFactory* Set the preferred key exchange method. *
* ** There is only one supported key exchange algorithm and as such this * method is supplied in preperation for future enhancements. *
* * @param name * @throws IOException * @throws SshException */ public void setPreferredKeyExchange(String name) throws IOException, SshException { if (keyExchanges.contains(name)) { prefKeyExchange = name; setKeyExchangePreferredPosition(name, 0); } else { throw new IOException(name + " is not supported"); } } /** * Set the compression level to use if compression is enabled * * @param compressionLevel * int */ public void setCompressionLevel(int compressionLevel) { this.compressionLevel = compressionLevel; } /** * Get the current compression level * * @return int */ public int getCompressionLevel() { return compressionLevel; } public int getMaximumSocketsBacklogPerRemotelyForwardedConnection() { return maximumSocketsBacklogPerRemotelyForwardedConnection; } public void setMaximumSocketsBacklogPerRemotelyForwardedConnection( int maximumSocketsBacklogPerRemotelyForwardedConnection) { this.maximumSocketsBacklogPerRemotelyForwardedConnection = maximumSocketsBacklogPerRemotelyForwardedConnection; } /** * Get the ciphers for the Server->Client stream. * * @return the Server-Client ciphers in order of preference */ public String getCiphersSC() { return ciphersSC.list(prefCipherSC); } public String getCiphersCS() { return ciphersCS.list(prefCipherCS); } /** * Get the ciphers for the Client->Server stream. * * @return the Client-Server ciphers in order of preference */ public String getMacsCS() { return macCS.list(prefMacCS); } /** * Get the ciphers for the Server->Client stream. * * @return the Server-Client ciphers in order of preference */ public String getMacsSC() { return macSC.list(prefMacSC); } /** * Get the ciphers for the Server->Client stream. * * @return the Server-Client ciphers in order of preference */ public String getPublicKeys() { return publicKeys.list(prefPublicKey); } /** * Get the ciphers for the Server->Client stream. * * @return the Server-Client ciphers in order of preference */ public String getKeyExchanges() { return keyExchanges.list(prefKeyExchange); } /** * Set the preferred SC cipher order * * @param order * , list of indices to be moved to the top. * @throws SshException */ public void setPreferredCipherSC(int[] order) throws SshException { prefCipherSC = ciphersSC.createNewOrdering(order); } /** * Set the preferred SC cipher order * @param order * @throws SshException */ public void setPreferredCipherSC(String[] order) throws SshException { prefCipherSC = ciphersSC.order(order); } /** * Set the preferred SC cipher order * * @param order * , list of indices to be moved to the top. * @throws SshException */ public void setPreferredCipherCS(int[] order) throws SshException { prefCipherCS = ciphersCS.createNewOrdering(order); } /** * Set the preferred CS cipher order * @param order * @throws SshException */ public void setPreferredCipherCS(String[] order) throws SshException { prefCipherCS = ciphersCS.order(order); } /** * Set the preferred SC Mac order * * @param order * , list of indices to be moved to the top. * @throws SshException */ public void setPreferredMacSC(int[] order) throws SshException { prefMacSC = macSC.createNewOrdering(order); } /** * * @param order * @throws SshException */ public void setPreferredMacSC(String[] order) throws SshException { prefMacSC = macSC.order(order); } /** * * @param order * @throws SshException */ public void setPreferredKeyExchange(String[] order) throws SshException { prefKeyExchange = keyExchanges.order(order); } /** * Set the preferred CS Mac order * * @param order * , list of indices to be moved to the top. * @throws SshException */ public void setPreferredMacCS(int[] order) throws SshException { prefMacSC = macCS.createNewOrdering(order); } public void setPreferredMacCS(String[] order) throws SshException { prefMacCS = macCS.order(order); } public void setCipherPreferredPositionCS(String name, int position) throws SshException { prefCipherCS = ciphersCS.changePositionofAlgorithm(name, position); } public void setCipherPreferredPositionSC(String name, int position) throws SshException { prefCipherSC = ciphersSC.changePositionofAlgorithm(name, position); } public void setMacPreferredPositionSC(String name, int position) throws SshException { prefMacSC = macSC.changePositionofAlgorithm(name, position); } public void setMacPreferredPositionCS(String name, int position) throws SshException { prefMacCS = macCS.changePositionofAlgorithm(name, position); } public void setPublicKeyPreferredPosition(String name, int position) throws SshException { prefMacCS = publicKeys.changePositionofAlgorithm(name, position); } public void setKeyExchangePreferredPosition(String name, int position) throws SshException { prefMacCS = keyExchanges.changePositionofAlgorithm(name, position); } /** * Set the maximum supported length of an SSH packet. * * @param maximumPacketLength * int */ public void setMaximumPacketLength(int maximumPacketLength) { this.maximumPacketLength = maximumPacketLength; } /** * Get the maximum supported length of an SSH packet. * * @return int */ public int getMaximumPacketLength() { return maximumPacketLength; } /** * This limit tells the server when to force a key exchange. * * @param MAX_NUM_BYTES_BEFORE_REKEY * int */ public void setKeyExchangeTransferLimit(long MAX_NUM_BYTES_BEFORE_REKEY) { if (MAX_NUM_BYTES_BEFORE_REKEY < 1024000) throw new IllegalArgumentException( "The minimum number of bytes allowed between key exchange is 1MB (1024000 bytes)"); this.MAX_NUM_BYTES_BEFORE_REKEY = MAX_NUM_BYTES_BEFORE_REKEY; } /** * This tells the server how many packets to use before a key exchange. * * @param MAX_NUM_PACKETS_BEFORE_REKEY * int */ public void setKeyExchangePacketLimit(int MAX_NUM_PACKETS_BEFORE_REKEY) { if (MAX_NUM_PACKETS_BEFORE_REKEY < 100) throw new IllegalArgumentException( "The minimum number of packets allowed between key exchanges is 100"); this.MAX_NUM_PACKETS_BEFORE_REKEY = MAX_NUM_PACKETS_BEFORE_REKEY; } /** * Get the number of bytes to transfer before a key exchange is forced. * * @return int */ public long getKeyExchangeTransferLimit() { return MAX_NUM_BYTES_BEFORE_REKEY; } /** * Get the number of packets to send before a key exchange is forced * * @return int */ public long getKeyExchangePacketLimit() { return MAX_NUM_PACKETS_BEFORE_REKEY; } /** * Should the connection be disconnected on session timeout? * * @return */ public int getIdleConnectionTimeoutSeconds() { return idleConnectionTimeout; } /** * Inform the context that the connection should be disconnected on session * timeout * * @param idleConnectionTimeout */ public void setIdleConnectionTimeoutSeconds(int idleConnectionTimeout) { this.idleConnectionTimeout = idleConnectionTimeout; } public ComponentFactory