Catch Bouncy Castle Crypto not installed when loading SSH keys
If the Bouncy Castle Crypto library isn't installed but the site administrator has created PEM encoded host keys for the server we should let them know the library is missing, rather than throw a more obtuse NoClassDefError from deep within the PEM reader. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2009 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.ssh;
|
||||
|
||||
import com.google.gerrit.server.config.SitePath;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
|
||||
import org.apache.sshd.common.KeyPairProvider;
|
||||
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
|
||||
import org.apache.sshd.common.util.SecurityUtils;
|
||||
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class HostKeyProvider implements Provider<KeyPairProvider> {
|
||||
private final File sitePath;
|
||||
|
||||
@Inject
|
||||
HostKeyProvider(@SitePath final File sitePath) {
|
||||
this.sitePath = sitePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPairProvider get() {
|
||||
final File anyKey = new File(sitePath, "ssh_host_key");
|
||||
final File rsaKey = new File(sitePath, "ssh_host_rsa_key");
|
||||
final File dsaKey = new File(sitePath, "ssh_host_dsa_key");
|
||||
|
||||
final List<String> keys = new ArrayList<String>(2);
|
||||
if (rsaKey.exists()) {
|
||||
keys.add(rsaKey.getAbsolutePath());
|
||||
}
|
||||
if (dsaKey.exists()) {
|
||||
keys.add(dsaKey.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (anyKey.exists() && !keys.isEmpty()) {
|
||||
// If both formats of host key exist, we don't know which format
|
||||
// should be authoritative. Complain and abort.
|
||||
//
|
||||
keys.add(anyKey.getAbsolutePath());
|
||||
throw new ProvisionException("Multiple host keys exist: " + keys);
|
||||
}
|
||||
|
||||
if (keys.isEmpty()) {
|
||||
// No administrator created host key? Generate and save our own.
|
||||
//
|
||||
final SimpleGeneratorHostKeyProvider keyp;
|
||||
|
||||
keyp = new SimpleGeneratorHostKeyProvider();
|
||||
keyp.setPath(anyKey.getAbsolutePath());
|
||||
return keyp;
|
||||
}
|
||||
|
||||
if (!SecurityUtils.isBouncyCastleRegistered()) {
|
||||
throw new ProvisionException("Bouncy Castle Crypto not installed;"
|
||||
+ " needed to read server host keys: " + keys + "");
|
||||
}
|
||||
return new FileKeyPairProvider(keys.toArray(new String[keys.size()]));
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ package com.google.gerrit.server.ssh;
|
||||
|
||||
import com.google.gerrit.server.GerritServer;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.config.SitePath;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Singleton;
|
||||
@@ -39,7 +38,6 @@ import org.apache.sshd.common.cipher.BlowfishCBC;
|
||||
import org.apache.sshd.common.cipher.CipherNone;
|
||||
import org.apache.sshd.common.cipher.TripleDESCBC;
|
||||
import org.apache.sshd.common.compression.CompressionNone;
|
||||
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
|
||||
import org.apache.sshd.common.mac.HMACMD5;
|
||||
import org.apache.sshd.common.mac.HMACMD596;
|
||||
import org.apache.sshd.common.mac.HMACSHA1;
|
||||
@@ -60,13 +58,11 @@ import org.apache.sshd.server.auth.UserAuthPublicKey;
|
||||
import org.apache.sshd.server.channel.ChannelSession;
|
||||
import org.apache.sshd.server.kex.DHG1;
|
||||
import org.apache.sshd.server.kex.DHG14;
|
||||
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
|
||||
import org.apache.sshd.server.session.ServerSession;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spearce.jgit.lib.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
@@ -105,8 +101,7 @@ import java.util.List;
|
||||
public class SshDaemon extends SshServer implements SshInfo {
|
||||
private static final int DEFAULT_PORT = 29418;
|
||||
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(SshDaemon.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(SshDaemon.class);
|
||||
|
||||
private static String format(final SocketAddress addr) {
|
||||
if (addr instanceof InetSocketAddress) {
|
||||
@@ -132,7 +127,8 @@ public class SshDaemon extends SshServer implements SshInfo {
|
||||
|
||||
@Inject
|
||||
SshDaemon(final GerritServer srv, final CommandFactory commandFactory,
|
||||
final PublickeyAuthenticator userAuth, @SitePath final File sitePath,
|
||||
final PublickeyAuthenticator userAuth,
|
||||
final KeyPairProvider hostKeyProvider,
|
||||
@GerritServerConfig final Config cfg) {
|
||||
setPort(22/* never used */);
|
||||
|
||||
@@ -151,7 +147,7 @@ public class SshDaemon extends SshServer implements SshInfo {
|
||||
initChannels();
|
||||
initCompression();
|
||||
initUserAuth(userAuth);
|
||||
setKeyPairProvider(initHostKey(sitePath));
|
||||
setKeyPairProvider(hostKeyProvider);
|
||||
setCommandFactory(commandFactory);
|
||||
setShellFactory(new NoShell());
|
||||
setSessionFactory(new SessionFactory() {
|
||||
@@ -481,38 +477,4 @@ public class SshDaemon extends SshServer implements SshInfo {
|
||||
.<NamedFactory<UserAuth>> asList(new UserAuthPublicKey.Factory()));
|
||||
setPublickeyAuthenticator(pubkey);
|
||||
}
|
||||
|
||||
private KeyPairProvider initHostKey(final File sitePath) {
|
||||
final File anyKey = new File(sitePath, "ssh_host_key");
|
||||
final File rsaKey = new File(sitePath, "ssh_host_rsa_key");
|
||||
final File dsaKey = new File(sitePath, "ssh_host_dsa_key");
|
||||
|
||||
final List<String> keys = new ArrayList<String>(2);
|
||||
if (rsaKey.exists()) {
|
||||
keys.add(rsaKey.getAbsolutePath());
|
||||
}
|
||||
if (dsaKey.exists()) {
|
||||
keys.add(dsaKey.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (anyKey.exists() && !keys.isEmpty()) {
|
||||
// If both formats of host key exist, we don't know which format
|
||||
// should be authoritative. Complain and abort.
|
||||
//
|
||||
keys.add(anyKey.getAbsolutePath());
|
||||
throw new IllegalStateException("Multiple host keys exist: " + keys);
|
||||
}
|
||||
|
||||
if (keys.isEmpty()) {
|
||||
// No administrator created host key? Generate and save our own.
|
||||
//
|
||||
final SimpleGeneratorHostKeyProvider keyp;
|
||||
|
||||
keyp = new SimpleGeneratorHostKeyProvider();
|
||||
keyp.setPath(anyKey.getAbsolutePath());
|
||||
return keyp;
|
||||
}
|
||||
|
||||
return new FileKeyPairProvider(keys.toArray(new String[keys.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.google.inject.Provider;
|
||||
import com.google.inject.servlet.RequestScoped;
|
||||
import com.google.inject.servlet.SessionScoped;
|
||||
|
||||
import org.apache.sshd.common.KeyPairProvider;
|
||||
import org.apache.sshd.common.session.AbstractSession;
|
||||
import org.apache.sshd.server.CommandFactory;
|
||||
import org.apache.sshd.server.PublickeyAuthenticator;
|
||||
@@ -54,6 +55,7 @@ public class SshModule extends FactoryModule {
|
||||
bind(CommandFactory.class).toProvider(CommandFactoryProvider.class);
|
||||
|
||||
bind(PublickeyAuthenticator.class).to(DatabasePubKeyAuth.class);
|
||||
bind(KeyPairProvider.class).toProvider(HostKeyProvider.class).in(SINGLETON);
|
||||
|
||||
install(new DefaultCommandModule());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user