You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
7.8 KiB

import json, re, os, sys
from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path
import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error, six.moves.urllib.request
class LookupHelper:
app = ""
base_url = ""
def __init__(self, sessionKey):
# sessionkey gets passed in when a new object is created
self.sessionKey = sessionKey
self.app = "Splunk_Security_Essentials"
self.debug = []
self.EnableDebug = False
# import the libraries we need
from LookupHelper import LookupHelper
def add_to_sys_path(paths, prepend=False):
for path in paths:
if prepend:
if path in sys.path:
sys.path.remove(path)
sys.path.insert(0, path)
elif not path in sys.path:
sys.path.append(path)
add_to_sys_path([make_splunkhome_path(['etc', 'apps', 'Splunk_Security_Essentials', 'lib', 'py23', 'splunklib'])], prepend=True)
# We should not rely on core enterprise packages:
add_to_sys_path([make_splunkhome_path(['etc', 'apps', 'Splunk_Security_Essentials', 'lib', 'py3'])], prepend=True)
# Common libraries like future
add_to_sys_path([make_splunkhome_path(['etc', 'apps', 'Splunk_Security_Essentials', 'lib', 'py23'])], prepend=True)
from six.moves import reload_module
try:
if 'future' in sys.modules:
import future
reload_module(future)
except Exception:
'''noop: future was not loaded yet'''
import time
from splunk.clilib.cli_common import getConfKeyValue
if sys.platform == "win32":
import msvcrt
# Binary mode is required for persistent mode on Windows.
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
import splunklib.client as client
try:
# Getting configurations
mgmtHostname, mgmtHostPort = getConfKeyValue('web', 'settings', 'mgmtHostPort').split(":")
self.base_url = "https://" + mgmtHostname + ":" + mgmtHostPort
except Exception as e:
# debug.append(json.dumps({"status": "ERROR", "description": "Error getting the base_url configuration!", "message": str(e)}))
throwErrorMessage = True
try:
service = client.connect(host=mgmtHostname, port=mgmtHostPort, token=self.sessionKey)
service.namespace['owner'] = 'nobody'
service.namespace['app'] = app
except Exception as e:
# debug.append(json.dumps({"status": "ERROR", "description": "Error grabbing a service object", "message": str(e)}))
throwErrorMessage = True
# only used above when trying to get session information
def errorOut(self, obj):
print("Error!")
print('"' + json.dumps(obj).replace('"', '""') + '"')
sys.exit()
# These functions are not using the service definition above. Straight api requests instead.
def listLookups(self,query=""):
'''
@param query: Wildcard query to list lookups with, i.e. mitre_*_matrix.csv.
'''
lookup_list =""
owner="nobody"
namespace = self.app
params = { 'output_mode' : 'json'}
if (query!=""):
params = { 'output_mode' : 'json','search' : query}
total_url = self.base_url + '/servicesNS/' + owner + '/' + namespace + '/data/lookup-table-files' + '?' + six.moves.urllib.parse.urlencode(params)
# total_url = base_url + "/services/data/lookup-table-files/?f=" +query
else:
# total_url = base_url + "/services/data/lookup-table-files/"
total_url = self.base_url + '/servicesNS/' + owner + '/' + namespace + '/data/lookup-table-files' + '?' + six.moves.urllib.parse.urlencode(params)
try:
request = six.moves.urllib.request.Request(total_url,
headers = { 'Authorization': ('Splunk %s' % self.sessionKey)})
search_results = six.moves.urllib.request.urlopen(request)
# self.debug.append({"message": "search_results.read()", "search_results.read()": search_results.read()})
lookup_list = json.loads(search_results.read())["entry"]
lookup_filename = lookup_list[0]["content"]["eai:data"]
# self.debug.append({"message": "lookup_filename returned", "lookup_filename": lookup_filename})
# self.debug.append({"message": "lookup returned", "lookup": lookup_list})
except Exception as e:
self.debug.append({"status": "Failed to do get lookups method", "error": str(e)})
return lookup_list
def deleteLookup(self,lookup):
'''
@param lookup: The lookup FILE name (NOT the stanza name).
'''
owner="nobody"
namespace = self.app
total_url = self.base_url + '/servicesNS/' + owner + '/' + namespace + '/data/lookup-table-files/' + lookup
# self.debug.append({"message": "deleteLookup", lookup: lookup})
try:
request = six.moves.urllib.request.Request(total_url,method="DELETE",
headers = { 'Authorization': ('Splunk %s' % self.sessionKey)})
search_results = six.moves.urllib.request.urlopen(request)
except Exception as e:
self.debug.append({"status": "Failed to delete lookup", "error": str(e)})
# if self.EnableDebug:
# print(json.dumps(self.debug))
return "Lookup deleted"
def getLookup(self,lookup):
'''
@param lookup: The lookup FILE name (NOT the stanza name).
'''
lookupentry = listLookups(query=lookup)
lookup_filename = matrix_lookup_path+lookupentry[0]["name"]
# self.debug.append({"message": "lookup_filename", "lookup_filename": lookup_filename})
if os.path.exists(lookup_filename):
with open(lookup_filename) as f:
return f.read()
else:
self.debug.append({"message": "lookup not found", "lookup_filename": lookup_filename})
return "Lookup not found"
def addLookup(self,lookup_file):
'''
@param lookup_file: The lookup FILE name (NOT the stanza name). This file should already exist in the lookup tmp folder.
'''
owner="nobody"
namespace = self.app
total_url = self.base_url + '/servicesNS/' + owner + '/' + namespace + '/data/lookup-table-files/' + lookup_file
lookup_tmp = make_splunkhome_path(['var', 'run', 'splunk', 'lookup_tmp'])
if not os.path.exists(lookup_tmp):
os.makedirs(lookup_tmp)
destination_lookup_full_path = os.path.join(lookup_tmp, lookup_file)
# self.debug.append({"message": "addLookup", destination_lookup_full_path: destination_lookup_full_path})
# self.debug.append({"message": "addLookup", lookup_tmp: lookup_tmp})
params = {
'output_mode': 'json',
'eai:data': str(destination_lookup_full_path),
'name': lookup_file
}
data = six.moves.urllib.parse.urlencode(params)
data = data.encode('utf-8')
# self.debug.append({"message": "addLookup", data: data})
try:
request = six.moves.urllib.request.Request(total_url,data=data,method="POST",
headers = { 'Authorization': ('Splunk %s' % self.sessionKey)})
search_results = six.moves.urllib.request.urlopen(request)
except Exception as e:
self.debug.append({"status": "Failed to add lookup", "error": str(e)})
# if self.EnableDebug:
# print(json.dumps(self.debug))
return "Lookup added"