Skip to content

Commit

Permalink
Merge pull request #12 from trendmicro/update_to_latest_version_v1.2.0
Browse files Browse the repository at this point in the history
update to latest version: v1.2.0
  • Loading branch information
830d953e authored Jul 9, 2024
2 parents 5c04eec + 494201d commit cb1782a
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 64 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.2.0 - 2024-07-05

* Support verbose scan result

## 1.1.2 - 2024-04-10

* Update README.md
Expand Down
86 changes: 77 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ You can enable SPN feedback by calling the `SetFeedbackEnable` function:
client.SetFeedbackEnable()
```

### Enable Verbose Scan Result

You can enable verbose scan result by calling the `SetVerboseEnable` function:

```go
client.SetVerboseEnable()
```

## Golang Client SDK API Reference

### ```func NewClient(key string, region string) (c *AmaasClient, e error)```
Expand All @@ -152,14 +160,14 @@ Creates a new instance of the client object, and provisions essential settings,
**_Parameters_**

| Parameter | Description |
|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key (string) | A valid API key must be provided if the environment variable `TM_AM_AUTH_KEY` is not set. |
| region (string) | The region you obtained your api key. Value provided must be one of the Vision One regions: `us-east-1`, `eu-central-1`, `ap-southeast-1`, `ap-southeast-2`, `ap-northeast-1`, `ap-south-1` |

**_Return values_**

| Parameter | Description |
|------------------|-------------------------------------------------------|
| ---------------- | ----------------------------------------------------- |
| c (*AmaasClient) | Pointer to an client object. Nil if error encountered |
| e (error) | Nil if no error encountered; non-nil otherwise. |

Expand All @@ -179,7 +187,7 @@ Submit content of a file or buffer to be scanned.
**_Parameters_**

| Parameter | Description |
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| filePath (string) | Path of the file to scan |
| buffer ([]byte) | Buffer containing the data to scan |
| identifier (string) | A caller-chosen string to associate with the scan that will be returned in JSON response as part of `fileName` name/value; can be empty |
Expand All @@ -188,12 +196,14 @@ Submit content of a file or buffer to be scanned.
**_Return values_**

| Parameter | Description |
|---------------|----------------------------------------------------|
| ------------- | -------------------------------------------------- |
| resp (string) | JSON-formatted response describing the scan result |
| e (error) | Nil if no error encountered; non-nil otherwise. |

**_Sample JSON response_**

***_Concise Format_***

```json
{
"scannerVersion":"1.0.0-27",
Expand All @@ -214,6 +224,58 @@ Submit content of a file or buffer to be scanned.
}
```

***_Verbose Format_***

```json
{
"scanType": "sdk",
"objectType": "file",
"timestamp": {
"start": "2024-07-05T20:01:21.064Z",
"end": "2024-07-05T20:01:21.069Z"
},
"schemaVersion": "1.0.0",
"scannerVersion": "1.0.0-59",
"fileName": "eicar.com",
"rsSize": 68,
"scanId": "40d7a38e-a1d3-400b-a09c-7aa9cd62658f",
"accountId": "",
"result": {
"atse": {
"elapsedTime": 4693,
"fileType": 5,
"fileSubType": 0,
"version": {
"engine": "23.57.0-1002",
"lptvpn": 385,
"ssaptn": 731,
"tmblack": 253,
"tmwhite": 239,
"macvpn": 914
},
"malwareCount": 1,
"malware": [
{
"name": "Eicar_test_file",
"fileName": "eicar.com",
"type": "",
"fileType": 5,
"fileSubType": 0,
"fileTypeName": "COM",
"fileSubTypeName": "VSDT_COM_DOS"
}
],
"error": null,
"fileTypeName": "COM",
"fileSubTypeName": "VSDT_COM_DOS"
}
},
"fileSHA1": "3395856ce81f2b7382dee72602f798b642f14140",
"fileSHA256": "275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f",
"appName": "V1FS"
}
```

When malicious content is detected in the scanned object, `scanResult` will show a non-zero value. Otherwise, the value will be `0`. Moreover, when malware is detected, `foundMalwares` will be non-empty containing one or more name/value pairs of `fileName` and `malwareName`. `fileName` will be filename of malware detected while `malwareName` will be the name of the virus/malware found.

**_Errors Conditions_**
Expand All @@ -240,7 +302,7 @@ For configuring the SDK's active logging level. The change is applied globally t
**_Parameters_**
| Parameter | Description |
|------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| level (LogLevel) | Valid values are LogLevelOff, LogLevelFatal, LogLevelError, LogLevelWarning, LogLevelInfo, and LogLevelDebug; default level is LogLevelOff |
---
Expand All @@ -252,7 +314,7 @@ For setting up custom logging by provisioning the SDK with a custom callback fun
**_Parameters_**
| Parameter | Description |
|--------------|--------------------------------------------------------------------------------------------------------|
| ------------ | ------------------------------------------------------------------------------------------------------ |
| f (function) | A function with the prototype `func(level LogLevel, levelStr string, format string, a ...interface{})` |
## Usage Examples
Expand Down Expand Up @@ -306,6 +368,9 @@ Specify to enable PML (Predictive Machine Learning) detection
`-feedback`
Specify to enable SPN feedback
`-verbose`
Specify to enable verbose scan result
`-tag <string>`
Specify the tags to be used for scanning, separated by commas
Expand Down Expand Up @@ -344,6 +409,9 @@ Specify to enable PML (Predictive Machine Learning) detection
`-feedback`
Specify to enable SPN feedback
`-verbose`
Specify to enable verbose scan result
`-tag <string>`
Specify the tags to be used for scanning, separated by commas
Expand All @@ -352,9 +420,9 @@ Specify the tags to be used for scanning, separated by commas
The cli tool loads the proxy configuration from the following set of optional environment variables
| Environment Variable | Required/Optional | Description |
|----------------------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NO_PROXY` | Optional | Add the endpoints to the comma-separated list of host names if you want to skip proxy settings. Note: only an asterisk, '\*' matches all hosts |
| `HTTP_PROXY` | Optional | `http://proxy.example.com` |
| `HTTP_PROXY` | Optional | `http://proxy.example.com` |
| `HTTPS_PROXY` | Optional | `https://proxy.example.com`<br><br>If the proxy server is a SOCKS5 proxy, you must specify the SOCKS5 protocol in the URL as `socks5://socks_proxy.example.com` |
| `PROXY_USER` | Optional | Optional username for authentication header used in `Proxy-Authorization` |
| `PROXY_PASS` | Optional | Optional password for authentication header used in `Proxy-Authorization`, used only when `PROXY_USER` is configured |
Expand All @@ -366,7 +434,7 @@ The following environment variables are supported by Golang Client SDK and can b
For example, the API key can be specified using the `TM_AM_AUTH_KEY` environment variable instead of hardcoded into the application.
| Variable Name | Description & Purpose | Valid Values |
|---------------------------|-----------------------------------------------------------------------------|----------------------------|
| ------------------------- | --------------------------------------------------------------------------- | -------------------------- |
| `TM_AM_SCAN_TIMEOUT_SECS` | Specify, in number of seconds, to override the default scan timeout period | 0, 1, 2, ... ; default=300 |
| `TM_AM_AUTH_KEY` | Can be used to specify the authorization key; overrides function call value | empty or string |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.2
1.2.0
25 changes: 25 additions & 0 deletions datamodel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package client

type ScanResult2Client struct {
ScannerVersion string `json:"scannerVersion"`
SchemaVersion string `json:"schemaVersion"`
ScanResult int32 `json:"scanResult"`
ScanId string `json:"scanId"`
ScanTimestamp string `json:"scanTimestamp"`
FileName string `json:"fileName"`
FoundMalwares []MalwareDetail `json:"foundMalwares"`
FoundErrors []ErrMsg `json:"foundErrors,omitempty"`
FileSha1 string `json:"fileSHA1,omitempty"`
FileSha256 string `json:"fileSHA256,omitempty"`
}

type MalwareDetail struct {
FileName string `json:"fileName"`
MalwareName string `json:"malwareName"`
Engine string `json:"engine,omitempty"`
}

type ErrMsg struct {
Name string `json:"name"`
Description string `json:"description"`
}
41 changes: 31 additions & 10 deletions grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,11 @@ type AmaasClient struct {
archHandler AmaasClientArchiveHandler
pml bool
feedback bool
verbose bool
}

func scanRun(ctx context.Context, cancel context.CancelFunc, c pb.ScanClient, dataReader AmaasClientReader, disableCache bool, tags []string, pml bool, bulk bool, feedback bool) (string, error) {
func scanRun(ctx context.Context, cancel context.CancelFunc, c pb.ScanClient, dataReader AmaasClientReader,
disableCache bool, tags []string, pml bool, bulk bool, feedback bool, verbose bool) (string, error) {

defer cancel()

Expand Down Expand Up @@ -275,7 +277,8 @@ func scanRun(ctx context.Context, cancel context.CancelFunc, c pb.ScanClient, da

hashSha1, _ := dataReader.Hash("sha1")

if err = runInitRequest(stream, dataReader.Identifier(), uint64(size), hashSha256, hashSha1, tags, pml, bulk, feedback); err != nil {
if err = runInitRequest(stream, dataReader.Identifier(), uint64(size), hashSha256, hashSha1, tags, pml, bulk, feedback,
verbose); err != nil {
return makeFailedScanJSONResp(), err
}

Expand All @@ -291,14 +294,27 @@ func scanRun(ctx context.Context, cancel context.CancelFunc, c pb.ScanClient, da
return result, nil
}

func runInitRequest(stream pb.Scan_RunClient, identifier string, dataSize uint64, hashSha256 string, hashSha1 string, tags []string, pml bool, bulk bool, feedback bool) error {
func runInitRequest(stream pb.Scan_RunClient, identifier string, dataSize uint64, hashSha256 string, hashSha1 string,
tags []string, pml bool, bulk bool, feedback bool, verbose bool) error {
if err := stream.Send(&pb.C2S{Stage: pb.Stage_STAGE_INIT,
FileName: identifier, RsSize: dataSize, FileSha256: hashSha256, FileSha1: hashSha1, Tags: tags, Trendx: pml, Bulk: bulk, SpnFeedback: feedback}); err != nil {
FileName: identifier, RsSize: dataSize, FileSha256: hashSha256, FileSha1: hashSha1, Tags: tags, Trendx: pml,
Bulk: bulk, SpnFeedback: feedback, Verbose: verbose}); err != nil {

_, receiveErr := stream.Recv()
if receiveErr != nil {
if receiveErr == io.EOF {
logMsg(LogLevelDebug, MSG("MSG_ID_DEBUG_CLOSED_CONN"))
} else {
msg := fmt.Sprintf(MSG("MSG_ID_ERR_INIT"), receiveErr.Error())
logMsg(LogLevelError, msg)
}
return sanitizeGRPCError(receiveErr)
}

err = sanitizeGRPCError(err)
logMsg(LogLevelError, MSG("MSG_ID_ERR_INIT"), err)
return err
}

return nil
}

Expand Down Expand Up @@ -370,11 +386,10 @@ func runUploadLoop(stream pb.Scan_RunClient, dataReader AmaasClientReader, bulk
Stage: pb.Stage_STAGE_RUN,
Offset: offset[i],
Chunk: buf}); err != nil {

err = sanitizeGRPCError(err)
msg := fmt.Sprintf(MSG("MSG_ID_ERR_SEND_DATA"), err.Error())
logMsg(LogLevelError, msg)
overallErr = makeInternalError(msg)
return
break
}
totalUpload += length[i]
}
Expand Down Expand Up @@ -410,7 +425,8 @@ func (ac *AmaasClient) bufferScanRun(buffer []byte, identifier string, tags []st

ctx = ac.buildAppNameContext(ctx)

return scanRun(ctx, cancel, pb.NewScanClient(ac.conn), bufferReader, ac.disableCache, tags, ac.pml, true, ac.feedback)
return scanRun(ctx, cancel, pb.NewScanClient(ac.conn), bufferReader, ac.disableCache, tags, ac.pml, true, ac.feedback,
ac.verbose)
}

func (ac *AmaasClient) fileScanRun(fileName string, tags []string) (string, error) {
Expand Down Expand Up @@ -440,7 +456,8 @@ func (ac *AmaasClient) fileScanRunNormalFile(fileName string, tags []string) (st

ctx = ac.buildAppNameContext(ctx)

return scanRun(ctx, cancel, pb.NewScanClient(ac.conn), fileReader, ac.disableCache, tags, ac.pml, true, ac.feedback)
return scanRun(ctx, cancel, pb.NewScanClient(ac.conn), fileReader, ac.disableCache, tags, ac.pml, true, ac.feedback,
ac.verbose)
}

func (ac *AmaasClient) setupComm() error {
Expand Down Expand Up @@ -1006,6 +1023,10 @@ func (ac *AmaasClient) SetFeedbackEnable() {
ac.feedback = true
}

func (ac *AmaasClient) SetVerboseEnable() {
ac.verbose = true
}

func validateTags(tags []string) error {
if len(tags) == 0 {
return errors.New("tags cannot be empty")
Expand Down
2 changes: 1 addition & 1 deletion grpc_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ func TestScanRunWithInvalidTags(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(180))

// act
_, err := scanRun(ctx, cancel, nil, nil, false, tt.tags, false, true, false)
_, err := scanRun(ctx, cancel, nil, nil, false, tt.tags, false, true, false, false)

// assert
assert.Equal(t, tt.expectedErr, err.Error())
Expand Down
Loading

0 comments on commit cb1782a

Please sign in to comment.