Skip to content
This repository has been archived by the owner on Aug 7, 2020. It is now read-only.

Commit

Permalink
Allow the use of Managed Credentials in scan configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
tenableAndrew committed Dec 12, 2019
1 parent d5d6d09 commit d37ee61
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 5 deletions.
40 changes: 39 additions & 1 deletion examples/scans.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
from time import time

from tenable_io.api.models import Scan
from tenable_io.api.scans import ScanExportRequest
from tenable_io.api.credentials import CredentialPermission, CredentialRequest
from tenable_io.api.scans import ScanExportRequest, ScanSettings, ScanCreateRequest, ScanCredentials
from tenable_io.client import TenableIOClient
from tenable_io.exceptions import TenableIOApiException

Expand Down Expand Up @@ -123,6 +124,43 @@ def example(test_targets):
assert imported_scan.details().info.name == scan.details().info.name
os.remove(test_nessus_file)

'''
Create a new scan using managed credentials.
Note: First we must create a new managed credential
'''
# Created managed credential for SSH
test_user = client.users_api.list().users[0]
test_permission = CredentialPermission(grantee_uuid=test_user.uuid,
type=CredentialPermission.USER_TYPE,
permissions=CredentialPermission.CAN_EDIT,
name=test_user.username,
isPending=True)
credential_request = CredentialRequest(name='Lab SSH',
description='SSH Credentials for Lab',
type_='SSH',
settings={
'auth_method': 'password',
'elevate_privledges_with': 'Nothing',
'username': 'username',
'password': 'password'
},
permissions=[test_permission])
credential_uuid = client.credentials_api.create(credential_request)
credential_detail = client.credentials_api.details(credential_uuid)

# Create scan settings
settings = ScanSettings(name='Credentialed Scan',
text_targets=test_targets)
credentials = ScanCredentials(add=[credential_detail])
template_uuid = client.scan_helper.template('basic').uuid

# Create Scan
scan_request = ScanCreateRequest(uuid=template_uuid,
settings=settings,
credentials=credentials)
scan_id = client.scans_api.create(scan_request)
assert scan_id

'''
Stop all scans.
Note: Use with caution as this will stop all ongoing scans (including any automated test).
Expand Down
5 changes: 4 additions & 1 deletion tenable_io/api/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ def details(self, uuid):
:return: An instance of :class:`tenable_io.api.models.CredentialDetails`.
"""
response = self._client.get('credentials/%(uuid)s', path_params={'uuid': uuid})
return CredentialDetails.from_json(response.text)
# We manually add the uuid back to the response object to it can be referenced later more easily
credential_details = loads(response.text)
credential_details['uuid'] = uuid
return CredentialDetails.from_dict(credential_details)


def update(self, uuid, credential_request):
Expand Down
37 changes: 37 additions & 0 deletions tenable_io/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,41 @@ def scans(self, scans):
self._scans = scans


class ScanCredentials(BaseModel):

def __init__(
self,
add=[],
edit=[],
delete=[],
):
self.add = add
self.edit = edit
self.delete = delete

def _parse_credential_list(self, credential_list):
_parsed_credentials = {}
for cd in credential_list:
if cd.category.id not in _parsed_credentials:
_parsed_credentials[cd.category.id] = {}
_parsed_credentials[cd.category.id][cd.type.id] = [{'id': cd.uuid}]
else:
if cd.type.id not in _parsed_credentials[cd.category.id]:
_parsed_credentials[cd.category.id][cd.type.id] = [{'id': cd.uuid}]
else:
_parsed_credentials[cd.category.id][cd.type.id].append({'id': cd.uuid})
return _parsed_credentials

def as_payload(self, filter_=None):
payload = {}
# All items for each attribute will be an instance of CredentialDetails
payload['add'] = self._parse_credential_list(self.add)
payload['edit'] = self._parse_credential_list(self.edit)
payload['delete'] = []

return payload


class ScanSettings(BaseModel):

def __init__(
Expand Down Expand Up @@ -3541,6 +3576,7 @@ class CredentialDetails(BaseModel):

def __init__(
self,
uuid=None,
name=None,
description=None,
category=None,
Expand All @@ -3555,6 +3591,7 @@ def __init__(
self._permissions = None
self._settings = None

self.uuid = uuid
self.name = name
self.description = description
self.category = category
Expand Down
15 changes: 12 additions & 3 deletions tenable_io/api/scans.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from json import loads

from tenable_io.api.base import BaseApi
from tenable_io.api.models import Scan, ScanDetails, ScanHistory, ScanHostDetails, ScanList, ScanSettings
from tenable_io.api.models import Scan, ScanCredentials, ScanDetails, ScanHistory, \
ScanHostDetails, ScanList, ScanSettings
from tenable_io.api.base import BaseRequest


Expand Down Expand Up @@ -266,17 +267,23 @@ def __init__(
self,
uuid,
settings,
credentials
):
assert isinstance(settings, ScanSettings)
self.uuid = uuid
self.settings = settings
self.credentials = credentials

def as_payload(self, filter_=None):
payload = super(ScanSaveRequest, self).as_payload(True)
if isinstance(self.settings, ScanSettings):
payload.__setitem__('settings', self.settings.as_payload())
else:
payload.pop('settings', None)
if self.credentials is not None and isinstance(self.credentials, ScanCredentials):
payload.__setitem__('credentials', self.credentials.as_payload())
else:
payload.pop('credentials', None)
return payload


Expand All @@ -286,8 +293,9 @@ def __init__(
self,
uuid,
settings=None,
credentials=None,
):
super(ScanCreateRequest, self).__init__(uuid, settings)
super(ScanCreateRequest, self).__init__(uuid, settings, credentials)


class ScanConfigureRequest(ScanSaveRequest):
Expand All @@ -296,8 +304,9 @@ def __init__(
self,
uuid=None,
settings=None,
credentials=None,
):
super(ScanConfigureRequest, self).__init__(uuid, settings)
super(ScanConfigureRequest, self).__init__(uuid, settings, credentials)


class ScanExportRequest(BaseRequest):
Expand Down

0 comments on commit d37ee61

Please sign in to comment.