Exemple #1
0
def test_lan_server(testmanager):
    if onionrvalues.IS_QUBES:
        logger.warn("Cannot test LAN on QubesOS", terminal=True)
        return
    start_time = get_epoch()
    for i in range(1337, 1340):
        try:
            if not best_ip or not best_ip.startswith(('192.168')):
                logger.warn(
                    "lanservertest not running, not in standard 192.168 lan " +
                    "run this test on a lan before release",
                    terminal=True)
                return
            if requests.get(f"http://{best_ip}:{i}/ping").text == 'onionr!':
                bl = insert('test data')
                sleep(10)
                bl2 = insert('test data2')
                sleep(30)
                bl3 = insert('test data3')
                l = requests.get(f"http://{best_ip}:{i}/blist/0").text.split(
                    '\n')
                if bl not in l or bl2 not in l or bl3 not in l:
                    logger.error('blocks not in blist ' + '-'.join(l))
                    raise ValueError
                time = blockmetadb.get_block_date(bl3) - 1
                l = requests.get(
                    f"http://{best_ip}:{i}/blist/{time}").text.split('\n')

                if (bl in l and bl2 in l and bl3 in l) or len(l) == 0:
                    logger.error('Failed to get appopriate time' + '-'.join(l))
                    raise ValueError
                if onionrblockapi.Block(bl).raw != requests.get(
                        f"http://{best_ip}:{i}/get/{bl}",
                        stream=True).raw.read(6000000):
                    logger.error('Block doesn\'t match')
                    raise ValueError

                break

        except requests.exceptions.ConnectionError:
            pass
    else:
        raise ValueError
Exemple #2
0
    def decrypt(self, encodedData=True):
        """
            Decrypt a block, loading decrypted data into their vars
        """

        if self.decrypted:
            return True
        retData = False
        # decrypt data
        if self.getHeader('encryptType') == 'asym':
            try:
                try:
                    self.bcontent = encryption.pub_key_decrypt(
                        self.bcontent, encodedData=encodedData)
                except (binascii.Error, ValueError) as e:
                    self.bcontent = encryption.pub_key_decrypt(
                        self.bcontent, encodedData=False)
                bmeta = encryption.pub_key_decrypt(self.bmetadata,
                                                   encodedData=encodedData)
                try:
                    bmeta = bmeta.decode()
                except AttributeError:
                    # yet another bytes fix
                    pass
                self.bmetadata = json.loads(bmeta)
                self.signature = encryption.pub_key_decrypt(
                    self.signature, encodedData=encodedData)
                self.signer = encryption.pub_key_decrypt(
                    self.signer, encodedData=encodedData)
                self.bheader['signer'] = self.signer.decode()
                self.signedData = json.dumps(
                    self.bmetadata).encode() + self.bcontent

                if not self.signer is None:
                    if not self.verifySig():
                        raise onionrexceptions.SignatureError(
                            "Block has invalid signature")

                # Check for replay attacks
                try:
                    if epoch.get_epoch() - blockmetadb.get_block_date(
                            self.hash) > 60:
                        if not cryptoutils.replay_validator(
                                self.bmetadata['rply']):
                            raise onionrexceptions.ReplayAttack
                except (AssertionError, KeyError, TypeError,
                        onionrexceptions.ReplayAttack) as e:
                    if not self.bypassReplayCheck:
                        # Zero out variables to prevent reading of replays
                        self.bmetadata = {}
                        self.signer = ''
                        self.bheader['signer'] = ''
                        self.signedData = ''
                        self.signature = ''
                        raise onionrexceptions.ReplayAttack(
                            'Signature is too old. possible replay attack')
                try:
                    if not self.bmetadata['forwardEnc']: raise KeyError
                except (AssertionError, KeyError) as e:
                    pass
                else:
                    try:
                        self.bcontent = onionrusers.OnionrUser(
                            self.signer).forwardDecrypt(self.bcontent)
                    except (onionrexceptions.DecryptionError,
                            nacl.exceptions.CryptoError) as e:
                        #logger.error(str(e))
                        pass
            except nacl.exceptions.CryptoError:
                pass
                #logger.debug('Could not decrypt block. Either invalid key or corrupted data')
            except onionrexceptions.ReplayAttack:
                logger.warn('%s is possibly a replay attack' % (self.hash, ))
            else:
                retData = True
                self.decrypted = True
        return retData
Exemple #3
0
    def update(self, data=None, file=None):
        """
            Loads data from a block in to the current object.

            Inputs:
            - data (str):
              - if None: will load from file by hash
              - else: will load from `data` string
            - file (str):
              - if None: will load from file specified in this parameter
              - else: will load from wherever block is stored by hash

            Outputs:
            - (bool): indicates whether or not the operation was successful
        """
        try:
            # import from string
            blockdata = data

            # import from file
            if blockdata is None:
                try:
                    blockdata = onionrstorage.getData(
                        self.getHash())  #.decode()
                except AttributeError:
                    raise onionrexceptions.NoDataAvailable(
                        'Block does not exist')
            else:
                self.blockFile = None
            # parse block
            self.raw = blockdata
            self.bheader = json.loads(
                self.getRaw()[:self.getRaw().index(b'\n')])
            self.bcontent = self.getRaw()[self.getRaw().index(b'\n') + 1:]
            if ('encryptType' in self.bheader) and (self.bheader['encryptType']
                                                    in ('asym', 'sym')):
                self.bmetadata = self.getHeader('meta', None)
                self.isEncrypted = True
            else:
                self.bmetadata = json.loads(self.getHeader('meta', None))
            self.btype = self.getMetadata('type', None)
            self.signed = ('sig' in self.getHeader()
                           and self.getHeader('sig') != '')
            # TODO: detect if signer is hash of pubkey or not
            self.signer = self.getHeader('signer', None)
            self.signature = self.getHeader('sig', None)
            # signed data is jsonMeta + block content (no linebreak)
            self.signedData = (None if not self.isSigned() else
                               self.getHeader('meta').encode() +
                               self.getContent())
            self.date = blockmetadb.get_block_date(self.getHash())
            self.claimedTime = self.getHeader('time', None)

            if not self.getDate() is None:
                self.date = datetime.datetime.fromtimestamp(self.getDate())

            self.valid = True

            if self.autoDecrypt:
                self.decrypt()

            return True
        except Exception as e:
            logger.warn('Failed to parse block %s' % self.getHash(),
                        error=e,
                        timestamp=False)

            # if block can't be parsed, it's a waste of precious space. Throw it away.
            if not self.delete():
                logger.warn('Failed to delete invalid block %s.' %
                            self.getHash(),
                            error=e)
            else:
                logger.debug('Deleted invalid block %s.' % self.getHash(),
                             timestamp=False)

        self.valid = False
        return False