/**
* Copyright 2003-2016 SSHTOOLS Limited. All Rights Reserved.
*
* For product documentation visit https://www.sshtools.com/
*
* This file is part of J2SSH Maverick.
*
* J2SSH Maverick 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.
*
* J2SSH Maverick 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with J2SSH Maverick. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sshtools.ssh2;
import java.util.Vector;
import com.sshtools.logging.Log;
import com.sshtools.ssh.ForwardingRequestListener;
import com.sshtools.ssh.HostKeyVerification;
import com.sshtools.ssh.SshConnector;
import com.sshtools.ssh.SshContext;
import com.sshtools.ssh.SshException;
import com.sshtools.ssh.components.ComponentFactory;
import com.sshtools.ssh.components.ComponentManager;
/**
* <p>
* This class implements <a href="../ssh/SshContext.html">SshContext</a>to
* provide SSH2 connection configuration through the <a
* href="../ssh/SshConnector.html">SshConnector</a> class.
* </p>
*
* <p>
* To configure an authentication banner for SSH2 connections see <a
* href="BannerDisplay.html">BannerDisplay</a>.
* </p>
*
* <p>
* The preferred message authentication algorithm for each data stream can be
* set using: <blockquote>
*
* <pre>
* SshConnector con = SshConnector.getInstance();
* Ssh2Context context = (Ssh2Context) con.getContext(SshConnector.SSH2);
*
* context.setPreferredMacCS(Ssh2Context.HMAC_MD5); // Client->Server data stream
* context.setPreferredMacSC(Ssh2Context.HMAC_MD5); // Server->Client data stream
* </pre>
*
* </blockquote> Once further cipher, public key and compression algorithms have
* been implemented the same process will apply.
* </p>
*
* @author Lee David Painter
*/
public final class Ssh2Context implements SshContext {
ComponentFactory compressionsCS;
ComponentFactory compressionsSC;
ComponentFactory ciphersCS;
ComponentFactory ciphersSC;
ComponentFactory keyExchanges;
ComponentFactory macCS;
ComponentFactory macSC;
ComponentFactory publicKeys;
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";
/** SHA1 message authentication **/
public static final String HMAC_SHA1 = "hmac-sha1";
/** 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";
/** MD5 96 bit message authentication **/
public static final String HMAC_MD5_96 = "hmac-md5-96";
public static final String HMAC_SHA256 = "hmac-sha256";
/** Compression off **/
public static final String COMPRESSION_NONE = "none";
/** Optional zlib compression (requires sshtools-zlib.jar in classpath) */
public static final String COMPRESSION_ZLIB = "zlib";
/** The required key exchange method **/
public static final String KEX_DIFFIE_HELLMAN_GROUP1_SHA1 = "diffie-hellman-group1-sha1";
public static final String KEX_DIFFIE_HELLMAN_GROUP14_SHA1 = "diffie-hellman-group14-sha1";
/**
* Optional key exchange mechanism in which the server maintains a list of
* acceptable generators and primes
**/
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";
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 **/
public static final String PUBLIC_KEY_SSHDSS = "ssh-dss";
/** SSH2 RSA Public Key **/
public static final String PUBLIC_KEY_SSHRSA = "ssh-rsa";
public static final String PUBLIC_KEY_ECDSA_256 = "ecdsa-sha2-nistp256";
public static final String PUBLIC_KEY_ECDSA_384 = "ecdsa-sha2-nistp384";
public static final String PUBLIC_KEY_ECDSA_521 = "ecdsa-sha2-nistp521";
String prefCipherCS = CIPHER_AES128_CTR;
String prefCipherSC = CIPHER_AES128_CTR;
String prefMacCS = HMAC_SHA1;
String prefMacSC = HMAC_SHA1;
String prefCompressionCS = COMPRESSION_NONE;
String prefCompressionSC = COMPRESSION_NONE;
String prefKeyExchange = KEX_DIFFIE_HELLMAN_ECDH_NISTP_256;
String prefPublicKey = PUBLIC_KEY_ECDSA_256;
String sftpProvider = "/usr/libexec/sftp-server";
int maxChannels = 100;
BannerDisplay bannerdisplay;
HostKeyVerification verify;
String xDisplay = null;
byte[] x11FakeCookie = null;
byte[] x11RealCookie = null;
ForwardingRequestListener x11Listener = null;
String jceProvider = "";
int maxPacketLength = 131072;
boolean keyReExchangeDisabled = false;
int partialMessageTimeout = 30000;
int keepAliveMaxDataLength = 128;
int idleConnectionTimeoutSeconds = 0;
boolean sendIgnorePacketOnIdle = false;
int dhGroupExchangeKeySize = 1024;
boolean dhGroupExchangeBackwardCompatible = false;
int socketTimeout = 0;
SshConnector con;
/**
* Contructs a default context
*
* @throws SshException
*/
public Ssh2Context() throws SshException {
try {
ciphersCS = ComponentManager.getInstance().supportedSsh2CiphersCS();
ciphersSC = ComponentManager.getInstance().supportedSsh2CiphersSC();
keyExchanges = ComponentManager.getInstance()
.supportedKeyExchanges();
macCS = ComponentManager.getInstance().supportedHMacsCS();
macSC = ComponentManager.getInstance().supportedHMacsSC();
publicKeys = ComponentManager.getInstance().supportedPublicKeys();
if (Log.isDebugEnabled()) {
Log.debug(this, "Creating compression factory");
}
compressionsSC = new ComponentFactory(
Class.forName("com.sshtools.ssh.compression.SshCompression"));
if (Log.isDebugEnabled()) {
Log.debug(this, "Adding None Compression");
}
compressionsSC.add(COMPRESSION_NONE,
Class.forName("java.lang.Object" /* We never use it */));
try {
if (Log.isDebugEnabled()) {
Log.debug(this, "Adding ZLib Compression");
}
compressionsSC.add("zlib",
Class.forName("com.sshtools.zlib.ZLibCompression"));
compressionsSC.add("zlib@openssh.com", Class
.forName("com.sshtools.zlib.OpenSSHZLibCompression"));
} catch (Throwable t) {
}
compressionsCS = new ComponentFactory(
Class.forName("com.sshtools.ssh.compression.SshCompression"));
if (Log.isDebugEnabled()) {
Log.debug(this, "Adding None Compression");
}
compressionsCS.add(COMPRESSION_NONE,
Class.forName("java.lang.Object" /* We never use it */));
try {
if (Log.isDebugEnabled()) {
Log.debug(this, "Adding ZLib Compression");
}
compressionsCS.add("zlib",
Class.forName("com.sshtools.zlib.ZLibCompression"));
compressionsCS.add("zlib@openssh.com", Class
.forName("com.sshtools.zlib.OpenSSHZLibCompression"));
} catch (Throwable t) {
}
} catch (Throwable t) {
t.printStackTrace();
throw new SshException(t.getMessage() != null ? t.getMessage() : t
.getClass().getName(), SshException.INTERNAL_ERROR); // SSHException
}
if (Log.isDebugEnabled()) {
Log.debug(this, "Completed Ssh2Context creation");
}
}
/**
* Get the maximim packet size supported by the transport layer.
*
* @return int
*/
public int getMaximumPacketLength() {
return maxPacketLength;
}
MaverickCallbackHandler gsscall = null;
public void setGssCallback(MaverickCallbackHandler gsscall) {
this.gsscall = gsscall;
}
public MaverickCallbackHandler getGssCallback() {
return gsscall;
}
/**
* Set the maximum packet size supported by the transport layer. This would
* not normally require changing but some servers may support larger
* packets. The default and minimum size is 35,000 bytes.
*
* @param maxPacketLength
* int
*/
public void setMaximumPacketLength(int maxPacketLength) {
if (maxPacketLength < 35000)
throw new IllegalArgumentException(
"The minimum packet length supported must be 35,000 bytes or greater!");
this.maxPacketLength = maxPacketLength;
}
public void setChannelLimit(int maxChannels) {
this.maxChannels = maxChannels;
}
public int getChannelLimit() {
return maxChannels;
}
public void setX11Display(String xDisplay) {
this.xDisplay = xDisplay;
}
public String getX11Display() {
return xDisplay;
}
public byte[] getX11AuthenticationCookie() throws SshException {
if (x11FakeCookie == null) {
x11FakeCookie = new byte[16];
ComponentManager.getInstance().getRND().nextBytes(x11FakeCookie);
}
return x11FakeCookie;
}
public void setX11AuthenticationCookie(byte[] x11FakeCookie) {
this.x11FakeCookie = x11FakeCookie;
}
public void setX11RealCookie(byte[] x11RealCookie) {
this.x11RealCookie = x11RealCookie;
}
public byte[] getX11RealCookie() throws SshException {
if (x11RealCookie == null) {
x11RealCookie = getX11AuthenticationCookie();
}
return x11RealCookie;
}
public void setX11RequestListener(ForwardingRequestListener x11Listener) {
this.x11Listener = x11Listener;
}
public ForwardingRequestListener getX11RequestListener() {
return x11Listener;
}
/**
* Get the contexts banner display
*
* @return the banner display, may be null
*/
public BannerDisplay getBannerDisplay() {
return bannerdisplay;
}
/**
* Set a banner display for callback of authentication banners
*
* @param bannerdisplay
* the banner display, may be null
*/
public void setBannerDisplay(BannerDisplay bannerdisplay) {
this.bannerdisplay = bannerdisplay;
}
/**
* Returns this context's supported cipher algorithms.
*
* @return the component factory
*/
public ComponentFactory supportedCiphersSC() {
return ciphersSC;
}
public ComponentFactory supportedCiphersCS() {
return ciphersCS;
}
/**
* 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.
*
* @param name
* @throws SshException
*/
public void setPreferredCipherCS(String name) throws SshException {
if (name == null)
return;
if (ciphersCS.contains(name)) {
prefCipherCS = name;
setCipherPreferredPositionCS(name, 0);
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* Get the currently preferred cipher for the Server->Client stream.
*
* @return the preferred Server-Client cipher
*/
public String getPreferredCipherSC() {
return prefCipherSC;
}
/**
* Get the ciphers for the Client->Server stream.
*
* @return the Client-Server ciphers in order of preference
*/
public String getCiphersCS() {
return ciphersCS.list(prefCipherCS);
}
/**
* Get the ciphers for the Server->Client stream.
*
* @return the Server-Client ciphers in order of preference
*/
public String getCiphersSC() {
return ciphersSC.list(prefCipherSC);
}
/**
* 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
* , list of indices to be moved to the top.
* @throws SshException
*/
public void setPreferredCipherCS(int[] order) throws SshException {
prefCipherCS = ciphersCS.createNewOrdering(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);
}
/**
* 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 {
prefCipherSC = macSC.createNewOrdering(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 {
prefCipherSC = macCS.createNewOrdering(order);
}
/**
* Set the preferred cipher for the Server->Client stream.
*
* @param name
* @throws SshException
*/
public void setPreferredCipherSC(String name) throws SshException {
if (name == null)
return;
if (ciphersSC.contains(name)) {
prefCipherSC = name;
setCipherPreferredPositionSC(name, 0);
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* Get this context's supported message authentication algorithms SC.
*
* @return the component factory
*/
public ComponentFactory supportedMacsSC() {
return macSC;
}
/**
* Get this context's supported message authentication algorithms CS.
*
* @return the component factory
*/
public ComponentFactory supportedMacsCS() {
return macCS;
}
/**
* Get the currently preferred mac for the Client->Server stream.
*
* @return the preferred Client-Server mac
*/
public String getPreferredMacCS() {
return prefMacCS;
}
/**
* Set the preferred mac for the Client->Server stream.
*
* @param name
* @throws SshException
*/
public void setPreferredMacCS(String name) throws SshException {
if (name == null)
return;
if (macCS.contains(name)) {
prefMacCS = name;
setMacPreferredPositionCS(name, 0);
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* Get the currently supported mac for the Server-Client stream.
*
* @return the preferred Server-Client mac
*/
public String getPreferredMacSC() {
return prefMacSC;
}
/**
* Set the preferred mac for the Server->Client stream.
*
* @param name
* @throws SshException
*/
public void setPreferredMacSC(String name) throws SshException {
if (name == null)
return;
if (macSC.contains(name)) {
prefMacSC = name;
setMacPreferredPositionSC(name, 0);
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* Get this context's supported SC compression algorithms.
*
* @return the component factory
*/
public ComponentFactory supportedCompressionsSC() {
return compressionsSC;
}
/**
* Get this context's supported CS compression algorithms.
*
* @return the component factory
*/
public ComponentFactory supportedCompressionsCS() {
return compressionsCS;
}
/**
* Get the currently preferred compression for the Client->Server stream.
*
* @return the preferred Client-Server compression
*/
public String getPreferredCompressionCS() {
return prefCompressionCS;
}
/**
* Set the preferred compression for the Client->Server stream.
*
* @param name
* @throws SshException
*/
public void setPreferredCompressionCS(String name) throws SshException {
if (name == null)
return;
if (compressionsCS.contains(name)) {
prefCompressionCS = name;
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* 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.
*
* @param name
* @throws SshException
*/
public void setPreferredCompressionSC(String name) throws SshException {
if (name == null)
return;
if (compressionsSC.contains(name)) {
prefCompressionSC = name;
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
public void enableCompression() throws SshException {
supportedCompressionsCS().changePositionofAlgorithm("zlib", 0);
supportedCompressionsCS().changePositionofAlgorithm("zlib@openssh.com",
1);
prefCompressionCS = supportedCompressionsCS()
.changePositionofAlgorithm("none", 2);
supportedCompressionsSC().changePositionofAlgorithm("zlib", 0);
supportedCompressionsSC().changePositionofAlgorithm("zlib@openssh.com",
1);
prefCompressionSC = supportedCompressionsSC()
.changePositionofAlgorithm("none", 2);
}
public void disableCompression() throws SshException {
supportedCompressionsCS().changePositionofAlgorithm("none", 0);
supportedCompressionsCS().changePositionofAlgorithm("zlib", 1);
prefCompressionCS = supportedCompressionsCS()
.changePositionofAlgorithm("zlib@openssh.com", 2);
supportedCompressionsSC().changePositionofAlgorithm("none", 0);
supportedCompressionsSC().changePositionofAlgorithm("zlib", 1);
prefCompressionSC = supportedCompressionsSC()
.changePositionofAlgorithm("zlib@openssh.com", 2);
}
/**
* Get this context's supported key exchange methods.
*
* @return the component factory
*/
public ComponentFactory supportedKeyExchanges() {
return keyExchanges;
}
/**
* Get the currently preferred key exchange method.
*
* @return the preferred key exhcange
*/
public String getPreferredKeyExchange() {
return prefKeyExchange;
}
/**
* Set the preferred key exchange method.
*
* @param name
* @throws SshException
*/
public void setPreferredKeyExchange(String name) throws SshException {
if (name == null)
return;
if (keyExchanges.contains(name)) {
prefKeyExchange = name;
setKeyExchangePreferredPosition(name, 0);
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* Get this context's supported public keys.
*
* @return the component factory
*/
public ComponentFactory supportedPublicKeys() {
return publicKeys;
}
/**
* Get the currently preferred public key algorithm.
*
* @return the preferred public key
*/
public String getPreferredPublicKey() {
return prefPublicKey;
}
/**
* Set the preferred public key algorithm.
*
* @param name
* @throws SshException
*/
public void setPreferredPublicKey(String name) throws SshException {
if (name == null)
return;
if (publicKeys.contains(name)) {
prefPublicKey = name;
setPublicKeyPreferredPosition(name, 0);
} else {
throw new SshException(name + " is not supported",
SshException.UNSUPPORTED_ALGORITHM);
}
}
/**
* Set the host key verification implementation
*
* @param verify
*/
public void setHostKeyVerification(HostKeyVerification verify) {
this.verify = verify;
}
/**
* Get the host key verification implementation
*
* @return HostKeyVerification
*/
public HostKeyVerification getHostKeyVerification() {
return verify;
}
public void setSFTPProvider(String sftpProvider) {
this.sftpProvider = sftpProvider;
}
public String getSFTPProvider() {
return sftpProvider;
}
public void setPartialMessageTimeout(int partialMessageTimeout) {
this.partialMessageTimeout = partialMessageTimeout;
}
public int getPartialMessageTimeout() {
return partialMessageTimeout;
}
public boolean isKeyReExchangeDisabled() {
return keyReExchangeDisabled;
}
public void setKeyReExchangeDisabled(boolean keyReExchangeDisabled) {
this.keyReExchangeDisabled = keyReExchangeDisabled;
}
public void setPublicKeyPreferredPosition(String name, int position)
throws SshException {
prefPublicKey = publicKeys.changePositionofAlgorithm(name, position);
}
public void setKeyExchangePreferredPosition(String name, int position)
throws SshException {
prefKeyExchange = keyExchanges
.changePositionofAlgorithm(name, position);
}
public int getIdleConnectionTimeoutSeconds() {
return idleConnectionTimeoutSeconds;
}
public void setIdleConnectionTimeoutSeconds(int idleConnectionTimeoutSeconds) {
this.idleConnectionTimeoutSeconds = idleConnectionTimeoutSeconds;
}
public boolean isDHGroupExchangeBackwardsCompatible() {
return dhGroupExchangeBackwardCompatible;
}
public int getDHGroupExchangeKeySize() {
return dhGroupExchangeKeySize;
}
public void setDHGroupExchangeKeySize(int dhGroupExchangeKeySize) {
if (dhGroupExchangeKeySize < 1024 || dhGroupExchangeKeySize > 8192) {
throw new IllegalArgumentException(
"DH group exchange key size must be between 1024 and 8192");
}
this.dhGroupExchangeKeySize = dhGroupExchangeKeySize;
}
public void setDHGroupExchangeBackwardsCompatible(
boolean dhGroupExchangeBackwardCompatible) {
this.dhGroupExchangeBackwardCompatible = dhGroupExchangeBackwardCompatible;
}
public boolean isSendIgnorePacketOnIdle() {
return sendIgnorePacketOnIdle;
}
public void setSendIgnorePacketOnIdle(boolean sendIgnorePacketOnIdle) {
this.sendIgnorePacketOnIdle = sendIgnorePacketOnIdle;
}
public int getKeepAliveMaxDataLength() {
return keepAliveMaxDataLength;
}
public void setKeepAliveMaxDataLength(int keepAliveMaxDataLength) {
if (keepAliveMaxDataLength < 8)
throw new IllegalArgumentException(
"There must be at least 8 bytes of random data");
this.keepAliveMaxDataLength = keepAliveMaxDataLength;
}
public int getSocketTimeout() {
return socketTimeout;
}
public void setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
}
public void enableFIPSMode() throws SshException {
Log.info(this, "Enabling FIPS mode");
if (!keyExchanges.contains(Ssh2Context.KEX_DIFFIE_HELLMAN_GROUP14_SHA1)) {
throw new SshException(
"Cannot enable FIPS mode because diffie-hellman-group14-sha1 "
+ "keyexchange was not supported by this configuration. "
+ "Install a JCE Provider that supports a prime size of 2048 bits (for example BouncyCastle provider)",
SshException.BAD_API_USAGE);
}
if (dhGroupExchangeKeySize < 2048) {
dhGroupExchangeKeySize = 2048;
}
Vector<String> allowed = new Vector<String>();
allowed.addElement(Ssh2Context.KEX_DIFFIE_HELLMAN_GROUP14_SHA1);
allowed.addElement(Ssh2Context.KEX_DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA1);
allowed.addElement(Ssh2Context.KEX_DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA256);
String[] names = keyExchanges.toArray();
for (int i = 0; i < names.length; i++) {
if (!allowed.contains(names[i])) {
Log.info(this, "Removing key exchange " + names[i]);
keyExchanges.remove(names[i]);
}
}
keyExchanges.lockComponents();
allowed.clear();
allowed.addElement(Ssh2Context.CIPHER_AES128_CBC);
allowed.addElement(Ssh2Context.CIPHER_AES192_CBC);
allowed.addElement(Ssh2Context.CIPHER_AES256_CBC);
allowed.addElement(Ssh2Context.CIPHER_TRIPLEDES_CBC);
names = ciphersCS.toArray();
for (int i = 0; i < names.length; i++) {
if (!allowed.contains(names[i])) {
Log.info(this, "Removing cipher client->server "
+ names[i]);
ciphersCS.remove(names[i]);
}
}
ciphersCS.lockComponents();
names = ciphersSC.toArray();
for (int i = 0; i < names.length; i++) {
if (!allowed.contains(names[i])) {
Log.info(this, "Removing cipher server->client "
+ names[i]);
ciphersSC.remove(names[i]);
}
}
ciphersSC.lockComponents();
allowed.clear();
allowed.addElement(Ssh2Context.PUBLIC_KEY_SSHRSA);
names = publicKeys.toArray();
for (int i = 0; i < names.length; i++) {
if (!allowed.contains(names[i])) {
Log.info(this, "Removing public key " + names[i]);
publicKeys.remove(names[i]);
}
}
publicKeys.lockComponents();
allowed.clear();
allowed.addElement(Ssh2Context.HMAC_SHA1);
allowed.addElement(Ssh2Context.HMAC_SHA256);
allowed.addElement("hmac-sha256@ssh.com");
names = macCS.toArray();
for (int i = 0; i < names.length; i++) {
if (!allowed.contains(names[i])) {
Log.info(this, "Removing mac client->server "
+ names[i]);
macCS.remove(names[i]);
}
}
macCS.lockComponents();
names = macSC.toArray();
for (int i = 0; i < names.length; i++) {
if (!allowed.contains(names[i])) {
Log.info(this, "Removing mac server->client "
+ names[i]);
macSC.remove(names[i]);
}
}
macCS.lockComponents();
}
}