diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2021-02-25 10:29:07 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2021-02-28 00:58:04 +0100 |
commit | f6597971991e3350df568b0cde05c014dcd69c47 (patch) | |
tree | cb61592af3f53da45174beed517b3284d7bd55c6 /org.eclipse.jgit.ssh.apache | |
parent | 286ad23cb56ffeac77d4bfd03be575358fd5217c (diff) | |
parent | 789c0479a9294417db0375cce9f1949fe9052d8c (diff) | |
download | jgit-f6597971991e3350df568b0cde05c014dcd69c47.tar.gz jgit-f6597971991e3350df568b0cde05c014dcd69c47.zip |
Merge branch 'master' into next
* master: (143 commits)
Prepare 5.11.0-SNAPSHOT builds
JGit v5.11.0.202102240950-m3
[releng] japicmp: update last release version
IgnoreNode: include path to file for invalid .gitignore patterns
FastIgnoreRule: include bad pattern in log message
init: add config option to set default for the initial branch name
init: allow specifying the initial branch name for the new repository
Fail clone if initial branch doesn't exist in remote repository
GPG: fix reading unprotected old-format secret keys
Update Orbit to S20210216215844
Add missing bazel dependency for o.e.j.gpg.bc.test
GPG: handle extended private key format
dfs: handle short copies
[GPG] Provide a factory for the BouncyCastleGpgSigner
Fix boxing warnings
GPG: compute the keygrip to find a secret key
GPG signature verification via BouncyCastle
Post commit hook failure should not cause commit failure
Allow to define additional Hook classes outside JGit
GitHook: use default charset for output and error streams
...
Change-Id: I689f4070e79f4a0ac1c02b35698ccaab68ad2f34
Diffstat (limited to 'org.eclipse.jgit.ssh.apache')
11 files changed, 142 insertions, 240 deletions
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF index 96b40ad15e..faa52b26ac 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF @@ -33,49 +33,51 @@ 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.4.0,2.5.0)", - org.apache.sshd.client;version="[2.4.0,2.5.0)", - org.apache.sshd.client.auth;version="[2.4.0,2.5.0)", - org.apache.sshd.client.auth.keyboard;version="[2.4.0,2.5.0)", - org.apache.sshd.client.auth.password;version="[2.4.0,2.5.0)", - org.apache.sshd.client.auth.pubkey;version="[2.4.0,2.5.0)", - org.apache.sshd.client.channel;version="[2.4.0,2.5.0)", - org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)", - org.apache.sshd.client.config.keys;version="[2.4.0,2.5.0)", - org.apache.sshd.client.future;version="[2.4.0,2.5.0)", - org.apache.sshd.client.keyverifier;version="[2.4.0,2.5.0)", - org.apache.sshd.client.session;version="[2.4.0,2.5.0)", - org.apache.sshd.client.session.forward;version="[2.4.0,2.5.0)", - org.apache.sshd.client.subsystem.sftp;version="[2.4.0,2.5.0)", - org.apache.sshd.common;version="[2.4.0,2.5.0)", - org.apache.sshd.common.auth;version="[2.4.0,2.5.0)", - org.apache.sshd.common.channel;version="[2.4.0,2.5.0)", - org.apache.sshd.common.compression;version="[2.4.0,2.5.0)", - org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", - org.apache.sshd.common.config.keys.loader;version="[2.4.0,2.5.0)", - org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.4.0,2.5.0)", - org.apache.sshd.common.digest;version="[2.4.0,2.5.0)", - org.apache.sshd.common.forward;version="[2.4.0,2.5.0)", - org.apache.sshd.common.future;version="[2.4.0,2.5.0)", - org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)", - org.apache.sshd.common.io;version="[2.4.0,2.5.0)", - org.apache.sshd.common.kex;version="[2.4.0,2.5.0)", - org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", - org.apache.sshd.common.mac;version="[2.4.0,2.5.0)", - org.apache.sshd.common.random;version="[2.4.0,2.5.0)", - org.apache.sshd.common.session;version="[2.4.0,2.5.0)", - org.apache.sshd.common.session.helpers;version="[2.4.0,2.5.0)", - org.apache.sshd.common.signature;version="[2.4.0,2.5.0)", - org.apache.sshd.common.subsystem.sftp;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.closeable;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.io;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.io.resource;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)", - org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", - org.apache.sshd.server.auth;version="[2.4.0,2.5.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.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.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/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 0d6f3027f2..66713ba632 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 @@ -10,6 +10,7 @@ package org.eclipse.jgit.internal.transport.sshd; import static java.text.MessageFormat.format; +import static org.apache.sshd.core.CoreModuleProperties.MAX_IDENTIFICATION_SIZE; import java.io.IOException; import java.io.StreamCorruptedException; @@ -29,19 +30,14 @@ import java.util.Set; import org.apache.sshd.client.ClientFactoryManager; import org.apache.sshd.client.config.hosts.HostConfigEntry; -import org.apache.sshd.client.future.AuthFuture; import org.apache.sshd.client.keyverifier.ServerKeyVerifier; import org.apache.sshd.client.session.ClientSessionImpl; -import org.apache.sshd.client.session.ClientUserAuthService; import org.apache.sshd.common.AttributeRepository; import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.PropertyResolver; -import org.apache.sshd.common.PropertyResolverUtils; -import org.apache.sshd.common.SshException; 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.KexState; import org.apache.sshd.common.util.Readable; import org.apache.sshd.common.util.buffer.Buffer; import org.eclipse.jgit.errors.InvalidPatternException; @@ -66,7 +62,8 @@ public class JGitClientSession extends ClientSessionImpl { * protocol version exchange. 64kb is what OpenSSH < 8.0 read; OpenSSH 8.0 * changed it to 8Mb, but that seems excessive for the purpose stated in RFC * 4253. The Apache MINA sshd default in - * {@link FactoryManager#DEFAULT_MAX_IDENTIFICATION_SIZE} is 16kb. + * {@link org.apache.sshd.core.CoreModuleProperties#MAX_IDENTIFICATION_SIZE} + * is 16kb. */ private static final int DEFAULT_MAX_IDENTIFICATION_SIZE = 64 * 1024; @@ -77,17 +74,6 @@ public class JGitClientSession extends ClientSessionImpl { private volatile StatefulProxyConnector proxyHandler; /** - * Work-around for bug 565394 / SSHD-1050; remove when using sshd 2.6.0. - */ - private volatile AuthFuture authFuture; - - /** Records exceptions before there is an authFuture. */ - private List<Throwable> earlyErrors = new ArrayList<>(); - - /** Guards setting an earlyError and the authFuture together. */ - private final Object errorLock = new Object(); - - /** * @param manager * @param session * @throws Exception @@ -97,125 +83,6 @@ public class JGitClientSession extends ClientSessionImpl { super(manager, session); } - // BEGIN Work-around for bug 565394 / SSHD-1050 - // Remove when using sshd 2.6.0. - - @Override - public AuthFuture auth() throws IOException { - if (getUsername() == null) { - throw new IllegalStateException( - SshdText.get().sessionWithoutUsername); - } - ClientUserAuthService authService = getUserAuthService(); - String serviceName = nextServiceName(); - List<Throwable> errors = null; - AuthFuture future; - // Guard both getting early errors and setting authFuture - synchronized (errorLock) { - future = authService.auth(serviceName); - if (future == null) { - // Internal error; no translation. - throw new IllegalStateException( - "No auth future generated by service '" //$NON-NLS-1$ - + serviceName + '\''); - } - errors = earlyErrors; - earlyErrors = null; - authFuture = future; - } - if (errors != null && !errors.isEmpty()) { - Iterator<Throwable> iter = errors.iterator(); - Throwable first = iter.next(); - iter.forEachRemaining(t -> { - if (t != first && t != null) { - first.addSuppressed(t); - } - }); - // Mark the future as having had an exception; just to be on the - // safe side. Actually, there shouldn't be anyone waiting on this - // future yet. - future.setException(first); - if (log.isDebugEnabled()) { - log.debug("auth({}) early exception type={}: {}", //$NON-NLS-1$ - this, first.getClass().getSimpleName(), - first.getMessage()); - } - if (first instanceof SshException) { - throw new SshException( - ((SshException) first).getDisconnectCode(), - first.getMessage(), first); - } - throw new IOException(first.getMessage(), first); - } - return future; - } - - @Override - protected void signalAuthFailure(AuthFuture future, Throwable t) { - signalAuthFailure(t); - } - - private void signalAuthFailure(Throwable t) { - AuthFuture future = authFuture; - if (future == null) { - synchronized (errorLock) { - if (earlyErrors != null) { - earlyErrors.add(t); - } - future = authFuture; - } - } - if (future != null) { - future.setException(t); - } - if (log.isDebugEnabled()) { - boolean signalled = future != null && t == future.getException(); - log.debug("signalAuthFailure({}) type={}, signalled={}: {}", this, //$NON-NLS-1$ - t.getClass().getSimpleName(), Boolean.valueOf(signalled), - t.getMessage()); - } - } - - @Override - public void exceptionCaught(Throwable t) { - signalAuthFailure(t); - super.exceptionCaught(t); - } - - @Override - protected void preClose() { - signalAuthFailure( - new SshException(SshdText.get().authenticationOnClosedSession)); - super.preClose(); - } - - @Override - protected void handleDisconnect(int code, String msg, String lang, - Buffer buffer) throws Exception { - signalAuthFailure(new SshException(code, msg)); - super.handleDisconnect(code, msg, lang, buffer); - } - - @Override - protected <C extends Collection<ClientSessionEvent>> C updateCurrentSessionState( - C newState) { - if (closeFuture.isClosed()) { - newState.add(ClientSessionEvent.CLOSED); - } - if (isAuthenticated()) { // authFuture.isSuccess() - newState.add(ClientSessionEvent.AUTHED); - } - if (KexState.DONE.equals(getKexState())) { - AuthFuture future = authFuture; - if (future == null || future.isFailure()) { - newState.add(ClientSessionEvent.WAIT_AUTH); - } - } - return newState; - } - - // END Work-around for bug 565394 / SSHD-1050 - /** * Retrieves the {@link HostConfigEntry} this session was created for. * @@ -332,22 +199,6 @@ public class JGitClientSession extends ClientSessionImpl { } @Override - protected void checkKeys() throws SshException { - ServerKeyVerifier serverKeyVerifier = getServerKeyVerifier(); - // The super implementation always uses - // getIoSession().getRemoteAddress(). In case of a proxy connection, - // that would be the address of the proxy! - SocketAddress remoteAddress = getConnectAddress(); - PublicKey serverKey = getKex().getServerKey(); - if (!serverKeyVerifier.verifyServerKey(this, remoteAddress, - serverKey)) { - throw new SshException( - org.apache.sshd.common.SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE, - SshdText.get().kexServerKeyInvalid); - } - } - - @Override protected String resolveAvailableSignaturesProposal( FactoryManager manager) { Set<String> defaultSignatures = new LinkedHashSet<>(); @@ -477,9 +328,15 @@ public class JGitClientSession extends ClientSessionImpl { throw new IllegalStateException( "doReadIdentification of client called with server=true"); //$NON-NLS-1$ } - int maxIdentSize = PropertyResolverUtils.getIntProperty(this, - FactoryManager.MAX_IDENTIFICATION_SIZE, - DEFAULT_MAX_IDENTIFICATION_SIZE); + Integer maxIdentLength = MAX_IDENTIFICATION_SIZE.get(this).orElse(null); + int maxIdentSize; + if (maxIdentLength == null || maxIdentLength + .intValue() < DEFAULT_MAX_IDENTIFICATION_SIZE) { + maxIdentSize = DEFAULT_MAX_IDENTIFICATION_SIZE; + MAX_IDENTIFICATION_SIZE.set(this, Integer.valueOf(maxIdentSize)); + } else { + maxIdentSize = maxIdentLength.intValue(); + } int current = buffer.rpos(); int end = current + buffer.available(); if (current >= end) { diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java index 4abd6e901a..ff8caaacc0 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java @@ -9,7 +9,8 @@ */ package org.eclipse.jgit.internal.transport.sshd; -import org.apache.sshd.client.ClientAuthenticationManager; +import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS; + import org.apache.sshd.client.auth.keyboard.UserInteraction; import org.apache.sshd.client.auth.password.UserAuthPassword; import org.apache.sshd.client.session.ClientSession; @@ -29,9 +30,7 @@ public class JGitPasswordAuthentication extends UserAuthPassword { public void init(ClientSession session, String service) throws Exception { super.init(session, service); maxAttempts = Math.max(1, - session.getIntProperty( - ClientAuthenticationManager.PASSWORD_PROMPTS, - ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS)); + PASSWORD_PROMPTS.getRequired(session).intValue()); attempts = 0; } 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 beaaecaac9..74455dc808 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 @@ -10,6 +10,8 @@ package org.eclipse.jgit.internal.transport.sshd; import static java.text.MessageFormat.format; +import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS; +import static org.apache.sshd.core.CoreModuleProperties.PREFERRED_AUTHS; import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.positive; import java.io.IOException; @@ -32,7 +34,6 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.stream.Collectors; -import org.apache.sshd.client.ClientAuthenticationManager; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.config.hosts.HostConfigEntry; import org.apache.sshd.client.future.ConnectFuture; @@ -169,12 +170,15 @@ public class JGitSshClient extends SshClient { Map<AttributeKey<?>, Object> data = new HashMap<>(); data.put(HOST_CONFIG_ENTRY, hostConfig); data.put(ORIGINAL_REMOTE_ADDRESS, originalAddress); + data.put(TARGET_SERVER, new SshdSocketAddress(originalAddress)); String preferredAuths = hostConfig.getProperty( SshConstants.PREFERRED_AUTHENTICATIONS, resolveAttribute(PREFERRED_AUTHENTICATIONS)); if (!StringUtils.isEmptyOrNull(preferredAuths)) { data.put(SessionAttributes.PROPERTIES, - Collections.singletonMap(PREFERRED_AUTHS, preferredAuths)); + Collections.singletonMap( + PREFERRED_AUTHS.getName(), + preferredAuths)); } return new SessionAttributes( AttributeRepository.ofAttributesMap(data), @@ -267,8 +271,7 @@ public class JGitSshClient extends SshClient { session.setCredentialsProvider(getCredentialsProvider()); } int numberOfPasswordPrompts = getNumberOfPasswordPrompts(hostConfig); - session.getProperties().put(PASSWORD_PROMPTS, - Integer.valueOf(numberOfPasswordPrompts)); + PASSWORD_PROMPTS.set(session, Integer.valueOf(numberOfPasswordPrompts)); List<Path> identities = hostConfig.getIdentities().stream() .map(s -> { try { @@ -311,7 +314,7 @@ public class JGitSshClient extends SshClient { log.warn(format(SshdText.get().configInvalidPositive, SshConstants.NUMBER_OF_PASSWORD_PROMPTS, prompts)); } - return ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS; + return PASSWORD_PROMPTS.getRequiredDefault().intValue(); } /** diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java index 97e0fcc7d2..6b0d9fb70b 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java @@ -46,7 +46,7 @@ public class JGitSshConfig implements HostConfigEntryResolver { @Override public HostConfigEntry resolveEffectiveHost(String host, int port, - SocketAddress localAddress, String username, + SocketAddress localAddress, String username, String proxyJump, AttributeRepository attributes) throws IOException { SshConfigStore.HostConfig entry = configFile == null ? SshConfigStore.EMPTY_CONFIG 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 5bc1115f62..47e09b75d7 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 @@ -346,11 +346,14 @@ public class OpenSshServerKeyDatabase throws IOException { KnownHostEntry hostEntry = entry.getHostEntry(); String oldLine = hostEntry.getConfigLine(); + if (oldLine == null) { + return; + } String newLine = updateHostKeyLine(oldLine, serverKey); if (newLine == null || newLine.isEmpty()) { return; } - if (oldLine == null || oldLine.isEmpty() || newLine.equals(oldLine)) { + if (oldLine.isEmpty() || newLine.equals(oldLine)) { // Shouldn't happen. return; } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java index 078e411f29..2cd0669842 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java @@ -9,6 +9,8 @@ */ package org.eclipse.jgit.internal.transport.sshd; +import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS; + import java.io.IOException; import java.net.URISyntaxException; import java.security.GeneralSecurityException; @@ -18,7 +20,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -import org.apache.sshd.client.ClientAuthenticationManager; import org.apache.sshd.common.AttributeRepository.AttributeKey; import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.config.keys.FilePasswordProvider; @@ -62,15 +63,8 @@ public class PasswordProviderWrapper implements FilePasswordProvider { if (state == null) { state = new PerSessionState(); state.delegate = factory.get(); - Integer maxNumberOfAttempts = context - .getInteger(ClientAuthenticationManager.PASSWORD_PROMPTS); - if (maxNumberOfAttempts != null - && maxNumberOfAttempts.intValue() > 0) { - state.delegate.setAttempts(maxNumberOfAttempts.intValue()); - } else { - state.delegate.setAttempts( - ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS); - } + state.delegate.setAttempts( + PASSWORD_PROMPTS.getRequiredDefault().intValue()); context.setAttribute(STATE, state); } return state; diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpClientConnector.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpClientConnector.java index 8ac752bcce..e5d1e80f74 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpClientConnector.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpClientConnector.java @@ -135,7 +135,7 @@ public class HttpClientConnector extends AbstractClientProxyConnector { byte[] data = eol(msg).toString().getBytes(US_ASCII); Buffer buffer = new ByteArrayBuffer(data.length, false); buffer.putRawBytes(data); - session.writePacket(buffer).verify(getTimeout()); + session.writeBuffer(buffer).verify(getTimeout()); } private StringBuilder connect() { diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java index 78b8d456b4..8844efa6b7 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java @@ -235,7 +235,7 @@ public class Socks5ClientConnector extends AbstractClientProxyConnector { buffer.putByte((byte) authenticationProposals.length); buffer.putRawBytes(authenticationProposals); state = ProtocolState.INIT; - session.writePacket(buffer).verify(getTimeout()); + session.writeBuffer(buffer).verify(getTimeout()); } private byte[] getAuthenticationProposals() { @@ -298,7 +298,7 @@ public class Socks5ClientConnector extends AbstractClientProxyConnector { buffer.putByte((byte) ((port >> 8) & 0xFF)); buffer.putByte((byte) (port & 0xFF)); state = ProtocolState.CONNECTING; - session.writePacket(buffer).verify(getTimeout()); + session.writeBuffer(buffer).verify(getTimeout()); } private void doPasswordAuth(IoSession session) throws Exception { @@ -335,7 +335,7 @@ public class Socks5ClientConnector extends AbstractClientProxyConnector { "No data for proxy authentication with " //$NON-NLS-1$ + proxyAddress); } - session.writePacket(buffer).verify(getTimeout()); + session.writeBuffer(buffer).verify(getTimeout()); } finally { if (buffer != null) { buffer.clear(true); @@ -350,7 +350,7 @@ public class Socks5ClientConnector extends AbstractClientProxyConnector { authenticator.process(); buffer = authenticator.getToken(); if (buffer != null) { - session.writePacket(buffer).verify(getTimeout()); + session.writeBuffer(buffer).verify(getTimeout()); } } finally { if (buffer != null) { diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java index 0fb0610b99..33b234b1f1 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java @@ -11,6 +11,7 @@ package org.eclipse.jgit.transport.sshd; import static java.text.MessageFormat.format; import static org.apache.sshd.common.SshConstants.SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE; +import static org.apache.sshd.sftp.SftpModuleProperties.SFTP_CHANNEL_OPEN_TIMEOUT; import java.io.Closeable; import java.io.IOException; @@ -24,6 +25,7 @@ import java.util.Collections; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -37,23 +39,23 @@ import org.apache.sshd.client.config.hosts.HostConfigEntry; import org.apache.sshd.client.future.ConnectFuture; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.client.session.forward.PortForwardingTracker; -import org.apache.sshd.client.subsystem.sftp.SftpClient; -import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle; -import org.apache.sshd.client.subsystem.sftp.SftpClient.CopyMode; -import org.apache.sshd.client.subsystem.sftp.SftpClientFactory; import org.apache.sshd.common.AttributeRepository; import org.apache.sshd.common.SshException; import org.apache.sshd.common.future.CloseFuture; import org.apache.sshd.common.future.SshFutureListener; -import org.apache.sshd.common.subsystem.sftp.SftpException; import org.apache.sshd.common.util.io.IoUtils; import org.apache.sshd.common.util.net.SshdSocketAddress; +import org.apache.sshd.sftp.client.SftpClient; +import org.apache.sshd.sftp.client.SftpClient.CloseableHandle; +import org.apache.sshd.sftp.client.SftpClient.CopyMode; +import org.apache.sshd.sftp.client.SftpClientFactory; +import org.apache.sshd.sftp.common.SftpException; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.transport.sshd.JGitSshClient; import org.eclipse.jgit.internal.transport.sshd.SshdText; import org.eclipse.jgit.transport.FtpChannel; -import org.eclipse.jgit.transport.RemoteSession; +import org.eclipse.jgit.transport.RemoteSession2; import org.eclipse.jgit.transport.SshConstants; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.util.StringUtils; @@ -61,11 +63,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * An implementation of {@link RemoteSession} based on Apache MINA sshd. + * An implementation of {@link org.eclipse.jgit.transport.RemoteSession + * RemoteSession} based on Apache MINA sshd. * * @since 5.2 */ -public class SshdSession implements RemoteSession { +public class SshdSession implements RemoteSession2 { private static final Logger LOG = LoggerFactory .getLogger(SshdSession.class); @@ -203,7 +206,7 @@ public class SshdSession implements RemoteSession { private HostConfigEntry getHostConfig(String username, String host, int port) throws IOException { HostConfigEntry entry = client.getHostConfigEntryResolver() - .resolveEffectiveHost(host, port, null, username, null); + .resolveEffectiveHost(host, port, null, username, null, null); if (entry == null) { if (SshdSocketAddress.isIPv6Address(host)) { return new HostConfigEntry("", host, port, username); //$NON-NLS-1$ @@ -290,8 +293,15 @@ public class SshdSession implements RemoteSession { @Override public Process exec(String commandName, int timeout) throws IOException { + return exec(commandName, Collections.emptyMap(), timeout); + } + + @Override + public Process exec(String commandName, Map<String, String> environment, + int timeout) throws IOException { @SuppressWarnings("resource") - ChannelExec exec = session.createExecChannel(commandName); + ChannelExec exec = session.createExecChannel(commandName, null, + environment); if (timeout <= 0) { try { exec.open().verify(); @@ -430,13 +440,12 @@ public class SshdSession implements RemoteSession { @Override public void connect(int timeout, TimeUnit unit) throws IOException { if (timeout <= 0) { - session.getProperties().put( - SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, - Long.valueOf(Long.MAX_VALUE)); + // This timeout must not be null! + SFTP_CHANNEL_OPEN_TIMEOUT.set(session, + Duration.ofMillis(Long.MAX_VALUE)); } else { - session.getProperties().put( - SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, - Long.valueOf(unit.toMillis(timeout))); + SFTP_CHANNEL_OPEN_TIMEOUT.set(session, + Duration.ofMillis(unit.toMillis(timeout))); } ftp = SftpClientFactory.instance().createSftpClient(session); try { 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 df0e1d28a4..357994d431 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 @@ -35,10 +35,13 @@ 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.SshException; +import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.compression.BuiltinCompressions; import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions; import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.common.signature.BuiltinSignatures; +import org.apache.sshd.common.signature.Signature; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile; @@ -205,6 +208,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { .hostConfigEntryResolver(configFile) .serverKeyVerifier(new JGitServerKeyVerifier( getServerKeyDatabase(home, sshDir))) + .signatureFactories(getSignatureFactories()) .compressionFactories( new ArrayList<>(BuiltinCompressions.VALUES)) .build(); @@ -590,4 +594,35 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { protected String getDefaultPreferredAuthentications() { return null; } + + /** + * Apache MINA sshd 2.6.0 has removed DSA, DSA_CERT and RSA_CERT. We have to + * set it up explicitly to still allow users to connect with DSA keys. + * + * @return a list of supported signature factories + */ + @SuppressWarnings("deprecation") + private static List<NamedFactory<Signature>> getSignatureFactories() { + // @formatter:off + return Arrays.asList( + BuiltinSignatures.nistp256_cert, + BuiltinSignatures.nistp384_cert, + BuiltinSignatures.nistp521_cert, + BuiltinSignatures.ed25519_cert, + BuiltinSignatures.rsaSHA512_cert, + BuiltinSignatures.rsaSHA256_cert, + BuiltinSignatures.rsa_cert, + BuiltinSignatures.nistp256, + BuiltinSignatures.nistp384, + BuiltinSignatures.nistp521, + BuiltinSignatures.ed25519, + BuiltinSignatures.sk_ecdsa_sha2_nistp256, + BuiltinSignatures.sk_ssh_ed25519, + BuiltinSignatures.rsaSHA512, + BuiltinSignatures.rsaSHA256, + BuiltinSignatures.rsa, + BuiltinSignatures.dsa_cert, + BuiltinSignatures.dsa); + // @formatter:on + } } |