Skip to content

Commit

Permalink
Merge pull request #119 from peggy-ntt/sftp/publicKey
Browse files Browse the repository at this point in the history
sftp-public key authentication -code
  • Loading branch information
alexjoybc authored Sep 13, 2019
2 parents 70274cb + a933b9e commit 73567d1
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 15 deletions.
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ It support the [Common Options](#CommonOptions) and the following options:
| [bcgov.access.input.sftp.max-message-per-poll](#bcgovaccessinputsftpmaxmesssageperpoll) | String | No |
| [bcgov.access.input.sftp.ssh-private-key](#bcgovaccessinputsftpsshprivatekey) | Resource | No |
| [bcgov.access.input.sftp.ssh-private-passphrase](#bcgovaccessinputsftpsshprivatepassphrase) | String | No |
| [bcgov.access.input.sftp.allow-unknown-key](#bcgovaccessinputsftpallowunknownkey) | boolean | No |
| [bcgov.access.input.sftp.known-host-file](#bcgovaccessinputsftpknownhostfile) | String | Yes (if allow-unknown-key is false) |


##### bcgov.access.input.sftp.host

Expand Down Expand Up @@ -259,6 +262,19 @@ Sets the location of the private key.

Sets the passphrase for the private key.

##### bcgov.access.input.sftp.allow-unknown-key

* Value type is Boolean
* Default value is false
* When no UserInfo has been provided, set to true to unconditionally allow connecting to an unknown host or when a host's key has changed (see knownHosts)

##### bcgov.access.input.sftp.known-host-file

* Value type is String
* Specifies the filename that will be used for a host key repository. The file has the same format as OpenSSH's known_hosts file.
* If allow-unknown-key is false, this property must be set correctly, or KnownHostFileNotDefinedException or KnownHostFileNotFoundException will be thrown.
* If allow-unknown-key is true, this property will be ignored.

## Output Plugins

You can configure the document input using `bcgov.access.output` property.
Expand Down Expand Up @@ -449,22 +465,33 @@ To view the message in a queue, login to [rabbitmq management console](http://lo
![binding](docs/document.ready.bind.png)

####if you want to run the sample app using sftp do the following:
Create a sftp server container

step 1. Create a sftp server container (from WindowsPowerShell or GitBash)
```bash
docker run -p 22:22 -d atmoz/sftp myname:pass:::upload
```
User "myname" with password "pass" can login with sftp and upload files to a folder called "upload". We are forwarding the container's port 22 to the host's port 22.
Use a Sftp Client application ( such as Fillzilla, WinSCP, coreFTP) to connect to the server.(use sftp protocal and ip: localhost, port:22)
update the [application.yml](jrcc-access-spring-boot-sample-app/src/main/resources/application.yml)

step 2. User "myname" with password "pass" can login with sftp and upload files to a folder called "upload". We are forwarding the container's port 22 to the host's port 22.

step 3. Use a Sftp Client application ( such as Filezilla, WinSCP, coreFTP) to connect to the server.(use sftp protocal and ip: localhost, port:22)

step 4. If you do not want unconditionally allow connecting to an unknown host or when a host's key has changed, you need to provide known_hosts file.
User following command to generate known_hosts file for started sftp server (from WindowsPowerShell or GitBash).
```bash
ssh-keyscan -v -p 22 localhost>>known_hosts
```
step 5. Update the [application.yml](jrcc-access-spring-boot-sample-app/src/main/resources/application.yml)
```properties
spring:
main:
web-application-type: none
main:
web-application-type: none
logging:
level:
ca:
gov:
bc: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} %X{transaction.filename} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} %X{transaction.filename} - %msg%n"
bcgov:
access:
input:
Expand All @@ -478,6 +505,8 @@ bcgov:
remote-directory: /upload
max-message-per-poll: 5
cron: 0/5 * * * * *
allow-unknown-keys: false
known-host-file: C:\Users\user\.ssh\known_hosts
output:
document-type: test-doc
plugin: console
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ca.bc.gov.open.jrccaccess.autoconfigure.config.exceptions;

/**
* An exception which is thrown when using sftp known_hosts file is not defined in configuration while allowUnknownKey is set to false.
*
*/
public class KnownHostFileNotDefinedException extends InvalidConfigException {
/**
* Constructs a new KnownHostFileNotDefinedException with the specified detail message.
*
* @param message the detail message. The detail message is saved for later retrieval by the Throwable.getMessage() method.
*/
public KnownHostFileNotDefinedException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ca.bc.gov.open.jrccaccess.autoconfigure.config.exceptions;

/**
* An exception which is thrown when application cannot find specified known_hosts file.
*/
public class KnownHostFileNotFoundException extends InvalidConfigException{
/**
* Constructs a new InvalidConfigException with the specified detail message.
*
* @param message the detail message. The detail message is saved for later retrieval by the Throwable.getMessage() method.
*/
public KnownHostFileNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package ca.bc.gov.open.jrccaccess.autoconfigure.plugins.sftp;

import ca.bc.gov.open.jrccaccess.autoconfigure.config.exceptions.InvalidConfigException;
import ca.bc.gov.open.jrccaccess.autoconfigure.config.exceptions.KnownHostFileNotDefinedException;
import ca.bc.gov.open.jrccaccess.autoconfigure.config.exceptions.KnownHostFileNotFoundException;
import com.jcraft.jsch.ChannelSftp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -20,6 +23,7 @@
import org.springframework.integration.sftp.session.SftpRemoteFileTemplate;

import javax.websocket.MessageHandler;
import java.io.File;
import java.io.InputStream;

@Configuration
Expand All @@ -45,7 +49,7 @@ public AutoConfiguration(SftpInputProperties sftpInputProperties) {


@Bean
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() throws InvalidConfigException {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(properties.getHost());
factory.setPort(properties.getPort());
Expand All @@ -56,13 +60,32 @@ public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
} else {
factory.setPassword(properties.getPassword());
}
factory.setAllowUnknownKeys(true);
boolean isAllowUnknownKeys = properties.isAllowUnknownKeys();
factory.setAllowUnknownKeys(isAllowUnknownKeys);
if(!isAllowUnknownKeys){
String knownHostFileStr = properties.getKnownHostFile();
if(knownHostFileStr == null || knownHostFileStr == "" )
throw new KnownHostFileNotDefinedException("Must define known_hosts file when allow-unknown-keys is false. ");

File knownHostFile = new File(knownHostFileStr);
if( ! knownHostFile.exists() )
throw new KnownHostFileNotFoundException("Cannot find known_hosts file when allow-unknown-keys is false.");

factory.setKnownHosts(properties.getKnownHostFile());
}

return new CachingSessionFactory<>(factory);
}

@Bean
public SftpRemoteFileTemplate template() {
return new SftpRemoteFileTemplate(sftpSessionFactory());
try {
return new SftpRemoteFileTemplate(sftpSessionFactory());
}catch(InvalidConfigException ex)
{
logger.error(ex.getMessage());
}
return null;
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import javax.validation.constraints.Min;

/**
* Represents the rabbitmq output plugin properties
* Represents the rabbitmq input plugin properties
* @author alexjoybc
* @since 0.6.0
*
Expand Down Expand Up @@ -37,6 +37,10 @@ public class SftpInputProperties {

private String sshPrivatePassphrase;

private boolean allowUnknownKeys;

private String knownHostFile;

public String getRemoteDirectory() {
return remoteDirectory;
}
Expand Down Expand Up @@ -119,4 +123,34 @@ public void setSshPrivatePassphrase(String sshPrivatePassphrase) {
this.sshPrivatePassphrase = sshPrivatePassphrase;
}

/**
* @return if allow Unknown Keys
*/
public boolean isAllowUnknownKeys() {
return this.allowUnknownKeys;
}

/**
* Set to true to unconditionally allow connecting to an unknown host or when a host's key has changed (see knownHosts).
* Default false. Set to true if a knownHosts file is not provided.
* @param allowUnknowKeys : true or false
*/
public void setAllowUnknownKeys(boolean allowUnknowKeys) {
this.allowUnknownKeys = allowUnknowKeys;
}

/**
* @return the filename that will be used for a host key repository. The file has the same format as OpenSSH's known_hosts file.
*/
public String getKnownHostFile() {
return this.knownHostFile;
}

/**
* set the known_hosts file name, including path
* @param knownHostFile
*/
public void setKnownHostFile(String knownHostFile) {
this.knownHostFile = knownHostFile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,29 @@ public void with_ssh_key_should_return_ssh_key() {
}


@Test
public void default_allow_unknown_key_return_false() {
SftpInputProperties sut = new SftpInputProperties();
Assert.assertFalse(sut.isAllowUnknownKeys());
}

@Test
public void set_allow_unknown_key_should_succeed() {
SftpInputProperties sut = new SftpInputProperties();
sut.setAllowUnknownKeys(true);
Assert.assertTrue(sut.isAllowUnknownKeys());
}

@Test
public void default_get_known_hosts_return_null() {
SftpInputProperties sut = new SftpInputProperties();
Assert.assertNull(sut.getKnownHostFile());
}

@Test
public void set_known_hosts_should_succeed() {
SftpInputProperties sut = new SftpInputProperties();
sut.setKnownHostFile("c://test//known_hosts");
Assert.assertEquals(sut.getKnownHostFile(), "c://test//known_hosts");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
spring:
main:
web-application-type: none
main:
web-application-type: none
logging:
level:
ca:
Expand All @@ -16,4 +15,4 @@ bcgov:
plugin: console
output:
document-type: test-doc
plugin: console
plugin: console

0 comments on commit 73567d1

Please sign in to comment.