Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add security to FTP #276

Merged
merged 15 commits into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,19 @@ ext.testngVersion = "6.14.3"
ext.slf4jVersion = "1.7.30"
ext.javaFtpVersion = "1.6.2"
ext.fileTransportVersion = "6.0.57"
ext.commonsVfsVersion="2.6.0"
ext.commonsVfsVersion="2.2-wso2v1"
ext.commonsNetVersion="3.6"
ext.jschVersion= "0.1.54"
ext.mockFtpServerVersion= "2.7.1"
ext.sshdMinaVersion= "1.1.1"
ext.ftpServerVersion = "1.1.1"
ext.jcraftVersion = "0.1.54"
ext.bouncycastleVersion = "1.58"
ext.sshdCoreVersion = "1.7.0"
ext.ftpletApiVersion = "1.1.1"
ext.minaCoreVersion = "2.0.16"
ext.aopallianceVersion = "1.0"
ext.jclSlf4jVersion = "1.7.21"

allprojects {
group = 'org.ballerinalang'
Expand Down Expand Up @@ -122,11 +131,6 @@ subprojects {
ballerinaStdLibs "org.ballerinalang:log-ballerina:${stdlibLogVersion}"
ballerinaStdLibs "org.ballerinalang:io-ballerina:${stdlibIoVersion}"
ballerinaStdLibs "org.ballerinalang:task-ballerina:${stdlibTaskVersion}"
ballerinaStdLibs "org.wso2.transport.file:org.wso2.transport.remote-file-system:${fileTransportVersion}"
ballerinaStdLibs "org.mockftpserver:MockFtpServer:${mockFtpServerVersion}"
ballerinaStdLibs "org.slf4j:slf4j-api:${slf4jVersion}"
ballerinaStdLibs "org.testng:testng:${testngVersion}"
ballerinaStdLibs "org.apache.commons:commons-vfs2:${commonsVfsVersion}"
ballerinaStdLibs "org.ballerinalang:time-ballerina:${stdlibTimeVersion}"
}
}
Expand Down
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added
- [[#1438] Add SFTP and related security](https://github.com/ballerina-platform/ballerina-standard-library/issues/1438)

### Changed
- [[#1345] Introduce byte stream related functionality to FTP module](https://github.com/ballerina-platform/ballerina-standard-library/issues/1345)
- [[#1388] Add verification for tests](https://github.com/ballerina-platform/ballerina-standard-library/issues/1388)
62 changes: 59 additions & 3 deletions ftp-ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ name = "ftp"
version = "@toml.version@"

[[platform.java11.dependency]]
path = "./lib/commons-vfs2-2.6.0.jar"
groupId = "org.apache.commons"
path = "./lib/commons-vfs2-2.2-wso2v1.jar"
groupId = "org.wso2.org.apache.commons"
artifactId = "commons-vfs2"
version = "2.6.0"
version = "2.2-wso2v1"


[[platform.java11.dependency]]
path = "./lib/jsch-0.1.54.jar"
groupId = "com.jcraft"
artifactId = "jsch"
version = "0.1.54"


[[platform.java11.dependency]]
Expand All @@ -31,6 +38,55 @@ artifactId = "MockFtpServer"
version = "2.7.1"


[[platform.java11.dependency]]
path = "./lib/bcprov-jdk15on-1.58.jar"
groupId = "org.bouncycastle"
artifactId = "bcprov-jdk15on"
version = "1.58"


[[platform.java11.dependency]]
path = "./lib/sshd-core-1.7.0.jar"
groupId = "org.apache.sshd"
artifactId = "sshd-core"
version = "1.7.0"


[[platform.java11.dependency]]
path = "./lib/ftpserver-core-1.1.1.jar"
groupId = "org.apache.ftpserver"
artifactId = "ftpserver-core"
version = "1.1.1"


[[platform.java11.dependency]]
path = "./lib/ftplet-api-1.1.1.jar"
groupId = "org.apache.ftpserver"
artifactId = "ftplet-api"
version = "1.1.1"


[[platform.java11.dependency]]
path = "./lib/mina-core-2.0.16.jar"
groupId = "org.apache.mina"
artifactId = "mina-core"
version = "2.0.16"


[[platform.java11.dependency]]
path = "./lib/aopalliance-1.0.jar"
groupId = "aopalliance"
artifactId = "aopalliance"
version = "1.0"


[[platform.java11.dependency]]
path = "./lib/jcl-over-slf4j-1.7.21.jar"
groupId = "org.slf4j"
artifactId = "jcl-over-slf4j"
version = "1.7.21"


[[platform.java11.dependency]]
path = "./lib/org.wso2.transport.remote-file-system-6.0.57.jar"
groupId = "org.wso2.transport.file"
Expand Down
18 changes: 9 additions & 9 deletions ftp-ballerina/Module.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ The `ftp:Client` connects to an FTP server and performs various operations on th
generic FTP operations; `get`, `delete`, `put`, `append`, `mkdir`, `rmdir`, `isDirectory`, `rename`, `size`, and
`list`.

An FTP client endpoint is defined using the `protocol` and `host` parameters and optionally the `port` and
`secureSocket`. Authentication configuration can be configured using the `secureSocket` parameter for Basic Auth,
private key, or TrustStore/Keystore.
An FTP client is defined using the `protocol` and `host` parameters and optionally the `port` and
`auth`. Authentication configuration can be configured using the `auth` parameter for Basic Auth and
private key.

##### Creating a Client

The following code creates an FTP client and performs the I/O operations, which connect to the FTP server with Basic Auth.
```ballerina
// Define the FTP client configuration.
ftp:ClientEndpointConfig ftpConfig = {
ftp:ClientConfiguration ftpConfig = {
protocol: ftp:FTP,
host: "<The FTP host>",
port: <The FTP port>,
secureSocket: {
auth: {
basicAuth: {
username: "<The FTP username>",
password: "<The FTP passowrd>"
Expand Down Expand Up @@ -121,11 +121,11 @@ The `ftp:Listener` is used to listen to a remote FTP location and trigger a `Wat
files are added to or deleted from the directory. The `fileResource` function is invoked when a new file is added
and/or deleted.

An FTP listener endpoint is defined using the mandatory `protocol`, `host`, and `path` parameters. The authentication
configuration can be done using a `secureSocket` and the polling interval can be configured using the `pollingInterval` parameter.
An FTP listener is defined using the mandatory `protocol`, `host`, and `path` parameters. The authentication
configuration can be done using a `auth` and the polling interval can be configured using the `pollingInterval` parameter.
The default polling interval is 60 seconds.

The `fileNamePattern` parameter can be used to define the type of files the FTP listener endpoint will listen to.
The `fileNamePattern` parameter can be used to define the type of files the FTP listener will listen to.
For instance, if the listener gets invoked for text files, the value `(.*).txt` can be given for the config.

##### Creating a Listener
Expand All @@ -137,7 +137,7 @@ notify on file addition and deletion periodically.
listener ftp:Listener remoteServer = new({
protocol: ftp:FTP,
host: "<The FTP host>",
secureSocket: {
auth: {
basicAuth: {
username: "<The FTP username>",
password: "<The FTP passowrd>"
Expand Down
2 changes: 1 addition & 1 deletion ftp-ballerina/Package.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Package Overview

The `ftp` library is one of the standard library packages of the<a target="_blank" href="https://ballerina.io/"> Ballerina</a> language.
The `ftp` library is one of the standard library packages of the [Ballerina](https://ballerina.io/) language.

It provides an implementation for performing CRUD operations on remote FTP servers via the FTP protocol.

Expand Down
26 changes: 25 additions & 1 deletion ftp-ballerina/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ configurations {
}

dependencies {
externalJars(group: 'org.apache.commons', name: 'commons-vfs2', version: "${commonsVfsVersion}") {
externalJars(group: 'org.wso2.org.apache.commons', name: 'commons-vfs2', version: "${commonsVfsVersion}") {
transitive = false
}
externalJars(group: 'com.jcraft', name: 'jsch', version: "${jcraftVersion}") {
transitive = false
}
externalJars(group: 'commons-net', name: 'commons-net', version: "${commonsNetVersion}") {
Expand All @@ -75,6 +78,27 @@ dependencies {
externalJars(group: 'org.mockftpserver', name: 'MockFtpServer', version: "${mockFtpServerVersion}") {
transitive = false
}
externalJars(group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: "${bouncycastleVersion}") {
transitive = false
}
externalJars(group: 'org.apache.sshd', name: 'sshd-core', version: "${sshdCoreVersion}") {
transitive = false
}
externalJars(group: 'org.apache.ftpserver', name: 'ftpserver-core', version: "${ftpServerVersion}") {
transitive = false
}
externalJars(group: 'org.apache.ftpserver', name: 'ftplet-api', version: "${ftpletApiVersion}") {
transitive = false
}
externalJars(group: 'org.apache.mina', name: 'mina-core', version: "${minaCoreVersion}") {
transitive = false
}
externalJars(group: 'aopalliance', name: 'aopalliance', version: "${aopallianceVersion}") {
transitive = false
}
externalJars(group: 'org.slf4j', name: 'jcl-over-slf4j', version: "${jclSlf4jVersion}") {
transitive = false
}
externalJars(group: 'org.testng', name: 'testng', version: "${testngVersion}") {
transitive = false
}
Expand Down
18 changes: 9 additions & 9 deletions ftp-ballerina/client_endpoint.bal
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@
// specific language governing permissions and limitations
// under the License.

// FTP Client Endpoint
// FTP Client

import ballerina/io;
import ballerina/log;
import ballerina/jballerina.java;

# Represents an FTP client that intracts with an FTP server
public isolated client class Client {
private final readonly & ClientEndpointConfig config;
private final readonly & ClientConfiguration config;

# Gets invoked during object initialization.
#
# + clientConfig - Configurations for FTP client endpoint
public isolated function init(ClientEndpointConfig clientConfig) {
# + clientConfig - Configurations for FTP client
public isolated function init(ClientConfiguration clientConfig) {
self.config = clientConfig.cloneReadOnly();
Error? response = initEndpoint(self, self.config);
if (response is Error) {
Expand Down Expand Up @@ -174,17 +174,17 @@ public isolated client class Client {
}
}

# Configuration for FTP client endpoint.
# Configuration for FTP client.
#
# + protocol - Supported FTP protocols
# + host - Target service URL
# + port - Port number of the remote service
# + secureSocket - Authenthication options
public type ClientEndpointConfig record {|
# + auth - Authenthication options
public type ClientConfiguration record {|
Protocol protocol = FTP;
string host = "127.0.0.1";
int? port = 21;
SecureSocket? secureSocket = ();
int port = 21;
AuthConfiguration auth?;
|};

isolated function getInputContent(string path, stream<byte[] & readonly, io:Error?>|string|xml|json content,
Expand Down
30 changes: 12 additions & 18 deletions ftp-ballerina/commons.bal
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,38 @@
import ballerina/io;

# Represents the set of protocols supported by the FTP listener and client
public type Protocol "ftp"|"sftp"|"ftps";
public type Protocol "ftp"|"sftp";

# Underlying communication happens using FTP
public const FTP = "ftp";
# Underlying communication happens using SFTP
public const SFTP = "sftp";
# Underlying communication happens using FTPS.
public const FTPS = "ftps";

# Configuration to connect to a trust store.
#
# + path - Path to a trust store file
# + password - Trust store password
public type TrustStore record {|
string? path = ();
string? password = ();
string path?;
string password?;
|};

# Configuration to connect to a key store.
#
# + path - Path to the key store file
# + password - Key store password
public type KeyStore record {|
string? path = ();
string? password = ();
string path?;
string password?;
|};

# Configuration to read a privte key.
#
# + path - Path to the private key file
# + password - Private key password
public type PrivateKey record {|
string? path = ();
string? password = ();
string path?;
string password?;
|};

# Basic Auth related configurations.
Expand All @@ -65,15 +63,11 @@ public type BasicAuth record {|
# Configurations for facilitating secure communication with a remote
# FTP server.
#
# + trustStore - Trust store to be used
# + keyStore - Key store to be used
# + basicAuth - Username and password to be used
# + privateKey - Private key to be used
public type SecureSocket record {|
TrustStore? trustStore = ();
KeyStore? keyStore = ();
BasicAuth? basicAuth = ();
PrivateKey? privateKey = ();
public type AuthConfiguration record {|
BasicAuth basicAuth?;
PrivateKey privateKey?;
|};

# Configuration for the input given for `put` and `append` operations of
Expand All @@ -87,7 +81,7 @@ public type SecureSocket record {|
public type InputContent record{|
string filePath;
boolean isFile = false;
stream<byte[] & readonly, io:Error?>? fileContent = ();
string? textContent = ();
stream<byte[] & readonly, io:Error?> fileContent?;
string textContent?;
boolean compressInput = false;
|};
4 changes: 2 additions & 2 deletions ftp-ballerina/external_functions.bal
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ isolated function isDirectory(Client clientEndpoint, handle path) returns boolea
'class: "org.ballerinalang.stdlib.ftp.client.FTPClient"
} external;

isolated function poll(ListenerConfig config) returns Error? = @java:Method{
isolated function poll(ListenerConfiguration config) returns Error? = @java:Method{
name: "poll",
'class: "org.ballerinalang.stdlib.ftp.server.FTPListenerHelper"
} external;

isolated function register(Listener listenerEndpoint, ListenerConfig config, service object {} ftpService, handle name)
isolated function register(Listener listenerEndpoint, ListenerConfiguration config, service object {} ftpService, handle name)
returns handle|Error = @java:Method{
name: "register",
'class: "org.ballerinalang.stdlib.ftp.server.FTPListenerHelper"
Expand Down
Loading