summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.ssh.apache
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2019-06-21 22:39:19 +0200
committerThomas Wolf <thomas.wolf@paranor.ch>2019-09-02 21:30:27 +0200
commit2d34d0bd9c6e5bad80befd42b76d5658de8e0d4d (patch)
tree225681308b2dfbaa2b152ead24430ebe1f4d59cf /org.eclipse.jgit.ssh.apache
parent124fbbc33a05c177767c5f4233717765acb1ab4d (diff)
downloadjgit-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')
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java8
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java48
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java8
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