Skip to content
This repository was archived by the owner on Oct 29, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions securitycenter/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class BaseAPI(object):
_session = None
_timeout = (30, 300)

def __init__(self, host, port=443, ssl_verify=False, scheme='https', log=False, timeout=None):
def __init__(self, host, port=443, ssl_verify=False, scheme='https',
log=False, timeout=None):
'''BaseAPI Initialization'''
self._session = requests.Session()
self._host = host
Expand All @@ -48,7 +49,8 @@ def _reset_session(self):
self._session = requests.Session()

def _url(self, path):
return '%s://%s:%s/%s%s' % (self._scheme, self._host, self._port, self._pre, path)
return '%s://%s:%s/%s%s' % (self._scheme, self._host, self._port,
self._pre, path)

def _builder(self, **kwargs):
if 'headers' not in kwargs:
Expand Down
16 changes: 9 additions & 7 deletions securitycenter/nessus.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from .base import BaseAPI, APIError, logging
from .base import BaseAPI, APIError


class Nessus(BaseAPI):
_access = None
_secret = None
managed = False
enterprise = False
def __init__(self, host, port=8834, ssl_verify=False, scheme='https', log=False, timeout=None):

def __init__(self, host, port=8834, ssl_verify=False, scheme='https',
log=False, timeout=None):
BaseAPI.__init__(self, host, port, ssl_verify, scheme, log, timeout)
#try:

d = self.get('server/properties').json()
try:
if 'managed' in d:
Expand All @@ -26,14 +28,16 @@ def __init__(self, host, port=8834, ssl_verify=False, scheme='https', log=False,
def _builder(self, **kwargs):
kwargs = BaseAPI._builder(self, **kwargs)
if self._access and self._secret:
kwargs['headers']['X-APIKeys'] = 'accessKey=%s; secretKey=%s' % (self._access, self._secret)
kwargs['headers']['X-APIKeys'] = ('accessKey=%s; secretKey=%s'
% (self._access, self._secret))
elif self._token:
kwargs['headers']['X-Cookie'] = 'token=%s' % self._token
return kwargs

def login(self, username=None, password=None, access=None, secret=None):
if username and password:
resp = self.post('session', json={'username': username, 'password': password})
resp = self.post('session',
json={'username': username, 'password': password})
if resp.status_code == 200:
self._token = resp.json()['token']
else:
Expand All @@ -43,5 +47,3 @@ def login(self, username=None, password=None, access=None, secret=None):
self._secret = secret
else:
raise APIError(404, 'No Authentication Methods Found')


12 changes: 5 additions & 7 deletions securitycenter/pvs.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
from .base import BaseAPI, APIError, logging
from .base import BaseAPI, APIError


class PVS(BaseAPI):
def __init__(self, host, port=8835, ssl_verify=False, scheme='https', log=False, timeout=None):
def __init__(self, host, port=8835, ssl_verify=False, scheme='https',
log=False, timeout=None):
BaseAPI.__init__(self, host, port, ssl_verify, scheme, log, timeout)

def _builder(self, **kwargs):
kwargs = BaseAPI._builder(self, **kwargs)
return kwargs

def login(self, username, password):
resp = self.post('login', data={
'login': username,
'password': password,
'json': 1,
})
resp = self.post('login', data={'login': username,
'password': password, 'json': 1})
if resp.status_code == 200:
self._token = resp.json()['reply']['contents']['token']
else:
Expand Down
104 changes: 63 additions & 41 deletions securitycenter/sc4.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
from datetime import date, datetime, timedelta
import random, calendar, json, sys
import random
import calendar
import json
import sys
from zipfile import ZipFile
from .base import APIError, BaseAPI

if sys.version_info > (3,0):
if sys.version_info > (3, 0):
from io import StringIO
else:
from StringIO import StringIO


class SecurityCenter4(BaseAPI):
'''
Connects to the SecurityCenter API based on the parameters specified.
Expand All @@ -33,7 +37,8 @@ class SecurityCenter4(BaseAPI):
'SSA',
]

def __init__(self, host, port=443, ssl_verify=False, scheme='https', log=False, timeout=None):
def __init__(self, host, port=443, ssl_verify=False, scheme='https',
log=False, timeout=None):
BaseAPI.__init__(self, host, port, ssl_verify, scheme, log, timeout)
self.system = self._system()
self.version = self.system['version']
Expand Down Expand Up @@ -96,7 +101,7 @@ def _builder(self, **kwargs):
if self._token:
kwargs['data']['token'] = self._token

# Then the module, action, and input fields as required from the API.
# Then the module, action, and input fields as required from the API.
if 'module' in kwargs:
kwargs['data']['module'] = kwargs['module']
del kwargs['module']
Expand All @@ -107,7 +112,7 @@ def _builder(self, **kwargs):
# The input data must be dumped as a string value in order to
# be correctly interpreted.
kwargs['data']['input'] = json.dumps(kwargs['input'])
del kwargs['input']
del kwargs['input']
return kwargs

def raw_query(self, module, action, data=None, dejson=True, **kwargs):
Expand All @@ -119,7 +124,8 @@ def raw_query(self, module, action, data=None, dejson=True, **kwargs):
data = self.post('', **kwargs)
if dejson:
if data.json()['error_code']:
raise APIError(data.json()['error_code'], data.json()['error_msg'])
raise APIError(data.json()['error_code'],
data.json()['error_msg'])
return data.json()['response']
else:
return data
Expand Down Expand Up @@ -161,10 +167,15 @@ def query(self, tool, filters=None, source='cumulative', sort=None,

"""

data = [] # This is the list that we will be returning back to
# the calling function once we complete.
payload = {} # The dataset that we will be sending to the API via the
# raw_query function.
# This is the list that we will be returning back to
# the calling function once we complete.

data = []

# The dataset that we will be sending to the API via the
# raw_query function.

payload = {}

# A simple data dictionary to determine the module that we will be used
stype = {
Expand All @@ -177,7 +188,8 @@ def query(self, tool, filters=None, source='cumulative', sort=None,

# When the source is "individual", scan and directory should be provided
# as well, and will be set in the payload.
if source == "individual" and scan is not None and directory is not None:
if source == ("individual" and scan is not None
and directory is not None):
# convert directory passed as datetime to string if necessary
if isinstance(directory, date):
directory = directory.strftime("%Y-%m-%d")
Expand Down Expand Up @@ -215,17 +227,24 @@ def query(self, tool, filters=None, source='cumulative', sort=None,
# Now that we have everything we need, a quick sanity check first to
# make sure some idiot didn't give us a completely empty filterset to
# work with. If they did for some reason, just return an empty list.
#if len(filters) < 1:
# if len(filters) < 1:
# return []

# Everything is set, checks out, and is ready to go. Now we have to
# start running through the query loop and actually pull everything
# together. We know that we will
items = [] # This is the resultset. It'll be different every time
# we loop. to get things going however, we will just
# set it to an empty list.
count = 0 # A simple counter to track the total number of results
# that have been returned.

# This is the resultset. It'll be different every time
# we loop. to get things going however, we will just
# set it to an empty list.

items = []

# A simple counter to track the total number of results
# that have been returned.

count = 0

while len(items) == req_size or count == 0:
# The API requires that we set an offset for the start and end of
# the request, so we will add these to the payload here.
Expand Down Expand Up @@ -263,7 +282,7 @@ def login(self, user, passwd):
queries.
"""
data = self.raw_query('auth', 'login',
data={'username': user, 'password': passwd})
data={'username': user, 'password': passwd})
self._token = data["token"]
self._user = data

Expand Down Expand Up @@ -318,7 +337,6 @@ def asset_update(self, asset_id, name=None, description=None,
if asset['type'] == 'dnsname':
payload['definedDNSNames'] = asset['definedDNSNames']


# New we need to check to see if we actually got to pre-load the
# payload. If we didnt, then there isn an existing Asset list and we
# should error out.
Expand All @@ -344,12 +362,14 @@ def asset_update(self, asset_id, name=None, description=None,
for user in users:
ulist.append({'id': int(user)})
payload['users'] = ulist
if payload['type'] == 'dynamic' and rules is not None and isinstance(rules, list):
if payload['type'] == ('dynamic' and rules is not None
and isinstance(rules, list)):
payload['rules'] = rules
if payload['type'] == 'static' and ips is not None and isinstance(ips, list):
if payload['type'] == ('static' and ips is not None
and isinstance(ips, list)):
payload['definedIPs'] = ','.join(ips)
if payload['type'] == 'dnsname' and dns is not None\
and isinstance(dns, list):
if payload['type'] == ('dnsname' and dns is not None
and isinstance(dns, list)):
payload['definedDNSNames'] = ','.join(dns)

# And now that we have everything defined, we can go ahead and send
Expand Down Expand Up @@ -401,7 +421,8 @@ def credential_update(self, cred_id, **options):
payload['username'] = cred['username']
payload['publickey'] = cred['publickey']
payload['privatekey'] = cred['privatekey']
payload['priviledgeEscalation'] = cred['priviledgeEscalation']
payload['priviledgeEscalation'] = (
cred['priviledgeEscalation'])
payload['escalationUsername'] = cred['escalationUsername']

if cred['type'] == 'windows':
Expand Down Expand Up @@ -520,9 +541,11 @@ def credential_add(self, name, cred_type, **options):
'''

if 'pirvateKey' in options:
options['privateKey'] = self._upload(options['privateKey'])['filename']
options['privateKey'] = (
self._upload(options['privateKey'])['filename'])
if 'publicKey' in options:
options['publicKey'] = self._upload(options['publicKey'])['filename']
options['publicKey'] = (
self._upload(options['publicKey'])['filename'])

return self.raw_query("credential", "add", data=options)

Expand Down Expand Up @@ -567,7 +590,8 @@ def credential_delete(self, *ids):
})

def plugins(self, plugin_type='all', sort='id', direction='asc',
size=1000, offset=0, all=True, loops=0, since=None, **filterset):
size=1000, offset=0, all=True, loops=0, since=None,
**filterset):
"""plugins
Returns a list of of the plugins and their associated families. For
simplicity purposes, the plugin family names will be injected into the
Expand Down Expand Up @@ -614,14 +638,14 @@ def plugins(self, plugin_type='all', sort='id', direction='asc',
# Instance up and running to test...
# ---
# Next we convert the family dictionary list into a flat dictionary.
#fams = {}
#for famitem in data['families']:
# fams = {}
# for famitem in data['families']:
# fams[famitem['id']] = famitem['name']

# Then we parse thtrough the data set, adding in the family name
# into the plugin definition before adding it into the plugins list.
for plugin in data['plugins']:
# plugin['familyName'] = fams[plugin['familyID']]
# plugin['familyName'] = fams[plugin['familyID']]
plugins.append(plugin)
# ---

Expand Down Expand Up @@ -776,17 +800,18 @@ def scan_download(self, scan_id, format='v2'):
'downloadType': format,
'scanResultID': scan_id,
}
data = self.raw_query('scanResult', 'download', data=payload, dejson=False)
data = self.raw_query('scanResult', 'download', data=payload,
dejson=False)
bobj = StringIO()
bobj.write(data)
zfile = ZipFile(bobj)
return zfile.read(zfile.namelist()[0])

### WARNING ###
# ### WARNING ###
# All of the functions below are not part of the API documentation. This
# means that it is entirely possible for one or all of these to change
# without notification as they are not part of the documented API.
###############
# ##############

def _upload(self, fileobj):
"""_upload filename
Expand All @@ -795,8 +820,9 @@ def _upload(self, fileobj):

UN-DOCUMENTED CALL: This function is not considered stable.
"""
return self.raw_query('file', 'upload',
data={'returnContent': 'false'}, files={'Filedata': fileobj})
return self.raw_query('file', 'upload',
data={'returnContent': 'false'},
files={'Filedata': fileobj})

def dashboard_import(self, name, fileobj):
"""dashboard_import Dashboard_Name, filename
Expand All @@ -822,7 +848,6 @@ def report_import(self, name, filename):
'name': name,
})


def download_repository(self, repo_id):
'''download_repository Repository_Id
Download the tarball of the repository id specified.
Expand All @@ -833,7 +858,6 @@ def download_repository(self, repo_id):
'id': repo_id
}, dejson=False)


def asset_create(self, name, items, tag='', description='', atype='static'):
'''asset_create_static name, ips, tags, description
Create a new asset list with the defined information.
Expand Down Expand Up @@ -862,7 +886,6 @@ def asset_create(self, name, items, tag='', description='', atype='static'):
data['definedDNSNames'] = ' '.join(items)
return self.raw_query('asset', 'add', data=data)


def asset_create_combo(self, name, combo, tag='', description=''):
'''asset_create_combo name, combination, tag, description
Creates a new combination asset list. Operands can be either asset list
Expand Down Expand Up @@ -903,7 +926,6 @@ def asset_create_combo(self, name, combo, tag='', description=''):
'combinations': combo,
})


def risk_rule(self, rule_type, rule_value, port, proto, plugin_id,
repo_ids, comment='', expires='-1', severity=None):
'''accept_risk rule_type, rule_value, port, proto, plugin_id, comment
Expand Down Expand Up @@ -943,11 +965,11 @@ def risk_rule(self, rule_type, rule_value, port, proto, plugin_id,
data['expires'] = expires
return self.raw_query('acceptRiskRule', 'add', data=data)
else:
sevlevels = {'info': 0, 'low': 1, 'medium': 2, 'high': 3, 'critical': 4}
sevlevels = {'info': 0, 'low': 1, 'medium': 2, 'high': 3,
'critical': 4}
data['severity'] = sevlevels[severity]
return self.raw_query('recastRiskRule', 'add', data=data)


def group_add(self, name, restrict, repos, lces=[], assets=[], queries=[],
policies=[], dashboards=[], credentials=[], description=''):
'''group_add name, restrict, repos
Expand Down
Loading