Hack SshDaemon to not use SecureRandom during tests
We previously needed 8 bytes of data from a SecureRandom in order to start an SSH daemon. Unfortunately, sometimes machines run out of entropy, for example when running the Gerrit test suite several times in a row. Add an undocumented configuration option to use a different Random factory for Apache SSHD that uses a hard-coded seed instead of depending on SecureRandom. Unfortunately, because SshDaemon is constructed using Daemon's injector stack, we can't easily modify its modules to swap out the provider, so a configuration option is the easiest solution. Change-Id: I539b8e3d39d2da9908962fdb8d9633adf935fb4c
This commit is contained in:
parent
d6a48f0201
commit
a5f3a69707
@ -131,6 +131,7 @@ public class GerritServer {
|
|||||||
cfg.setString("gerrit", null, "canonicalWebUrl", url);
|
cfg.setString("gerrit", null, "canonicalWebUrl", url);
|
||||||
cfg.setString("httpd", null, "listenUrl", url);
|
cfg.setString("httpd", null, "listenUrl", url);
|
||||||
cfg.setString("sshd", null, "listenAddress", forceEphemeralPort);
|
cfg.setString("sshd", null, "listenAddress", forceEphemeralPort);
|
||||||
|
cfg.setBoolean("sshd", null, "testUseInsecureRandom", true);
|
||||||
cfg.setString("cache", null, "directory", null);
|
cfg.setString("cache", null, "directory", null);
|
||||||
cfg.setString("gerrit", null, "basePath", "git");
|
cfg.setString("gerrit", null, "basePath", "git");
|
||||||
cfg.setBoolean("sendemail", null, "enable", false);
|
cfg.setBoolean("sendemail", null, "enable", false);
|
||||||
|
@ -45,6 +45,7 @@ import org.apache.sshd.common.ForwardingFilter;
|
|||||||
import org.apache.sshd.common.KeyExchange;
|
import org.apache.sshd.common.KeyExchange;
|
||||||
import org.apache.sshd.common.KeyPairProvider;
|
import org.apache.sshd.common.KeyPairProvider;
|
||||||
import org.apache.sshd.common.NamedFactory;
|
import org.apache.sshd.common.NamedFactory;
|
||||||
|
import org.apache.sshd.common.Random;
|
||||||
import org.apache.sshd.common.Session;
|
import org.apache.sshd.common.Session;
|
||||||
import org.apache.sshd.common.Signature;
|
import org.apache.sshd.common.Signature;
|
||||||
import org.apache.sshd.common.SshdSocketAddress;
|
import org.apache.sshd.common.SshdSocketAddress;
|
||||||
@ -94,6 +95,8 @@ import org.apache.sshd.server.channel.ChannelSession;
|
|||||||
import org.apache.sshd.server.kex.DHG1;
|
import org.apache.sshd.server.kex.DHG1;
|
||||||
import org.apache.sshd.server.kex.DHG14;
|
import org.apache.sshd.server.kex.DHG14;
|
||||||
import org.apache.sshd.server.session.SessionFactory;
|
import org.apache.sshd.server.session.SessionFactory;
|
||||||
|
import org.bouncycastle.crypto.prng.RandomGenerator;
|
||||||
|
import org.bouncycastle.crypto.prng.VMPCRandomGenerator;
|
||||||
import org.eclipse.jgit.lib.Config;
|
import org.eclipse.jgit.lib.Config;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -197,7 +200,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
|
|||||||
MinaServiceFactory.class.getName());
|
MinaServiceFactory.class.getName());
|
||||||
|
|
||||||
if (SecurityUtils.isBouncyCastleRegistered()) {
|
if (SecurityUtils.isBouncyCastleRegistered()) {
|
||||||
initProviderBouncyCastle();
|
initProviderBouncyCastle(cfg);
|
||||||
} else {
|
} else {
|
||||||
initProviderJce();
|
initProviderJce();
|
||||||
}
|
}
|
||||||
@ -366,11 +369,42 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
|
|||||||
return r.toString();
|
return r.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initProviderBouncyCastle() {
|
private void initProviderBouncyCastle(Config cfg) {
|
||||||
setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>> asList(
|
setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>> asList(
|
||||||
new DHG14.Factory(), new DHG1.Factory()));
|
new DHG14.Factory(), new DHG1.Factory()));
|
||||||
setRandomFactory(new SingletonRandomFactory(
|
NamedFactory<Random> factory;
|
||||||
new BouncyCastleRandom.Factory()));
|
if (cfg.getBoolean("sshd", null, "testUseInsecureRandom", false)) {
|
||||||
|
factory = new InsecureBouncyCastleRandom.Factory();
|
||||||
|
} else {
|
||||||
|
factory = new BouncyCastleRandom.Factory();
|
||||||
|
}
|
||||||
|
setRandomFactory(new SingletonRandomFactory(factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class InsecureBouncyCastleRandom implements Random {
|
||||||
|
private static class Factory implements NamedFactory<Random> {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "INSECURE_bouncycastle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Random create() {
|
||||||
|
return new InsecureBouncyCastleRandom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final RandomGenerator random;
|
||||||
|
|
||||||
|
private InsecureBouncyCastleRandom() {
|
||||||
|
random = new VMPCRandomGenerator();
|
||||||
|
random.addSeedMaterial(1234);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fill(byte[] bytes, int start, int len) {
|
||||||
|
random.nextBytes(bytes, start, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initProviderJce() {
|
private void initProviderJce() {
|
||||||
|
Loading…
Reference in New Issue
Block a user