def GetSecretsFilePath(data_config): """ Return secrets data file location. If it doesnt exist, creates a new one in the 'DefaultPath' specified in config file """ try: data_file_path = putils.find_file_in_path(data_config['FileName'], data_config['SearchPath']) return data_file_path except FileNotFoundError as e: logger.warn('provisioning secrets data file missing') default_file_path = os.path.realpath( os.path.join(data_config['DefaultPath'], data_config['FileName'])) try: os.makedirs(os.path.dirname(default_file_path), exist_ok=True) open(default_file_path, "w").close() logger.debug('save secrets data file to %s', default_file_path) return default_file_path except Exception as e: logger.warning('Error creating new secrets data file; %s', str(e)) raise e return None
def create_from_file(cls, name, source_name=None, search_path=['.', '..', './contracts'], interpreter='gipsy', compilation_report=None): """Create a code object from a Gipsy source file :param name str: the name of the scheme contract class :param source_name str: the name of the source file :param search_path list of str: directories to search for the source file """ if source_name is None: source_name = name basename = putils.build_simple_file_name( source_name, extension=cls.__extension__[interpreter]) filename = putils.find_file_in_path(basename, search_path) logger.debug('load %s contract from %s', interpreter, filename) with open(filename, "r") as cfile: code = cfile.read() report = compilation_report if interpreter == 'wawaka-aot' and report is None: report = ContractCompilationReport.create_from_file( source_name, search_path) return cls(code, name, compilation_report=report)
def read_from_file(cls, file_name, search_path=['.', './keys']): full_file = putils.find_file_in_path(file_name, search_path) with open(full_file, "r") as ff: hex_encoded_private_key = ff.read() priv = binascii.unhexlify(hex_encoded_private_key) return cls(secp256k1.PrivateKey(priv))
def __find_enclave_library(config): enclave_file_name = 'libpdo-enclave.signed.so' enclave_file_path = None if config: enclave_file_name = config.get('enclave_library', enclave_file_name) enclave_file_path = config.get('enclave_library_path', enclave_file_path) if enclave_file_path: filep = os.path.join(enclave_file_path, enclave_file_name) if os.path.exists(filep): return filep else: script_directory = os.path.abspath( os.path.dirname(os.path.realpath(__file__))) search_path = [ script_directory, os.path.abspath(os.path.join(script_directory, '..')), os.path.abspath(os.path.join(script_directory, '..', 'lib')), os.path.abspath(os.path.join(script_directory, '..', '..')), os.path.abspath(os.path.join(script_directory, '..', '..', 'lib')), os.path.abspath(os.path.join('/usr', 'lib')) ] return putils.find_file_in_path(enclave_file_name, search_path)
def do_load_plugin(self, args) : """load -- load a new command processor from a file, the file should define a function called load_commands """ if self.deferred > 0 : return False try : pargs = self.__arg_parse__(args) parser = argparse.ArgumentParser(prog='load_plugin') group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-c', '--contract-class', help='load contract plugin from data directory', type=str) group.add_argument('-f', '--file', help='file from which to read the plugin', type=str) options = parser.parse_args(pargs) if options.file : plugin_file = options.file if options.contract_class : contract_paths = self.state.get(['Contract', 'SourceSearchPath'], ['.']) plugin_file = find_file_in_path(options.contract_class + '.py', contract_paths) with open(plugin_file) as f: code = compile(f.read(), plugin_file, 'exec') exec(code, globals()) load_commands(ContractController) except SystemExit as se : return self.__arg_error__('load_plugin', args, se.code) except Exception as e : return self.__error__('load_plugin', args, str(e)) return False
def parse_configuration_files(cfiles, search_path, variable_map = None) : """ Locate and parse a collection of configuration files stored in a TOML format. :param list(str) cfiles: list of configuration files to load :param list(str) search_path: list of directores where the files may be located :param dict variable_map: a set of substitutions for variables in the files :return dict:an aggregated dictionary of configuration information """ config = {} files_found = [] try : for cfile in cfiles : files_found.append(find_file_in_path(cfile, search_path)) except FileNotFoundError as e : raise ConfigurationException(e.filename, e.strerror) for filename in files_found : try : config.update(parse_configuration_file(filename, variable_map)) except IOError as detail : raise ConfigurationException(filename, "IO error; {0}".format(str(detail))) except ValueError as detail : raise ConfigurationException(filename, "Value error; {0}".format(str(detail))) except NameError as detail : raise ConfigurationException(filename, "Name error; {0}".format(str(detail))) except KeyError as detail : raise ConfigurationException(filename, "Key error; {0}".format(str(detail))) except : raise ConfigurationException(filename, "Unknown error") return config
def create_from_file(cls, report_name, search_path=['.', '..', './contracts']): """Create a code object from a wawaka-aot source file :param report_name str: the name of the compilation report file :param search_path list of str: directories to search for the source file """ if report_name.endswith('.b64'): # we may get the full file path for the contract as the report name # so drop the extension, so we actually find and load the report file report_name = os.path.basename(report_name) # only works on Linux report_name = report_name[:-4] basename = putils.build_simple_file_name(report_name, extension='.cdi') filename = putils.find_file_in_path(basename, search_path) logger.debug('load wawaka-aot compilation report from %s', filename) # file is json-encoded with open(filename, "r") as rfile: contents = rfile.read() contents = contents.rstrip('\0') report = json.loads(contents) logger.debug('loaded report %s', json.dumps(report)) return cls.init_from_dict(report)
def LocalMain(config): try: key_config = config.get('Key', {}) keyfile = putils.find_file_in_path(key_config['FileName'], key_config['SearchPath']) logger.debug('read key from %s', keyfile) with open(keyfile, "r") as f: config['SigningKeyPrivate'] = f.read() except FileNotFoundError as e: logger.warning('Unable to locate signing key file') sys.exit(-1) try: data_config = config.get('ProvisioningData', {}) config["SecretsFilePath"] = GetSecretsFilePath(data_config) except Exception as e: logger.warning( 'Unable to locate or create provisioning secrets data file') sys.exit(-1) signing_key = pcrypto.SIG_PrivateKey() signing_key.Deserialize(config['SigningKeyPrivate']) config['SigningKeyPublic'] = signing_key.GetPublicKey().Serialize() RunProvisioningService(config)
def __parse_pem_file_list(key_list, search_path): keys = [] for key_file in key_list: logger.debug('opening key file %s', key_file) full_file = putils.find_file_in_path(key_file, search_path) with open(full_file, 'r') as k: key = k.read() assert key.startswith('-----BEGIN PUBLIC KEY-----\n') and key.endswith( '\n-----END PUBLIC KEY-----\n'), "Malformed .pem key" keys.append(key) return keys
def do_set(self, args) : """set -- assign a value to a symbol that can be retrieved with a $expansion """ if self.deferred > 0 : return False try : pargs = self.__arg_parse__(args) parser = argparse.ArgumentParser(prog='set') parser.add_argument('-q', '--quiet', help='suppress printing the result', action='store_true') parser.add_argument('-s', '--symbol', help='symbol in which to store the identifier', required=True) parser.add_argument('-c', '--conditional', help='set the value only if it is undefined', action='store_true') eparser = parser.add_mutually_exclusive_group(required=True) eparser.add_argument('-i', '--identity', help='identity to use for retrieving public keys') eparser.add_argument('-f', '--file', help='name of the file to read for the value') eparser.add_argument('-v', '--value', help='string value to associate with the symbol') eparser.add_argument('-r', '--random', help='generate a random string', type=int) eparser.add_argument('--state', help='pull a value from current state', nargs="+") options = parser.parse_args(pargs) if options.conditional and self.bindings.isbound(options.symbol) : return value = options.value if options.identity : keypath = self.state.get(['Key', 'SearchPath']) keyfile = find_file_in_path("{0}_public.pem".format(options.identity), keypath) with open (keyfile, "r") as myfile: value = myfile.read() if options.file : with open (options.file, "r") as myfile: value = myfile.read() if options.random : value = "{:X}".format(random.getrandbits(options.random)) if options.state : value = self.state.get(options.state) self.bindings.bind(options.symbol,value) if not options.quiet : print("${} = {}".format(options.symbol, value)) except SystemExit as se : return self.__arg_error__('set', args, se.code) except Exception as e : return self.__error__('set', args, str(e)) return False
def create_from_scheme_file(cls, name, source_name = None, search_path = ['.', '..', './contracts']) : """Create a code object from a Gipsy source file :param name str: the name of the scheme contract class :param source_name str: the name of the source file :param search_path list of str: directories to search for the source file """ if source_name is None : source_name = name basename = putils.build_simple_file_name(source_name, extension=cls.__extension__) filename = putils.find_file_in_path(basename, search_path) with open(filename, "r") as cfile : code = cfile.read() return cls(code, name)
def create_from_file(cls, name, source_name = None, search_path = ['.', '..', './contracts'], interpreter=None) : """Create a code object from a Gipsy source file :param name str: the name of the scheme contract class :param source_name str: the name of the source file :param search_path list of str: directories to search for the source file """ if source_name is None : source_name = name if interpreter is None : interpreter = os.environ.get("PDO_INTERPRETER", "wawaka") basename = putils.build_simple_file_name(source_name, extension=cls.__extension__[interpreter]) filename = putils.find_file_in_path(basename, search_path) logger.debug('load %s contract from %s', interpreter, filename) with open(filename, "r") as cfile : code = cfile.read() return cls(code, name)
def ParseCommandLine(config, args): global use_ledger, use_pservice, use_eservice parser = argparse.ArgumentParser() parser.add_argument('--ledger', help='URL for the Sawtooth ledger', type=str) parser.add_argument('--no-ledger', help='Do not attempt ledger registration', action="store_true") parser.add_argument('--data', help='Path for storing generated files', type=str) parser.add_argument('--secret-count', help='Number of secrets to generate', type=int, default=3) parser.add_argument('--contract', help='Name of the contract to use', default='integer-key') parser.add_argument('--expressions', help='Name of a file to read for expressions', default=None) parser.add_argument('--eservice', help='URL of the enclave service to use', type=str) parser.add_argument('--pservice', help='URLs for provisioning services to contact', type=str, nargs='+', default=[]) parser.add_argument( '--logfile', help='Name of the log file, __screen__ for standard output', type=str) parser.add_argument('--loglevel', help='Logging level', type=str) options = parser.parse_args(args) if config.get('Logging') is None: config['Logging'] = {'LogFile': '__screen__', 'LogLevel': 'INFO'} if options.logfile: config['Logging']['LogFile'] = options.logfile if options.loglevel: config['Logging']['LogLevel'] = options.loglevel.upper() if config.get('PDO') is None: config['PDO'] = { 'DataPath': 'mock_data', 'SchemeSearchPath': ['contracts'] } if options.data: config['PDO']['DataPath'] = options.data if config.get('Sawtooth') is None: config['Sawtooth'] = { 'LedgerURL': 'http://localhost:8008', 'Organization': 'Organization' } if options.ledger: config['Sawtooth']['LedgerURL'] = options.ledger if options.no_ledger: use_ledger = False config.pop('Sawtooth', None) if options.eservice: use_eservice = True config['eservice-url'] = options.eservice if options.pservice: use_pservice = True config['pservice-urls'] = options.pservice config['secrets'] = options.secret_count config['contract'] = options.contract if options.expressions: expression_file = options.expressions else: expression_file = config['contract'] + '.exp' config['expressions'] = putils.find_file_in_path(expression_file, ['.', '..', 'contracts'])
def read_from_file(cls, file_name, search_path=['.', './keys']): full_file = putils.find_file_in_path(file_name, search_path) with open(full_file, "r") as ff: pem_encoded_signing_key = ff.read() return cls(crypto.SIG_PrivateKey(pem_encoded_signing_key))
def Main(): global use_ledger global use_eservice global use_pservice # parse out the configuration file first conffiles = ['pcontract.toml', 'enclave.toml'] confpaths = [".", "./etc", ContractEtc] parser = argparse.ArgumentParser() parser.add_argument('--config', help='configuration file', nargs='+') parser.add_argument( '--config-dir', help='directories to search for the configuration file', nargs='+') parser.add_argument('-i', '--identity', help='Identity to use for the process', default='test-request', type=str) parser.add_argument( '--logfile', help='Name of the log file, __screen__ for standard output', type=str) parser.add_argument('--loglevel', help='Logging level', type=str) parser.add_argument('--ledger', help='URL for the Sawtooth ledger', type=str) parser.add_argument('--no-ledger', help='Do not attempt ledger registration', action="store_true") parser.add_argument('--data-dir', help='Directory for storing generated files', type=str) parser.add_argument('--source-dir', help='Directories to search for contract source', nargs='+', type=str) parser.add_argument('--key-dir', help='Directories to search for key files', nargs='+') parser.add_argument('--eservice-url', help='List of enclave service URLs to use', nargs='+') parser.add_argument('--randomize-eservice', help="Randomize eservice used for each update", action="store_true") parser.add_argument('--pservice-url', help='List of provisioning service URLs to use', nargs='+') parser.add_argument('--block-store', help='Name of the file where blocks are stored', type=str) parser.add_argument('--secret-count', help='Number of secrets to generate', type=int, default=3) parser.add_argument('--contract', help='Name of the contract to use', default='mock-contract') parser.add_argument('--interpreter', help='Name of the contract to to require', default=ContractInterpreter) parser.add_argument('--expressions', help='Name of a file to read for expressions', default=None) parser.add_argument( '--num-provable-replicas', help='Number of sservice signatures needed for proof of replication', type=int, default=1) parser.add_argument( '--availability-duration', help= 'duration (in seconds) for which the replicas are stored at storage service', type=int, default=60) options = parser.parse_args() # first process the options necessary to load the default configuration if options.config: conffiles = options.config if options.config_dir: confpaths = options.config_dir # customize the configuration file for the current request global config_map config_map['identity'] = options.identity if options.data_dir: config_map['data'] = options.data_dir config_map['contract'] = options.contract # parse the configuration file try: config = pconfig.parse_configuration_files(conffiles, confpaths, config_map) except pconfig.ConfigurationException as e: logger.error(str(e)) sys.exit(-1) # set up the logging configuration if config.get('Logging') is None: config['Logging'] = {'LogFile': '__screen__', 'LogLevel': 'INFO'} if options.logfile: config['Logging']['LogFile'] = options.logfile if options.loglevel: config['Logging']['LogLevel'] = options.loglevel.upper() plogger.setup_loggers(config.get('Logging', {})) sys.stdout = plogger.stream_to_logger(logging.getLogger('STDOUT'), logging.DEBUG) sys.stderr = plogger.stream_to_logger(logging.getLogger('STDERR'), logging.WARN) # set up the ledger configuration if config.get('Sawtooth') is None: config['Sawtooth'] = { 'LedgerURL': 'http://localhost:8008', } if options.ledger: config['Sawtooth']['LedgerURL'] = options.ledger if options.no_ledger or not config['Sawtooth']['LedgerURL']: use_ledger = False config.pop('Sawtooth', None) # set up the key search paths if config.get('Key') is None: config['Key'] = { 'SearchPath': ['.', './keys', ContractKeys], 'FileName': options.identity + ".pem" } if options.key_dir: config['Key']['SearchPath'] = options.key_dir # set up the service configuration if config.get('Service') is None: config['Service'] = { 'EnclaveServiceURLs': [], 'ProvisioningServiceURLs': [], 'EnclaveServiceDatabaseFile': None, 'Randomize_Eservice': False } if options.randomize_eservice: config['Service']['Randomize_Eservice'] = True else: config['Service']['Randomize_Eservice'] = False if options.eservice_url: use_eservice = True config['Service']['EnclaveServiceURLs'] = options.eservice_url if options.pservice_url: use_pservice = True config['Service']['ProvisioningServiceURLs'] = options.pservice_url # replication parameters if options.num_provable_replicas: config['Replication'][ 'NumProvableReplicas'] = options.num_provable_replicas if options.availability_duration: config['Replication']['Duration'] = options.availability_duration # set up the data paths if config.get('Contract') is None: config['Contract'] = { 'DataDirectory': ContractData, 'SourceSearchPath': [".", "./contract", os.path.join(ContractHome, 'contracts')] } if config['Contract'].get('Name') is None: config['Contract']['Name'] = options.contract config['Contract']['SourceFile'] = '_{0}'.format(options.contract) config['Contract']['Interpreter'] = options.interpreter if options.data_dir: config['Contract']['DataDirectory'] = options.data_dir if options.source_dir: config['Contract']['SourceSearchPath'] = options.source_dir putils.set_default_data_directory(config['Contract']['DataDirectory']) # set up the storage service configuration if config.get('StorageService') is None: config['StorageService'] = { 'BlockStore': os.path.join(config['Contract']['DataDirectory'], options.identity + '.mdb'), } if options.block_store: config['StorageService']['BlockStore'] = options.block_store config['secrets'] = options.secret_count if options.expressions: expression_file = options.expressions else: expression_file = putils.build_simple_file_name( options.contract, '.exp') try: config['expressions'] = putils.find_file_in_path( expression_file, ['.', '..', 'tests']) except FileNotFoundError as fe: logger.error('unable to locate expression file "%s"', expression_file) sys.exit(-1) LocalMain(config)
def do_set(self, args): """ set -- assign a value to a symbol that can be retrieved with a $expansion """ pargs = shlex.split(self.bindings.expand(args)) try: parser = argparse.ArgumentParser(prog='set') parser.add_argument('-q', '--quiet', help='suppress printing the result', action='store_true') parser.add_argument('-s', '--symbol', help='symbol in which to store the identifier', required=True) parser.add_argument('-c', '--conditional', help='set the value only if it is undefined', action='store_true') eparser = parser.add_mutually_exclusive_group(required=True) eparser.add_argument( '-i', '--identity', help='identity to use for retrieving public keys') eparser.add_argument('-f', '--file', help='name of the file to read for the value') eparser.add_argument( '-v', '--value', help='string value to associate with the symbol') options = parser.parse_args(pargs) if options.conditional and self.bindings.isbound(options.symbol): return value = options.value if options.identity: keypath = self.state.get(['Key', 'SearchPath']) keyfile = find_file_in_path( "{0}_public.pem".format(options.identity), keypath) with open(keyfile, "r") as myfile: value = myfile.read() if options.file: with open(options.file, "r") as myfile: value = myfile.read() self.bindings.bind(options.symbol, value) if not options.quiet: print("${} = {}".format(options.symbol, value)) return except SystemExit as se: if se.code > 0: print('An error occurred processing {0}: {1}'.format( args, str(se))) return except Exception as e: print('An error occurred processing {0}: {1}'.format(args, str(e))) return
def Main(): global use_ledger global use_eservice global use_pservice import pdo.common.config as pconfig import pdo.common.logger as plogger # parse out the configuration file first conffiles = ['pcontract.toml', 'enclave.toml'] confpaths = [".", "./etc", ContractEtc] parser = argparse.ArgumentParser() parser.add_argument('--config', help='configuration file', nargs='+') parser.add_argument( '--config-dir', help='directories to search for the configuration file', nargs='+') parser.add_argument('-i', '--identity', help='Identity to use for the process', type=str) parser.add_argument( '--logfile', help='Name of the log file, __screen__ for standard output', type=str) parser.add_argument('--loglevel', help='Logging level', type=str) parser.add_argument('--ledger', help='URL for the Sawtooth ledger', type=str) parser.add_argument('--no-ledger', help='Do not attempt ledger registration', action="store_true") parser.add_argument('--data-dir', help='Directory for storing generated files', type=str) parser.add_argument('--source-dir', help='Directories to search for contract source', nargs='+', type=str) parser.add_argument('--key-dir', help='Directories to search for key files', nargs='+') parser.add_argument('--eservice-url', help='List of enclave service URLs to use', nargs='+') parser.add_argument('--pservice-url', help='List of provisioning service URLs to use', nargs='+') parser.add_argument('--secret-count', help='Number of secrets to generate', type=int, default=3) parser.add_argument('--contract', help='Name of the contract to use', default='integer-key') parser.add_argument('--expressions', help='Name of a file to read for expressions', default=None) options = parser.parse_args() # first process the options necessary to load the default configuration if options.config: conffiles = options.config if options.config_dir: confpaths = options.config_dir # customize the configuration file for the current request global config_map config_map['identity'] = 'test-request' if options.identity: config_map['identity'] = options.identity if options.data_dir: config_map['data'] = options.data_dir config_map['contract'] = options.contract # parse the configuration file try: config = pconfig.parse_configuration_files(conffiles, confpaths, config_map) except pconfig.ConfigurationException as e: logger.error(str(e)) sys.exit(-1) # set up the logging configuration if config.get('Logging') is None: config['Logging'] = {'LogFile': '__screen__', 'LogLevel': 'INFO'} if options.logfile: config['Logging']['LogFile'] = options.logfile if options.loglevel: config['Logging']['LogLevel'] = options.loglevel.upper() plogger.setup_loggers(config.get('Logging', {})) sys.stdout = plogger.stream_to_logger(logging.getLogger('STDOUT'), logging.DEBUG) sys.stderr = plogger.stream_to_logger(logging.getLogger('STDERR'), logging.WARN) # set up the ledger configuration if config.get('Sawtooth') is None: config['Sawtooth'] = { 'LedgerURL': 'http://localhost:8008', } if options.ledger: config['Sawtooth']['LedgerURL'] = options.ledger # set up the key search paths if config.get('Key') is None: config['Key'] = { 'SearchPath': ['.', './keys', ContractKeys], 'FileName': options.identity + ".pem" } if options.key_dir: config['Key']['SearchPath'] = options.key_dir # set up the service configuration if config.get('Service') is None: config['Service'] = { 'EnclaveServiceURLs': [], 'ProvisioningServiceURLs': [] } if options.eservice_url: use_eservice = True config['Service']['EnclaveServiceURLs'] = options.eservice_url if options.pservice_url: use_pservice = True config['Service']['ProvisioningServiceURLs'] = options.pservice_url # set up the data paths if config.get('Contract') is None: config['Contract'] = { 'DataDirectory': ContractData, 'SourceSearchPath': [".", "./contract", os.path.join(ContractHome, 'contracts')] } if options.data_dir: config['Contract']['DataDirectory'] = options.data_dir if options.source_dir: config['Contract']['SourceSearchPath'] = options.source_dir putils.set_default_data_directory(config['Contract']['DataDirectory']) if options.no_ledger or not config['Sawtooth']['LedgerURL']: use_ledger = False config.pop('Sawtooth', None) config['secrets'] = options.secret_count if options.expressions: expression_file = options.expressions else: expression_file = putils.build_simple_file_name( options.contract, '.exp') try: config['expressions'] = putils.find_file_in_path( expression_file, ['.', '..', 'tests']) except FileNotFoundError as fe: logger.error('unable to locate expression file "%s"', expression_file) sys.exit(-1) LocalMain(config)