Пример #1
0
    def sendEncrypt(self):
        '''
            Create a private message and send it
        '''

        invalidID = True
        while invalidID:
            try:
                peer = logger.readline('Peer to send to: ')
            except KeyboardInterrupt:
                break
            else:
                if self.onionrUtils.validatePubKey(peer):
                    invalidID = False
                else:
                    logger.error('Invalid peer ID')
        else:
            try:
                message = logger.readline("Enter a message: ")
            except KeyboardInterrupt:
                pass
            else:
                logger.info("Sending message to: " + logger.colors.underline +
                            peer)
                self.onionrUtils.sendPM(peer, message)
Пример #2
0
    def start(self):
        logger.warn("Please note: everything said here is public, even if a random channel name is used.", terminal=True)
        message = ""
        self.flowRunning = True
        try:
            self.channel = logger.readline("Enter a channel name or none for default:").strip()
        except (KeyboardInterrupt, EOFError) as e:
            self.flowRunning = False
        newThread = threading.Thread(target=self.showOutput, daemon=True)
        newThread.start()
        while self.flowRunning:
            if self.channel == "":
                self.channel = "global"
            try:
                message = logger.readline('\nInsert message into flow:').strip().replace('\n', '\\n').replace('\r', '\\r')
            except EOFError:
                pass
            except KeyboardInterrupt:
                self.flowRunning = False
            else:
                if message == "q":
                    self.flowRunning = False
                expireTime = epoch.get_epoch() + 43200
                if len(message) > 0:
                    logger.info('Inserting message as block...', terminal=True)
                    onionrblocks.insert(message, header='brd', expire=expireTime, meta={'ch': self.channel})

        logger.info("Flow is exiting, goodbye", terminal=True)
        return
Пример #3
0
    def start(self):
        logger.warn(
            "Please note: everything said here is public, even if a random channel name is used."
        )
        message = ""
        self.flowRunning = True
        newThread = threading.Thread(target=self.showOutput)
        newThread.start()
        try:
            self.channel = logger.readline(
                "Enter a channel name or none for default:")
        except (KeyboardInterrupt, EOFError) as e:
            self.flowRunning = False
        while self.flowRunning:
            try:
                message = logger.readline(
                    '\nInsert message into flow:').strip().replace(
                        '\n', '\\n').replace('\r', '\\r')
            except EOFError:
                pass
            except KeyboardInterrupt:
                self.flowRunning = False
            else:
                if message == "q":
                    self.flowRunning = False
                expireTime = self.myCore._utils.getEpoch() + 43200
                if len(message) > 0:
                    self.myCore.insertBlock(message,
                                            header='txt',
                                            expire=expireTime,
                                            meta={'ch': self.channel})

        logger.info("Flow is exiting, goodbye")
        return
Пример #4
0
    def draft_message(self, recip=''):
        message = ''
        newLine = ''
        subject = ''
        entering = False
        if len(recip) == 0:
            entering = True
            while entering:
                try:
                    recip = logger.readline(
                        'Enter peer address, or -q to stop:').strip()
                    if recip in ('-q', 'q'):
                        raise EOFError
                    if not self.myCore._utils.validatePubKey(recip):
                        raise onionrexceptions.InvalidPubkey(
                            'Must be a valid ed25519 base32 encoded public key'
                        )
                except onionrexceptions.InvalidPubkey:
                    logger.warn('Invalid public key')
                except (KeyboardInterrupt, EOFError):
                    entering = False
                else:
                    break
            else:
                # if -q or ctrl-c/d, exit function here, otherwise we successfully got the public key
                return
        try:
            subject = logger.readline('Message subject: ')
        except (KeyboardInterrupt, EOFError):
            pass

        cancelEnter = False
        logger.info(
            'Enter your message, stop by entering -q on a new line. -c to cancel'
        )
        while newLine != '-q':
            try:
                newLine = input()
            except (KeyboardInterrupt, EOFError):
                cancelEnter = True
            if newLine == '-c':
                cancelEnter = True
                break
            if newLine == '-q':
                continue
            newLine += '\n'
            message += newLine

        if not cancelEnter:
            logger.info('Inserting encrypted message as Onionr block....')

            blockID = self.myCore.insertBlock(message,
                                              header='pm',
                                              encryptType='asym',
                                              asymPeer=recip,
                                              sign=self.doSigs,
                                              meta={'subject': subject})
Пример #5
0
def ban_block():
    """Deletes a block, permanently blacklisting it"""
    blacklist = onionrblacklist.OnionrBlackList()
    try:
        ban = sys.argv[2]
    except IndexError:
        # Get the hash if its not provided as a CLI argument
        ban = logger.readline('Enter a block hash:').strip()
    # Make sure the hash has no truncated zeroes
    ban = reconstructhash.reconstruct_hash(ban)
    if stringvalidators.validate_hash(ban):
        if not blacklist.inBlacklist(ban):
            try:
                blacklist.addToDB(ban)
                removeblock.remove_block(ban)
                deleteBlock(ban)
            except Exception as error:
                logger.error('Could not blacklist block',
                             error=error,
                             terminal=True)
            else:
                logger.info('Block blacklisted', terminal=True)
        else:
            logger.warn('That block is already blacklisted', terminal=True)
    else:
        logger.error('Invalid block hash', terminal=True)
Пример #6
0
    def getPassword(self, message='Enter password: '******'''
            Get a password without showing the users typing and confirm the input
        '''
        # Get a password safely with confirmation and return it
        while True:
            print(message)
            pass1 = getpass.getpass()
            if confirm:
                print('Confirm password: ')
                pass2 = getpass.getpass()
                if pass1 != pass2:
                    logger.error("Passwords do not match.")
                    logger.readline()
                else:
                    break
            else:
                break

        return pass1
Пример #7
0
    def sendEncrypt(self):
        '''
            Create a private message and send it
        '''

        while True:
            try:
                peer = logger.readline('Peer to send to: ')
            except KeyboardInterrupt:
                break
            else:
                if self.onionrUtils.validateID(peer):
                    break
                else:
                    logger.error('Invalid peer ID')
        else:
            try:
                message = logger.readline("Enter a message: ")
            except KeyboardInterrupt:
                pass
            else:
                logger.info("Sending message to " + peer)
                self.onionrUtils.sendPM(peer, message)
Пример #8
0
    def addMessage(self):
        '''
            Broadcasts a message to the Onionr network
        '''

        while True:
            messageToAdd = '-txt-' + logger.readline(
                'Broadcast message to network: ')
            if len(messageToAdd) >= 1:
                break

        addedHash = self.onionrCore.setData(messageToAdd)
        self.onionrCore.addToBlockDB(addedHash, selfInsert=True)
        self.onionrCore.setBlockType(addedHash, 'txt')

        return
Пример #9
0
def ban_block(o_inst):
    try:
        ban = sys.argv[2]
    except IndexError:
        ban = logger.readline('Enter a block hash:')
    if o_inst.onionrUtils.validateHash(ban):
        if not o_inst.onionrCore._blacklist.inBlacklist(ban):
            try:
                o_inst.onionrCore._blacklist.addToDB(ban)
                o_inst.onionrCore.removeBlock(ban)
            except Exception as error:
                logger.error('Could not blacklist block', error=error)
            else:
                logger.info('Block blacklisted')
        else:
            logger.warn('That block is already blacklisted')
    else:
        logger.error('Invalid block hash')
Пример #10
0
    def addMessage(self, header="txt"):
        '''
            Broadcasts a message to the Onionr network
        '''

        while True:
            try:
                messageToAdd = logger.readline(
                    'Broadcast message to network: ')
                if len(messageToAdd) >= 1:
                    break
            except KeyboardInterrupt:
                return

        #addedHash = self.onionrCore.setData(messageToAdd)
        addedHash = self.onionrCore.insertBlock(messageToAdd, header='txt')
        #self.onionrCore.addToBlockDB(addedHash, selfInsert=True)
        #self.onionrCore.setBlockType(addedHash, 'txt')
        if addedHash != '':
            logger.info("Message inserted as as block %s" % addedHash)
        return
Пример #11
0
    def menu(self):
        choice = ''
        while True:
            sigMsg = 'Message Signing: %s'

            logger.info(self.strings.programTag + '\n\nUser ID: ' +
                        self.myCore._crypto.pubKey)
            if self.doSigs:
                sigMsg = sigMsg % ('enabled', )
            else:
                sigMsg = sigMsg % (
                    'disabled (Your messages cannot be trusted)', )
            if self.doSigs:
                logger.info(sigMsg)
            else:
                logger.warn(sigMsg)
            logger.info(self.strings.mainMenu.title())  # print out main menu
            try:
                choice = logger.readline(
                    'Enter 1-%s:\n' %
                    (len(self.strings.mainMenuChoices))).lower().strip()
            except (KeyboardInterrupt, EOFError):
                choice = '5'

            if choice in (self.strings.mainMenuChoices[0], '1'):
                self.inbox()
            elif choice in (self.strings.mainMenuChoices[1], '2'):
                self.sentbox()
            elif choice in (self.strings.mainMenuChoices[2], '3'):
                self.draft_message()
            elif choice in (self.strings.mainMenuChoices[3], '4'):
                self.toggle_signing()
            elif choice in (self.strings.mainMenuChoices[4], '5'):
                logger.info('Goodbye.')
                break
            elif choice == '':
                pass
            else:
                logger.warn('Invalid choice.')
        return
Пример #12
0
def commandInstallPlugin():
    if len(sys.argv) >= 3:
        check()

        pluginname = sys.argv[2]
        pkobh = None  # public key or block hash

        version = None
        if ':' in pluginname:
            details = pluginname
            pluginname = sanitize(details[0])
            version = details[1]

        sanitize(pluginname)

        if len(sys.argv) >= 4:
            # public key or block hash specified
            pkobh = sys.argv[3]
        else:
            # none specified, check if in config file
            pkobh = getKey(pluginname)

        if pkobh is None:
            # still nothing found, try searching repositories
            logger.info('Searching for public key in repositories...')
            try:
                repos = getRepositories()
                distributors = list()
                for repo, records in repos.items():
                    if pluginname in records:
                        logger.debug(
                            'Found %s in repository %s for plugin %s.' %
                            (records[pluginname], repo, pluginname))
                        distributors.append(records[pluginname])

                if len(distributors) != 0:
                    distributor = None

                    if len(distributors) == 1:
                        logger.info('Found distributor: %s' % distributors[0])
                        distributor = distributors[0]
                    else:
                        distributors_message = ''

                        index = 1
                        for dist in distributors:
                            distributors_message += '    ' + logger.colors.bold + str(
                                index) + ') ' + logger.colors.reset + str(
                                    dist) + '\n'
                            index += 1

                        logger.info(
                            (logger.colors.bold + 'Found distributors (%s):' +
                             logger.colors.reset + '\n' + distributors_message)
                            % len(distributors))

                        valid = False
                        while not valid:
                            choice = logger.readline(
                                'Select the number of the key to use, from 1 to %s, or press Ctrl+C to cancel:'
                                % (index - 1))

                            try:
                                if int(choice) < index and int(choice) >= 1:
                                    distributor = distributors[int(choice)]
                                    valid = True
                            except KeyboardInterrupt:
                                logger.info('Installation cancelled.')
                                return True
                            except:
                                pass

                    if not distributor is None:
                        pkobh = distributor
            except Exception as e:
                logger.warn('Failed to lookup plugin in repositories.',
                            timestamp=False)
                logger.error('asdf', error=e, timestamp=False)

        if pkobh is None:
            logger.error(
                'No key for this plugin found in keystore or repositories, please specify.'
            )
            help()
            return True

        valid_hash = pluginapi.get_utils().validateHash(pkobh)
        real_block = False
        valid_key = pluginapi.get_utils().validatePubKey(pkobh)
        real_key = False

        if valid_hash:
            real_block = Block.exists(pkobh)
        elif valid_key:
            real_key = pluginapi.get_utils().hasKey(pkobh)

        blockhash = None

        if valid_hash and not real_block:
            logger.error(
                'Block hash not found. Perhaps it has not been synced yet?')
            logger.debug(
                'Is valid hash, but does not belong to a known block.')

            return True
        elif valid_hash and real_block:
            blockhash = str(pkobh)
            logger.debug('Using block %s...' % blockhash)

            installBlock(blockhash)
        elif valid_key and not real_key:
            logger.error(
                'Public key not found. Try adding the node by address manually, if possible.'
            )
            logger.debug('Is valid key, but the key is not a known one.')
        elif valid_key and real_key:
            publickey = str(pkobh)
            logger.debug('Using public key %s...' % publickey)

            saveKey(pluginname, pkobh)

            signedBlocks = Block.getBlocks(type='plugin',
                                           signed=True,
                                           signer=publickey)

            mostRecentTimestamp = None
            mostRecentVersionBlock = None

            for block in signedBlocks:
                try:
                    blockContent = json.loads(block.getContent())

                    if not (('author' in blockContent) and
                            ('info' in blockContent) and
                            ('date' in blockContent) and
                            ('name' in blockContent)):
                        raise ValueError(
                            'Missing required parameter `date` in block %s.' %
                            block.getHash())

                    blockDatetime = datetime.datetime.strptime(
                        blockContent['date'], '%Y-%m-%d %H:%M:%S')

                    if blockContent['name'] == pluginname:
                        if ('version' in blockContent['info']) and (
                                blockContent['info']['version']
                                == version) and (not version is None):
                            mostRecentTimestamp = blockDatetime
                            mostRecentVersionBlock = block.getHash()
                            break
                        elif mostRecentTimestamp is None:
                            mostRecentTimestamp = blockDatetime
                            mostRecentVersionBlock = block.getHash()
                        elif blockDatetime > mostRecentTimestamp:
                            mostRecentTimestamp = blockDatetime
                            mostRecentVersionBlock = block.getHash()
                except Exception as e:
                    pass

            logger.warn(
                'Only continue the installation is you are absolutely certain that you trust the plugin distributor. Public key of plugin distributor: %s'
                % publickey,
                timestamp=False)
            installBlock(mostRecentVersionBlock)
        else:
            logger.error(
                'Unknown data "%s"; must be public key or block hash.' %
                str(pkobh))
            return
    else:
        logger.info(sys.argv[0] + ' ' + sys.argv[1] +
                    ' <plugin> [public key/block hash]')

    return True
Пример #13
0
    def inbox(self):
        blockCount = 0
        pmBlockMap = {}
        pmBlocks = {}
        logger.info('Decrypting messages...')
        choice = ''
        displayList = []
        subject = ''

        # this could use a lot of memory if someone has received a lot of messages
        for blockHash in self.myCore.getBlocksByType('pm'):
            pmBlocks[blockHash] = Block(blockHash, core=self.myCore)
            pmBlocks[blockHash].decrypt()
            blockCount = 0
        for blockHash in pmBlocks:
            if not pmBlocks[blockHash].decrypted:
                continue
            blockCount += 1
            pmBlockMap[blockCount] = blockHash

            block = pmBlocks[blockHash]
            senderKey = block.signer
            try:
                senderKey = senderKey.decode()
            except AttributeError:
                pass
            senderDisplay = onionrusers.OnionrUser(self.myCore,
                                                   senderKey).getName()
            if senderDisplay == 'anonymous':
                senderDisplay = senderKey

            blockDate = pmBlocks[blockHash].getDate().strftime("%m/%d %H:%M")
            try:
                subject = pmBlocks[blockHash].bmetadata['subject']
            except KeyError:
                subject = ''

            displayList.append('%s. %s - %s - <%s>: %s' %
                               (blockCount, blockDate, senderDisplay[:12],
                                subject[:10], blockHash))
        while choice not in ('-q', 'q', 'quit'):
            for i in displayList:
                logger.info(i)
            try:
                choice = logger.readline(
                    'Enter a block number, -r to refresh, or -q to stop: '
                ).strip().lower()
            except (EOFError, KeyboardInterrupt):
                choice = '-q'

            if choice in ('-q', 'q', 'quit'):
                continue

            if choice in ('-r', 'r', 'refresh'):
                # dirty hack
                self.inbox()
                return

            try:
                choice = int(choice)
            except ValueError:
                pass
            else:
                try:
                    pmBlockMap[choice]
                    readBlock = pmBlocks[pmBlockMap[choice]]
                except KeyError:
                    pass
                else:
                    cancel = ''
                    readBlock.verifySig()
                    senderDisplay = self.myCore._utils.bytesToStr(
                        readBlock.signer)
                    if len(senderDisplay.strip()) == 0:
                        senderDisplay = 'Anonymous'
                    logger.info('Message received from %s' % (senderDisplay, ))
                    logger.info('Valid signature: %s' % readBlock.validSig)

                    if not readBlock.validSig:
                        logger.warn(
                            'This message has an INVALID/NO signature. ANYONE could have sent this message.'
                        )
                        cancel = logger.readline(
                            'Press enter to continue to message, or -q to not open the message (recommended).'
                        )
                        print('')
                    if cancel != '-q':
                        try:
                            print(
                                draw_border(
                                    self.myCore._utils.escapeAnsi(
                                        readBlock.bcontent.decode().strip())))
                        except ValueError:
                            logger.warn(
                                'Error presenting message. This is usually due to a malformed or blank message.'
                            )
                            pass
                        if readBlock.validSig:
                            reply = logger.readline(
                                "Press enter to continue, or enter %s to reply"
                                % ("-r", ))
                            print('')
                            if reply == "-r":
                                self.draft_message(
                                    self.myCore._utils.bytesToStr(
                                        readBlock.signer, ))
                        else:
                            logger.readline("Press enter to continue")
                            print('')
        return