summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.ssh.apache
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2021-09-09 14:41:30 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2021-09-13 23:53:34 +0200
commita19494b735528b6eb678ac9dbc6a92b8db8560ab (patch)
tree29df569134d27876ad3b32a8f3f6daf4dffde5b5 /org.eclipse.jgit.ssh.apache
parentb9653ccdad437c5449f8eaf0c4e9cfdd2afe4519 (diff)
parenta3a8de310847963bd8fadba33de17abd974ae710 (diff)
downloadjgit-a19494b735528b6eb678ac9dbc6a92b8db8560ab.tar.gz
jgit-a19494b735528b6eb678ac9dbc6a92b8db8560ab.zip
Merge branch 'master' into next
* master: (38 commits) Revert "DFS block cache: Refactor to enable parallel index loading" GitServlet: allow to override default error handlers Silence API error for new interface method ProtocolV2Hook#onObjectInfo transport: add object-info capability Ignore IllegalStateException if JVM is already shutting down Update orbit to R20210825222808 for 2021-09 Update spotbugs-maven-plugin to 4.3.0 Update ant to 1.10.11 also in pom.xml DFS block cache: add additional stats to DfsReaderIoStats Update Orbit to S20210817231813 [gpg] Better GPG home directory determination FS: cleanup use of final modifier Ensure FS#searchPath only selects executable files RevWalk: getMergedInto's result is wrong on the second call DFS block cache: Refactor to enable parallel index loading [test] Create keystore with the keytool of the running JDK [gpg] Update to Bouncy Castle 1.69 [test] Create keystore with the keytool of the running JDK [sshd] Minor code clean-up Support commit.template config property ... Change-Id: I9f99e9a513a23c0c0d252334e79c351512d7355e
Diffstat (limited to 'org.eclipse.jgit.ssh.apache')
-rw-r--r--org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF94
-rw-r--r--org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties1
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java214
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java163
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java218
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java20
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java25
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java1
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java4
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java2
10 files changed, 259 insertions, 483 deletions
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 89b5133afc..03b0462711 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -33,53 +33,53 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.0.0";x-inter
org.apache.sshd.client.session,
org.apache.sshd.client.keyverifier"
Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
- org.apache.sshd.agent;version="[2.6.0,2.7.0)",
- org.apache.sshd.client;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.auth;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.auth.keyboard;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.auth.password;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.auth.pubkey;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.channel;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.config.keys;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.future;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.keyverifier;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.session;version="[2.6.0,2.7.0)",
- org.apache.sshd.client.session.forward;version="[2.6.0,2.7.0)",
- org.apache.sshd.common;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.auth;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.channel;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.compression;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.config.keys.loader;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.digest;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.forward;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.future;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.io;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.kex;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.kex.extension;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.kex.extension.parser;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.mac;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.random;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.session;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.session.helpers;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.signature;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.closeable;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.io;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.io.resource;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)",
- org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)",
- org.apache.sshd.core;version="[2.6.0,2.7.0)",
- org.apache.sshd.server.auth;version="[2.6.0,2.7.0)",
- org.apache.sshd.sftp;version="[2.6.0,2.7.0)",
- org.apache.sshd.sftp.client;version="[2.6.0,2.7.0)",
- org.apache.sshd.sftp.common;version="[2.6.0,2.7.0)",
+ org.apache.sshd.agent;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.auth;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.auth.keyboard;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.auth.password;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.auth.pubkey;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.channel;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.config.hosts;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.config.keys;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.future;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.keyverifier;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.session;version="[2.7.0,2.8.0)",
+ org.apache.sshd.client.session.forward;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.auth;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.channel;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.compression;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.config.keys;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.config.keys.loader;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.digest;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.forward;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.future;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.helpers;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.io;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.kex;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.kex.extension;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.kex.extension.parser;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.keyprovider;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.mac;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.random;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.session;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.session.helpers;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.signature;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.buffer;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.closeable;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.io;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.io.resource;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.logging;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.net;version="[2.7.0,2.8.0)",
+ org.apache.sshd.common.util.security;version="[2.7.0,2.8.0)",
+ org.apache.sshd.core;version="[2.7.0,2.8.0)",
+ org.apache.sshd.server.auth;version="[2.7.0,2.8.0)",
+ org.apache.sshd.sftp;version="[2.7.0,2.8.0)",
+ org.apache.sshd.sftp.client;version="[2.7.0,2.8.0)",
+ org.apache.sshd.sftp.common;version="[2.7.0,2.8.0)",
org.eclipse.jgit.annotations;version="[6.0.0,6.1.0)",
org.eclipse.jgit.errors;version="[6.0.0,6.1.0)",
org.eclipse.jgit.fnmatch;version="[6.0.0,6.1.0)",
diff --git a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
index 5bc0867674..defcbdcfc1 100644
--- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
+++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
@@ -8,6 +8,7 @@ configInvalidProxyJump=Ssh config, host ''{0}'': Cannot parse ProxyJump ''{1}''
configNoKnownAlgorithms=Ssh config ''{0}'' ''{1}'' resulted in empty list (none known, or all known removed); using default.
configProxyJumpNotSsh=Non-ssh URI in ProxyJump ssh config
configProxyJumpWithPath=ProxyJump ssh config: jump host specification must not have a path
+configUnknownAlgorithm=Ssh config {0}: ignoring unknown algorithm ''{1}'' in {2} {3}
ftpCloseFailed=Closing the SFTP channel failed
gssapiFailure=GSS-API error for mechanism OID {0}
gssapiInitFailure=GSS-API initialization failure for mechanism {0}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
index f9e80121ed..f7b37d7816 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018, 2019 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -16,7 +16,6 @@ import java.io.IOException;
import java.io.StreamCorruptedException;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collection;
@@ -29,17 +28,27 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import org.apache.sshd.client.ClientBuilder;
import org.apache.sshd.client.ClientFactoryManager;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.client.session.ClientSessionImpl;
import org.apache.sshd.common.AttributeRepository;
import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.kex.BuiltinDHFactories;
+import org.apache.sshd.common.kex.DHFactory;
import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.kex.KeyExchangeFactory;
+import org.apache.sshd.common.kex.extension.KexExtensionHandler;
+import org.apache.sshd.common.kex.extension.KexExtensionHandler.AvailabilityPhase;
+import org.apache.sshd.common.kex.extension.KexExtensions;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.signature.BuiltinSignatures;
import org.apache.sshd.common.util.Readable;
import org.apache.sshd.common.util.buffer.Buffer;
import org.eclipse.jgit.errors.InvalidPatternException;
@@ -70,6 +79,8 @@ public class JGitClientSession extends ClientSessionImpl {
*/
private static final int DEFAULT_MAX_IDENTIFICATION_SIZE = 64 * 1024;
+ private static final AttributeKey<Boolean> INITIAL_KEX_DONE = new AttributeKey<>();
+
private HostConfigEntry hostConfig;
private CredentialsProvider credentialsProvider;
@@ -136,51 +147,38 @@ public class JGitClientSession extends ClientSessionImpl {
}
@Override
- protected IoWriteFuture sendIdentification(String ident)
- throws IOException {
+ protected IoWriteFuture sendIdentification(String ident,
+ List<String> extraLines) throws Exception {
StatefulProxyConnector proxy = proxyHandler;
if (proxy != null) {
- try {
- // We must not block here; the framework starts reading messages
- // from the peer only once the initial sendKexInit() following
- // this call to sendIdentification() has returned!
- proxy.runWhenDone(() -> {
- JGitClientSession.super.sendIdentification(ident);
- return null;
- });
- // Called only from the ClientSessionImpl constructor, where the
- // return value is ignored.
+ // We must not block here; the framework starts reading messages
+ // from the peer only once the initial sendKexInit() following
+ // this call to sendIdentification() has returned!
+ proxy.runWhenDone(() -> {
+ JGitClientSession.super.sendIdentification(ident, extraLines);
return null;
- } catch (IOException e) {
- throw e;
- } catch (Exception other) {
- throw new IOException(other.getLocalizedMessage(), other);
- }
+ });
+ // Called only from the ClientSessionImpl constructor, where the
+ // return value is ignored.
+ return null;
}
- return super.sendIdentification(ident);
+ return super.sendIdentification(ident, extraLines);
}
@Override
- protected byte[] sendKexInit()
- throws IOException, GeneralSecurityException {
+ protected byte[] sendKexInit() throws Exception {
StatefulProxyConnector proxy = proxyHandler;
if (proxy != null) {
- try {
- // We must not block here; the framework starts reading messages
- // from the peer only once the initial sendKexInit() has
- // returned!
- proxy.runWhenDone(() -> {
- JGitClientSession.super.sendKexInit();
- return null;
- });
- // This is called only from the ClientSessionImpl
- // constructor, where the return value is ignored.
+ // We must not block here; the framework starts reading messages
+ // from the peer only once the initial sendKexInit() has
+ // returned!
+ proxy.runWhenDone(() -> {
+ JGitClientSession.super.sendKexInit();
return null;
- } catch (IOException | GeneralSecurityException e) {
- throw e;
- } catch (Exception other) {
- throw new IOException(other.getLocalizedMessage(), other);
- }
+ });
+ // This is called only from the ClientSessionImpl
+ // constructor, where the return value is ignored.
+ return null;
}
return super.sendKexInit();
}
@@ -219,6 +217,32 @@ public class JGitClientSession extends ClientSessionImpl {
return result;
}
+ Set<String> getAllAvailableSignatureAlgorithms() {
+ Set<String> allAvailable = new HashSet<>();
+ BuiltinSignatures.VALUES.forEach(s -> allAvailable.add(s.getName()));
+ BuiltinSignatures.getRegisteredExtensions()
+ .forEach(s -> allAvailable.add(s.getName()));
+ return allAvailable;
+ }
+
+ private void setNewFactories(Collection<String> defaultFactories,
+ Collection<String> finalFactories) {
+ // If new factory names were added make sure we actually have factories
+ // for them all.
+ //
+ // But add new ones at the end: we don't want to change the order for
+ // pubkey auth, and any new ones added here were not included in the
+ // default set for some reason, such as being deprecated or weak.
+ //
+ // The order for KEX is determined by the order in the proposal string,
+ // but the order in pubkey auth is determined by the order in the
+ // factory list (possibly overridden via ssh config
+ // PubkeyAcceptedAlgorithms; see JGitPublicKeyAuthentication).
+ Set<String> resultSet = new LinkedHashSet<>(defaultFactories);
+ resultSet.addAll(finalFactories);
+ setSignatureFactoriesNames(resultSet);
+ }
+
@Override
protected String resolveAvailableSignaturesProposal(
FactoryManager manager) {
@@ -229,16 +253,17 @@ public class JGitClientSession extends ClientSessionImpl {
.getProperty(SshConstants.HOST_KEY_ALGORITHMS);
if (!StringUtils.isEmptyOrNull(algorithms)) {
List<String> result = modifyAlgorithmList(defaultSignatures,
- algorithms, SshConstants.HOST_KEY_ALGORITHMS);
+ getAllAvailableSignatureAlgorithms(), algorithms,
+ SshConstants.HOST_KEY_ALGORITHMS);
if (!result.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug(SshConstants.HOST_KEY_ALGORITHMS + ' ' + result);
}
+ setNewFactories(defaultSignatures, result);
return String.join(",", result); //$NON-NLS-1$
}
log.warn(format(SshdText.get().configNoKnownAlgorithms,
- SshConstants.HOST_KEY_ALGORITHMS,
- algorithms));
+ SshConstants.HOST_KEY_ALGORITHMS, algorithms));
}
// No HostKeyAlgorithms; using default -- change order to put existing
// keys first.
@@ -253,6 +278,11 @@ public class JGitClientSession extends ClientSessionImpl {
if (key != null) {
String keyType = KeyUtils.getKeyType(key);
if (keyType != null) {
+ if (KeyPairProvider.SSH_RSA.equals(keyType)) {
+ // Add all available signatures for ssh-rsa.
+ reordered.add(KeyUtils.RSA_SHA512_KEY_TYPE_ALIAS);
+ reordered.add(KeyUtils.RSA_SHA256_KEY_TYPE_ALIAS);
+ }
reordered.add(keyType);
}
}
@@ -261,6 +291,10 @@ public class JGitClientSession extends ClientSessionImpl {
if (log.isDebugEnabled()) {
log.debug(SshConstants.HOST_KEY_ALGORITHMS + ' ' + reordered);
}
+ // Make sure we actually have factories for them all.
+ if (reordered.size() > defaultSignatures.size()) {
+ setNewFactories(defaultSignatures, reordered);
+ }
return String.join(",", reordered); //$NON-NLS-1$
}
if (log.isDebugEnabled()) {
@@ -270,15 +304,87 @@ public class JGitClientSession extends ClientSessionImpl {
return String.join(",", defaultSignatures); //$NON-NLS-1$
}
+ private List<String> determineKexProposal() {
+ List<KeyExchangeFactory> kexFactories = getKeyExchangeFactories();
+ List<String> defaultKexMethods = NamedResource
+ .getNameList(kexFactories);
+ HostConfigEntry config = resolveAttribute(
+ JGitSshClient.HOST_CONFIG_ENTRY);
+ String algorithms = config.getProperty(SshConstants.KEX_ALGORITHMS);
+ if (!StringUtils.isEmptyOrNull(algorithms)) {
+ Set<String> allAvailable = new HashSet<>();
+ BuiltinDHFactories.VALUES
+ .forEach(s -> allAvailable.add(s.getName()));
+ BuiltinDHFactories.getRegisteredExtensions()
+ .forEach(s -> allAvailable.add(s.getName()));
+ List<String> result = modifyAlgorithmList(defaultKexMethods,
+ allAvailable, algorithms, SshConstants.KEX_ALGORITHMS);
+ if (!result.isEmpty()) {
+ // If new ones were added, update the installed factories
+ Set<String> configuredKexMethods = new HashSet<>(
+ defaultKexMethods);
+ List<KeyExchangeFactory> newKexFactories = new ArrayList<>();
+ result.forEach(name -> {
+ if (!configuredKexMethods.contains(name)) {
+ DHFactory factory = BuiltinDHFactories
+ .resolveFactory(name);
+ if (factory == null) {
+ // Should not occur here
+ if (log.isDebugEnabled()) {
+ log.debug(
+ "determineKexProposal({}) unknown KEX algorithm {} ignored", //$NON-NLS-1$
+ this, name);
+ }
+ } else {
+ newKexFactories
+ .add(ClientBuilder.DH2KEX.apply(factory));
+ }
+ }
+ });
+ if (!newKexFactories.isEmpty()) {
+ newKexFactories.addAll(kexFactories);
+ setKeyExchangeFactories(newKexFactories);
+ }
+ return result;
+ }
+ log.warn(format(SshdText.get().configNoKnownAlgorithms,
+ SshConstants.KEX_ALGORITHMS, algorithms));
+ }
+ return defaultKexMethods;
+ }
+
+ @Override
+ protected String resolveSessionKexProposal(String hostKeyTypes)
+ throws IOException {
+ String kexMethods = String.join(",", determineKexProposal()); //$NON-NLS-1$
+ Boolean isRekey = getAttribute(INITIAL_KEX_DONE);
+ if (isRekey == null || !isRekey.booleanValue()) {
+ // First time
+ KexExtensionHandler extHandler = getKexExtensionHandler();
+ if (extHandler != null && extHandler.isKexExtensionsAvailable(this,
+ AvailabilityPhase.PROPOSAL)) {
+ if (kexMethods.isEmpty()) {
+ kexMethods = KexExtensions.CLIENT_KEX_EXTENSION;
+ } else {
+ kexMethods += ',' + KexExtensions.CLIENT_KEX_EXTENSION;
+ }
+ }
+ setAttribute(INITIAL_KEX_DONE, Boolean.TRUE);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(SshConstants.KEX_ALGORITHMS + ' ' + kexMethods);
+ }
+ return kexMethods;
+ }
+
/**
* Modifies a given algorithm list according to a list from the ssh config,
- * including remove ('-') and reordering ('^') operators. Addition ('+') is
- * not handled since we have no way of adding dynamically implementations,
- * and the defaultList is supposed to contain all known implementations
- * already.
+ * including add ('+'), remove ('-') and reordering ('^') operators.
*
* @param defaultList
* to modify
+ * @param allAvailable
+ * all available values
* @param fromConfig
* telling how to modify the {@code defaultList}, must not be
* {@code null} or empty
@@ -288,22 +394,22 @@ public class JGitClientSession extends ClientSessionImpl {
* set
*/
public List<String> modifyAlgorithmList(List<String> defaultList,
- String fromConfig, String overrideKey) {
+ Set<String> allAvailable, String fromConfig, String overrideKey) {
Set<String> defaults = new LinkedHashSet<>();
defaults.addAll(defaultList);
switch (fromConfig.charAt(0)) {
case '+':
- // Additions make not much sense -- it's either in
- // defaultList already, or we have no implementation for
- // it. No point in proposing it.
- return defaultList;
+ List<String> newSignatures = filteredList(allAvailable, overrideKey,
+ fromConfig.substring(1));
+ defaults.addAll(newSignatures);
+ return new ArrayList<>(defaults);
case '-':
// This takes wildcard patterns!
removeFromList(defaults, overrideKey, fromConfig.substring(1));
return new ArrayList<>(defaults);
case '^':
// Specified entries go to the front of the default list
- List<String> allSignatures = filteredList(defaults,
+ List<String> allSignatures = filteredList(allAvailable, overrideKey,
fromConfig.substring(1));
Set<String> atFront = new HashSet<>(allSignatures);
for (String sig : defaults) {
@@ -315,7 +421,7 @@ public class JGitClientSession extends ClientSessionImpl {
default:
// Default is overridden -- only accept the ones for which we do
// have an implementation.
- return filteredList(defaults, fromConfig);
+ return filteredList(allAvailable, overrideKey, fromConfig);
}
}
@@ -342,11 +448,15 @@ public class JGitClientSession extends ClientSessionImpl {
}
}
- private List<String> filteredList(Set<String> known, String values) {
+ private List<String> filteredList(Set<String> known, String key,
+ String values) {
List<String> newNames = new ArrayList<>();
for (String newValue : values.split("\\s*,\\s*")) { //$NON-NLS-1$
if (known.contains(newValue)) {
newNames.add(newValue);
+ } else {
+ log.warn(format(SshdText.get().configUnknownAlgorithm, this,
+ newValue, key, values));
}
}
return newNames;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java
deleted file mode 100644
index 9446aaa7d6..0000000000
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-package org.eclipse.jgit.internal.transport.sshd;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.sshd.common.AttributeRepository.AttributeKey;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.kex.KexProposalOption;
-import org.apache.sshd.common.kex.extension.KexExtensionHandler;
-import org.apache.sshd.common.kex.extension.KexExtensions;
-import org.apache.sshd.common.kex.extension.parser.ServerSignatureAlgorithms;
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.signature.Signature;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-import org.eclipse.jgit.util.StringUtils;
-
-/**
- * Do not use the DefaultClientKexExtensionHandler from sshd; it doesn't work
- * properly because of misconceptions. See SSHD-1141.
- *
- * @see <a href="https://issues.apache.org/jira/browse/SSHD-1141">SSHD-1141</a>
- */
-public class JGitKexExtensionHandler extends AbstractLoggingBean
- implements KexExtensionHandler {
-
- /** Singleton instance. */
- public static final JGitKexExtensionHandler INSTANCE = new JGitKexExtensionHandler();
-
- /**
- * Session {@link AttributeKey} used to store whether the extension
- * indicator was already sent.
- */
- private static final AttributeKey<Boolean> CLIENT_PROPOSAL_MADE = new AttributeKey<>();
-
- /**
- * Session {@link AttributeKey} storing the algorithms announced by the
- * server as known.
- */
- public static final AttributeKey<Set<String>> SERVER_ALGORITHMS = new AttributeKey<>();
-
- private JGitKexExtensionHandler() {
- // No public instantiation for singleton
- }
-
- @Override
- public boolean isKexExtensionsAvailable(Session session,
- AvailabilityPhase phase) throws IOException {
- return !AvailabilityPhase.PREKEX.equals(phase);
- }
-
- @Override
- public void handleKexInitProposal(Session session, boolean initiator,
- Map<KexProposalOption, String> proposal) throws IOException {
- // If it's the very first time, we may add the marker telling the server
- // that we are ready to handle SSH_MSG_EXT_INFO
- if (session == null || session.isServerSession() || !initiator) {
- return;
- }
- if (session.getAttribute(CLIENT_PROPOSAL_MADE) != null) {
- return;
- }
- String kexAlgorithms = proposal.get(KexProposalOption.SERVERKEYS);
- if (StringUtils.isEmptyOrNull(kexAlgorithms)) {
- return;
- }
- List<String> algorithms = new ArrayList<>();
- // We're a client. We mustn't send the server extension, and we should
- // send the client extension only once.
- for (String algo : kexAlgorithms.split(",")) { //$NON-NLS-1$
- if (KexExtensions.CLIENT_KEX_EXTENSION.equalsIgnoreCase(algo)
- || KexExtensions.SERVER_KEX_EXTENSION
- .equalsIgnoreCase(algo)) {
- continue;
- }
- algorithms.add(algo);
- }
- // Tell the server that we want to receive SSH2_MSG_EXT_INFO
- algorithms.add(KexExtensions.CLIENT_KEX_EXTENSION);
- if (log.isDebugEnabled()) {
- log.debug(
- "handleKexInitProposal({}): proposing HostKeyAlgorithms {}", //$NON-NLS-1$
- session, algorithms);
- }
- proposal.put(KexProposalOption.SERVERKEYS,
- String.join(",", algorithms)); //$NON-NLS-1$
- session.setAttribute(CLIENT_PROPOSAL_MADE, Boolean.TRUE);
- }
-
- @Override
- public boolean handleKexExtensionRequest(Session session, int index,
- int count, String name, byte[] data) throws IOException {
- if (ServerSignatureAlgorithms.NAME.equals(name)) {
- handleServerSignatureAlgorithms(session,
- ServerSignatureAlgorithms.INSTANCE.parseExtension(data));
- }
- return true;
- }
-
- /**
- * Perform updates after a server-sig-algs extension has been received.
- *
- * @param session
- * the message was received for
- * @param serverAlgorithms
- * signature algorithm names announced by the server
- */
- protected void handleServerSignatureAlgorithms(Session session,
- Collection<String> serverAlgorithms) {
- if (log.isDebugEnabled()) {
- log.debug("handleServerSignatureAlgorithms({}): {}", session, //$NON-NLS-1$
- serverAlgorithms);
- }
- // Client determines order; server says what it supports. Re-order
- // such that supported ones are at the front, in client order,
- // followed by unsupported ones, also in client order.
- if (serverAlgorithms != null && !serverAlgorithms.isEmpty()) {
- List<NamedFactory<Signature>> clientAlgorithms = new ArrayList<>(
- session.getSignatureFactories());
- if (log.isDebugEnabled()) {
- log.debug(
- "handleServerSignatureAlgorithms({}): PubkeyAcceptedAlgorithms before: {}", //$NON-NLS-1$
- session, clientAlgorithms);
- }
- List<NamedFactory<Signature>> unknown = new ArrayList<>();
- Set<String> known = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
- known.addAll(serverAlgorithms);
- for (Iterator<NamedFactory<Signature>> iter = clientAlgorithms
- .iterator(); iter.hasNext();) {
- NamedFactory<Signature> algo = iter.next();
- if (!known.contains(algo.getName())) {
- unknown.add(algo);
- iter.remove();
- }
- }
- // Re-add the unknown ones at the end. Per RFC 8308, some
- // servers may not announce _all_ their supported algorithms,
- // and a client may use unknown algorithms.
- clientAlgorithms.addAll(unknown);
- if (log.isDebugEnabled()) {
- log.debug(
- "handleServerSignatureAlgorithms({}): PubkeyAcceptedAlgorithms after: {}", //$NON-NLS-1$
- session, clientAlgorithms);
- }
- session.setAttribute(SERVER_ALGORITHMS, known);
- session.setSignatureFactories(clientAlgorithms);
- }
- }
-}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
index 6755094420..08da18f5aa 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
@@ -9,216 +9,56 @@
*/
package org.eclipse.jgit.internal.transport.sshd;
-import java.io.IOException;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.text.MessageFormat;
-import java.util.Deque;
-import java.util.HashSet;
-import java.util.LinkedList;
+import static java.text.MessageFormat.format;
+import static org.eclipse.jgit.transport.SshConstants.PUBKEY_ACCEPTED_ALGORITHMS;
+
import java.util.List;
-import java.util.Set;
import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey;
+import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.RuntimeSshException;
-import org.apache.sshd.common.SshConstants;
-import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.signature.Signature;
-import org.apache.sshd.common.signature.SignatureFactoriesHolder;
-import org.apache.sshd.common.util.buffer.Buffer;
+import org.eclipse.jgit.util.StringUtils;
/**
- * Custom {@link UserAuthPublicKey} implementation fixing SSHD-1105: if there
- * are several signature algorithms applicable for a public key type, we must
- * try them all, in the correct order.
- *
- * @see <a href="https://issues.apache.org/jira/browse/SSHD-1105">SSHD-1105</a>
- * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572056">Bug
- * 572056</a>
+ * Custom {@link UserAuthPublicKey} implementation for handling SSH config
+ * PubkeyAcceptedAlgorithms.
*/
public class JGitPublicKeyAuthentication extends UserAuthPublicKey {
- private final Deque<String> currentAlgorithms = new LinkedList<>();
-
- private String chosenAlgorithm;
-
JGitPublicKeyAuthentication(List<NamedFactory<Signature>> factories) {
super(factories);
}
@Override
- protected boolean sendAuthDataRequest(ClientSession session, String service)
+ public void init(ClientSession rawSession, String service)
throws Exception {
- if (current == null) {
- currentAlgorithms.clear();
- chosenAlgorithm = null;
- }
- String currentAlgorithm = null;
- if (current != null && !currentAlgorithms.isEmpty()) {
- currentAlgorithm = currentAlgorithms.poll();
- if (chosenAlgorithm != null) {
- Set<String> knownServerAlgorithms = session.getAttribute(
- JGitKexExtensionHandler.SERVER_ALGORITHMS);
- if (knownServerAlgorithms != null
- && knownServerAlgorithms.contains(chosenAlgorithm)) {
- // We've tried key 'current' with 'chosenAlgorithm', but it
- // failed. However, the server had told us it supported
- // 'chosenAlgorithm'. Thus it makes no sense to continue
- // with this key and other signature algorithms. Skip to the
- // next key, if any.
- currentAlgorithm = null;
- }
- }
+ if (!(rawSession instanceof JGitClientSession)) {
+ throw new IllegalStateException("Wrong session type: " //$NON-NLS-1$
+ + rawSession.getClass().getCanonicalName());
}
- if (currentAlgorithm == null) {
- try {
- if (keys == null || !keys.hasNext()) {
- if (log.isDebugEnabled()) {
- log.debug(
- "sendAuthDataRequest({})[{}] no more keys to send", //$NON-NLS-1$
- session, service);
- }
- current = null;
- return false;
- }
- current = keys.next();
- currentAlgorithms.clear();
- chosenAlgorithm = null;
- } catch (Error e) { // Copied from superclass
- throw new RuntimeSshException(e);
- }
- }
- PublicKey key;
- try {
- key = current.getPublicKey();
- } catch (Error e) { // Copied from superclass
- throw new RuntimeSshException(e);
- }
- if (currentAlgorithm == null) {
- String keyType = KeyUtils.getKeyType(key);
- Set<String> aliases = new HashSet<>(
- KeyUtils.getAllEquivalentKeyTypes(keyType));
- aliases.add(keyType);
- List<NamedFactory<Signature>> existingFactories;
- if (current instanceof SignatureFactoriesHolder) {
- existingFactories = ((SignatureFactoriesHolder) current)
- .getSignatureFactories();
- } else {
- existingFactories = getSignatureFactories();
- }
- if (existingFactories != null) {
+ JGitClientSession session = ((JGitClientSession) rawSession);
+ HostConfigEntry hostConfig = session.getHostConfigEntry();
+ // Set signature algorithms for public key authentication
+ String pubkeyAlgos = hostConfig.getProperty(PUBKEY_ACCEPTED_ALGORITHMS);
+ if (!StringUtils.isEmptyOrNull(pubkeyAlgos)) {
+ List<String> signatures = session.getSignatureFactoriesNames();
+ signatures = session.modifyAlgorithmList(signatures,
+ session.getAllAvailableSignatureAlgorithms(), pubkeyAlgos,
+ PUBKEY_ACCEPTED_ALGORITHMS);
+ if (!signatures.isEmpty()) {
if (log.isDebugEnabled()) {
- log.debug(
- "sendAuthDataRequest({})[{}] selecting from PubKeyAcceptedAlgorithms {}", //$NON-NLS-1$
- session, service,
- NamedResource.getNames(existingFactories));
+ log.debug(PUBKEY_ACCEPTED_ALGORITHMS + ' ' + signatures);
}
- // Select the factories by name and in order
- existingFactories.forEach(f -> {
- if (aliases.contains(f.getName())) {
- currentAlgorithms.add(f.getName());
- }
- });
+ setSignatureFactoriesNames(signatures);
+ } else {
+ log.warn(format(SshdText.get().configNoKnownAlgorithms,
+ PUBKEY_ACCEPTED_ALGORITHMS, pubkeyAlgos));
}
- currentAlgorithm = currentAlgorithms.isEmpty() ? keyType
- : currentAlgorithms.poll();
}
- String name = getName();
- if (log.isDebugEnabled()) {
- log.debug(
- "sendAuthDataRequest({})[{}] send SSH_MSG_USERAUTH_REQUEST request {} type={} - fingerprint={}", //$NON-NLS-1$
- session, service, name, currentAlgorithm,
- KeyUtils.getFingerPrint(key));
- }
-
- chosenAlgorithm = currentAlgorithm;
- Buffer buffer = session
- .createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST);
- buffer.putString(session.getUsername());
- buffer.putString(service);
- buffer.putString(name);
- buffer.putBoolean(false);
- buffer.putString(currentAlgorithm);
- buffer.putPublicKey(key);
- session.writePacket(buffer);
- return true;
- }
-
- @Override
- protected boolean processAuthDataRequest(ClientSession session,
- String service, Buffer buffer) throws Exception {
- String name = getName();
- int cmd = buffer.getUByte();
- if (cmd != SshConstants.SSH_MSG_USERAUTH_PK_OK) {
- throw new IllegalStateException(MessageFormat.format(
- SshdText.get().pubkeyAuthWrongCommand,
- SshConstants.getCommandMessageName(cmd),
- session.getConnectAddress(), session.getServerVersion()));
- }
- PublicKey key;
- try {
- key = current.getPublicKey();
- } catch (Error e) { // Copied from superclass
- throw new RuntimeSshException(e);
- }
- String rspKeyAlgorithm = buffer.getString();
- PublicKey rspKey = buffer.getPublicKey();
- if (log.isDebugEnabled()) {
- log.debug(
- "processAuthDataRequest({})[{}][{}] SSH_MSG_USERAUTH_PK_OK type={}, fingerprint={}", //$NON-NLS-1$
- session, service, name, rspKeyAlgorithm,
- KeyUtils.getFingerPrint(rspKey));
- }
- if (!KeyUtils.compareKeys(rspKey, key)) {
- throw new InvalidKeySpecException(MessageFormat.format(
- SshdText.get().pubkeyAuthWrongKey,
- KeyUtils.getFingerPrint(key),
- KeyUtils.getFingerPrint(rspKey),
- session.getConnectAddress(), session.getServerVersion()));
- }
- if (!chosenAlgorithm.equalsIgnoreCase(rspKeyAlgorithm)) {
- // 'algo' SHOULD be the same as 'chosenAlgorithm', which is the one
- // we sent above. See https://tools.ietf.org/html/rfc4252#page-9 .
- //
- // However, at least Github (SSH-2.0-babeld-383743ad) servers seem
- // to return the key type, not the algorithm name.
- //
- // So we don't check but just log the inconsistency. We sign using
- // 'chosenAlgorithm' in any case, so we don't really care what the
- // server says here.
- log.warn(MessageFormat.format(
- SshdText.get().pubkeyAuthWrongSignatureAlgorithm,
- chosenAlgorithm, rspKeyAlgorithm, session.getConnectAddress(),
- session.getServerVersion()));
- }
- String username = session.getUsername();
- Buffer out = session
- .createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST);
- out.putString(username);
- out.putString(service);
- out.putString(name);
- out.putBoolean(true);
- out.putString(chosenAlgorithm);
- out.putPublicKey(key);
- if (log.isDebugEnabled()) {
- log.debug(
- "processAuthDataRequest({})[{}][{}]: signing with algorithm {}", //$NON-NLS-1$
- session, service, name, chosenAlgorithm);
- }
- appendSignature(session, service, name, username, chosenAlgorithm, key,
- out);
- session.writePacket(out);
- return true;
- }
-
- @Override
- protected void releaseKeys() throws IOException {
- currentAlgorithms.clear();
- current = null;
- chosenAlgorithm = null;
- super.releaseKeys();
+ // If we don't set signature factories here, the default ones from the
+ // session will be used.
+ super.init(session, service);
}
}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
index 071e1979d3..ae12c2028d 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -267,24 +267,6 @@ public class JGitSshClient extends SshClient {
session.setUsername(username);
session.setConnectAddress(address);
session.setHostConfigEntry(hostConfig);
- // Set signature algorithms for public key authentication
- String pubkeyAlgos = hostConfig
- .getProperty(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS);
- if (!StringUtils.isEmptyOrNull(pubkeyAlgos)) {
- List<String> signatures = getSignatureFactoriesNames();
- signatures = session.modifyAlgorithmList(signatures, pubkeyAlgos,
- SshConstants.PUBKEY_ACCEPTED_ALGORITHMS);
- if (!signatures.isEmpty()) {
- if (log.isDebugEnabled()) {
- log.debug(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS + ' '
- + signatures);
- }
- session.setSignatureFactoriesNames(signatures);
- } else {
- log.warn(format(SshdText.get().configNoKnownAlgorithms,
- SshConstants.PUBKEY_ACCEPTED_ALGORITHMS, pubkeyAlgos));
- }
- }
if (session.getCredentialsProvider() == null) {
session.setCredentialsProvider(getCredentialsProvider());
}
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 1a530b7743..85e406f422 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018, 2019 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -182,10 +182,13 @@ public class OpenSshServerKeyDatabase
for (HostKeyFile file : filesToUse) {
for (HostEntryPair current : file.get()) {
KnownHostEntry entry = current.getHostEntry();
- for (SshdSocketAddress host : candidates) {
- if (entry.isHostMatch(host.getHostName(), host.getPort())) {
- result.add(current.getServerKey());
- break;
+ if (!isRevoked(entry)) {
+ for (SshdSocketAddress host : candidates) {
+ if (entry.isHostMatch(host.getHostName(),
+ host.getPort())) {
+ result.add(current.getServerKey());
+ break;
+ }
}
}
}
@@ -266,6 +269,10 @@ public class OpenSshServerKeyDatabase
private static final long serialVersionUID = 1L;
}
+ private boolean isRevoked(KnownHostEntry entry) {
+ return MARKER_REVOKED.equals(entry.getMarker());
+ }
+
private boolean find(Collection<SshdSocketAddress> candidates,
PublicKey serverKey, List<HostEntryPair> entries,
HostEntryPair[] modified) throws RevokedKeyException {
@@ -273,22 +280,22 @@ public class OpenSshServerKeyDatabase
KnownHostEntry entry = current.getHostEntry();
for (SshdSocketAddress host : candidates) {
if (entry.isHostMatch(host.getHostName(), host.getPort())) {
- boolean isRevoked = MARKER_REVOKED
- .equals(entry.getMarker());
+ boolean revoked = isRevoked(entry);
if (KeyUtils.compareKeys(serverKey,
current.getServerKey())) {
// Exact match
- if (isRevoked) {
+ if (revoked) {
throw new RevokedKeyException();
}
modified[0] = null;
return true;
- } else if (!isRevoked) {
+ } else if (!revoked) {
// Server sent a different key
modified[0] = current;
// Keep going -- maybe there's another entry for this
// host
}
+ break;
}
}
}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
index 73c2288ccc..c0f5719629 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
@@ -28,6 +28,7 @@ public final class SshdText extends TranslationBundle {
/***/ public String configNoKnownAlgorithms;
/***/ public String configProxyJumpNotSsh;
/***/ public String configProxyJumpWithPath;
+ /***/ public String configUnknownAlgorithm;
/***/ public String ftpCloseFailed;
/***/ public String gssapiFailure;
/***/ public String gssapiInitFailure;
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 b8e6cfd14d..b1b3c1808a 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
@@ -30,7 +30,7 @@ import org.eclipse.jgit.transport.CredentialsProvider;
public interface ServerKeyDatabase {
/**
- * Retrieves all known host keys for the given addresses.
+ * Retrieves all known and not revoked host keys for the given addresses.
*
* @param connectAddress
* IP address the session tried to connect to
@@ -39,7 +39,7 @@ public interface ServerKeyDatabase {
* @param config
* giving access to potentially interesting configuration
* settings
- * @return the list of known keys for the given addresses
+ * @return the list of known and not revoked keys for the given addresses
*/
@NonNull
List<PublicKey> lookup(@NonNull String connectAddress,
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
index 2d7e0c7c77..cad959c904 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
@@ -47,7 +47,6 @@ import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile;
import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException;
import org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider;
import org.eclipse.jgit.internal.transport.sshd.GssApiWithMicAuthFactory;
-import org.eclipse.jgit.internal.transport.sshd.JGitKexExtensionHandler;
import org.eclipse.jgit.internal.transport.sshd.JGitPasswordAuthFactory;
import org.eclipse.jgit.internal.transport.sshd.JGitPublicKeyAuthFactory;
import org.eclipse.jgit.internal.transport.sshd.JGitServerKeyVerifier;
@@ -217,7 +216,6 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
new JGitUserInteraction(credentialsProvider));
client.setUserAuthFactories(getUserAuthFactories());
client.setKeyIdentityProvider(defaultKeysProvider);
- client.setKexExtensionHandler(JGitKexExtensionHandler.INSTANCE);
// JGit-specific things:
JGitSshClient jgitClient = (JGitSshClient) client;
jgitClient.setKeyCache(getKeyCache());