diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py
index fd78155f..e226eefd 100644
--- a/backend/app_sdk/app_base.py
+++ b/backend/app_sdk/app_base.py
@@ -606,11 +606,14 @@ class AppBase:
if "len" in thistype or "length" in thistype or "lenght" in thistype:
tmp = ""
try:
- tmpdata = data.replace("\'", "\"")
tmp = json.loads(tmpdata)
except:
- print("Passing bug")
- pass
+ try:
+ tmpdata = data.replace("\'", "\"")
+ tmp = json.loads(tmpdata)
+ except:
+ print("[ERROR] Parsing bug for length in app sdk")
+ pass
if isinstance(tmp, list):
return len(tmp)
@@ -649,14 +652,14 @@ class AppBase:
return tmp
except IndexError as e:
return default_error
-
+
# Parses the INNER value and recurses until everything is done
def parse_wrapper(data):
try:
if "(" not in data or ")" not in data:
- return data
+ return (data, False)
except TypeError:
- return data
+ return (data, False)
#print("Running %s" % data)
@@ -671,7 +674,7 @@ class AppBase:
break
if not found:
- return data
+ return (data, False)
# Do stuff here.
innervalue = parse_nested_param(data, maxDepth(data)-0)
@@ -692,10 +695,11 @@ class AppBase:
parsed_value = parse_type(innervalue[0], thistype.lower())
print("Parsed value from %s: %s" % (thistype, parsed_value))
- return parsed_value
+ return (parsed_value, True)
print("DATA: %s\n" % data)
- return parse_wrapper(data)
+ return (parse_wrapper(data)[0], True)
+
# Looks for parantheses to grab special cases within a string, e.g:
# int(1) lower(HELLO) or length(what's the length)
@@ -737,15 +741,20 @@ class AppBase:
if len(newstring) > 0:
newdata.append(newstring)
- print("Newdata: ", newdata)
parsedlist = []
non_string = False
+ parsed = False
for item in newdata:
ret = parse_wrapper(item)
- if not isinstance(ret, str):
+ if not isinstance(ret[0], str):
non_string = True
-
- parsedlist.append(ret)
+
+ parsedlist.append(ret[0])
+ if ret[1]:
+ parsed = True
+
+ if not parsed:
+ return data
if len(parsedlist) > 0 and not non_string:
print("Returning parsed list: ", parsedlist)
@@ -949,7 +958,6 @@ class AppBase:
if len(parsersplit) == 1:
return str(baseresult)+str(appendresult), False
- baseresult = baseresult.replace("\'", "\"")
baseresult = baseresult.replace(" True,", " true,")
baseresult = baseresult.replace(" False", " false,")
@@ -958,8 +966,12 @@ class AppBase:
try:
basejson = json.loads(baseresult)
except json.decoder.JSONDecodeError as e:
- print("Parser issue with JSON: %s" % e)
- return str(baseresult)+str(appendresult), False
+ try:
+ baseresult = baseresult.replace("\'", "\"")
+ basejson = json.loads(baseresult)
+ except json.decoder.JSONDecodeError as e:
+ print("Parser issue with JSON: %s" % e)
+ return str(baseresult)+str(appendresult), False
print("After fourth parser return as JSON")
@@ -1365,14 +1377,17 @@ class AppBase:
if replacement.startswith("\"") and replacement.endswith("\""):
replacement = replacement[1:len(replacement)-1]
- replacement = replacement.replace("\'", "\"", -1)
print("POST replacement: %s" % replacement)
json_replacement = replacement
try:
json_replacement = json.loads(replacement)
except json.decoder.JSONDecodeError as e:
- print("JSON error singular: %s" % e)
+ try:
+ replacement = replacement.replace("\'", "\"", -1)
+ json_replacement = json.loads(replacement)
+ except:
+ print("JSON error singular: %s" % e)
if len(json_replacement) > minlength:
minlength = len(json_replacement)
diff --git a/backend/app_sdk/build.sh b/backend/app_sdk/build.sh
index fe988a1c..f96da989 100644
--- a/backend/app_sdk/build.sh
+++ b/backend/app_sdk/build.sh
@@ -1,6 +1,6 @@
#!/bin/bash
NAME=shuffle-app_sdk
-VERSION=0.8.32
+VERSION=0.8.4
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go
index 3d48871c..03720e3b 100644
--- a/backend/go-app/docker.go
+++ b/backend/go-app/docker.go
@@ -230,6 +230,7 @@ func buildImageMemory(fs billy.Filesystem, tags []string, dockerfileFolder strin
}
// Build the actual image
+ log.Printf("Building %s. This may take up to a few minutes.", dockerfileFolder)
imageBuildResponse, err := client.ImageBuild(
ctx,
dockerFileTarReader,
diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index b29e9fcf..263e0872 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -2483,7 +2483,7 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) {
if len(users) != 1 {
log.Printf(`Found multiple or no users with the same username: %s: %d`, data.Username, len(users))
resp.WriteHeader(401)
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Found %d users with the same username: %s"}`, len(users), data.Username)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Error: %d users with username %s"}`, len(users), data.Username)))
return
}
@@ -4785,7 +4785,7 @@ func getDocList(resp http.ResponseWriter, request *http.Request) {
if len(item1) == 0 {
resp.WriteHeader(500)
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No docs available."`)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No docs available."}`)))
return
}
@@ -4844,7 +4844,7 @@ func getDocs(resp http.ResponseWriter, request *http.Request) {
location := strings.Split(request.URL.String(), "/")
if len(location) != 5 {
resp.WriteHeader(404)
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"`)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"}`)))
return
}
@@ -4868,7 +4868,7 @@ func getDocs(resp http.ResponseWriter, request *http.Request) {
)
if err != nil {
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"`)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"}`)))
resp.WriteHeader(404)
//setBadMemcache(ctx, docPath)
return
@@ -4877,7 +4877,7 @@ func getDocs(resp http.ResponseWriter, request *http.Request) {
newresp, err := client.Do(req)
if err != nil {
resp.WriteHeader(404)
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"`)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"}`)))
//setBadMemcache(ctx, docPath)
return
}
@@ -4885,7 +4885,7 @@ func getDocs(resp http.ResponseWriter, request *http.Request) {
body, err := ioutil.ReadAll(newresp.Body)
if err != nil {
resp.WriteHeader(500)
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't parse data"`)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't parse data"}`)))
//setBadMemcache(ctx, docPath)
return
}
@@ -5958,7 +5958,7 @@ func echoOpenapiData(resp http.ResponseWriter, request *http.Request) {
if err != nil {
log.Printf("[ERROR] URLbody error: %s", err)
resp.WriteHeader(500)
- resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't get data from selected uri"`)))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't get data from selected uri"}`)))
return
}
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index 448d677c..d2d99d56 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -4015,7 +4015,7 @@ func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
log.Printf("ID: %s", fileId)
app, err := getApp(ctx, fileId)
if err != nil {
- log.Printf("Error getting app %s: %s", app.Name, err)
+ log.Printf("Error getting app (delete) %s: %s", fileId, err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
@@ -4169,7 +4169,7 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
ctx := context.Background()
app, err := getApp(ctx, fileId)
if err != nil {
- log.Printf("Error getting app: %s", app.Name)
+ log.Printf("Error getting app (app config): %s", fileId)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
@@ -4438,7 +4438,7 @@ func updateWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
ctx := context.Background()
app, err := getApp(ctx, fileId)
if err != nil {
- log.Printf("Error getting app: %s (update app)", app.Name)
+ log.Printf("Error getting app (update app): %s", fileId)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
diff --git a/docker-compose.yml b/docker-compose.yml
index a39b58c7..7a356dff 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,7 +2,7 @@ version: '3'
services:
frontend:
#build: ./frontend
- image: ghcr.io/frikky/shuffle-frontend:0.8.4
+ image: ghcr.io/frikky/shuffle-frontend:0.8.42
container_name: shuffle-frontend
hostname: shuffle-frontend
ports:
@@ -45,7 +45,7 @@ services:
- database
orborus:
#build: ./functions/onprem/orborus
- image: ghcr.io/frikky/shuffle-orborus:0.8.31
+ image: ghcr.io/frikky/shuffle-orborus:0.8.32
container_name: shuffle-orborus
hostname: shuffle-orborus
networks:
diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx
index e50a5a0c..b809cf62 100644
--- a/frontend/src/views/Admin.jsx
+++ b/frontend/src/views/Admin.jsx
@@ -470,6 +470,33 @@ const Admin = (props) => {
})
}
+ const flushQueue = (name) => {
+ // Just use this one?
+ const url = globalUrl + '/api/v1/flush_queue';
+ fetch(url, {
+ method: 'DELETE',
+ credentials: "include",
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ .then(response =>
+ response.json().then(responseJson => {
+ if (responseJson["success"] === false) {
+ alert.error(responseJson.reason)
+ getEnvironments()
+ } else {
+ setLoginInfo("")
+ setModalOpen(false)
+ getEnvironments()
+ }
+ }),
+ )
+ .catch(error => {
+ console.log("Error when deleting: ", error)
+ })
+ }
+
const deleteEnvironment = (name) => {
// FIXME - add some check here ROFL
alert.info("Deleting environment " + name)
@@ -2094,6 +2121,7 @@ const Admin = (props) => {
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
>
+ {/**/}
{
const cloudSyncEnabled = props.userdata !== undefined && props.userdata.active_org !== null && props.userdata.active_org !== undefined ? props.userdata.active_org.cloud_sync === true : false
//const triggerEnvironments = cloudSyncEnabled ? ["cloud", "onprem"] : environments
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"
- const triggerEnvironments = isCloud ? ["cloud"] : ["cloud", "onprem"]
+ const triggerEnvironments = isCloud ? ["cloud"] : ["onprem", "cloud"]
const unloadText = 'Are you sure you want to leave without saving (CTRL+S)?'
useBeforeunload(() => {
@@ -2663,7 +2663,6 @@ const AngularWorkflow = (props) => {
foundResult.result = foundResult.result.split(" None").join(" \"None\"")
foundResult.result = foundResult.result.split(" False").join(" false")
foundResult.result = foundResult.result.split(" True").join(" true")
- foundResult.result = foundResult.result.split("\'").join("\"")
var jsonvalid = true
try {
@@ -2672,7 +2671,15 @@ const AngularWorkflow = (props) => {
jsonvalid = false
}
} catch (e) {
- jsonvalid = false
+ try {
+ foundResult.result = foundResult.result.split("\'").join("\"")
+ const tmp = String(JSON.parse(foundResult.result))
+ if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) {
+ jsonvalid = false
+ }
+ } catch (e) {
+ jsonvalid = false
+ }
}
// Finds the FIRST json only
@@ -5874,7 +5881,6 @@ const AngularWorkflow = (props) => {
const parsedExecutionArgument = () => {
var showResult = executionData.execution_argument.trim()
showResult = showResult.split(" None").join(" \"None\"")
- showResult = showResult.split("\'").join("\"")
showResult = showResult.split(" False").join(" false")
showResult = showResult.split(" True").join(" true")
@@ -5885,7 +5891,16 @@ const AngularWorkflow = (props) => {
jsonvalid = false
}
} catch (e) {
- jsonvalid = false
+ showResult = showResult.split("\'").join("\"")
+
+ try {
+ const tmp = String(JSON.parse(showResult))
+ if (!showResult.includes("{") && !showResult.includes("[")) {
+ jsonvalid = false
+ }
+ } catch (e) {
+ jsonvalid = false
+ }
}
if (jsonvalid) {
@@ -6070,21 +6085,28 @@ const AngularWorkflow = (props) => {
//
// FIXME: The latter replace doens't really work if ' is used in a string
var showResult = data.result.trim()
+ //console.log(showResult)
showResult = showResult.split(" None").join(" \"None\"")
showResult = showResult.split(" False").join(" false")
showResult = showResult.split(" True").join(" true")
- showResult = showResult.split("\'").join("\"")
var jsonvalid = true
try {
const tmp = String(JSON.parse(showResult))
if (!showResult.includes("{") && !showResult.includes("[")) {
- //console.log("IN HERE: ", tmp)
jsonvalid = false
}
} catch (e) {
- //console.log("Error: ", e)
- jsonvalid = false
+ showResult = showResult.split("\'").join("\"")
+
+ try {
+ const tmp = String(JSON.parse(showResult))
+ if (!showResult.includes("{") && !showResult.includes("[")) {
+ jsonvalid = false
+ }
+ } catch (e) {
+ jsonvalid = false
+ }
}
const curapp = apps.find(a => a.name === data.action.app_name && a.app_version === data.action.app_version)
diff --git a/frontend/src/views/Apps.jsx b/frontend/src/views/Apps.jsx
index dadbe288..c081f94f 100644
--- a/frontend/src/views/Apps.jsx
+++ b/frontend/src/views/Apps.jsx
@@ -46,6 +46,10 @@ const inputColor = "#383B40"
export const GetParsedPaths = (inputdata, basekey) => {
const splitkey = " > "
var parsedValues = []
+ if (inputdata === undefined || inputdata === null) {
+ return parsedValues
+ }
+
if (typeof(inputdata) !== "object") {
return parsedValues
}
diff --git a/frontend/src/views/LoginPage.jsx b/frontend/src/views/LoginPage.jsx
index 5f9e49f2..b365336f 100644
--- a/frontend/src/views/LoginPage.jsx
+++ b/frontend/src/views/LoginPage.jsx
@@ -69,7 +69,7 @@ const LoginDialog = props => {
}),
)
.catch(error => {
- setLoginInfo("Error in userdata: ", error)
+ setLoginInfo("Error logging in: ", error)
})
}
@@ -80,6 +80,7 @@ const LoginDialog = props => {
const onSubmit = (e) => {
e.preventDefault()
+ setLoginInfo("")
// FIXME - add some check here ROFL
// Just use this one?
@@ -114,7 +115,7 @@ const LoginDialog = props => {
}),
)
.catch(error => {
- setLoginInfo("Error in userdata: " + error)
+ setLoginInfo("Error logging in: " + error)
});
} else {
url = baseurl + '/api/v1/users/register';
diff --git a/functions/extensions/wazuh/custom-shuffle b/functions/extensions/wazuh/custom-shuffle
new file mode 100644
index 00000000..bd540414
--- /dev/null
+++ b/functions/extensions/wazuh/custom-shuffle
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Created by Shuffle, AS. .
+
+WPYTHON_BIN="framework/python/bin/python3"
+
+SCRIPT_PATH_NAME="$0"
+
+DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)"
+SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})"
+
+case ${DIR_NAME} in
+ */active-response/bin | */wodles*)
+ if [ -z "${WAZUH_PATH}" ]; then
+ WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)"
+ fi
+
+ PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
+ ;;
+ */bin)
+ if [ -z "${WAZUH_PATH}" ]; then
+ WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
+ fi
+
+ PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py"
+ ;;
+ */integrations)
+ if [ -z "${WAZUH_PATH}" ]; then
+ WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
+ fi
+
+ PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
+ ;;
+esac
+
+
+${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} "$@"
diff --git a/functions/extensions/wazuh/custom-shuffle.py b/functions/extensions/wazuh/custom-shuffle.py
new file mode 100644
index 00000000..06fa4c7d
--- /dev/null
+++ b/functions/extensions/wazuh/custom-shuffle.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+# Created by Shuffle, AS. .
+# Based on the Slack integration using Webhooks
+
+import json
+import sys
+import time
+import os
+
+try:
+ import requests
+ from requests.auth import HTTPBasicAuth
+except Exception as e:
+ print("No module 'requests' found. Install: pip install requests")
+ sys.exit(1)
+
+# ADD THIS TO ossec.conf configuration:
+#
+# custom-shuffle
+# http://:3001/api/v1/hooks/
+# 3
+# json
+#
+
+# Global vars
+
+debug_enabled = False
+pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+json_alert = {}
+now = time.strftime("%a %b %d %H:%M:%S %Z %Y")
+
+# Set paths
+log_file = '{0}/logs/integrations.log'.format(pwd)
+
+
+def main(args):
+ debug("# Starting")
+
+ # Read args
+ alert_file_location = args[1]
+ webhook = args[3]
+
+ debug("# Webhook")
+ debug(webhook)
+
+ debug("# File location")
+ debug(alert_file_location)
+
+ # Load alert. Parse JSON object.
+ with open(alert_file_location) as alert_file:
+ json_alert = json.load(alert_file)
+ debug("# Processing alert")
+ debug(json_alert)
+
+ debug("# Generating message")
+ msg = generate_msg(json_alert)
+ if isinstance(msg, str):
+ if len(msg) == 0:
+ return
+ debug(msg)
+
+ debug("# Sending message")
+ send_msg(msg, webhook)
+
+
+def debug(msg):
+ if debug_enabled:
+ msg = "{0}: {1}\n".format(now, msg)
+ print(msg)
+ f = open(log_file, "a")
+ f.write(msg)
+ f.close()
+
+# Skips container kills to stop self-recursion
+def filter_msg(alert):
+ # These are things that recursively happen because Shuffle starts Docker containers
+ # Docker integration rules: https://github.com/wazuh/wazuh-ruleset/blob/ae36745db1d3f312db0392f5925c2f2b0ec009a9/rules/0560-docker_integration_rules.xml
+ skip = ["87924", "87900", "87901", "87902", "87903", "87904", "86001", "86002", "86003", "87932", "80710", "87929", "87928",]
+ if alert["rule"]["id"] in skip:
+ return False
+
+ #try:
+ # if "docker" in alert["rule"]["description"].lower() and "
+ #msg['text'] = alert.get('full_log')
+ #except:
+ # pass
+ #msg['title'] = alert['rule']['description'] if 'description' in alert['rule'] else "N/A"
+
+ return True
+
+def generate_msg(alert):
+ if not filter_msg(alert):
+ print("Skipping rule %s" % alert["rule"]["id"])
+ return ""
+
+ level = alert['rule']['level']
+
+ if (level <= 4):
+ color = "good"
+ elif (level >= 5 and level <= 7):
+ color = "warning"
+ else:
+ color = "danger"
+
+ msg = {}
+ msg['color'] = color
+ msg['pretext'] = "WAZUH Alert"
+ msg['title'] = alert['rule']['description'] if 'description' in alert['rule'] else "N/A"
+ msg['text'] = alert.get('full_log')
+ msg['rule_id'] = alert["rule"]["id"]
+ msg['timestamp'] = alert["timestamp"]
+ msg['id'] = alert['id']
+ msg["all_fields"] = alert
+
+ #msg['fields'] = []
+ # msg['fields'].append({
+ # "title": "Agent",
+ # "value": "({0}) - {1}".format(
+ # alert['agent']['id'],
+ # alert['agent']['name']
+ # ),
+ # })
+ #if 'agentless' in alert:
+ # msg['fields'].append({
+ # "title": "Agentless Host",
+ # "value": alert['agentless']['host'],
+ # })
+
+ #msg['fields'].append({"title": "Location", "value": alert['location']})
+ #msg['fields'].append({
+ # "title": "Rule ID",
+ # "value": "{0} _(Level {1})_".format(alert['rule']['id'], level),
+ #})
+
+ #attach = {'attachments': [msg]}
+
+ return json.dumps(msg)
+
+
+def send_msg(msg, url):
+ headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
+ res = requests.post(url, data=msg, headers=headers)
+ debug(res)
+
+
+if __name__ == "__main__":
+ try:
+ # Read arguments
+ bad_arguments = False
+ if len(sys.argv) >= 4:
+ msg = '{0} {1} {2} {3} {4}'.format(
+ now,
+ sys.argv[1],
+ sys.argv[2],
+ sys.argv[3],
+ sys.argv[4] if len(sys.argv) > 4 else '',
+ )
+ debug_enabled = (len(sys.argv) > 4 and sys.argv[4] == 'debug')
+ else:
+ msg = '{0} Wrong arguments'.format(now)
+ bad_arguments = True
+
+ # Logging the call
+ f = open(log_file, 'a')
+ f.write(msg + '\n')
+ f.close()
+
+ if bad_arguments:
+ debug("# Exiting: Bad arguments.")
+ sys.exit(1)
+
+ # Main function
+ main(sys.argv)
+
+ except Exception as e:
+ debug(str(e))
+ raise
diff --git a/functions/extensions/wazuh/ossec.conf b/functions/extensions/wazuh/ossec.conf
index dfaf0394..5b55f5d3 100644
--- a/functions/extensions/wazuh/ossec.conf
+++ b/functions/extensions/wazuh/ossec.conf
@@ -1,7 +1,5 @@
- Shuffle
+ custom-shuffle
http://:3001/api/v1/hooks/webhook_
- 2
- multiple_drops|authentication_failures
json
diff --git a/functions/extensions/wazuh/requirements.txt b/functions/extensions/wazuh/requirements.txt
deleted file mode 100644
index f2293605..00000000
--- a/functions/extensions/wazuh/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-requests
diff --git a/functions/extensions/wazuh/shuffle.py b/functions/extensions/wazuh/shuffle.py
deleted file mode 100644
index 306d3715..00000000
--- a/functions/extensions/wazuh/shuffle.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-
-# Based on
-# https://wazuh.com/blog/how-to-integrate-external-software-using-integrator/
-
-import sys
-import json
-import requests
-from requests.auth import HTTPBasicAuth
-
-# Set the project attributes
-project_alias = 'TI'
-issue_name ='FIM'
-
-# Read configuration parameters
-alert_file = open(sys.argv[1])
-user = sys.argv[2].split(':')[0]
-api_key = sys.argv[2].split(':')[1]
-hook_url = sys.argv[3]
-
-# Read the alert file
-alert_json = json.loads(alert_file.read())
-alert_file.close()
-
-# Extract issue fields
-alert_level = alert_json['rule']['level']
-description = alert_json['rule']['description']
-path = alert_json['syscheck']['path']
-
-# Generate request
-msg_data = {}
-msg_data['fields'] = {}
-msg_data['fields']['project'] = {}
-msg_data['fields']['project']['key'] = project_alias
-msg_data['fields']['summary'] = 'FIM alert on [' + path + ']'
-msg_data['fields']['description'] = '- State: ' + description + '\n- Alert level: ' + str(alert_level)
-msg_data['fields']['issuetype'] = {}
-msg_data['fields']['issuetype']['name'] = issue_name
-headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
-
-# Send the request
-requests.post(hook_url, data=json.dumps(msg_data), headers=headers, auth=(user, api_key))
-
-sys.exit(0)
diff --git a/functions/onprem/orborus/build.sh b/functions/onprem/orborus/build.sh
index a580aefc..57fe63a2 100644
--- a/functions/onprem/orborus/build.sh
+++ b/functions/onprem/orborus/build.sh
@@ -1,5 +1,5 @@
NAME=shuffle-orborus
-VERSION=0.8.31
+VERSION=0.8.32
echo "Running docker build with $NAME:$VERSION"
#docker rmi frikky/shuffle:$NAME --force
diff --git a/functions/onprem/orborus/orborus.go b/functions/onprem/orborus/orborus.go
index 8e5cf442..06a938ff 100644
--- a/functions/onprem/orborus/orborus.go
+++ b/functions/onprem/orborus/orborus.go
@@ -562,6 +562,7 @@ func zombiecheck(workerTimeout int) error {
stopContainers := []string{}
removeContainers := []string{}
+ log.Printf("Workertimeout: %d", int64(workerTimeout))
for _, container := range containers {
// Skip random containers. Only handle things related to Shuffle.
if !strings.Contains(container.Image, baseimagename) {
@@ -587,10 +588,10 @@ func zombiecheck(workerTimeout int) error {
continue
}
- log.Printf("[INFO] NAME: %s", name)
+ currenttime := time.Now().Unix()
+ log.Printf("[INFO] (%s) NAME: %s. TIME: %d", container.State, name, currenttime-container.Created)
// Need to check time here too because a container can be removed the same instant as its created
- currenttime := time.Now().Unix()
if container.State != "running" && currenttime-container.Created > int64(workerTimeout) {
removeContainers = append(removeContainers, container.ID)
containerNames[container.ID] = name
@@ -606,6 +607,7 @@ func zombiecheck(workerTimeout int) error {
}
// FIXME - add killing of apps with same execution ID too
+ log.Printf("[INFO] Should STOP %d containers.", len(stopContainers))
for _, containername := range stopContainers {
log.Printf("[INFO] Stopping and removing container %s", containerNames[containername])
go dockercli.ContainerStop(ctx, containername, nil)
@@ -617,6 +619,7 @@ func zombiecheck(workerTimeout int) error {
Force: true,
}
+ log.Printf("[INFO] Should REMOVE %d containers.", len(removeContainers))
for _, containername := range removeContainers {
go dockercli.ContainerRemove(ctx, containername, removeOptions)
}