Skip to content

Commit

Permalink
Merge pull request #3 from polarityio/develop
Browse files Browse the repository at this point in the history
Initial Integration Development
  • Loading branch information
penwoodjon authored Feb 4, 2020
2 parents 90d881b + 29100aa commit 783390c
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 45 deletions.
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Ignore Maven Compiled Project Files
*/target/

# Ignore IntelliJ Project Information
*.iml
.idea/

# Ignore Sublime Text Project Files
*.sublime-project
*.sublime-workspace
sftp-config.json

# Ignore Eclipse Project Information
*.settings
*.project
*.classpath
dependency-reduced-pom.xml

# Ignore Excel Files
*.xlsx

# Ignore local log files
*.log
*.remote-sync.json

# Ignore Generated HTML README Files
README.html

# Ignored installed NPM modules
node_modules/
test-runner.js

.polarity.conf
10 changes: 5 additions & 5 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
The MIT License

Copyright (c) 2017 Breach Intelligence, Inc.

Copyright (c) 2019 Breach Intelligence, Inc. DBA Polarity
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

The Polarity TrapX integration allows Polarity to search the TrapX DeceptionGrid API to return event information on IP addresses.

## TrapX URL
The base URL for the DeceptionGrid TSOC API including the schema (i.e., https://).

## TrapX API Key
Your TrapX API key.

## Trap Type
Search Events with the specified Trap Type (Full OS or Emulation).

## Installation Instructions

Installation instructions for integrations are provided on the [PolarityIO GitHub Page](https://polarityio.github.io/).
Expand Down
12 changes: 6 additions & 6 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,22 @@ module.exports = {
},
request: {
// Provide the path to your certFile. Leave an empty string to ignore this option.
// Relative paths are relative to the Urlhaus integration's root directory
// Relative paths are relative to the TrapX integration's root directory
cert: '',
// Provide the path to your private key. Leave an empty string to ignore this option.
// Relative paths are relative to the Urlhaus integration's root directory
// Relative paths are relative to the TrapX integration's root directory
key: '',
// Provide the key passphrase if required. Leave an empty string to ignore this option.
// Relative paths are relative to the Urlhaus integration's root directory
// Relative paths are relative to the TrapX integration's root directory
passphrase: '',
// Provide the Certificate Authority. Leave an empty string to ignore this option.
// Relative paths are relative to the Urlhaus integration's root directory
// Relative paths are relative to the TrapX integration's root directory
ca: '',
// An HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for
// the url parameter (by embedding the auth info in the uri)
proxy: '',

rejectUnauthorized: false
rejectUnauthorized: true
},
logging: {
level: 'info' //trace, debug, info, warn, error, fatal
Expand Down Expand Up @@ -103,7 +103,7 @@ module.exports = {
description:
'Search Events with the specified Trap Type (Full OS or Emulation)',
default: {
value: 'fullOS',
value: 'Full OS',
display: 'Full OS'
},
type: 'select',
Expand Down
69 changes: 39 additions & 30 deletions integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,32 @@ function startup(logger) {
requestWithDefaults = request.defaults(defaults);
}

function doLookup(entities, options, cb) {
function doLookup(entities, { url, ...optionsWithoutUrl }, cb) {
let lookupResults = [];
let tasks = [];
const options = {
...optionsWithoutUrl,
url: url && url.endsWith("/") ? url.substring(0, url.length - 1) : url
};

Logger.debug(entities);

entities.forEach(entity => {
let postData = {"api_key": options.apiKey,"filter":{"trap_type":options.trapType.value,"attacker_address":entity.value}};
entities.forEach((entity) => {
let postData = {
api_key: options.apiKey,
filter: { trap_type: options.trapType.value, attacker_address: entity.value }
};
let requestOptions = {
method: 'POST',
method: "POST",
uri: `${options.url}/api/v1.2/events/search`,
body: postData,
json: true
};

Logger.trace({ uri: requestOptions }, "Request URI");

tasks.push(function (done) {
requestWithDefaults(requestOptions, function (error, res, body) {
tasks.push(function(done) {
requestWithDefaults(requestOptions, function(error, res, body) {
if (error) {
return done(error);
}
Expand All @@ -85,7 +92,7 @@ function doLookup(entities, options, cb) {
entity,
body
};
} else if (res.statusCode === 404 || res.statusCode === 202) {
} else if (res.statusCode === 202) {
result = {
entity,
body: null
Expand All @@ -97,28 +104,30 @@ function doLookup(entities, options, cb) {
};
if (res.statusCode === 401) {
error = {
err: 'Unauthorized',
detail: 'Request had Authorization header but token was missing or invalid. Please ensure your API key is valid.'
err: "Unauthorized",
detail:
"Request had Authorization header but token was missing or invalid. Please ensure your API key is valid."
};
} else if (res.statusCode === 403) {
error = {
err: 'Access Denied',
detail: 'Not enough access permissions.'
err: "Access Denied",
detail: "Not enough access permissions."
};
} else if (res.statusCode === 404) {
error = {
err: 'Not Found',
detail: 'Requested item doesn’t exist or not enough access permissions.'
err: "Not Found",
detail: "Requested item doesn’t exist or not enough access permissions."
};
} else if (res.statusCode === 429) {
error = {
err: 'Too Many Requests',
detail: 'Daily number of requests exceeds limit. Check Retry-After header to get information about request delay.'
err: "Too Many Requests",
detail:
"Daily number of requests exceeds limit. Check Retry-After header to get information about request delay."
};
} else if (Math.round(res.statusCode / 10) * 10 === 500) {
error = {
err: 'Server Error',
detail: 'Unexpected Server Error'
err: "Server Error",
detail: "Unexpected Server Error"
};
}

Expand All @@ -137,7 +146,7 @@ function doLookup(entities, options, cb) {
return;
}

results.forEach(result => {
results.forEach((result) => {
if (result.body === null || result.body.number_of_events === 0) {
lookupResults.push({
entity: result.entity,
Expand All @@ -159,6 +168,15 @@ function doLookup(entities, options, cb) {
});
}

function validateUrl(errors, url) {
if (url && url.endsWith("//")) {
errors.push({
key: "url",
message: "Your Url must not end with a //"
});
}
}

function validateStringOption(errors, options, optionName, errMessage) {
if (
typeof options[optionName].value !== "string" ||
Expand All @@ -175,18 +193,9 @@ function validateStringOption(errors, options, optionName, errMessage) {
function validateOptions(options, callback) {
let errors = [];

validateStringOption(
errors,
options,
"url",
"You must provide a valid URL"
);
validateStringOption(
errors,
options,
"apiKey",
"You must provide a valid API Key"
);
validateUrl(errors, options.url.value);
validateStringOption(errors, options, "url", "You must provide a valid URL");
validateStringOption(errors, options, "apiKey", "You must provide a valid API Key");

callback(null, errors);
}
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"version": "3.0.0-beta",
"private": true,
"dependencies": {
"request": "^2.88",
"lodash": "^4.17.11",
"async": "^2.6"
"async": "^2.6",
"request": "^2.88"
}
}
2 changes: 1 addition & 1 deletion templates/tx-block.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
{{#if (eq result.severity "low")}}
<div>
<span class="p-key">Event Severity:</span>
<span class="p-value" style="color:yellow">LOW</span>
<span class="p-value" style="color:gray">LOW</span>
</div>
{{/if}}
{{/if}}
Expand Down

0 comments on commit 783390c

Please sign in to comment.