コード例 #1
0
    async def deliver_update_wrapper(self, session, response_body):
        ''' Handles update pings.
        '''
        # # Shit, I have a race condition somewhere.
        # time.sleep(.01)
        subscribed_ghid = Ghid.from_bytes(response_body[0:65])
        notification_ghid = Ghid.from_bytes(response_body[65:130])

        # for callback in self._subscriptions[subscribed_ghid]:
        #     callback(notification_ghid)

        # Well this is a huge hack. But something about the event loop
        # itself is f*****g up control flow and causing the world to hang
        # here. May want to create a dedicated thread just for pushing
        # updates? Like autoresponder, but autoupdater?
        # TODO: fix this gross mess

        def run_callbacks(subscribed_ghid, notification_ghid):
            for callback in self._subscriptions[subscribed_ghid]:
                callback(subscribed_ghid, notification_ghid)

        worker = threading.Thread(
            target=run_callbacks,
            daemon=True,
            args=(subscribed_ghid, notification_ghid),
            name=_generate_threadnames('remoupd')[0],
        )
        worker.start()

        return b'\x01'
コード例 #2
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 def _unpack_object_def(self, data):
     ''' Deserializes an object from bytes.
     
     General format:
     version     1B      int16 unsigned
     address     65B     ghid
     author      65B     ghid
     private     1B      bool
     dynamic     1B      bool
     _legroom    1B      int8 unsigned
     api_id      65B     bytes
     is_link     1B      bool
     state       ?B      bytes (implicit length)
     '''
     try:
         # version = data[0:1]
         address = data[1:66]
         author = data[66:131]
         private = data[131:132]
         dynamic = data[132:133]
         _legroom = data[133:134]
         api_id = ApiID.from_bytes(data[134:199])
         is_link = data[199:200]
         state = data[200:]
         
     except Exception:
         logger.error(
             'Unable to unpack IPC object definition w/ traceback:\n'
             ''.join(traceback.format_exc())
         )
         raise
         
     # Version stays unmodified (unused)
     if address == bytes(65):
         address = None
     else:
         address = Ghid.from_bytes(address)
     if author == bytes(65):
         author = None
     else:
         author = Ghid.from_bytes(author)
     private = bool(int.from_bytes(private, 'big'))
     dynamic = bool(int.from_bytes(dynamic, 'big'))
     _legroom = int.from_bytes(_legroom, 'big')
     if _legroom == 0:
         _legroom = None
     is_link = bool(int.from_bytes(is_link, 'big'))
     # state also stays unmodified
     
     return (address,
             author,
             state,
             is_link,
             api_id,
             private,
             dynamic,
             _legroom)
コード例 #3
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def share_ghid(self, connection, body):
     ''' Handles object share requests.
     '''
     ghid = Ghid.from_bytes(body[0:65])
     origin = Ghid.from_bytes(body[65:130])
     api_id = ApiID.from_bytes(body[130:195])
     
     await self._hgxlink.handle_share(ghid, origin, api_id)
     return b'\x01'
コード例 #4
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def new_obj(self, connection, body):
     ''' Handles requests for new objects.
     '''
     (address,    # Unused and set to None.
      author,     # Unused and set to None.
      state,
      is_link,
      api_id,
      private,
      dynamic,
      legroom) = self._unpack_object_def(body)
     
     if is_link:
         raise NotImplementedError('Linked objects are not yet supported.')
         state = Ghid.from_bytes(state)
     
     obj = await self._oracle.new_object(
         gaoclass = _Dispatchable,
         dispatch = self._dispatch,
         ipc_protocol = self,
         state = state,
         dynamic = dynamic,
         legroom = legroom,
         api_id = api_id,
         account = self._dispatch._account
     )
         
     # Add the endpoint as a listener.
     await self._dispatch.register_object(connection, obj.ghid, private)
     await self._dispatch.track_object(connection, obj.ghid)
     
     return bytes(obj.ghid)
コード例 #5
0
ファイル: remotes.py プロジェクト: Muterra/py_hypergolix
 async def query_debindings(self, connection, body):
     ''' Handles debinding query requests.
     '''
     ghid = Ghid.from_bytes(body)
     ghidlist = await self._librarian.debind_status(ghid)
     parser = generate_ghidlist_parser()
     return parser.pack(list(ghidlist))
コード例 #6
0
 async def list_debindings_wrapper(self, session, request_body):
     ''' Deserializes a publish request and forwards it to the 
     persister.
     '''
     ghid = Ghid.from_bytes(request_body)
     ghidlist = self._bookie.debind_status(ghid)
     parser = generate_ghidlist_parser()
     return parser.pack(ghidlist)
コード例 #7
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def new_ghid(self, connection, response, exc):
     ''' Handles responses to requests for new objects.
     '''
     if exc is not None:
         raise exc
     
     else:
         return Ghid.from_bytes(response)
コード例 #8
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def get_whoami(self, connection, response, exc):
     ''' Handles responses to whoami requests.
     '''
     if exc is not None:
         raise exc
     else:
         ghid = Ghid.from_bytes(response)
         return ghid
コード例 #9
0
ファイル: remotes.py プロジェクト: Muterra/py_hypergolix
 async def query_existence(self, connection, body):
     ''' Handle existence queries.
     '''
     ghid = Ghid.from_bytes(body)
     if (await self._librarian.contains(ghid)):
         return b'\x01'
     else:
         return b'\x00'
コード例 #10
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def freeze_ghid(self, connection, response, exc):
     ''' Handles responses to object freezing requests.
     '''
     if exc is not None:
         raise exc
     
     else:
         return Ghid.from_bytes(response)
コード例 #11
0
 async def query_wrapper(self, session, request_body):
     ''' Deserializes a publish request and forwards it to the 
     persister.
     '''
     ghid = Ghid.from_bytes(request_body)
     if ghid in self._librarian:
         return b'\x01'
     else:
         return b'\x00'
コード例 #12
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def get_startup_obj(self, connection, response, exc):
     ''' Handle the response to retrieving startup obj ghids.
     '''
     if exc is not None:
         raise exc
     elif response == b'':
         return None
     else:
         ghid = Ghid.from_bytes(response)
         return ghid
コード例 #13
0
ファイル: ghidutils.py プロジェクト: wpkita/py_hypergolix
def make_random_ghid():
    ''' Pseudorandom ghid generator. Uses a module-level check to ensure
    uniqueness, without needing system entropy.
    '''
    ghid = None
    while ghid in MADE_RANDOM_GHIDS:
        algo = b'\x01' 
        digest = (random.getrandbits(512)).to_bytes(length=64, byteorder='big')
        ghid = Ghid.from_bytes(algo + digest)
    MADE_RANDOM_GHIDS.add(ghid)
    return ghid
コード例 #14
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def share_obj(self, connection, body):
     ''' Handles object share requests.
     '''
     ghid = Ghid.from_bytes(body[0:65])
     recipient = Ghid.from_bytes(body[65:130])
     
     # Instead of forbidding unregistered apps from sharing objects,
     # go for it, but document that you will never be notified of a
     # share success or failure without an app token.
     requesting_token = self._dispatch.token_lookup(connection)
     if requesting_token is None:
         logger.info(
             'CONN ' + str(connection) + ' is sharing ' + str(ghid) +
             ' with ' + str(recipient) + ' without defining an app ' +
             'token, and therefore cannot be notified of share success ' +
             'or failure.'
         )
         
     await self._rolodex.share_object(ghid, recipient, requesting_token)
     return b'\x01'
コード例 #15
0
ファイル: utils.py プロジェクト: wpkita/py_hypergolix
    def _unpack_object_def(self, data):
        ''' Deserializes an object from bytes.
        '''
        try:
            version = data[0:1]
            address = data[1:66]
            author = data[66:131]
            private = data[131:132]
            dynamic = data[132:133]
            _legroom = data[133:134]
            api_id = data[134:199]
            is_link = data[199:200]
            state = data[200:]

        except:
            logger.error(
                'Unable to unpack IPC object definition w/ traceback:\n'
                ''.join(traceback.format_exc()))
            raise

        # Version stays unmodified (unused)
        if address == bytes(65):
            address = None
        else:
            address = Ghid.from_bytes(address)
        if author == bytes(65):
            author = None
        else:
            author = Ghid.from_bytes(author)
        private = bool(int.from_bytes(private, 'big'))
        dynamic = bool(int.from_bytes(dynamic, 'big'))
        _legroom = int.from_bytes(_legroom, 'big')
        if _legroom == 0:
            _legroom = None
        if api_id == bytes(65):
            api_id = None
        is_link = bool(int.from_bytes(is_link, 'big'))
        # state also stays unmodified

        return (address, author, state, is_link, api_id, private, dynamic,
                _legroom)
コード例 #16
0
ファイル: remotes.py プロジェクト: Muterra/py_hypergolix
 async def unsubscribe(self, connection, body):
     ''' Handle unsubscription requests.
     '''
     ghid = Ghid.from_bytes(body)
     had_subscription = await self._postman.unsubscribe(connection, ghid)
     
     if had_subscription:
         return b'\x01'
     
     # Still successful, but idempotent
     else:
         return b'\x00'
コード例 #17
0
 async def unsubscribe_wrapper(self, session, request_body):
     ''' Deserializes a publish request and forwards it to the 
     persister.
     '''
     ghid = Ghid.from_bytes(request_body)
     callback = session._subscriptions[ghid]
     unsubbed = self._postman.unsubscribe(ghid, callback)
     del session._subscriptions[ghid]
     if unsubbed:
         return b'\x01'
     else:
         return b'\x00'
コード例 #18
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def update_obj(self, connection, body):
     ''' Handles update object requests.
     '''
     logger.debug('Handling update request from ' + str(connection))
     (ghid,
      author,    # Unused and set to None.
      state,
      is_link,
      api_id,    # Unused and set to None.
      private,   # TODO: use this.
      dynamic,   # Unused and set to None.
      legroom   # TODO: use this.
      ) = self._unpack_object_def(body)
     
     if is_link:
         raise NotImplementedError('Linked objects are not yet supported.')
         state = Ghid.from_bytes(state)
         
     obj = await self._oracle.get_object(
         gaoclass = _Dispatchable,
         ghid = ghid,
         api_id = None,  # Let _pull() apply this.
         state = None,   # Let _pull() apply this.
         dispatch = self._dispatch,
         ipc_protocol = self,
         account = self._dispatch._account
     )
     obj.state = state
     
     # Converting a private object to a public one
     if self._dispatch.private_parent_lookup(ghid):
         if not private:
             await self._dispatch.make_public(ghid)
     
     else:
         if private:
             raise CatOuttaBagError(
                 'Once made public, objects cannot be made private. They ' +
                 'have already been distributed to other applications.'
             )
         
     await obj.push()
     
     # Schedule an update in the background.
     make_background_future(
         self._dispatch.distribute_update(
             obj.ghid,
             skip_conn = connection
         )
     )
     
     return b'\x01'
コード例 #19
0
ファイル: trashtest_ipc.py プロジェクト: wpkita/py_hypergolix
 def __init__(self, dispatch, ipc_core, author, dynamic, api_id, frozen, held, deleted, state, oracle, *args, **kwargs):
     self.ghid = Ghid.from_bytes(b'\x01' + os.urandom(64))
     self.author = author
     self.dynamic = dynamic
     self.api_id = api_id
     # Don't forget that dispatchables assign state as a _DispatchableState
     self.state = state[1]
     self.frozen = frozen
     self.held = held
     self.deleted = deleted
     self.ipccore = ipc_core
     
     self.oracle = oracle
     self.dispatch = dispatch
コード例 #20
0
    async def subscribe_wrapper(self, session, request_body):
        ''' Deserializes a publish request and forwards it to the 
        persister.
        '''
        ghid = Ghid.from_bytes(request_body)

        def updater(subscribed_ghid,
                    notification_ghid,
                    call=session.send_subs_update):
            call(subscribed_ghid, notification_ghid)

        self._postman.subscribe(ghid, updater)
        session._subscriptions[ghid] = updater
        return b'\x01'
コード例 #21
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def hold_obj(self, connection, body):
     ''' Handles object holding requests.
     '''
     ghid = Ghid.from_bytes(body)
     obj = await self._oracle.get_object(
         gaoclass = _Dispatchable,
         ghid = ghid,
         api_id = None,  # Let _pull() apply this.
         state = None,   # Let _pull() apply this.
         dispatch = self._dispatch,
         ipc_protocol = self,
         account = self._dispatch._account
     )
     await obj.hold()
     return b'\x01'
コード例 #22
0
ファイル: config.py プロジェクト: wpkita/py_hypergolix
    def fingerprint(self):
        ''' The fingerprint! Use this for a sharing target.
        '''
        try:
            fingerprint = self._cfg['user'].fingerprint

            # May be undefined, in which case return None
            if fingerprint is None:
                return fingerprint

            # Convert to a ghid if defined.
            else:
                return Ghid.from_str(fingerprint)

        except Exception as exc:
            raise ConfigError('Invalid configuration.') from exc
コード例 #23
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def freeze_obj(self, connection, body):
     ''' Handles object freezing requests.
     '''
     ghid = Ghid.from_bytes(body)
     obj = await self._oracle.get_object(
         gaoclass = _Dispatchable,
         ghid = ghid,
         api_id = None,  # Let _pull() apply this.
         state = None,   # Let _pull() apply this.
         dispatch = self._dispatch,
         ipc_protocol = self,
         account = self._dispatch._account
     )
     frozen_address = await obj.freeze()
     
     return bytes(frozen_address)
コード例 #24
0
ファイル: config.py プロジェクト: wpkita/py_hypergolix
    def user_id(self):
        ''' Gets the user_id from the config. Returns a ghid.
        '''
        try:
            user_id = self._cfg['user'].user_id

            # May be undefined, in which case return None
            if user_id is None:
                return user_id

            # Convert to a ghid if defined.
            else:
                return Ghid.from_str(user_id)

        except Exception as exc:
            raise ConfigError('Invalid configuration.') from exc
コード例 #25
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def update_ghid(self, connection, body):
     ''' Handles update object requests.
     '''
     (address,
      author,    # Will be unused and set to None
      state,
      is_link,
      api_id,    # Will be unused and set to None
      private,   # Will be unused and set to None
      dynamic,   # Will be unused and set to None
      _legroom   # Will be unused and set to None
      ) = self._unpack_object_def(body)
     
     if is_link:
         state = Ghid.from_bytes(state)
         
     await self._hgxlink._pull_state(address, state)
         
     return b'\x01'
コード例 #26
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def delete_obj(self, connection, body):
     ''' Handles object deletion requests.
     '''
     ghid = Ghid.from_bytes(body)
     obj = await self._oracle.get_object(
         gaoclass = _Dispatchable,
         ghid = ghid,
         api_id = None,  # Let _pull() apply this.
         state = None,   # Let _pull() apply this.
         dispatch = self._dispatch,
         ipc_protocol = self,
         account = self._dispatch._account
     )
     await self._dispatch.untrack_object(connection, ghid)
     # TODO: shift to a dispatch.delete_object method that can ignore this
     # connection when the intevitable "deleted that object!" warning comes
     # back
     await obj.delete()
     return b'\x01'
コード例 #27
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def get_obj(self, connection, body):
     ''' Handles requests for an object. Server only.
     '''
     ghid = Ghid.from_bytes(body)
     obj = await self._oracle.get_object(
         gaoclass = _Dispatchable,
         ghid = ghid,
         api_id = None,  # Let _pull() apply this.
         state = None,   # Let _pull() apply this.
         dispatch = self._dispatch,
         ipc_protocol = self,
         account = self._dispatch._account
     )
     
     await self._dispatch.track_object(connection, obj.ghid)
         
     if isinstance(obj.state, Ghid):
         is_link = True
         state = bytes(obj.state)
     else:
         is_link = False
         state = obj.state
         
     # For now, anyways.
     # Note: need to add some kind of handling for legroom.
     _legroom = None
     
     # Not a big fan of how this works, seems inelegant to me
     private = bool(self._dispatch.private_parent_lookup(obj.ghid))
     
     return self._pack_object_def(
         obj.ghid,
         obj.author,
         state,
         is_link,
         obj.api_id,
         private,
         obj.dynamic,
         _legroom
     )
コード例 #28
0
ファイル: remotes.py プロジェクト: Muterra/py_hypergolix
 async def subscription_update(self, connection, body):
     ''' Handles an incoming subscription update.
     '''
     subscribed_ghid = Ghid.from_bytes(body[0:65])
     notification = body[65:]
     
     try:
         # Note that this handles postman scheduling as well.
         ingested = await self._percore.ingest(
             notification,
             remotable = False,
             skip_conn = connection
         )
         
     except AlreadyDebound as exc:
         vomitus = exc.ghid
         debindings = await self._librarian.debind_status(vomitus)
         debinding_ghid = next(debinding for debinding in debindings)
         logger.info(str(subscribed_ghid) +
                     ' subscription update already debound: ' +
                     str(vomitus) + '. Pushing debinding upstream: ' +
                     str(debinding_ghid))
         
         make_background_future(
             self._salmonator.push(debinding_ghid)
         )
         
     else:
         # But, if ingested, we need to notify the salmonator, so it can (if
         # needed) also acquire the target
         if ingested:
             make_background_future(
                 self._salmonator.notify(subscribed_ghid)
             )
     
     return b'\x01'
コード例 #29
0
ファイル: bootstrapping.py プロジェクト: wpkita/py_hypergolix
    def load(cls,
             librarian,
             oracle,
             privateer,
             user_id,
             password,
             _scrypt_hardness=None):
        ''' Loads a credential container from the <librarian>, with a
        ghid of <user_id>, encrypted with scrypted <password>.
        '''
        # User_id resolves the "primary manifest", a dynamic object containing:
        #   <private key container dynamic ghid>                65b
        #   <private key container master secret>               53b
        #   <privateer persistent store dynamic ghid>           65b
        #   <privateer persistent store master secret>          53b
        #   <privateer quarantine store dynamic ghid>           65b
        #   <privateer quarantine master secret>                53b
        #   <secondary manifest dynamic ghid>                   65b
        #   <secondary manifest master secret>                  53b
        #   <random length, random fill padding>

        # The primary manifest is encrypted via the privateer.ratchet_bootstrap
        # process, using the inflated password as the master secret.

        # The secondary manifest secret is maintained by the privateer. From
        # there forwards, everything is business as usual.

        logger.info(
            'Recovering the primary manifest from the persistence subsystem.')

        primary_manifest = librarian.summarize(user_id)
        fingerprint = primary_manifest.author
        logger.info('Expanding password using scrypt. Please be patient.')
        primary_master = cls._password_expansion(fingerprint, password,
                                                 _scrypt_hardness)
        del password

        # Calculate the primary secret and then inject it into the temporary
        # storage at privateer
        cls._inject_secret(librarian,
                           privateer,
                           proxy=user_id,
                           master_secret=primary_master)
        # We're done with the summary, so go ahead and overwrite this name
        primary_manifest = oracle.get_object(gaoclass=_GAO, ghid=user_id)

        logger.info(
            'Password successfully expanded. Extracting the primary manifest.')
        manifest = primary_manifest.extract_state()

        logger.info('Verifying password. Please be patient.')
        # Check the password so we can fail with a meaningful message!
        # Should probably not hard-code the password validator length or summat
        password_validator = manifest[0:32]
        checker = cls._make_password_validator(secret=primary_master,
                                               hardness=_scrypt_hardness)
        if checker != password_validator:
            logger.critical('Incorrect password.')
            raise ValueError('Incorrect password.')

        else:
            logger.info(
                'Password correct. Proceeding with manifest extraction.')

        identity_ghid = Ghid.from_bytes(manifest[32:97])
        identity_master = Secret.from_bytes(manifest[97:150])
        persistent_ghid = Ghid.from_bytes(manifest[150:215])
        persistent_master = Secret.from_bytes(manifest[215:268])
        quarantine_ghid = Ghid.from_bytes(manifest[268:333])
        quarantine_master = Secret.from_bytes(manifest[333:386])
        secondary_manifest = Ghid.from_bytes(manifest[386:451])
        secondary_master = Secret.from_bytes(manifest[451:504])
        # Inject all the needed secrets.
        cls._inject_secret(librarian,
                           privateer,
                           proxy=identity_ghid,
                           master_secret=identity_master)
        cls._inject_secret(librarian,
                           privateer,
                           proxy=persistent_ghid,
                           master_secret=persistent_master)
        cls._inject_secret(librarian,
                           privateer,
                           proxy=quarantine_ghid,
                           master_secret=quarantine_master)
        cls._inject_secret(librarian,
                           privateer,
                           proxy=secondary_manifest,
                           master_secret=secondary_master)

        logger.info('Manifest recovered. Retrieving private keys.')
        identity_container = oracle.get_object(gaoclass=_GAODict,
                                               ghid=identity_ghid)
        identity = FirstParty._from_serialized(
            identity_container.extract_state())

        logger.info('Rebuilding credential.')
        self = cls(identity=identity,
                   primary_master=primary_master,
                   identity_master=identity_master,
                   persistent_master=persistent_master,
                   quarantine_master=quarantine_master,
                   secondary_master=secondary_master)

        if _scrypt_hardness:
            self._scrypt_hardness = _scrypt_hardness

        self.declare_primary(user_id, identity_ghid, persistent_ghid,
                             quarantine_ghid, secondary_manifest)

        return self
コード例 #30
0
ファイル: remotes.py プロジェクト: Muterra/py_hypergolix
 async def subscribe(self, connection, body):
     ''' Handle subscription requests.
     '''
     ghid = Ghid.from_bytes(body)
     await self._postman.subscribe(connection, ghid)
     return b'\x01'
コード例 #31
0
ファイル: trashtest_spec.py プロジェクト: wpkita/py_golix
from golix import Ghid

# These are abnormal (don't use in production) inclusions
from golix._spec import _gidc, _geoc, _gobs, _gobd, _gdxx, _garq
from golix._spec import _asym_hand, _asym_ak, _asym_nk, _asym_else
from golix.utils import _dummy_signature
from golix.utils import _dummy_mac
from golix.utils import _dummy_asym
from golix.utils import _dummy_address
from golix.utils import _dummy_pubkey

# ###############################################
# Testing
# ###############################################

_dummy_ghid = Ghid(0, _dummy_address)


def run():
    # GIDC test parsers
    gidc_1 = {
        'magic': b'GIDC',
        'version': 2,
        'cipher': 0,
        'body': {
            'signature_key': _dummy_pubkey,
            'encryption_key': _dummy_pubkey,
            'exchange_key': _dummy_pubkey,
        },
        'ghid': _dummy_ghid,
        'signature': None
コード例 #32
0
ファイル: privateer.py プロジェクト: wpkita/py_hypergolix
class _GaoDictBootstrap(dict):
    # Just inject a class-level ghid.
    ghid = Ghid.from_bytes(b'\x01' + bytes(64))
コード例 #33
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def get_whoami(self, connection, body):
     ''' Handles whoami requests.
     '''
     ghid = Ghid.from_bytes(body)
     self._hgxlink.whoami = ghid
     return b''
コード例 #34
0
 async def load(cls, librarian, oracle, privateer, user_id, password,
         _scrypt_hardness=None):
     ''' Loads a credential container from the <librarian>, with a
     ghid of <user_id>, encrypted with scrypted <password>.
     '''
     # User_id resolves the "primary manifest", a dynamic object containing:
     #   <private key container dynamic ghid>                65b
     #   <private key container master secret>               53b
     #   <privateer persistent store dynamic ghid>           65b
     #   <privateer persistent store master secret>          53b
     #   <privateer quarantine store dynamic ghid>           65b
     #   <privateer quarantine master secret>                53b
     #   <secondary manifest dynamic ghid>                   65b
     #   <secondary manifest master secret>                  53b
     #   <random length, random fill padding>
     
     # The primary manifest is encrypted via the privateer.ratchet_bootstrap
     # process, using the inflated password as the master secret.
     
     # The secondary manifest secret is maintained by the privateer. From
     # there forwards, everything is business as usual.
     
     logger.info(
         'Recovering the primary manifest from the persistence subsystem.'
     )
     
     primary_manifest = await librarian.summarize(user_id)
     fingerprint = primary_manifest.author
     logger.info('Expanding password using scrypt. Please be patient.')
     primary_master = cls._password_expansion(
         fingerprint,
         password,
         _scrypt_hardness
     )
     del password
     
     # Calculate the primary secret and then inject it into the temporary
     # storage at privateer
     cls._inject_secret(
         librarian,
         privateer,
         proxy = user_id,
         master_secret = primary_master
     )
     # We're done with the summary, so go ahead and overwrite this name
     primary_manifest = oracle.get_object(
         gaoclass = _GAO,
         ghid = user_id
     )
     
     logger.info(
         'Password successfully expanded. Extracting the primary manifest.'
     )
     manifest = primary_manifest.extract_state()
     
     logger.info('Verifying password. Please be patient.')
     # Check the password so we can fail with a meaningful message!
     # Should probably not hard-code the password validator length or summat
     password_validator = manifest[0:32]
     checker = cls._make_password_validator(
         secret = primary_master,
         hardness = _scrypt_hardness
     )
     if checker != password_validator:
         logger.critical('Incorrect password.')
         raise ValueError('Incorrect password.')
         
     else:
         logger.info(
             'Password correct. Proceeding with manifest extraction.'
         )
         
     identity_ghid = Ghid.from_bytes(manifest[32:97])
     identity_master = Secret.from_bytes(manifest[97:150])
     persistent_ghid = Ghid.from_bytes(manifest[150:215])
     persistent_master = Secret.from_bytes(manifest[215:268])
     quarantine_ghid = Ghid.from_bytes(manifest[268:333])
     quarantine_master = Secret.from_bytes(manifest[333:386])
     secondary_manifest = Ghid.from_bytes(manifest[386:451])
     secondary_master = Secret.from_bytes(manifest[451:504])
     # Inject all the needed secrets.
     cls._inject_secret(
         librarian, 
         privateer, 
         proxy = identity_ghid, 
         master_secret = identity_master
     )
     cls._inject_secret(
         librarian, 
         privateer, 
         proxy = persistent_ghid, 
         master_secret = persistent_master
     )
     cls._inject_secret(
         librarian, 
         privateer, 
         proxy = quarantine_ghid, 
         master_secret = quarantine_master
     )
     cls._inject_secret(
         librarian, 
         privateer, 
         proxy = secondary_manifest, 
         master_secret = secondary_master
     )
     
     logger.info('Manifest recovered. Retrieving private keys.')
     identity_container = oracle.get_object(
         gaoclass = _GAODict,
         ghid = identity_ghid
     )
     identity = FirstParty._from_serialized(
         identity_container.extract_state()
     )
     
     logger.info('Rebuilding credential.')
     self = cls(
         identity = identity,
         primary_master = primary_master,
         identity_master = identity_master,
         persistent_master = persistent_master,
         quarantine_master = quarantine_master,
         secondary_master = secondary_master
     )
     
     if _scrypt_hardness:
         self._scrypt_hardness = _scrypt_hardness
     
     self.declare_primary(
         user_id,
         identity_ghid,
         persistent_ghid,
         quarantine_ghid,
         secondary_manifest
     )
     
     return self
コード例 #35
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def sync_obj(self, connection, body):
     ''' Handles manual syncing requests. Server only.
     '''
     ghid = Ghid.from_bytes(body)
     await self._salmonator.attempt_pull(ghid)
     return b'\x01'
コード例 #36
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def get_startup_obj(self, connection, body):
     ''' Handles requests for startup objects.
     '''
     ghid = Ghid.from_bytes(body)
     self._hgxlink._startup_obj = ghid
     return b'\x01'
コード例 #37
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def delete_ghid(self, connection, body):
     ''' Handles object deletion requests.
     '''
     ghid = Ghid.from_bytes(body)
     await self._hgxlink.handle_delete(ghid)
     return b'\x01'
コード例 #38
0
ファイル: remotes.py プロジェクト: Muterra/py_hypergolix
 async def get(self, connection, body):
     ''' Handle get requests.
     '''
     ghid = Ghid.from_bytes(body)
     return (await self._librarian.retrieve(ghid))
コード例 #39
0
 async def get_wrapper(self, session, request_body):
     ''' Deserializes a get request; forwards it to the persister.
     '''
     ghid = Ghid.from_bytes(request_body)
     return self._librarian.retrieve(ghid)
コード例 #40
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def register_startup_obj(self, connection, body):
     ''' Handles startup object registration. Server only.
     '''
     ghid = Ghid.from_bytes(body)
     await self._dispatch.register_startup(connection, ghid)
     return b'\x01'
コード例 #41
0
ファイル: ipc.py プロジェクト: Muterra/py_hypergolix
 async def discard_obj(self, connection, body):
     ''' Handles object discarding requests. Server only.
     '''
     ghid = Ghid.from_bytes(body)
     await self._dispatch.untrack_object(connection, ghid)
     return b'\x01'