GH-3211: Add DefSftpSF.setKnownHosts(Resource) (#3212)
* GH-3211: Add DefSftpSF.setKnownHosts(Resource) Fixes https://github.com/spring-projects/spring-integration/issues/3211 * Add `DefaultSftpSessionFactory.setKnownHosts(Resource)` to allow to configure externally any resource for file with known_hosts content * Deprecate an existing method in favor of new one * The new method makes it aligned with the `setPrivateKey(Resource)` * Fix tests do not use a deprecated method any more **Cherry-pick to 5.2.x** * * Rename to `setKnownHostsResource()` to avoid XML parser confusion * Change `sftp.adoc` to reflect a new property
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.sftp.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
@@ -27,6 +28,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.file.remote.session.SharedSessionCapable;
|
||||
@@ -81,7 +83,7 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
|
||||
private String password;
|
||||
|
||||
private String knownHosts;
|
||||
private Resource knownHosts;
|
||||
|
||||
private Resource privateKey;
|
||||
|
||||
@@ -191,8 +193,21 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
* false (default).</b>
|
||||
* @param knownHosts The known hosts.
|
||||
* @see JSch#setKnownHosts(String)
|
||||
* @deprecated since 5.2.5 in favor of {@link #setKnownHostsResource(Resource)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setKnownHosts(String knownHosts) {
|
||||
setKnownHostsResource(new FileSystemResource(knownHosts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the filename that will be used for a host key repository.
|
||||
* The file has the same format as OpenSSH's known_hosts file.
|
||||
* @param knownHosts the resource for known hosts.
|
||||
* @see JSch#setKnownHosts(InputStream)
|
||||
* @since 5.2.5
|
||||
*/
|
||||
public void setKnownHostsResource(Resource knownHosts) {
|
||||
this.knownHosts = knownHosts;
|
||||
}
|
||||
|
||||
@@ -323,7 +338,7 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
* implementation must respond to Jsch calls in a suitable way.
|
||||
* <p>
|
||||
* Jsch calls {@link UserInfo#promptYesNo(String)} when connecting to an unknown host,
|
||||
* or when a known host's key has changed (see {@link #setKnownHosts(String)
|
||||
* or when a known host's key has changed (see {@link #setKnownHostsResource(Resource)}
|
||||
* knownHosts}). Generally, it should return false as returning true will accept all
|
||||
* new keys or key changes.
|
||||
* <p>
|
||||
@@ -347,7 +362,7 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
/**
|
||||
* When no {@link UserInfo} has been provided, set to true to unconditionally allow
|
||||
* connecting to an unknown host or when a host's key has changed (see
|
||||
* {@link #setKnownHosts(String) knownHosts}). Default false (since 4.2).
|
||||
* {@link #setKnownHostsResource(Resource) knownHosts}). Default false (since 4.2).
|
||||
* Set to true if a knownHosts file is not provided.
|
||||
* @param allowUnknownKeys true to allow connecting to unknown hosts.
|
||||
* @since 4.1.7
|
||||
@@ -380,8 +395,7 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
freshJschSession = true;
|
||||
}
|
||||
sftpSession = new SftpSession(jschSession);
|
||||
JavaUtils.INSTANCE
|
||||
.acceptIfNotNull(this.channelConnectTimeout, sftpSession::setChannelConnectTimeout);
|
||||
JavaUtils.INSTANCE.acceptIfNotNull(this.channelConnectTimeout, sftpSession::setChannelConnectTimeout);
|
||||
sftpSession.connect();
|
||||
if (this.isSharedSession && freshJschSession) {
|
||||
this.sharedJschSession = jschSession;
|
||||
@@ -408,8 +422,8 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
if (this.port <= 0) {
|
||||
this.port = 22;
|
||||
}
|
||||
if (StringUtils.hasText(this.knownHosts)) {
|
||||
this.jsch.setKnownHosts(this.knownHosts);
|
||||
if (this.knownHosts != null) {
|
||||
this.jsch.setKnownHosts(this.knownHosts.getInputStream());
|
||||
}
|
||||
|
||||
// private key
|
||||
@@ -467,6 +481,7 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
* sensible defaults if null. As the password is configured in this Factory, the
|
||||
* wrapper will return the factory's configured password and only delegate to the
|
||||
* UserInfo if null.
|
||||
*
|
||||
* @since 4.1.7
|
||||
*/
|
||||
private class UserInfoWrapper implements UserInfo, UIKeyboardInteractive {
|
||||
@@ -548,7 +563,7 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
|
||||
}
|
||||
else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("No UserInfo provided - " + message + ", returning:"
|
||||
LOGGER.debug("No UserInfo provided - " + message + ", returning: "
|
||||
+ DefaultSftpSessionFactory.this.allowUnknownKeys);
|
||||
}
|
||||
return DefaultSftpSessionFactory.this.allowUnknownKeys;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<beans:bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<beans:property name="host" value="loclahost"/>
|
||||
<beans:property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<beans:property name="knownHostsResource" value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<beans:property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftp_rsa"/>
|
||||
<beans:property name="privateKeyPassphrase" value="ghj"/>
|
||||
<beans:property name="password" value="hello"/>
|
||||
|
||||
@@ -3,25 +3,17 @@
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:lang="http://www.springframework.org/schema/lang"
|
||||
xmlns:sftp="http://www.springframework.org/schema/integration/sftp"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://www.springframework.org/schema/tool https://www.springframework.org/schema/tool/spring-tool.xsd
|
||||
http://www.springframework.org/schema/lang https://www.springframework.org/schema/lang/spring-lang.xsd
|
||||
http://www.springframework.org/schema/integration/sftp https://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd">
|
||||
|
||||
<channel id="requestChannel"/>
|
||||
|
||||
<beans:bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<beans:property name="host" value="loclahost"/>
|
||||
<beans:property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<beans:property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<beans:property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<beans:property name="privateKeyPassphrase" value="ghj"/>
|
||||
<beans:property name="password" value="hello"/>
|
||||
@@ -30,17 +22,17 @@
|
||||
</beans:bean>
|
||||
|
||||
<sftp:inbound-channel-adapter id="sftpAdapterNoAutoCreate"
|
||||
channel="requestChannel"
|
||||
session-factory="sftpSessionFactory"
|
||||
filter="filter"
|
||||
remote-directory="/foo"
|
||||
local-directory="file:foo"
|
||||
auto-create-local-directory="false"
|
||||
delete-remote-files="false">
|
||||
channel="requestChannel"
|
||||
session-factory="sftpSessionFactory"
|
||||
filter="filter"
|
||||
remote-directory="/foo"
|
||||
local-directory="file:foo"
|
||||
auto-create-local-directory="false"
|
||||
delete-remote-files="false">
|
||||
<poller fixed-rate="1000"/>
|
||||
</sftp:inbound-channel-adapter>
|
||||
|
||||
<beans:bean id="filter" class="org.springframework.integration.sftp.filters.SftpPatternMatchingFileListFilter">
|
||||
<beans:bean id="filter" class="org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter">
|
||||
<beans:constructor-arg value="."/>
|
||||
</beans:bean>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<beans:bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.SimpleSftpSessionFactory">
|
||||
<beans:property name="host" value="loclahost"/>
|
||||
<beans:property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<beans:property name="knownHostsResource" value="local, foo.com, bar.foo"/>
|
||||
<beans:property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<beans:property name="privateKeyPassphrase" value="ghj"/>
|
||||
<beans:property name="password" value="hello"/>
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
<beans:bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<beans:property name="host" value="loclahost"/>
|
||||
<beans:property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<beans:property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<beans:property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftp_rsa"/>
|
||||
<beans:property name="privateKeyPassphrase" value="ghj"/>
|
||||
<beans:property name="password" value="hello"/>
|
||||
|
||||
@@ -3,25 +3,17 @@
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:lang="http://www.springframework.org/schema/lang"
|
||||
xmlns:sftp="http://www.springframework.org/schema/integration/sftp"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://www.springframework.org/schema/tool https://www.springframework.org/schema/tool/spring-tool.xsd
|
||||
http://www.springframework.org/schema/lang https://www.springframework.org/schema/lang/spring-lang.xsd
|
||||
http://www.springframework.org/schema/integration/sftp https://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd">
|
||||
|
||||
<channel id="inboundFilesChannel"/>
|
||||
|
||||
<beans:bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<beans:property name="host" value="loclahost"/>
|
||||
<beans:property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<beans:property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<beans:property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<beans:property name="privateKeyPassphrase" value="ghj"/>
|
||||
<beans:property name="password" value="hello"/>
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<property name="privateKeyPassphrase" value="ghj"/>
|
||||
<property name="password" value="hello"/>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.SimpleSftpSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<property name="knownHostsResource" value="local, foo.com, bar.foo"/>
|
||||
<property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<property name="privateKeyPassphrase" value="ghj"/>
|
||||
<property name="password" value="hello"/>
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<property name="privateKeyPassphrase" value="ghj"/>
|
||||
<property name="password" value="hello"/>
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
|
||||
<property name="privateKeyPassphrase" value="ghj"/>
|
||||
<property name="password" value="hello"/>
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
|
||||
<property name="host" value="loclahost"/>
|
||||
<property name="knownHosts" value="local, foo.com, bar.foo"/>
|
||||
<property name="knownHostsResource"
|
||||
value="#{ new org.springframework.core.io.ByteArrayResource('local, foo.com, bar.foo'.bytes)}"/>
|
||||
<property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftp_rsa"/>
|
||||
<property name="privateKeyPassphrase" value="ghj"/>
|
||||
<property name="password" value="hello"/>
|
||||
|
||||
@@ -111,7 +111,7 @@ Required.
|
||||
|
||||
`hostKeyAlias`::Sets the host key alias, which is used when comparing the host key to the known hosts list.
|
||||
|
||||
`knownHosts`::Specifies the filename that used for a host key repository.
|
||||
`knownHostsResource`::Specifies the file resource that used for a host key repository.
|
||||
The file has the same format as OpenSSH's `known_hosts` file and is required and must be pre-populated if `allowUnknownKeys` is false.
|
||||
|
||||
`password`::The password to authenticate against the remote host.
|
||||
@@ -163,7 +163,7 @@ If `false`, a pre-populated `knownHosts` file is required.
|
||||
In particular, `promptYesNo()` is invoked when an unknown (or changed) host key is received.
|
||||
See also <<sftp-unk-keys,`allowUnknownKeys`>>.
|
||||
When you provide a `UserInfo`, the `password` and private key `passphrase` are obtained from it, and you cannot set discrete
|
||||
`password` and `privateKeyPassprase` properties.
|
||||
`password` and `privateKeyPassphrase` properties.
|
||||
|
||||
[[sftp-proxy-factory-bean]]
|
||||
=== Proxy Factory Bean
|
||||
|
||||
Reference in New Issue
Block a user