Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## 1.5.0 - 2025-06-18

* Supports HTTP and SOCKS5 proxy
* Add example code `s3stream` for scanning an S3 object as an implementation of `AMaasReader`

## 1.4.5 - 2025-03-03

* Support new region me-central-1
Expand Down
107 changes: 100 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,17 @@ public static void main(String[] args) {
try {
// 1. Create an AMaaS Client object and configure it to carry out the scans in Vision One "us-east-1" region.
AMaasClient client = new AMaasClient("us-east-1", "your-api-key");

// 2. Call ScanFile() to scan the content of a file.
String scanResult = client.scanFile("path-of-file-to-scan");

if (scanResult != null) {
// 3. Print out the JSON response from ScanFile()
System.out.println("scan result " + scanResult);
try {
// 2. Call ScanFile() to scan the content of a file.
String scanResult = client.scanFile("path-of-file-to-scan");

if (scanResult != null) {
// 3. Print out the JSON response from ScanFile()
System.out.println("scan result " + scanResult);
}
} finally {
// 4. Always close the client to release resources
client.close();
}
} catch (AMaasException err) {
info("Exception {0}", err.getMessage());
Expand Down Expand Up @@ -218,6 +222,26 @@ Scan a file for malware, add a list of tags to the scan result and retrieves res
**_Return_**
String the scanned result in JSON format.

#### ```public String scanRun(final AMaasReader reader, final String[] tagList, final boolean pml, final boolean feedback, final boolean verbose, final boolean digest) throws AMaasException```

Scan an AMaasReader for malware and retrieves response data from the API. This is the core scanning method that provides the most flexibility by accepting an AMaasReader interface, allowing for different types of data sources.

**_Parameters_**

| Parameter | Description |
| ------------- | ---------------------------------------------------------------------------------------- |
| reader | `AMaasReader` to be scanned. This can be an `AMaasFileReader` or any custom implementation you develop to support your specific data sources. |
| tagList | A list of strings to be used to tag the scan result. At most 8 tags with the maximum length of 63 characters. |
| pml | A flag to indicate whether to use predictive machine learning detection. |
| feedback | A flag to indicate whether to use Trend Micro Smart Protection Network's Smart Feedback. |
| verbose | A flag to enable log verbose mode. |
| digest | A flag to enable calculation of digests for cache search and result lookup. |

**_Return_**
String the scanned result in JSON format.

**_Note_**: For an example of implementing a custom AMaasReader, please refer to the `examples/s3stream/S3Stream.java` code which demonstrates a streaming implementation of the AMaasReader interface.

#### ```public String scanBuffer(final byte[] buffer, final String identifier) throws AMaasException```

Scan a buffer for malware and retrieves response data from the API.
Expand Down Expand Up @@ -360,3 +384,72 @@ The File Security SDK consistently adopts TLS as the default communication chann
For customers who need to enable TLS channel encryption without verifying the provided CA certificate, the `TM_AM_DISABLE_CERT_VERIFY` environment variable can be set. However, this option is only recommended for use in testing environments.

When `TM_AM_DISABLE_CERT_VERIFY` is set to `1`, certificate verification is disabled. By default, the certificate will be verified.

## Proxy Configuration

The File Security Java SDK supports HTTP and SOCKS5 proxy configurations through environment variables. This allows the SDK to work in enterprise environments that require proxy servers for internet access.

### Supported Environment Variables

| Environment Variable | Required/Optional | Description |
| -------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HTTP_PROXY` | Optional | HTTP proxy URL for HTTP connections (e.g., `http://proxy.example.com:8080`) |
| `HTTPS_PROXY` | Optional | Proxy URL for HTTPS connections (e.g., `https://proxy.example.com:8443` or `socks5://socks.example.com:1080`) |
| `NO_PROXY` | Optional | Comma-separated list of host names to bypass proxy (e.g., `localhost,127.0.0.1,*.local`). Use `*` to bypass proxy for all hosts |
| `PROXY_USER` | Optional | Username for proxy authentication (used with `Proxy-Authorization` header) |
| `PROXY_PASS` | Optional | Password for proxy authentication (used only when `PROXY_USER` is configured) |

### Proxy Configuration Examples

#### Basic HTTP Proxy
```bash
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
```

#### SOCKS5 Proxy
```bash
export HTTPS_PROXY=socks5://socks-proxy.company.com:1080
```

**Important:** When using SOCKS5 proxy, ensure you call `client.close()` to properly release network resources. The SDK creates background threads for SOCKS5 connections that must be explicitly closed.

```java
AMaasClient client = new AMaasClient("us-east-1", "your-api-key");
try {
// Perform scanning operations
String result = client.scanFile("file.txt");
} finally {
// Always close the client when using SOCKS5 proxy
client.close();
}
```

#### Proxy with Authentication
```bash
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=https://secure-proxy.company.com:8443
export PROXY_USER=username
export PROXY_PASS=password
```

#### Bypassing Proxy for Specific Hosts
```bash
export HTTP_PROXY=http://proxy.company.com:8080
export NO_PROXY=localhost,127.0.0.1,*.internal.company.com
```

#### Disabling Proxy for All Connections
```bash
export NO_PROXY=*
```

### Notes

- The SDK automatically detects and uses proxy settings from environment variables
- For HTTPS connections, `HTTPS_PROXY` takes precedence over `HTTP_PROXY`
- SOCKS5 proxies are supported by specifying `socks5://` in the proxy URL
- Proxy authentication requires both `PROXY_USER` and `PROXY_PASS` to be set
- The `NO_PROXY` variable supports wildcards (e.g., `*.local`) and exact matches
- No code changes are required - simply set the appropriate environment variables before running your application
- **Resource Management:** Always call `client.close()` when finished, especially when using SOCKS5 proxies, to ensure proper cleanup of network resources and prevent applications from hanging
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.4.5
1.5.0
17 changes: 17 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ There are 4 examples under the following sub-folders:

3. After a build, the targeted jar(s) will be created under a newly created `target` folder under the respective example folder. For instance, `examples/filescan/target`.

## Important: Resource Management

All examples have been updated to properly manage AMaasClient resources. When using the SDK in your own applications, especially with SOCKS5 proxies, always ensure you call `client.close()` to release network resources:

```java
AMaasClient client = new AMaasClient("us-east-1", "your-api-key");
try {
// Perform scanning operations
String result = client.scanFile("file.txt");
} finally {
// Always close the client to release resources
client.close();
}
```

**Note:** Failure to properly close the client, particularly when using SOCKS5 proxies, may cause your application to hang as background network threads remain active.

### Use CLI examples

- `filescan`: This example is to scan a file or a folder sequentially. It takes 4 input options:
Expand Down
17 changes: 11 additions & 6 deletions examples/filescan/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static void scanFilesInSequential(final AMaasClient client, final String[] fList
private static Options getCmdOptions() {
Options optionList = new Options();
optionList.addRequiredOption("f", "filename", true, "File path or folder to be scanned");
optionList.addRequiredOption("k", "apikey", true, "Cloud One API key");
optionList.addRequiredOption("k", "apikey", true, "Vision One API key");
optionList.addRequiredOption("r", "region", true, "AMaaS service region to used. Ignore if self hosted.");
optionList.addOption("a", "addr", true, "host ip address of self hosted AMaaS scanner. Ignore if to use Trend AMaaS service");
optionList.addOption("t", "timeout", true, "Per scan timeout in seconds");
Expand Down Expand Up @@ -146,13 +146,18 @@ public static void main(final String[] args) {
}

AMaasClient client = new AMaasClient(region, addr, apikey, timeout, true, caCertPath);
String[] listOfFiles = listFiles(pathname);
long totalStartTs = System.currentTimeMillis();
try {
String[] listOfFiles = listFiles(pathname);
long totalStartTs = System.currentTimeMillis();

scanFilesInSequential(client, listOfFiles, tagList, pmlFlag, feedbackFlag, verbose, digest);
scanFilesInSequential(client, listOfFiles, tagList, pmlFlag, feedbackFlag, verbose, digest);

long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
} finally {
// Ensure client resources are properly closed
client.close();
}
} catch (ParseException err) {
helper.printHelp("Usage:", optionList);
} catch (NumberFormatException err) {
Expand Down
17 changes: 11 additions & 6 deletions examples/parallelscan/ConcurrentApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static void scanFilesInParallel(final AMaasClient client, final String[] fList,
private static Options getCmdOptions() {
Options optionList = new Options();
optionList.addRequiredOption("f", "filename", true, "File path or folder to be scanned");
optionList.addRequiredOption("k", "apikey", true, "Cloud One API key");
optionList.addRequiredOption("k", "apikey", true, "Vision One API key");
optionList.addRequiredOption("r", "region", true, "AMaaS service region");
optionList.addOption("t", "timeout", true, "Per scan timeout in seconds");
return optionList;
Expand Down Expand Up @@ -167,11 +167,16 @@ public static void main(final String[] args) {
timeout = Long.parseLong(cmd.getOptionValue("t"));
}
AMaasClient client = new AMaasClient(region, apikey, timeout);
String[] listOfFiles = listFiles(pathName);
long totalStartTs = System.currentTimeMillis();
scanFilesInParallel(client, listOfFiles, timeout);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
try {
String[] listOfFiles = listFiles(pathName);
long totalStartTs = System.currentTimeMillis();
scanFilesInParallel(client, listOfFiles, timeout);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
} finally {
// Ensure client resources are properly closed
client.close();
}
} catch (ParseException err) {
helper.printHelp("Usage:", optionList);
} catch (NumberFormatException err) {
Expand Down
20 changes: 7 additions & 13 deletions examples/pom.xml
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.trend</groupId>
<artifactId>file-security-sdk-examples</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<name>file-security-sdk-examples</name>
<modules>
<module>filescan</module>
<module>parallelscan</module>
<module>s3app</module>
<module>s3lambda</module>
<module>s3stream</module>
</modules>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
Expand Down Expand Up @@ -52,29 +47,28 @@
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.68.0</version>
<version>1.73.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.68.0</version>
<version>1.73.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>1.68.0</version>
<version>1.73.0</version>
</dependency>
<dependency>
<groupId>com.trend</groupId>
<artifactId>file-security-java-sdk</artifactId>
<version>[1.0,)</version>
</dependency>

</dependencies>

<build>
<sourceDirectory>.</sourceDirectory>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<pluginManagement>
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
Expand Down
21 changes: 13 additions & 8 deletions examples/s3app/S3App.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private static Options getCmdOptions() {
optionList.addRequiredOption("a", "awsregion", true, "AWS region");
optionList.addRequiredOption("b", "bucket", true, "S3 bucket name");
optionList.addRequiredOption("f", "S3key", true, "S3 key to be scanned");
optionList.addRequiredOption("k", "apikey", true, "Cloud One API key");
optionList.addRequiredOption("k", "apikey", true, "Vision One API key");
optionList.addRequiredOption("r", "region", true, "AMaaS service region");
optionList.addOption("t", "timeout", true, "Per scan timeout in seconds");
return optionList;
Expand All @@ -79,7 +79,7 @@ private static Options getCmdOptions() {
* -b S3 bucket name
* -f S3 key to be scanned
* -k the API key or bearer authentication token
* -r region where the C1 key/token was applied. eg, us-east-1
* -r region where the V1 key/token was applied. eg, us-east-1
* -t optional client maximum waiting time in seconds for a scan. 0 or missing means default.
*/
public static void main(final String[] args) {
Expand All @@ -105,10 +105,10 @@ public static void main(final String[] args) {
keyName = cmd.getOptionValue("f");
}
if (cmd.hasOption("r")) {
apikey = cmd.getOptionValue("r");
amaasRegion = cmd.getOptionValue("r");
}
if (cmd.hasOption("k")) {
amaasRegion = cmd.getOptionValue("k");
apikey = cmd.getOptionValue("k");
}
if (cmd.hasOption("t")) {
timeout = Long.parseLong(cmd.getOptionValue("t"));
Expand All @@ -117,10 +117,15 @@ public static void main(final String[] args) {
byte[] bytes = downloadS3Object(awsRegion, bucketName, keyName);
info("Completed downloading S3 Object....");
AMaasClient client = new AMaasClient(amaasRegion, apikey, timeout);
long totalStartTs = System.currentTimeMillis();
client.scanBuffer(bytes, keyName);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
try {
long totalStartTs = System.currentTimeMillis();
client.scanBuffer(bytes, keyName);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
} finally {
// Ensure client resources are properly closed
client.close();
}
} catch (ParseException err) {
helper.printHelp("Usage:", optionList);
} catch (NumberFormatException err) {
Expand Down
17 changes: 11 additions & 6 deletions examples/s3lambda/S3Lambda.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private static void sequentialScan(final AMaasClient client, final S3Client s3cl
* It can scan either a specific S3 key or a folder under a S3 bucket.
*
* TM_AM_AUTH_KEY the API key or bearer authentication token
* TM_AM_REGION region where the C1 key/token was applied. eg, us-east-1
* TM_AM_REGION region where the V1 key/token was applied. eg, us-east-1
* TM_AM_SCAN_TIMEOUT_SECS client maximum waiting time in seconds for a scan. 0 or missing means default.
*
* S3_BUCKET_NAME S3 bucket name
Expand Down Expand Up @@ -159,11 +159,16 @@ public String handleRequest(final Object input, final Context context) {
}

AMaasClient client = new AMaasClient(region, apikey, timeout);
long totalStartTs = System.currentTimeMillis();

sequentialScan(client, s3client, bucketName, keyList, tagList);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
try {
long totalStartTs = System.currentTimeMillis();

sequentialScan(client, s3client, bucketName, keyList, tagList);
long totalEndTs = System.currentTimeMillis();
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
} finally {
// Ensure client resources are properly closed
client.close();
}
} catch (Exception err) {
info("Exception encountered {0}", err);
}
Expand Down
Loading