diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2019-06-21 22:39:19 +0200 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2019-09-02 21:30:27 +0200 |
commit | 2d34d0bd9c6e5bad80befd42b76d5658de8e0d4d (patch) | |
tree | 225681308b2dfbaa2b152ead24430ebe1f4d59cf /org.eclipse.jgit.ssh.apache | |
parent | 124fbbc33a05c177767c5f4233717765acb1ab4d (diff) | |
download | jgit-2d34d0bd9c6e5bad80befd42b76d5658de8e0d4d.tar.gz jgit-2d34d0bd9c6e5bad80befd42b76d5658de8e0d4d.zip |
sshd: support the HashKnownHosts configuration
Add the constant, and implement hashing of known host names in
OpenSshServerKeyDatabase. Add a test verifying that the hashing
works.
Bug: 548492
Change-Id: Iabe82b666da627bd7f4d82519a366d166aa9ddd4
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit.ssh.apache')
3 files changed, 52 insertions, 12 deletions
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java index c1d10bd44a..b94515c157 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java @@ -42,6 +42,8 @@ */ package org.eclipse.jgit.internal.transport.sshd; +import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.flag; + import java.net.InetSocketAddress; import java.net.SocketAddress; import java.security.PublicKey; @@ -175,6 +177,12 @@ public class JGitServerKeyVerifier } @Override + public boolean getHashKnownHosts() { + HostConfigEntry entry = session.getHostConfigEntry(); + return flag(entry.getProperty(SshConstants.HASH_KNOWN_HOSTS)); + } + + @Override public String getUsername() { return session.getUsername(); } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java index e433109687..f4849ce4a3 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java @@ -58,6 +58,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.PublicKey; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -70,15 +71,18 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import org.apache.sshd.client.config.hosts.HostPatternsHolder; +import org.apache.sshd.client.config.hosts.KnownHostDigest; import org.apache.sshd.client.config.hosts.KnownHostEntry; import org.apache.sshd.client.config.hosts.KnownHostHashValue; import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier.HostEntryPair; import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.config.keys.AuthorizedKeyEntry; import org.apache.sshd.common.config.keys.KeyUtils; import org.apache.sshd.common.config.keys.PublicKeyEntry; import org.apache.sshd.common.config.keys.PublicKeyEntryResolver; import org.apache.sshd.common.digest.BuiltinDigests; +import org.apache.sshd.common.mac.Mac; import org.apache.sshd.common.util.io.ModifiableFileWatcher; import org.apache.sshd.common.util.net.SshdSocketAddress; import org.eclipse.jgit.annotations.NonNull; @@ -276,12 +280,13 @@ public class OpenSshServerKeyDatabase try { if (Files.exists(path) || !askAboutNewFile || ask.createNewFile(path)) { - updateKnownHostsFile(candidates, serverKey, path); + updateKnownHostsFile(candidates, serverKey, path, + config); toUpdate.resetReloadAttributes(); } - } catch (IOException e) { + } catch (Exception e) { LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate, - path)); + path), e); } } return true; @@ -342,9 +347,9 @@ public class OpenSshServerKeyDatabase } private void updateKnownHostsFile(Collection<SshdSocketAddress> candidates, - PublicKey serverKey, Path path) - throws IOException { - String newEntry = createHostKeyLine(candidates, serverKey); + PublicKey serverKey, Path path, Configuration config) + throws Exception { + String newEntry = createHostKeyLine(candidates, serverKey, config); if (newEntry == null) { return; } @@ -703,14 +708,33 @@ public class OpenSshServerKeyDatabase } private String createHostKeyLine(Collection<SshdSocketAddress> patterns, - PublicKey key) throws IOException { + PublicKey key, Configuration config) throws Exception { StringBuilder result = new StringBuilder(); - for (SshdSocketAddress address : patterns) { - if (result.length() > 0) { - result.append(','); + if (config.getHashKnownHosts()) { + // SHA1 is the only algorithm for host name hashing known to OpenSSH + // or to Apache MINA sshd. + NamedFactory<Mac> digester = KnownHostDigest.SHA1; + Mac mac = digester.create(); + SecureRandom prng = new SecureRandom(); + byte[] salt = new byte[mac.getDefaultBlockSize()]; + for (SshdSocketAddress address : patterns) { + if (result.length() > 0) { + result.append(','); + } + prng.nextBytes(salt); + KnownHostHashValue.append(result, digester, salt, + KnownHostHashValue.calculateHashValue( + address.getHostName(), address.getPort(), mac, + salt)); + } + } else { + for (SshdSocketAddress address : patterns) { + if (result.length() > 0) { + result.append(','); + } + KnownHostHashValue.appendHostPattern(result, + address.getHostName(), address.getPort()); } - KnownHostHashValue.appendHostPattern(result, address.getHostName(), - address.getPort()); } result.append(' '); PublicKeyEntry.appendPublicKeyEntry(result, key); diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java index ce58d9518b..bdfb96d0c7 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java @@ -159,6 +159,14 @@ public interface ServerKeyDatabase { StrictHostKeyChecking getStrictHostKeyChecking(); /** + * Obtains the value of the "HashKnownHosts" ssh config. + * + * @return {@code true} if new entries should be stored with hashed host + * information, {@code false} otherwise + */ + boolean getHashKnownHosts(); + + /** * Obtains the user name used in the connection attempt. * * @return the user name |