Skip to content

Commit

Permalink
Merge pull request #634 from nccgroup/enhancement/OCI-support
Browse files Browse the repository at this point in the history
Enhancement/OCI support
  • Loading branch information
x4v13r64 committed Feb 7, 2020
2 parents 008d456 + f04cfff commit 7d9e566
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 58 deletions.
17 changes: 13 additions & 4 deletions ScoutSuite/providers/oci/authentication_strategy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from oci.config import from_file
from oci.identity import IdentityClient

Expand All @@ -6,9 +8,14 @@

class OracleCredentials:

def __init__(self, config, compartment_id):
def __init__(self, config):
self.config = config
self.compartment_id = compartment_id

def get_scope(self):
if 'compartment-id' in self.config:
return self.config['compartment-id']
else:
return self.config['tenancy']


class OracleAuthenticationStrategy(AuthenticationStrategy):
Expand All @@ -20,14 +27,16 @@ def authenticate(self, profile=None, **kwargs):

try:

# Set logging level to error for libraries as otherwise generates a lot of warnings
logging.getLogger('oci').setLevel(logging.ERROR)

config = from_file(profile_name=profile)
compartment_id = config["tenancy"]

# Get the current user
identity = IdentityClient(config)
identity.get_user(config["user"]).data

return OracleCredentials(config, compartment_id)
return OracleCredentials(config)

except Exception as e:
raise AuthenticationException(e)
68 changes: 47 additions & 21 deletions ScoutSuite/providers/oci/facade/identity.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from oci.identity import IdentityClient
from ScoutSuite.providers.oci.authentication_strategy import OracleCredentials
from oci.pagination import list_call_get_all_results

from ScoutSuite.providers.oci.authentication_strategy import OracleCredentials
from ScoutSuite.core.console import print_exception

from ScoutSuite.providers.utils import run_concurrently


Expand All @@ -11,33 +13,57 @@ def __init__(self, credentials: OracleCredentials):
self._client = IdentityClient(self._credentials.config)

async def get_users(self):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_users, self._credentials.compartment_id))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_users, self._credentials.get_scope()))
return response.data
except Exception as e:
print_exception('Failed to retrieve users: {}'.format(e))
return []

async def get_user_api_keys(self, user_id):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_api_keys, user_id))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_api_keys, user_id))
return response.data
except Exception as e:
print_exception('Failed to retrieve user api keys: {}'.format(e))
return []

async def get_groups(self):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_groups, self._credentials.compartment_id))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_groups, self._credentials.get_scope()))
return response.data
except Exception as e:
print_exception('Failed to retrieve groups: {}'.format(e))
return []

async def get_group_users(self, group_id):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_user_group_memberships,
self._credentials.compartment_id,
group_id=group_id))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_user_group_memberships,
self._credentials.get_scope(),
group_id=group_id))
return response.data
except Exception as e:
print_exception('Failed to retrieve group users: {}'.format(e))
return []

async def get_policies(self):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_policies, self._credentials.compartment_id))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_policies, self._credentials.get_scope()))
return response.data
except Exception as e:
print_exception('Failed to retrieve policies: {}'.format(e))
return None

async def get_authentication_policy(self):
response = await run_concurrently(
lambda: self._client.get_authentication_policy(self._credentials.compartment_id))
return response.data
try:
response = await run_concurrently(
lambda: self._client.get_authentication_policy(self._credentials.config['tenancy']))
return response.data
except Exception as e:
print_exception('Failed to retrieve authentication policy: {}'.format(e))
return []
5 changes: 2 additions & 3 deletions ScoutSuite/providers/oci/facade/kms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
class KMSFacade:
def __init__(self, credentials: OracleCredentials):
self._credentials = credentials
# FIXME does this require regional support?
self._vault_client = KmsVaultClient(self._credentials.config)

async def get_vaults(self):
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._vault_client.list_vaults, self._credentials.compartment_id))
lambda: list_call_get_all_results(self._vault_client.list_vaults, self._credentials.get_scope()))
return response.data
except Exception as e:
print_exception('Failed to get KMS vaults: {}'.format(e))
Expand All @@ -25,7 +24,7 @@ async def get_keys(self, keyvault):
try:
key_client = KmsManagementClient(self._credentials.config, keyvault['management_endpoint'])
response = await run_concurrently(
lambda: list_call_get_all_results(key_client.list_keys, self._credentials.compartment_id))
lambda: list_call_get_all_results(key_client.list_keys, self._credentials.get_scope()))
return response.data
except Exception as e:
print_exception('Failed to get KMS vaults: {}'.format(e))
Expand Down
44 changes: 31 additions & 13 deletions ScoutSuite/providers/oci/facade/objectstorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from oci.pagination import list_call_get_all_results

from ScoutSuite.providers.utils import run_concurrently
from ScoutSuite.core.console import print_exception


class ObjectStorageFacade:
Expand All @@ -11,22 +12,39 @@ def __init__(self, credentials: OracleCredentials):
self._client = ObjectStorageClient(self._credentials.config)

async def get_namespace(self):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.get_namespace))
# for some reason it returns a list of chars instead of a string
return ''.join(response.data)
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.get_namespace))
# for some reason it returns a list of chars instead of a string
return ''.join(response.data)
except Exception as e:
print_exception('Failed to get Object Storage namespace: {}'.format(e))
return None

async def get_bucket_details(self, namespace, bucket_name):
response = await run_concurrently(
lambda: self._client.get_bucket(namespace, bucket_name))
return response.data
try:
response = await run_concurrently(
lambda: self._client.get_bucket(namespace, bucket_name)
)
return response.data
except Exception as e:
print_exception('Failed to get Object Storage bucket details: {}'.format(e))
return None

async def get_buckets(self, namespace):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_buckets, namespace, self._credentials.compartment_id))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_buckets, namespace, self._credentials.get_scope()))
return response.data
except Exception as e:
print_exception('Failed to get Object Storage buckets: {}'.format(e))
return []

async def get_bucket_objects(self, namespace, bucket_name):
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_objects, namespace, bucket_name))
return response.data
try:
response = await run_concurrently(
lambda: list_call_get_all_results(self._client.list_objects, namespace, bucket_name))
return response.data
except Exception as e:
print_exception('Failed to get Object Storage bucket objects: {}'.format(e))
return []
2 changes: 1 addition & 1 deletion ScoutSuite/providers/oci/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self,
self.services_config = OracleServicesConfig

self.credentials = kwargs['credentials']
self.account_id = self.credentials.compartment_id
self.account_id = self.credentials.get_scope()

super(OracleProvider, self).__init__(report_dir, timestamp, services, skipped_services)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ def __init__(self, facade: OracleFacade):

async def fetch_all(self):
raw_authentication_policy = await self.facade.identity.get_authentication_policy()
password_policy = self._parse_authentication_policy(raw_authentication_policy)
if raw_authentication_policy:
password_policy = self._parse_authentication_policy(raw_authentication_policy)
else:
password_policy = {}
self.update(password_policy)

def _parse_authentication_policy(self, raw_authentication_policy):
Expand Down
32 changes: 17 additions & 15 deletions ScoutSuite/providers/oci/resources/objectstorage/buckets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,26 @@ async def fetch_all(self):
async def _parse_bucket(self, raw_bucket):
bucket_dict = {}

bucket_dict['id'] = bucket_dict['name'] = raw_bucket.name
bucket_dict['compartment_id'] = raw_bucket.compartment_id
bucket_dict['namespace'] = raw_bucket.namespace
bucket_dict['created_by'] = raw_bucket.created_by
bucket_dict['etag'] = raw_bucket.etag
bucket_dict['freeform_tags'] = list(raw_bucket.freeform_tags) if raw_bucket.freeform_tags else []
bucket_dict['defined_tags'] = list(raw_bucket.defined_tags) if raw_bucket.defined_tags else []

raw_bucket_details = await self.facade.objectstorage.get_bucket_details(raw_bucket.namespace,
raw_bucket.name)

bucket_dict['id'] = bucket_dict['name'] = raw_bucket_details.name
bucket_dict['kms_key_id'] = raw_bucket_details.kms_key_id
bucket_dict['compartment_id'] = raw_bucket_details.compartment_id
bucket_dict['approximate_count'] = raw_bucket_details.approximate_count
bucket_dict['namespace'] = raw_bucket_details.namespace
bucket_dict['created_by'] = raw_bucket_details.created_by
bucket_dict['etag'] = raw_bucket_details.etag
bucket_dict['time_created'] = raw_bucket_details.time_created
bucket_dict['public_access_type'] = raw_bucket_details.public_access_type
bucket_dict['approximate_size'] = raw_bucket_details.approximate_size
bucket_dict['storage_tier'] = raw_bucket_details.storage_tier
bucket_dict['metadata'] = list(raw_bucket_details.metadata)
bucket_dict['freeform_tags'] = list(raw_bucket_details.freeform_tags)
bucket_dict['defined_tags'] = list(raw_bucket_details.defined_tags)
bucket_dict['object_lifecycle_policy_etag'] = raw_bucket_details.object_lifecycle_policy_etag
bucket_dict['kms_key_id'] = raw_bucket_details.kms_key_id if raw_bucket_details else None
bucket_dict['approximate_count'] = raw_bucket_details.approximate_count if raw_bucket_details else None
bucket_dict['time_created'] = raw_bucket_details.time_created if raw_bucket_details else None
bucket_dict['public_access_type'] = raw_bucket_details.public_access_type if raw_bucket_details else None
bucket_dict['approximate_size'] = raw_bucket_details.approximate_size if raw_bucket_details else None
bucket_dict['storage_tier'] = raw_bucket_details.storage_tier if raw_bucket_details else None
bucket_dict['metadata'] = list(raw_bucket_details.metadata) if raw_bucket_details else None
bucket_dict['object_lifecycle_policy_etag'] = raw_bucket_details.object_lifecycle_policy_etag if \
raw_bucket_details else None

# objects = await self.facade.objectstorage.get_bucket_objects(bucket_dict['namespace'],
# bucket_dict['name'])
Expand Down

0 comments on commit 7d9e566

Please sign in to comment.