Skip to content

Commit 0d690d2

Browse files
authored
Merge pull request #24 from trendmicro/update_to_latest_version_v1.5.0
update to latest version: v1.5.0
2 parents 9938a9c + 132f72f commit 0d690d2

File tree

16 files changed

+1220
-66
lines changed

16 files changed

+1220
-66
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
## 1.5.0 - 2025-06-18
4+
5+
* Supports HTTP and SOCKS5 proxy
6+
* Add example code `s3stream` for scanning an S3 object as an implementation of `AMaasReader`
7+
38
## 1.4.5 - 2025-03-03
49

510
* Support new region me-central-1

README.md

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,17 @@ public static void main(String[] args) {
5959
try {
6060
// 1. Create an AMaaS Client object and configure it to carry out the scans in Vision One "us-east-1" region.
6161
AMaasClient client = new AMaasClient("us-east-1", "your-api-key");
62-
63-
// 2. Call ScanFile() to scan the content of a file.
64-
String scanResult = client.scanFile("path-of-file-to-scan");
65-
66-
if (scanResult != null) {
67-
// 3. Print out the JSON response from ScanFile()
68-
System.out.println("scan result " + scanResult);
62+
try {
63+
// 2. Call ScanFile() to scan the content of a file.
64+
String scanResult = client.scanFile("path-of-file-to-scan");
65+
66+
if (scanResult != null) {
67+
// 3. Print out the JSON response from ScanFile()
68+
System.out.println("scan result " + scanResult);
69+
}
70+
} finally {
71+
// 4. Always close the client to release resources
72+
client.close();
6973
}
7074
} catch (AMaasException err) {
7175
info("Exception {0}", err.getMessage());
@@ -218,6 +222,26 @@ Scan a file for malware, add a list of tags to the scan result and retrieves res
218222
**_Return_**
219223
String the scanned result in JSON format.
220224

225+
#### ```public String scanRun(final AMaasReader reader, final String[] tagList, final boolean pml, final boolean feedback, final boolean verbose, final boolean digest) throws AMaasException```
226+
227+
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.
228+
229+
**_Parameters_**
230+
231+
| Parameter | Description |
232+
| ------------- | ---------------------------------------------------------------------------------------- |
233+
| reader | `AMaasReader` to be scanned. This can be an `AMaasFileReader` or any custom implementation you develop to support your specific data sources. |
234+
| tagList | A list of strings to be used to tag the scan result. At most 8 tags with the maximum length of 63 characters. |
235+
| pml | A flag to indicate whether to use predictive machine learning detection. |
236+
| feedback | A flag to indicate whether to use Trend Micro Smart Protection Network's Smart Feedback. |
237+
| verbose | A flag to enable log verbose mode. |
238+
| digest | A flag to enable calculation of digests for cache search and result lookup. |
239+
240+
**_Return_**
241+
String the scanned result in JSON format.
242+
243+
**_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.
244+
221245
#### ```public String scanBuffer(final byte[] buffer, final String identifier) throws AMaasException```
222246

223247
Scan a buffer for malware and retrieves response data from the API.
@@ -360,3 +384,72 @@ The File Security SDK consistently adopts TLS as the default communication chann
360384
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.
361385

362386
When `TM_AM_DISABLE_CERT_VERIFY` is set to `1`, certificate verification is disabled. By default, the certificate will be verified.
387+
388+
## Proxy Configuration
389+
390+
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.
391+
392+
### Supported Environment Variables
393+
394+
| Environment Variable | Required/Optional | Description |
395+
| -------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
396+
| `HTTP_PROXY` | Optional | HTTP proxy URL for HTTP connections (e.g., `http://proxy.example.com:8080`) |
397+
| `HTTPS_PROXY` | Optional | Proxy URL for HTTPS connections (e.g., `https://proxy.example.com:8443` or `socks5://socks.example.com:1080`) |
398+
| `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 |
399+
| `PROXY_USER` | Optional | Username for proxy authentication (used with `Proxy-Authorization` header) |
400+
| `PROXY_PASS` | Optional | Password for proxy authentication (used only when `PROXY_USER` is configured) |
401+
402+
### Proxy Configuration Examples
403+
404+
#### Basic HTTP Proxy
405+
```bash
406+
export HTTP_PROXY=http://proxy.company.com:8080
407+
export HTTPS_PROXY=http://proxy.company.com:8080
408+
```
409+
410+
#### SOCKS5 Proxy
411+
```bash
412+
export HTTPS_PROXY=socks5://socks-proxy.company.com:1080
413+
```
414+
415+
**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.
416+
417+
```java
418+
AMaasClient client = new AMaasClient("us-east-1", "your-api-key");
419+
try {
420+
// Perform scanning operations
421+
String result = client.scanFile("file.txt");
422+
} finally {
423+
// Always close the client when using SOCKS5 proxy
424+
client.close();
425+
}
426+
```
427+
428+
#### Proxy with Authentication
429+
```bash
430+
export HTTP_PROXY=http://proxy.company.com:8080
431+
export HTTPS_PROXY=https://secure-proxy.company.com:8443
432+
export PROXY_USER=username
433+
export PROXY_PASS=password
434+
```
435+
436+
#### Bypassing Proxy for Specific Hosts
437+
```bash
438+
export HTTP_PROXY=http://proxy.company.com:8080
439+
export NO_PROXY=localhost,127.0.0.1,*.internal.company.com
440+
```
441+
442+
#### Disabling Proxy for All Connections
443+
```bash
444+
export NO_PROXY=*
445+
```
446+
447+
### Notes
448+
449+
- The SDK automatically detects and uses proxy settings from environment variables
450+
- For HTTPS connections, `HTTPS_PROXY` takes precedence over `HTTP_PROXY`
451+
- SOCKS5 proxies are supported by specifying `socks5://` in the proxy URL
452+
- Proxy authentication requires both `PROXY_USER` and `PROXY_PASS` to be set
453+
- The `NO_PROXY` variable supports wildcards (e.g., `*.local`) and exact matches
454+
- No code changes are required - simply set the appropriate environment variables before running your application
455+
- **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

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.4.5
1+
1.5.0

examples/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@ There are 4 examples under the following sub-folders:
3434

3535
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`.
3636

37+
## Important: Resource Management
38+
39+
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:
40+
41+
```java
42+
AMaasClient client = new AMaasClient("us-east-1", "your-api-key");
43+
try {
44+
// Perform scanning operations
45+
String result = client.scanFile("file.txt");
46+
} finally {
47+
// Always close the client to release resources
48+
client.close();
49+
}
50+
```
51+
52+
**Note:** Failure to properly close the client, particularly when using SOCKS5 proxies, may cause your application to hang as background network threads remain active.
53+
3754
### Use CLI examples
3855

3956
- `filescan`: This example is to scan a file or a folder sequentially. It takes 4 input options:

examples/filescan/App.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static void scanFilesInSequential(final AMaasClient client, final String[] fList
5252
private static Options getCmdOptions() {
5353
Options optionList = new Options();
5454
optionList.addRequiredOption("f", "filename", true, "File path or folder to be scanned");
55-
optionList.addRequiredOption("k", "apikey", true, "Cloud One API key");
55+
optionList.addRequiredOption("k", "apikey", true, "Vision One API key");
5656
optionList.addRequiredOption("r", "region", true, "AMaaS service region to used. Ignore if self hosted.");
5757
optionList.addOption("a", "addr", true, "host ip address of self hosted AMaaS scanner. Ignore if to use Trend AMaaS service");
5858
optionList.addOption("t", "timeout", true, "Per scan timeout in seconds");
@@ -146,13 +146,18 @@ public static void main(final String[] args) {
146146
}
147147

148148
AMaasClient client = new AMaasClient(region, addr, apikey, timeout, true, caCertPath);
149-
String[] listOfFiles = listFiles(pathname);
150-
long totalStartTs = System.currentTimeMillis();
149+
try {
150+
String[] listOfFiles = listFiles(pathname);
151+
long totalStartTs = System.currentTimeMillis();
151152

152-
scanFilesInSequential(client, listOfFiles, tagList, pmlFlag, feedbackFlag, verbose, digest);
153+
scanFilesInSequential(client, listOfFiles, tagList, pmlFlag, feedbackFlag, verbose, digest);
153154

154-
long totalEndTs = System.currentTimeMillis();
155-
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
155+
long totalEndTs = System.currentTimeMillis();
156+
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
157+
} finally {
158+
// Ensure client resources are properly closed
159+
client.close();
160+
}
156161
} catch (ParseException err) {
157162
helper.printHelp("Usage:", optionList);
158163
} catch (NumberFormatException err) {

examples/parallelscan/ConcurrentApp.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static void scanFilesInParallel(final AMaasClient client, final String[] fList,
129129
private static Options getCmdOptions() {
130130
Options optionList = new Options();
131131
optionList.addRequiredOption("f", "filename", true, "File path or folder to be scanned");
132-
optionList.addRequiredOption("k", "apikey", true, "Cloud One API key");
132+
optionList.addRequiredOption("k", "apikey", true, "Vision One API key");
133133
optionList.addRequiredOption("r", "region", true, "AMaaS service region");
134134
optionList.addOption("t", "timeout", true, "Per scan timeout in seconds");
135135
return optionList;
@@ -167,11 +167,16 @@ public static void main(final String[] args) {
167167
timeout = Long.parseLong(cmd.getOptionValue("t"));
168168
}
169169
AMaasClient client = new AMaasClient(region, apikey, timeout);
170-
String[] listOfFiles = listFiles(pathName);
171-
long totalStartTs = System.currentTimeMillis();
172-
scanFilesInParallel(client, listOfFiles, timeout);
173-
long totalEndTs = System.currentTimeMillis();
174-
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
170+
try {
171+
String[] listOfFiles = listFiles(pathName);
172+
long totalStartTs = System.currentTimeMillis();
173+
scanFilesInParallel(client, listOfFiles, timeout);
174+
long totalEndTs = System.currentTimeMillis();
175+
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
176+
} finally {
177+
// Ensure client resources are properly closed
178+
client.close();
179+
}
175180
} catch (ParseException err) {
176181
helper.printHelp("Usage:", optionList);
177182
} catch (NumberFormatException err) {

examples/pom.xml

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
1-
<?xml version="1.0" encoding="UTF-8"?>
2-
3-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1+
<?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">
52
<modelVersion>4.0.0</modelVersion>
6-
73
<groupId>com.trend</groupId>
84
<artifactId>file-security-sdk-examples</artifactId>
95
<version>1.0.0</version>
106
<packaging>pom</packaging>
11-
127
<name>file-security-sdk-examples</name>
138
<modules>
149
<module>filescan</module>
1510
<module>parallelscan</module>
1611
<module>s3app</module>
1712
<module>s3lambda</module>
13+
<module>s3stream</module>
1814
</modules>
19-
2015
<properties>
2116
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2217
<maven.compiler.source>1.8</maven.compiler.source>
@@ -52,29 +47,28 @@
5247
<dependency>
5348
<groupId>io.grpc</groupId>
5449
<artifactId>grpc-stub</artifactId>
55-
<version>1.68.0</version>
50+
<version>1.73.0</version>
5651
</dependency>
5752
<dependency>
5853
<groupId>io.grpc</groupId>
5954
<artifactId>grpc-protobuf</artifactId>
60-
<version>1.68.0</version>
55+
<version>1.73.0</version>
6156
</dependency>
6257
<dependency>
6358
<groupId>io.grpc</groupId>
6459
<artifactId>grpc-netty</artifactId>
65-
<version>1.68.0</version>
60+
<version>1.73.0</version>
6661
</dependency>
6762
<dependency>
6863
<groupId>com.trend</groupId>
6964
<artifactId>file-security-java-sdk</artifactId>
7065
<version>[1.0,)</version>
7166
</dependency>
72-
7367
</dependencies>
74-
7568
<build>
7669
<sourceDirectory>.</sourceDirectory>
77-
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
70+
<pluginManagement>
71+
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
7872
<plugins>
7973
<plugin>
8074
<artifactId>maven-clean-plugin</artifactId>

examples/s3app/S3App.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ private static Options getCmdOptions() {
6666
optionList.addRequiredOption("a", "awsregion", true, "AWS region");
6767
optionList.addRequiredOption("b", "bucket", true, "S3 bucket name");
6868
optionList.addRequiredOption("f", "S3key", true, "S3 key to be scanned");
69-
optionList.addRequiredOption("k", "apikey", true, "Cloud One API key");
69+
optionList.addRequiredOption("k", "apikey", true, "Vision One API key");
7070
optionList.addRequiredOption("r", "region", true, "AMaaS service region");
7171
optionList.addOption("t", "timeout", true, "Per scan timeout in seconds");
7272
return optionList;
@@ -79,7 +79,7 @@ private static Options getCmdOptions() {
7979
* -b S3 bucket name
8080
* -f S3 key to be scanned
8181
* -k the API key or bearer authentication token
82-
* -r region where the C1 key/token was applied. eg, us-east-1
82+
* -r region where the V1 key/token was applied. eg, us-east-1
8383
* -t optional client maximum waiting time in seconds for a scan. 0 or missing means default.
8484
*/
8585
public static void main(final String[] args) {
@@ -105,10 +105,10 @@ public static void main(final String[] args) {
105105
keyName = cmd.getOptionValue("f");
106106
}
107107
if (cmd.hasOption("r")) {
108-
apikey = cmd.getOptionValue("r");
108+
amaasRegion = cmd.getOptionValue("r");
109109
}
110110
if (cmd.hasOption("k")) {
111-
amaasRegion = cmd.getOptionValue("k");
111+
apikey = cmd.getOptionValue("k");
112112
}
113113
if (cmd.hasOption("t")) {
114114
timeout = Long.parseLong(cmd.getOptionValue("t"));
@@ -117,10 +117,15 @@ public static void main(final String[] args) {
117117
byte[] bytes = downloadS3Object(awsRegion, bucketName, keyName);
118118
info("Completed downloading S3 Object....");
119119
AMaasClient client = new AMaasClient(amaasRegion, apikey, timeout);
120-
long totalStartTs = System.currentTimeMillis();
121-
client.scanBuffer(bytes, keyName);
122-
long totalEndTs = System.currentTimeMillis();
123-
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
120+
try {
121+
long totalStartTs = System.currentTimeMillis();
122+
client.scanBuffer(bytes, keyName);
123+
long totalEndTs = System.currentTimeMillis();
124+
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
125+
} finally {
126+
// Ensure client resources are properly closed
127+
client.close();
128+
}
124129
} catch (ParseException err) {
125130
helper.printHelp("Usage:", optionList);
126131
} catch (NumberFormatException err) {

examples/s3lambda/S3Lambda.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private static void sequentialScan(final AMaasClient client, final S3Client s3cl
108108
* It can scan either a specific S3 key or a folder under a S3 bucket.
109109
*
110110
* TM_AM_AUTH_KEY the API key or bearer authentication token
111-
* TM_AM_REGION region where the C1 key/token was applied. eg, us-east-1
111+
* TM_AM_REGION region where the V1 key/token was applied. eg, us-east-1
112112
* TM_AM_SCAN_TIMEOUT_SECS client maximum waiting time in seconds for a scan. 0 or missing means default.
113113
*
114114
* S3_BUCKET_NAME S3 bucket name
@@ -159,11 +159,16 @@ public String handleRequest(final Object input, final Context context) {
159159
}
160160

161161
AMaasClient client = new AMaasClient(region, apikey, timeout);
162-
long totalStartTs = System.currentTimeMillis();
163-
164-
sequentialScan(client, s3client, bucketName, keyList, tagList);
165-
long totalEndTs = System.currentTimeMillis();
166-
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
162+
try {
163+
long totalStartTs = System.currentTimeMillis();
164+
165+
sequentialScan(client, s3client, bucketName, keyList, tagList);
166+
long totalEndTs = System.currentTimeMillis();
167+
info("*************** Total scan time {0}", totalEndTs - totalStartTs);
168+
} finally {
169+
// Ensure client resources are properly closed
170+
client.close();
171+
}
167172
} catch (Exception err) {
168173
info("Exception encountered {0}", err);
169174
}

0 commit comments

Comments
 (0)