diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2021-05-11 09:04:52 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2021-07-06 13:22:38 +0200 |
commit | 66c9c7bf876bd81ebf57a769f14f5403861f83db (patch) | |
tree | 72cbe6dc03e52ce10ceab15e335a0d5a0465d3a8 /org.eclipse.jgit.ssh.apache/src/org | |
parent | 1c6bd377ffd39a9473a54012ba8f515e55ee1709 (diff) | |
download | jgit-66c9c7bf876bd81ebf57a769f14f5403861f83db.tar.gz jgit-66c9c7bf876bd81ebf57a769f14f5403861f83db.zip |
Update target platform to I20210626190330
Update
- com.google.gson to 2.8.7.v20210624-1215
- javaewah to 1.1.12.v20210622-2206
- org.apache.sshd.osgi to 2.7.0.v20210623-0618
- org.apache.sshd.sftp to 2.7.0.v20210623-0618
- org.tukaani.xz to 1.9.0.v20210624-1259
- Apache MINA sshd to 2.7.0
- Remove work-arounds for problems resolved upstream since 2.6.0, and
adapt to upstream API changes.
- update DEPENDENCIES.
CQ: 23469
CQ: 23470
CQ: 23496
CQ: 23497
CQ: 23498
Bug: 574220
Change-Id: I898b216c3492f8488fbf25fa4b49f1250f86f3c8
Also-by: David Ostrovsky <david@ostrovsky.org>
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit.ssh.apache/src/org')
5 files changed, 8 insertions, 432 deletions
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..7656fe8d08 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 @@ -136,8 +136,8 @@ 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 { @@ -145,7 +145,8 @@ public class JGitClientSession extends ClientSessionImpl { // from the peer only once the initial sendKexInit() following // this call to sendIdentification() has returned! proxy.runWhenDone(() -> { - JGitClientSession.super.sendIdentification(ident); + JGitClientSession.super.sendIdentification(ident, + extraLines); return null; }); // Called only from the ClientSessionImpl constructor, where the @@ -157,12 +158,11 @@ public class JGitClientSession extends ClientSessionImpl { throw new IOException(other.getLocalizedMessage(), other); } } - 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 { 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/JGitPublicKeyAuthFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java deleted file mode 100644 index 0e3e24dcff..0000000000 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 - * 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 org.apache.sshd.client.auth.pubkey.UserAuthPublicKey; -import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; -import org.apache.sshd.client.session.ClientSession; - -/** - * A customized authentication factory for public key user authentication. - */ -public class JGitPublicKeyAuthFactory extends UserAuthPublicKeyFactory { - - /** The singleton {@link JGitPublicKeyAuthFactory}. */ - public static final JGitPublicKeyAuthFactory FACTORY = new JGitPublicKeyAuthFactory(); - - private JGitPublicKeyAuthFactory() { - super(); - } - - @Override - public UserAuthPublicKey createUserAuth(ClientSession session) - throws IOException { - return new JGitPublicKeyAuthentication(getSignatureFactories()); - } -} 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 deleted file mode 100644 index 6755094420..0000000000 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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 - * 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.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.text.MessageFormat; -import java.util.Deque; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey; -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; - -/** - * 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> - */ -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) - 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 (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) { - if (log.isDebugEnabled()) { - log.debug( - "sendAuthDataRequest({})[{}] selecting from PubKeyAcceptedAlgorithms {}", //$NON-NLS-1$ - session, service, - NamedResource.getNames(existingFactories)); - } - // Select the factories by name and in order - existingFactories.forEach(f -> { - if (aliases.contains(f.getName())) { - currentAlgorithms.add(f.getName()); - } - }); - } - 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(); - } -} 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..d52e24adfb 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 @@ -32,6 +32,7 @@ import org.apache.sshd.client.ClientBuilder; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.auth.UserAuthFactory; import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory; +import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.SshException; @@ -47,9 +48,7 @@ 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; import org.eclipse.jgit.internal.transport.sshd.JGitSshClient; import org.eclipse.jgit.internal.transport.sshd.JGitSshConfig; @@ -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()); @@ -579,7 +577,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { // Password auth doesn't have this problem. return Collections.unmodifiableList( Arrays.asList(GssApiWithMicAuthFactory.INSTANCE, - JGitPublicKeyAuthFactory.FACTORY, + UserAuthPublicKeyFactory.INSTANCE, JGitPasswordAuthFactory.INSTANCE, UserAuthKeyboardInteractiveFactory.INSTANCE)); } |