ssh: Prefer algorithms of the known host keys
JSch prefers ssh-rsa key type. When the remote server supports ssh-rsa key type then this key type will be used even if the known_hosts file contains a host key for that host, but with different key type. This caused an unexpected UnknownHostKey error. To fix the issue first scan the known_hosts, the HostKeyRepository in JSch API, for any already existing host keys for the target host and modify the default session settings to prefer their algorithms. However, do this only if there is no HostKeyAlgorithms setting active. Change-Id: I236df2a860ddd9289a0a820ddf09c2dea3673d36
This commit is contained in:
parent
6dd50d2e1b
commit
b6e2800560
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2018, Sasa Zivkov <sasa.zivkov@sap.com>
|
||||
* Copyright (C) 2016, Mark Ingram <markdingram@gmail.com>
|
||||
* Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com>
|
||||
* Copyright (C) 2008-2009, Google Inc.
|
||||
|
@ -49,6 +50,10 @@
|
|||
|
||||
package org.eclipse.jgit.transport;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.jgit.transport.OpenSshConfig.SSH_PORT;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -59,9 +64,11 @@
|
|||
import java.net.UnknownHostException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
|
@ -71,6 +78,8 @@
|
|||
|
||||
import com.jcraft.jsch.ConfigRepository;
|
||||
import com.jcraft.jsch.ConfigRepository.Config;
|
||||
import com.jcraft.jsch.HostKey;
|
||||
import com.jcraft.jsch.HostKeyRepository;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
@ -224,6 +233,9 @@ Session createSession(CredentialsProvider credentialsProvider,
|
|||
credentialsProvider));
|
||||
}
|
||||
safeConfig(session, hc.getConfig());
|
||||
if (hc.getConfig().getValue("HostKeyAlgorithms") == null) { //$NON-NLS-1$
|
||||
setPreferredKeyTypesOrder(session);
|
||||
}
|
||||
configure(hc, session);
|
||||
return session;
|
||||
}
|
||||
|
@ -239,6 +251,36 @@ private void safeConfig(Session session, Config cfg) {
|
|||
"CheckSignatures"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private static void setPreferredKeyTypesOrder(Session session) {
|
||||
HostKeyRepository hkr = session.getHostKeyRepository();
|
||||
List<String> known = Stream.of(hkr.getHostKey(hostName(session), null))
|
||||
.map(HostKey::getType)
|
||||
.collect(toList());
|
||||
|
||||
if (!known.isEmpty()) {
|
||||
String serverHostKey = "server_host_key"; //$NON-NLS-1$
|
||||
String current = session.getConfig(serverHostKey);
|
||||
if (current == null) {
|
||||
session.setConfig(serverHostKey, String.join(",", known)); //$NON-NLS-1$
|
||||
return;
|
||||
}
|
||||
|
||||
String knownFirst = Stream.concat(
|
||||
known.stream(),
|
||||
Stream.of(current.split(",")) //$NON-NLS-1$
|
||||
.filter(s -> !known.contains(s)))
|
||||
.collect(joining(",")); //$NON-NLS-1$
|
||||
session.setConfig(serverHostKey, knownFirst);
|
||||
}
|
||||
}
|
||||
|
||||
private static String hostName(Session s) {
|
||||
if (s.getPort() == SSH_PORT) {
|
||||
return s.getHost();
|
||||
}
|
||||
return String.format("[%s]:%d", s.getHost(), s.getPort()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private void copyConfigValueToSession(Session session, Config cfg,
|
||||
String from, String to) {
|
||||
String value = cfg.getValue(from);
|
||||
|
|
Loading…
Reference in New Issue