INT-3796: More SFTP Refinements
JIRA: https://jira.spring.io/browse/INT-3796 When a `UserInfo` is provided, use it for the password and passphrase. Disallow local properies when a `UserInfo` is provided. Simple polishing and fixing `TestSftpServer` for the `this.server.stop(true);` to avoid `port is already in use` for other tests which use default SSH port.
This commit is contained in:
committed by
Artem Bilan
parent
56bfe6b0ac
commit
e82bfdc9a6
@@ -139,7 +139,7 @@ public class TestSftpServer implements InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.server.stop();
|
||||
this.server.stop(true);
|
||||
this.sftpFolder.delete();
|
||||
this.localFolder.delete();
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
*/
|
||||
public class SftpServerTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testUcPw() throws Exception {
|
||||
final int port = SocketUtils.findAvailableServerSocket();
|
||||
@@ -95,11 +94,20 @@ public class SftpServerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testPubPrivKey() throws Exception {
|
||||
testKeyExchange("id_rsa.pub", "id_rsa", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPubPrivKeyPassphrase() throws Exception {
|
||||
testKeyExchange("id_rsa_pp.pub", "id_rsa_pp", "secret");
|
||||
}
|
||||
|
||||
private void testKeyExchange(String pubKey, String privKey, String passphrase)
|
||||
throws Exception, IOException, InterruptedException {
|
||||
final int port = SocketUtils.findAvailableServerSocket();
|
||||
SshServer server = SshServer.setUpDefaultServer();
|
||||
final PublicKey allowedKey = decodePublicKey();
|
||||
final PublicKey allowedKey = decodePublicKey(pubKey);
|
||||
try {
|
||||
server.setPublickeyAuthenticator(new PublickeyAuthenticator() {
|
||||
|
||||
@@ -122,8 +130,9 @@ public class SftpServerTests {
|
||||
f.setPort(port);
|
||||
f.setUser("user");
|
||||
f.setAllowUnknownKeys(true);
|
||||
InputStream stream = new ClassPathResource("id_rsa").getInputStream();
|
||||
InputStream stream = new ClassPathResource(privKey).getInputStream();
|
||||
f.setPrivateKey(new ByteArrayResource(StreamUtils.copyToByteArray(stream)));
|
||||
f.setPrivateKeyPassphrase(passphrase);
|
||||
Session<LsEntry> session = f.getSession();
|
||||
doTest(server, session);
|
||||
}
|
||||
@@ -132,8 +141,8 @@ public class SftpServerTests {
|
||||
}
|
||||
}
|
||||
|
||||
private PublicKey decodePublicKey() throws Exception {
|
||||
InputStream stream = new ClassPathResource("id_rsa.pub").getInputStream();
|
||||
private PublicKey decodePublicKey(String key) throws Exception {
|
||||
InputStream stream = new ClassPathResource(key).getInputStream();
|
||||
byte[] decodeBuffer = Base64.decodeBase64(StreamUtils.copyToByteArray(stream));
|
||||
ByteBuffer bb = ByteBuffer.wrap(decodeBuffer);
|
||||
int len = bb.getInt();
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.sftp.session;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -44,6 +45,7 @@ import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.integration.test.util.SocketUtils;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.UserInfo;
|
||||
@@ -117,6 +119,41 @@ public class SftpSessionFactoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordPassPhraseViaUserInfo() throws Exception {
|
||||
DefaultSftpSessionFactory f = new DefaultSftpSessionFactory();
|
||||
f.setHost("localhost");
|
||||
f.setPort(9999);
|
||||
f.setUser("user");
|
||||
f.setAllowUnknownKeys(true);
|
||||
UserInfo ui = mock(UserInfo.class);
|
||||
when(ui.getPassword()).thenReturn("pass");
|
||||
when(ui.getPassphrase()).thenReturn("pp").thenReturn(null);
|
||||
f.setUserInfo(ui);
|
||||
UserInfo userInfo = TestUtils.getPropertyValue(f, "userInfoWrapper", UserInfo.class);
|
||||
assertEquals("pass", userInfo.getPassword());
|
||||
f.setPassword("foo");
|
||||
try {
|
||||
userInfo.getPassword();
|
||||
fail("expected Exception");
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
assertThat(e.getMessage(), startsWith("When a 'UserInfo' is provided, 'password' is not allowed"));
|
||||
}
|
||||
assertEquals("pp", userInfo.getPassphrase());
|
||||
f.setPrivateKeyPassphrase("bar");
|
||||
try {
|
||||
userInfo.getPassphrase();
|
||||
fail("expected Exception");
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
assertThat(e.getMessage(), startsWith("When a 'UserInfo' is provided, 'privateKeyPassphrase' is not allowed"));
|
||||
}
|
||||
f.setUserInfo(null);
|
||||
assertEquals("foo", userInfo.getPassword());
|
||||
assertEquals("bar", userInfo.getPassphrase());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultUserInfoFalse() throws Exception {
|
||||
SshServer server = SshServer.setUpDefaultServer();
|
||||
@@ -143,7 +180,7 @@ public class SftpSessionFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomtUserInfoFalse() throws Exception {
|
||||
public void testCustomUserInfoFalse() throws Exception {
|
||||
SshServer server = SshServer.setUpDefaultServer();
|
||||
try {
|
||||
DefaultSftpSessionFactory f = createServerAndClient(server);
|
||||
@@ -171,7 +208,7 @@ public class SftpSessionFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomtUserInfoTrue() throws Exception {
|
||||
public void testCustomUserInfoTrue() throws Exception {
|
||||
SshServer server = SshServer.setUpDefaultServer();
|
||||
try {
|
||||
DefaultSftpSessionFactory f = createServerAndClient(server);
|
||||
|
||||
30
spring-integration-sftp/src/test/resources/id_rsa_pp
Normal file
30
spring-integration-sftp/src/test/resources/id_rsa_pp
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,26D1755B05980BA01B1E8D3B65EF98D3
|
||||
|
||||
J5fMQDf0HrwcnfYujq+q05GEOSEMVWMU0vr0hBtz2WvUeaFBBVAvUWbJo7PHTdDV
|
||||
vEdSv+k8FazOkIZpeOW26pKNaLSuFfN+lgtAW4p4yqGQhbL8byh+Ka5uGaPH1xQj
|
||||
o4exMFqbwFaHG10LJoPp5NnK+T64w8McJEihBPxv/qwtsz0YhhDVl/1eSwKsGa5y
|
||||
Usfdv0QbjNDtpV7+sy7OunpaaKjb8iQ/PbFDsX0TSiy6jJflPwCYVUoh3jCEJze3
|
||||
OUKwoQu7AiHmUrsnLtDuL49Q5hV+f9+IPJlzSqU5Fu8PlfCowH+e8WWLVQkh7Hht
|
||||
iwOQs5UIWH+Nzbguu3Gbph5lqMtgkQwK6/PSFLQXuJmf9l6eo7E+Wh5mFWwoIENT
|
||||
mKUlgVU0ymajPHcA7uOVXl5XX+Mt0DiMdGiB4N6RJ1OjWgqlRSJbVmGPrnZWmjdW
|
||||
VltNux6JrO1bOgwtApCouDZhnP7/JDhM2PCa/F2+XCc6s8Hnmmt+gBw6IM4fb+YH
|
||||
2gf1jx5Onp1yuBGe6tvbrfPAdXYU1R3kd2+Yf5mdsu2+xiC4wBKSfjleoHN4xJ/b
|
||||
wopjQvGV5dj/VjdUt99lMHGWPr+p4NmdEBoriCgjYuRjRDvCiTV2qKZe2MU+0CVE
|
||||
/jCA8iMRQnx3LMjnmJXP/96j2fyXHMowClTF43Cvdc5jh622WITOOFAIq9RfIXdS
|
||||
47G6FAN54V+Qt0pXEgIOmvG+B2C24A041fo3jUPZxFRSYYuv9vG6QJby3kCsaqqt
|
||||
ngYs2JSKx9CfOfGfyPbNt2/CO/bBsXgYzLR7REx5My1Mp9YsDmeIgbcd2V5hw/Me
|
||||
rlSXrG4Eqs9gRDrBUvsydUOJFC1PlnIXH3VSBc6X9o4n2H6XECOsJQSeXLCaeMav
|
||||
deKb0r1HvdbAYrdqw6mRM8Ok3fpSoD3mUsZQ8fp3luO3tHL1lddxHb7EsKzt/ubh
|
||||
B9lEzDTcILlINlCl41X0OZKr/c+Ec8EdaSvITYJj0fvaZmDF7Wcs/dDWNft2XUaD
|
||||
VcptOKbQVE1ufbrc2s1BdKOriAC6dSVKVDrAUQD/MlhT3p/YwbjSY2MqwRKztWRv
|
||||
sA1Kqjg1IdUQzQizRKuHa322qnduLjHy0rb0ElrMpFe3B+OcIPs1E7Gvo4BVQ5jU
|
||||
5GqHm83iaFIQaXmEsrVtCOBygVf00+WNRV3WFTOP9UEWFgtxsaHAU8UZhsDbKcZ5
|
||||
l/w6kQdNElQuJA+1n1OxRZ5wIpfrRIMaxBQg2plUTVb9Tgz1qTZxHIEYPAAePfvX
|
||||
tDn9SBiktj/8dhy1T0ko89yXCekpGxkU9rbmAd4Lrp6Wbc6+bKt4KzAqw319qq9U
|
||||
Pslq7EKNM0Zq5pfwn1MRjzvmyHxz2sYHeij0CmuZY7xuOa4NzXt1vr6nSlIpX77W
|
||||
ng/Rnd7qpyG2IWYihi6ztFHyj9h3FEcBHMk4JINLcdYOxXICz3KsRMfntrwQ4E6O
|
||||
NFJ3fPpVNkk4GZcxy6idNkUBz1s8ixVWC8yi36byxE+TTRtcvqXQnJVgs63vMUlC
|
||||
HVwaGau4YeUp4Nj2ZO44Srd/kQRy8yuCOPDdlJEiO6eDD4+XKedJQg1LuGeoXMVn
|
||||
-----END RSA PRIVATE KEY-----
|
||||
1
spring-integration-sftp/src/test/resources/id_rsa_pp.pub
Normal file
1
spring-integration-sftp/src/test/resources/id_rsa_pp.pub
Normal file
@@ -0,0 +1 @@
|
||||
AAAAB3NzaC1yc2EAAAADAQABAAABAQC6MIzgyVi8G1+HRhFHPWRH+3w/8/uxtiuIfb4puVPjHI53Lvf5odzfhv0T6Z2/jSXmI3I6dpjbsgiptdCTX4kqUFLXxkuJR4LHatNtgO1w32aVIdAvfj7KtrL3SmP2XWqQGVcUWHEn2H1RHFHKdC6ArYFb1X8p5N/BHSQjuttaeVi9FsDxvC5euIbtDEEJmmvjjfWlI1m/6qCqMYxDWA9i9APU/rB0QwFNUQ6HuZ2QzEaU/hQMGmqgW5o1I/W8JR0bqis8wZQDLv1fwCkXpWG5BAuiJH+FJMxRAkfEMBpVwO7Sl0ufePVuSM2BMAAe+4a75sVp8ahbOId6y0GUTeJl
|
||||
Reference in New Issue
Block a user