def __init__(self, logger, settings=None, globalSettings=None, env=None, poolSize=35, maxOverflow=5, poolRecycle=1800):
		"""Constructor for the database client connection.

		Arguments:
		  logger                : handler for the database log
		  settings (json)       : database connection parameters
		  globalSettings (json) : global settings
		  env                   : module containing the env paths
		  poolSize (int)        : pool_size param for sqlalchemy.create_engine()
		  maxOverflow (int)     : max_overflow param for sqlalchemy.create_engine()
		  poolRecycle (int)     : pool_recycle param for sqlalchemy.create_engine()

		"""
		try:
			self.session = None
			self.settings = settings
			if self.settings is None:
				self.settings = {}

			## Load an external database library for the wrapped connection;
			## the provided library must contain a 'createEngine' function that
			## takes a previously created dictionary with the database
			## settings (if empty, it will be filled), the globalSettings which
			## contains named references to modules in the external directory,
			## and parameters to use in the call for sqlalchemy.create_engine().	
			externalLibrary = utils.loadExternalLibrary('externalDatabaseLibrary', env, globalSettings)
			self.engine = externalLibrary.createEngine(self.settings, globalSettings, poolSize, maxOverflow, poolRecycle)

			## Validate we are actually talking to the DB
			engineInspector = sqlalchemy_inspect(self.engine)
			schemas = engineInspector.get_schema_names()
			if schemas is None or len(schemas) <= 0:
				raise EnvironmentError('Could not connect to database')
			logger.debug('Schemas found from connection pool inspection: {}'.format(str(schemas)))
			self.createScopedSession(logger)
			
		except exc.OperationalError:
			## Intentionally catch database connection errors
			logger.error('Exception in DatabaseClient: {}'.format(str(sys.exc_info()[1])))
			raise
		except:
			stacktrace = traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])
			logger.error('Exception in DatabaseClient: {}'.format(str(stacktrace)))
			raise
Beispiel #2
0
.. hidden::
	
	Author: Chris Satterthwaite (CS)
	Contributors:
	Version info:
	  1.0 : (CS) Created Jan 3, 2018

"""
## Using pythoncom since WMI is COM-based, and when using
## in a thread, it needs it's own COM threading model
import pythoncom

## Using an externally provided library defined in globalSettings and located
## in '<install_path>/external'.
import utils
externalProtocolLibrary = utils.loadExternalLibrary('externalProtocolWmi')

## PyMI is used in the external library:
##   import wmi
## To call this function for a remote connection:
##   wmi.WMI(moniker, computer, user, password)


class Wmi:
    """Wrapper class for WMI."""
    def __init__(self, runtime, logger, endpoint, reference, protocol,
                 **kwargs):
        self.runtime = runtime
        self.logger = logger
        self.endpoint = endpoint
        self.connection = None
import sys
import traceback
import json

## Using sqlalchemy for the wrapper around postgresql:
##     http://docs.sqlalchemy.org/en/latest/index.html
from sqlalchemy import create_engine

## Get relative paths based on install location
import env
env.addLibPath()
import utils
globalSettings = utils.loadSettings(
    os.path.join(env.configPath, 'globalSettings.json'))
## Import an externally-provided library for encoding/encrypting/hashing/etc
externalEncryptionLibrary = utils.loadExternalLibrary(
    'externalEncryptionLibrary', env, globalSettings)

requiredParameters = [
    'databaseServer', 'databasePort', 'databaseName', 'databaseUser'
]


def encode(sensitiveData):
    ## Use an externally library for sensitive data (defined and imported above)
    return externalEncryptionLibrary.encode(sensitiveData)


def decode(encodedData):
    ## Use an externally library for sensitive data (defined and imported above)
    return externalEncryptionLibrary.decode(encodedData)
Beispiel #4
0
def powerShell():
    import sys
    import traceback
    import os
    import re
    try:
        ## Add openContentPlatform directories onto the sys path
        thisPath = os.path.dirname(os.path.abspath(__file__))
        basePath = os.path.abspath(os.path.join(thisPath, '..'))
        if basePath not in sys.path:
            sys.path.append(basePath)
        import env
        env.addLibPath()
        env.addDatabasePath()
        env.addExternalPath()

        ## Setup requested log handlers
        globalSettings = utils.loadSettings(
            os.path.join(env.configPath, 'globalSettings.json'))
        logEntity = 'Protocols'
        logger = utils.setupLogger(logEntity, env, 'logSettingsCore.json')
        logger.info('Starting protocolWrapperPowershell...')

        import twisted.logger
        logFiles = utils.setupLogFile(
            'JobDetail',
            env,
            globalSettings['fileContainingContentGatheringLogSettings'],
            directoryName='client')
        logObserver = utils.setupObservers(
            logFiles, 'JobDetail', env,
            globalSettings['fileContainingContentGatheringLogSettings'])
        logger = twisted.logger.Logger(observer=logObserver,
                                       namespace='JobDetail')

        from remoteRuntime import Runtime
        runtime = Runtime(logger, env, 'TestPkg', 'TestJob', 'endpoint', {},
                          None, {}, None, {}, None)

        ## Manual creation of a protocol via protocolHandler
        externalProtocolHandler = utils.loadExternalLibrary(
            'externalProtocolHandler', env, globalSettings)
        protocolHandler = externalProtocolHandler.ProtocolHandler(
            None, globalSettings, env, logger)
        protocolType = 'ProtocolPowerShell'
        protocolData = {'user': '******', 'password': '******'}
        protocolHandler.createManual(runtime, protocolType, protocolData)
        protocol = externalProtocolHandler.getProtocolObject(runtime, 1)
        print('protocol to use: {}'.format(protocol))
        print('protocols: {}'.format(
            externalProtocolHandler.getProtocolObjects(runtime)))

        endpoint = '192.168.1.100'
        client = PowerShell(runtime, logger, endpoint, 1, protocol)
        client.open()

        osAttrDict = {}
        queryOperatingSystem(client, logger, osAttrDict)
        logger.debug('osAttrDict: {osAttrDict!r}', osAttrDict=osAttrDict)
        client.close()

    except:
        stacktrace = traceback.format_exception(sys.exc_info()[0],
                                                sys.exc_info()[1],
                                                sys.exc_info()[2])
        msg = str(sys.exc_info()[1])
        ## Cleanup message when we know what it is:
        ## "<x_wmi: The RPC server is unavailable.  (-2147023174, 'The RPC server is unavailable. ', (0, None, 'The RPC server is unavailable. ', None, None, -2147023174), None)>"
        if re.search(
                'The client cannot connect to the destination specified in the request',
                msg, re.I):
            ## Remove the rest of the fluff
            msg = 'The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests.'
            logger.debug('Main Exception: {exception!r}', exception=msg)
        else:
            logger.debug('Main Exception: {exception!r}', exception=stacktrace)
Beispiel #5
0
	Author: Chris Satterthwaite (CS)
	Contributors:
	Version info:
	  1.0 : (CS) Created Jan 3, 2018

"""
from contextlib import suppress
import sys
import os
import subprocess

import utils
from protocolWrapperShell import Shell, NonBlockingStreamReader
## Using an externally provided library defined in globalSettings and located
## in '<install_path>/external'.
externalProtocolLibrary = utils.loadExternalLibrary(
    'externalProtocolPowerShell')


class PowerShell(Shell):
    """Wrapper class for PowerShell."""
    def __init__(self, runtime, logger, endpoint, reference, protocol,
                 **kwargs):
        if ('shellExecutable' not in kwargs
                or kwargs['shellExecutable'] is None):
            ## Static v1.0 path still valid on v5.1, however relative paths work
            ## best with different environments setup through user preferences
            #kwargs['shellExecutable'] = 'C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
            kwargs['shellExecutable'] = 'powershell.exe'
        self.exitStatusPassRegEx = '^True$'
        self.exitStatusFailRegEx = '^False$'
        super().__init__(runtime, logger, endpoint, protocol, **kwargs)
Beispiel #6
0
"""External utility to work with WMI connections.

Externally referenced function:
  |  connection  : called by protocolWrapperWmi to make a WMI connection


The intention with an external wrapper, is to move responsibility of protecting
sensitive data away from the open-source platform. From a modular perspective,
this module would be best coded as a single Python class. However, doing that
provides easier access to internals and so we intentionally avoid encapsulation
with individual functions.

"""
import wmi
import utils
externalProtocolHandler = utils.loadExternalLibrary('externalProtocolHandler')


def connection(runtime, protocol, endpoint, namespace="root/cimv2"):
    """Extract user & password from protocol, and call wmi.WMI()."""
    protocol = externalProtocolHandler.extractProtocol(runtime, protocol)
    user = protocol['user']
    password = protocol['password']
    return wmi.WMI(moniker=namespace,
                   computer=endpoint,
                   user=user,
                   password=password)
Beispiel #7
0
## Add openContentPlatform directories onto the sys path
thisPath = os.path.dirname(os.path.abspath(__file__))
basePath = os.path.abspath(os.path.join(thisPath, '..'))
if basePath not in sys.path:
	sys.path.append(basePath)
import env
env.addLibPath()

## From openContentPlatform
import utils
from database.connectionPool import DatabaseClient
from database.schema.platformSchema import ProtocolSnmp, ProtocolWmi
from database.schema.platformSchema import ProtocolSsh, ProtocolPowerShell
from database.schema.platformSchema import ProtocolRestApi, Realm

externalEncryptionLibrary = utils.loadExternalLibrary('externalEncryptionLibrary', env)

def getPassInput(column):
	"""Simple validation and transformation of a password."""
	prettyEncoding = None
	pprompt = lambda: (getpass.getpass(' {}: '.format(column)), getpass.getpass(' retype {}: '.format(column)))
	while 1:
		pass1, pass2 = pprompt()
		if pass1 != pass2:
			print('Entries do not match; try again...')
			continue
		break
	prettyEncoding = externalEncryptionLibrary.encode(pass1)

	## end getPassInput
	return prettyEncoding
Classes:
  |  Snmp : wrapper class for SNMP

.. hidden::
	
	Author: Chris Satterthwaite (CS)
	Contributors:
	Version info:
	  1.0 : (CS) Created Jan 1, 2018
	  2.0 : (CS) Migrated to using external library, Apr 28, 2020

"""
## Using an externally provided library defined in globalSettings and located
## in '<install_path>/external'.
import utils
externalProtocolLibrary = utils.loadExternalLibrary('externalProtocolSnmp')

## Pysnmp is used in the external library:
##   from pysnmp.hlapi import *
## To call these functions:
##   getCmd(SnmpEngine(), CommunityData(communityString),
##          UdpTransportTarget((endpoint, port)), ContextData(),
##          ObjectType(ObjectIdentity(oid)))
##   nextCmd(SnmpEngine(), CommunityData(communityString),
##          UdpTransportTarget((endpoint, port)), ContextData(),
##          ObjectType(ObjectIdentity(oid)), lexicographicMode=False)


class Snmp:
    """Wrapper class for SNMP."""
    def __init__(self, runtime, logger, endpoint, reference, protocol):
def main():
    """Entry point for the database configuration utility.

	Usage::

	  $ python configureDatabase.py

	"""
    try:
        ## Setup requested log handlers
        logEntity = 'Database'
        logger = utils.setupLogger(logEntity, env, 'logSettingsCore.json')
        logger.info('Starting configureDatabase utility.')

        ## Using an externally provided library to create and/or update a local
        ## config file for database parameters; defined in globalSettings and
        ## located in '<install_path>/external/'.
        globalSettings = utils.loadSettings(
            os.path.join(env.configPath, 'globalSettings.json'))
        externalLibrary = utils.loadExternalLibrary('externalDatabaseLibrary',
                                                    env)

        dbClient = None
        while dbClient is None:
            try:
                ## Get settings from user (new or updated) and save to file
                externalLibrary.updateSettingsFile(globalSettings, logger)
                ## Attempt connection with the new or updated settings
                dbClient = DatabaseClient(logger)
                ## In case we fall through the cracks without an exception...
                if dbClient is None:
                    ## The settings didn't work; request a new set
                    print(
                        'Failed to connect to database with provided settings; try again...'
                    )
                    logger.debug(
                        'Failed to connect to database with provided settings; try again...'
                    )

            except exc.OperationalError:
                ## Intentionally catch database connection errors
                print('\nException in configureDatabase: {}'.format(
                    str(sys.exc_info()[1])))
                logger.error('Exception in configureDatabase: {}'.format(
                    str(sys.exc_info()[1])))
                ## The settings didn't work; request a new set
                print(
                    '\nFailed to connect to database with provided settings; try again...'
                )
                logger.debug(
                    'Failed to connect to database with provided settings; try again...'
                )

        print('\nDatabase connection successful\n')
        logger.debug('Database connection successful')

        ## Close the connection
        dbClient.close()
        logger.info('Exiting configureDatabase utility.')

    except:
        stacktrace = traceback.format_exception(sys.exc_info()[0],
                                                sys.exc_info()[1],
                                                sys.exc_info()[2])
        print('Failure in configureDatabase.main: {}'.format(stacktrace))
        with suppress(Exception):
            logger.debug('Failure in configureDatabase: {}'.format(stacktrace))

    ## end main
    return
Beispiel #10
0
.. hidden::

	Author: Chris Satterthwaite (CS)
	Contributors:
	Version info:
	  1.0 : (CS) Created Nov 24, 2020

"""
import sys
import traceback
import socket

## Using an externally provided library defined in globalSettings and located
## in '<install_path>/external'.
import utils
externalProtocolLibrary = utils.loadExternalLibrary(
    'externalProtocolSqlPostgres')

## Fabric is used by the external library:
##   from fabric import Connection
## To call this function for a remote connection:
##   Connection(host, user, connect_timeout, connect_kwargs)


class SqlPostgres():
    """Wrapper class for SQL connections."""
    def __init__(self,
                 runtime,
                 logger,
                 endpoint,
                 reference,
                 protocol,