Esempio n. 1
0
def do_verify_cmd(config, args):
    """subcommand to verify an entry in the database
    """
    parser = argparse.ArgumentParser(
        prog='verify', description='verify current binding in the database')
    parser.add_argument('-n',
                        '--name',
                        help='name given to the enclave service',
                        required=True)

    options = parser.parse_args(args)

    _load_database_(config)

    try:
        ledger_config = config['Ledger']
        enclave_info = eservice_db.get_by_name(options.name)
        if enclave_info is None:
            print('no enclave with name {0}'.format(options.name))
            sys.exit(-1)
        if not enclave_info.verify(ledger_config):
            print('verification failed')
            sys.exit(-1)
    except Exception as e:
        logger.error('unable to verify eservice data for %s; %s', options.name,
                     str(e))
        sys.exit(-1)

    print('verification succeeded')
Esempio n. 2
0
def __expand_eservice_names__(names):
    result = set()
    if names:
        for name in names:
            eservice_info = eservice_db.get_by_name(name)
            if eservice_info is None:
                raise Exception('unknown eservice name {0}'.format(name))
            result.add(eservice_info.url)

    return result
def do_list_cmd(config, args) :
    """subcommand to list entries in the database
    """

    _load_database_(config)

    enclave_names = list(eservice_db.get_enclave_names())
    enclave_names.sort()

    for enclave_name in enclave_names :
        enclave_info = eservice_db.get_by_name(enclave_name)
        enclave_short_id = _hashed_identity_(enclave_info.enclave_id)
        print("{0:<18} {1:<18} {2}".format(enclave_name, enclave_short_id, enclave_info.url))
Esempio n. 4
0
def compute_database_hash():
    """compute a hash that we can use to compare two versions
    of the enclave database
    """

    enclave_names = list(eservice_db.get_enclave_names())
    enclave_names.sort()
    serialized_einfo_list = []
    for enclave_name in enclave_names:
        einfo = eservice_db.get_by_name(enclave_name)
        serialized_einfo_list.append(einfo.serialize())

    serialized_db = json.dumps(serialized_einfo_list)
    return hash(serialized_db)
Esempio n. 5
0
def command_eservice_db(state, bindings, pargs):
    """controller command to manage the enclave service database
    """

    parser = argparse.ArgumentParser(prog='eservice')

    subparsers = parser.add_subparsers(dest='command')

    add_parser = subparsers.add_parser(
        'add', description='add an eservice to the database')
    add_parser.add_argument('--url',
                            help='URL for the enclave service to add',
                            type=str,
                            required=True)
    add_parser.add_argument('--name',
                            help='Short name for the enclave service',
                            type=str,
                            required=True)

    clear_parser = subparsers.add_parser(
        'clear', description='remove all eservices in the database')
    list_parser = subparsers.add_parser(
        'list', description='list eservices in the database')

    load_parser = subparsers.add_parser(
        'load', description='load an eservice database')
    load_parser.add_argument('--database',
                             help='Name of the eservice database to use',
                             type=str,
                             required=True)
    merge_group = load_parser.add_mutually_exclusive_group(required=False)
    merge_group.add_argument('--merge',
                             help='Merge new database with current db',
                             dest='merge',
                             action='store_true')
    merge_group.add_argument('--no-merge',
                             help='Overwrite current db with new database',
                             dest='merge',
                             action='store_false')
    load_parser.set_defaults(merge=False)

    remove_parser = subparsers.add_parser(
        'remove', description='remove eservice from the database')
    remove_group = remove_parser.add_mutually_exclusive_group(required=True)
    remove_group.add_argument('--name',
                              help='Short name for enclave service to remove',
                              type=str)

    save_parser = subparsers.add_parser(
        'save', description='save the current eservice database')
    save_parser.add_argument('--database',
                             help='Name of the eservice database to use',
                             type=str,
                             required=True)

    options = parser.parse_args(pargs)

    default_database = state.get(['Service', 'EnclaveServiceDatabaseFile'])
    ledger_config = state.get(['Sawtooth'])

    if options.command == 'add':
        if not eservice_db.add_by_url(
                ledger_config, options.url, name=options.name, update=True):
            raise Exception(
                'failed to add eservice {0} to the database'.format(
                    options.name))
        return

    if options.command == 'clear':
        eservice_db.clear_all_data()
        return

    if options.command == 'list':
        enclave_names = list(eservice_db.get_enclave_names())
        enclave_names.sort()

        for enclave_name in enclave_names:
            enclave_info = eservice_db.get_by_name(enclave_name)
            enclave_short_id = _hashed_identity_(enclave_info.enclave_id)
            print("{0:<18} {1:<18} {2}".format(enclave_name, enclave_short_id,
                                               enclave_info.url))

    if options.command == 'load':
        eservice_db.load_database(options.database, options.merge)
        return

    if options.command == 'remove':
        eservice_db.remove_by_name(name=options.name)
        return

    if options.command == 'save':
        eservice_db.save_database(options.database, True)
        return

    raise Exception('unknown subcommand')
Esempio n. 6
0
def command_eservice(state, bindings, pargs):
    """controller command to manage the list of enclave services
    """
    subcommands = ['add', 'remove', 'set', 'list', 'create-group', 'use']

    parser = argparse.ArgumentParser(prog='eservice')
    parser.add_argument('--group',
                        help='Name of the eservice group',
                        type=str,
                        default="default")

    subparsers = parser.add_subparsers(dest='command')

    subparser = subparsers.add_parser('add')
    subparser.add_argument('--url',
                           help='URLs for enclave services',
                           type=str,
                           nargs='+')
    subparser.add_argument('--name',
                           help='EService DB name for enclave services',
                           type=str,
                           nargs='+')

    subparser = subparsers.add_parser('remove')
    subparser.add_argument('--url',
                           help='URLs for enclave services',
                           type=str,
                           nargs='+')
    subparser.add_argument('--name',
                           help='EService DB name for enclave services',
                           type=str,
                           nargs='+')

    subparser = subparsers.add_parser('set')
    subparser.add_argument('--url',
                           help='URLs for enclave services',
                           type=str,
                           nargs='+')
    subparser.add_argument('--name',
                           help='EService DB name for enclave services',
                           type=str,
                           nargs='+')

    subparser = subparsers.add_parser('list')

    subparser = subparsers.add_parser('use')
    eservice_group = subparser.add_mutually_exclusive_group(required=True)
    eservice_group.add_argument('--url',
                                help='URLs for enclave services',
                                type=str)
    eservice_group.add_argument('--name',
                                help='EService DB name for enclave services',
                                type=str)
    eservice_group.add_argument('--random',
                                help='No preferred enclave service',
                                action='store_true')

    options = parser.parse_args(pargs)

    if options.command == 'add':
        services = set(
            state.get(
                ['Service', 'EnclaveServiceGroups', options.group, 'urls'],
                []))
        if options.url:
            services = services.union(options.url)
        if options.name:
            services = services.union(__expand_eservice_names__(options.name))
        state.set(['Service', 'EnclaveServiceGroups', options.group, 'urls'],
                  list(services))
        return

    if options.command == 'remove':
        services = set(
            state.get(
                ['Service', 'EnclaveServiceGroups', options.group, 'urls'],
                []))
        if options.url:
            services = services.difference(options.url)
        if options.name:
            services = services.difference(
                __expand_eservice_names__(options.name))
        state.set(['Service', 'EnclaveServiceGroups', options.group, 'urls'],
                  list(services))
        return

    if options.command == 'set':
        services = set()
        if options.url:
            services = services.union(options.url)
        if options.name:
            services = services.union(__expand_eservice_names__(options.name))
        state.set(['Service', 'EnclaveServiceGroups', options.group, 'urls'],
                  list(services))
        return

    if options.command == 'use':
        if options.random:
            state.set([
                'Service', 'EnclaveServiceGroups', options.group, 'preferred'
            ], 'random')
            return

        service_url = None
        if options.url:
            service_url = options.url
        if options.name:
            service_info = eservice_db.get_by_name(options.name)
            if service_info is None:
                raise Exception('unknown eservice name; %s', options.name)
            service_url = service_info.url

        services = state.get(
            ['Service', 'EnclaveServiceGroups', options.group, 'urls'], [])
        if service_url in services:
            state.set([
                'Service', 'EnclaveServiceGroups', options.group, 'preferred'
            ], service_url)
        else:
            raise Exception('preferred URL not in the service group')
        return

    if options.command == 'list':
        preferred = state.get(
            ['Service', 'EnclaveServiceGroups', options.group, 'preferred'],
            'random')
        services = state.get(
            ['Service', 'EnclaveServiceGroups', options.group, 'urls'], [])
        print("preferred: {0}".format(preferred))
        for service in services:
            print(service)
        return

    raise Exception('unknown subcommand')
def command_eservice_db(state, bindings, pargs):
    """controller command to manage the enclave service database
    """

    parser = argparse.ArgumentParser(prog='eservice_db')
    parser.add_argument('-q',
                        '--quiet',
                        help='Do not print the result',
                        action='store_true')

    subparsers = parser.add_subparsers(dest='command')

    add_parser = subparsers.add_parser(
        'add', description='add an eservice to the database')
    add_parser.add_argument('--url',
                            help='URL for the enclave service to add',
                            type=str,
                            required=True)
    add_parser.add_argument('--name',
                            help='Short name for the enclave service',
                            type=str,
                            required=True)

    clear_parser = subparsers.add_parser(
        'clear', description='remove all eservices in the database')
    list_parser = subparsers.add_parser(
        'list', description='list eservices in the database')

    info_parser = subparsers.add_parser(
        'info', description='get information about a specific eservice')
    info_parser.add_argument('--name',
                             help='Short name for enclave service',
                             type=str,
                             required=True)
    info_parser.add_argument('-s',
                             '--symbol',
                             help='binding symbol for the result',
                             type=str)
    info_parser.add_argument('-f',
                             '--field',
                             help='field to display',
                             type=str)

    load_parser = subparsers.add_parser(
        'load', description='load an eservice database')
    load_parser.add_argument('--database',
                             help='Name of the eservice database to use',
                             type=str,
                             required=True)
    merge_group = load_parser.add_mutually_exclusive_group(required=False)
    merge_group.add_argument('--merge',
                             help='Merge new database with current db',
                             dest='merge',
                             action='store_true')
    merge_group.add_argument('--no-merge',
                             help='Overwrite current db with new database',
                             dest='merge',
                             action='store_false')
    load_parser.set_defaults(merge=False)

    remove_parser = subparsers.add_parser(
        'remove', description='remove eservice from the database')
    remove_group = remove_parser.add_mutually_exclusive_group(required=True)
    remove_group.add_argument('--name',
                              help='Short name for enclave service to remove',
                              type=str)

    save_parser = subparsers.add_parser(
        'save', description='save the current eservice database')
    save_parser.add_argument('--database',
                             help='Name of the eservice database to use',
                             type=str,
                             required=True)

    options = parser.parse_args(pargs)

    default_database = state.get(['Service', 'EnclaveServiceDatabaseFile'])
    ledger_config = state.get(['Ledger'])

    if options.command == 'add':
        if not eservice_db.add_by_url(
                ledger_config, options.url, name=options.name, update=True):
            raise Exception(
                'failed to add eservice {0} to the database'.format(
                    options.name))
        return

    if options.command == 'clear':
        eservice_db.clear_all_data()
        return

    if options.command == 'list':
        enclave_names = list(eservice_db.get_enclave_names())
        enclave_names.sort()

        for enclave_name in enclave_names:
            enclave_info = eservice_db.get_by_name(enclave_name)
            enclave_short_id = _hashed_identity_(enclave_info.enclave_id)
            print("{0:<18} {1:<18} {2}".format(enclave_name, enclave_short_id,
                                               enclave_info.url))

        return

    if options.command == 'info':
        enclave_info = eservice_db.get_by_name(options.name)
        enclave_info.verify(state.get(['Ledger']))

        enclave = {}
        enclave['short_name'] = options.name
        enclave['short_id'] = _hashed_identity_(enclave_info.enclave_id)
        enclave['enclave_id'] = enclave_info.enclave_id
        enclave['url'] = enclave_info.url
        enclave['last_verified_time'] = enclave_info.last_verified_time
        enclave['interpreter'] = enclave_info.client.interpreter
        enclave[
            'storage_service_url'] = enclave_info.client.storage_service_url
        enclave['verifying_key'] = enclave_info.client.verifying_key
        enclave['encryption_key'] = enclave_info.client.encryption_key

        result = enclave
        if options.field:
            result = enclave[options.field]

        if not options.quiet:
            print(json.dumps(result, indent=4, sort_keys=True))

        if options.symbol:
            bindings.bind(options.symbol, result)

        return

    if options.command == 'load':
        eservice_db.load_database(options.database, options.merge)
        return

    if options.command == 'remove':
        eservice_db.remove_by_name(name=options.name)
        return

    if options.command == 'save':
        eservice_db.save_database(options.database, True)
        return

    raise Exception('unknown subcommand')
Esempio n. 8
0
# -----------------------------------------------------------------
# logger.info('create and load the database from the provided URLs')
# -----------------------------------------------------------------
names = []
enclave_count = 0
for url in options.url:
    names.append('enclave_{0}'.format(enclave_count))
    eservice_db.add_by_url(ledger_config, url, name=names[enclave_count])
    enclave_count += 1

# -----------------------------------------------------------------
# logger.info('verify that the information in the database is consistent')
# -----------------------------------------------------------------
for e in names:
    einfo_by_name = eservice_db.get_by_name(e)
    einfo_by_enclave_id = eservice_db.get_by_enclave_id(
        einfo_by_name.client.enclave_id)

    # this can probably be simplified to just a comparison of
    # the two objects
    assert einfo_by_name.name == e
    assert einfo_by_enclave_id.name == e
    assert einfo_by_name.name == einfo_by_enclave_id.name
    assert einfo_by_name.enclave_id == einfo_by_enclave_id.enclave_id

# -----------------------------------------------------------------
# logger.info('verify that database can be saved and loaded')
# -----------------------------------------------------------------
initial_hash = compute_database_hash()
eservice_db.save_database(options.eservice_db, overwrite=True)