Exemple #1
0
    def create_entry(self, group = None, title = "", image = 1, url = "",
                     username = "", password = "", comment = "",
                     y = 2999, mon = 12, d = 28, h = 23, min_ = 59,
                     s = 59):
        """This method creates a new entry.
        
        The group which should hold the entry is needed.

        image must be an unsigned int >0, group a v1Group.
        
        It is possible to give an expire date in the following way:
            - y is the year between 1 and 9999 inclusive
            - mon is the month between 1 and 12
            - d is a day in the given month
            - h is a hour between 0 and 23
            - min_ is a minute between 0 and 59
            - s is a second between 0 and 59

        The special date 2999-12-28 23:59:59 means that entry expires never.
        
        """
        
        if (type(title) is not str or
            type(image) is not int or image < 0 or
            type(url) is not str or
            type(username) is not str or
            type(password) is not str or
            type(comment) is not str or
            type(y) is not int or
            type(mon) is not int or
            type(d) is not int or
            type(h) is not int or
            type(min_) is not int
            or type(s) is not int or
            type(group) is not v1Group):
            raise KPError("One argument has not a valid type.")
        elif group not in self.groups:
            raise KPError("Group doesn't exist.")
        elif (y > 9999 or y < 1 or mon > 12 or mon < 1 or d > 31 or d < 1 or
              h > 23 or h < 0 or min_ > 59 or min_ < 0 or s > 59 or s < 0):
            raise KPError("No legal date")
        elif (((mon == 1 or mon == 3 or mon == 5 or mon == 7 or mon == 8 or
                mon == 10 or mon == 12) and d > 31) or
               ((mon == 4 or mon == 6 or mon == 9 or mon == 11) and d > 30) or
               (mon == 2 and d > 28)):
            raise KPError("Given day doesn't exist in given month")

        Random.atfork()
        uuid = Random.get_random_bytes(16)
        entry = v1Entry(group.id_, group, image, title, url, username,
                         password, comment, 
                         datetime.now().replace(microsecond = 0),
                         datetime.now().replace(microsecond = 0),
                         datetime.now().replace(microsecond = 0),
                         datetime(y, mon, d, h, min_, s),
                         uuid)
        self.entries.append(entry)
        group.entries.append(entry)
        self._num_entries += 1
        return True
 def start_journalist_server():
     Random.atfork()
     journalist.app.run(
         port=journalist_port,
         debug=True,
         use_reloader=False,
         threaded=True)
Exemple #3
0
    def __init__(self, filepath=None, password=None, keyfile=None, 
                 read_only=False, new = False):
        """ Initialize a new or an existing database.

        If a 'filepath' and a 'masterkey' is passed 'load' will try to open
        a database. If 'True' is passed to 'read_only' the database will open
        read-only. It's also possible to create a new one, just pass 'True' to
        new. This will be ignored if a filepath and a masterkey is given this
        will be ignored.
        
        """

        if filepath is not None and password is None and keyfile is None:
            raise KPError('Missing argument: Password or keyfile '
                          'needed additionally to open an existing database!')
        elif type(read_only) is not bool or type(new) is not bool:
            raise KPError('read_only and new must be bool')
        elif ((filepath is not None and type(filepath) is not str) or
              (type(password) is not str and password is not None) or
              (type(keyfile) is not str and keyfile is not None)):
            raise KPError('filepath, masterkey and keyfile must be a string')
        elif (filepath is None and password is None and keyfile is None and 
              new is False):
            raise KPError('Either an existing database should be opened or '
                          'a new should be created.')

        self.groups = []
        self.entries = []
        self.root_group = v1Group()
        self.read_only = read_only
        self.filepath = filepath
        self.password = password
        self.keyfile = keyfile

        # This are attributes that are needed internally. You should not
        # change them directly, it could damage the database!
        self._group_order = []
        self._entry_order = []
        self._signature1 = 0x9AA2D903
        self._signature2 = 0xB54BFB65
        self._enc_flag = 2
        self._version = 0x00030002
        self._final_randomseed = ''
        self._enc_iv = ''
        self._num_groups = 1
        self._num_entries = 0
        self._contents_hash = ''
        Random.atfork()
        self._transf_randomseed = Random.get_random_bytes(32)
        self._key_transf_rounds = 150000

        # Due to the design of KeePass, at least one group is needed.
        if new is True:
            self._group_order = [("id", 1), (1, 4), (2, 9), (7, 4), (8, 2),
                                 (0xFFFF, 0)]
            group = v1Group(1, 'Internet', 1, self, parent = self.root_group)
            self.root_group.children.append(group)
            self.groups.append(group)
Exemple #4
0
def reinit_crypto():
    """
    When a fork arises, pycrypto needs to reinit
    From its doc::

        Caveat: For the random number generator to work correctly,
        you must call Random.atfork() in both the parent and
        child processes after using os.fork()

    """
    if HAS_CRYPTODOME or HAS_CRYPTO:
        Random.atfork()
        def start_source_server():
            # We call Random.atfork() here because we fork the source and
            # journalist server from the main Python process we use to drive
            # our browser with multiprocessing.Process() below. These child
            # processes inherit the same RNG state as the parent process, which
            # is a problem because they would produce identical output if we
            # didn't re-seed them after forking.
            Random.atfork()

            config.SESSION_EXPIRATION_MINUTES = self.session_expiration

            source_app = create_app(config)

            source_app.run(port=source_port,
                           debug=True,
                           use_reloader=False,
                           threaded=True)
        def start_source_server():
            # We call Random.atfork() here because we fork the source and
            # journalist server from the main Python process we use to drive
            # our browser with multiprocessing.Process() below. These child
            # processes inherit the same RNG state as the parent process, which
            # is a problem because they would produce identical output if we
            # didn't re-seed them after forking.
            Random.atfork()

            config.SESSION_EXPIRATION_MINUTES = self.session_expiration

            source_app = create_app(config)

            source_app.run(
                port=source_port,
                debug=True,
                use_reloader=False,
                threaded=True)
 def start_journalist_server():
     Random.atfork()
     journalist.app.run(port=journalist_port,
                        debug=True,
                        use_reloader=False,
                        threaded=True)
Exemple #8
0
    def mine(self, q, privatekey_readable, public_key_hashed, address):
        Random.atfork()
        rndfile = Random.new()
        tries = 0
        key = RSA.importKey(privatekey_readable)

        if self.pool_conf == 1:
            #do not use pools public key to sign, signature will be invalid
            self_address = address
            address = self.pool_address
            self.connect_to_pool()

        while True:
            try:
                # block_hash = hashlib.sha224(str(block_send) + db_block_hash).hexdigest()
                db_block_hash, diff, diff_real, mining_condition = self.calculate_difficulty(
                )

                while tries < self.diff_recalc_conf:
                    start = time.time()

                    nonce = hashlib.sha224(rndfile.read(16)).hexdigest()[:32]
                    mining_hash = bin_convert(
                        hashlib.sha224(
                            (address + nonce +
                             db_block_hash).encode("utf-8")).hexdigest())

                    end = time.time()
                    if tries % 2500 == 0:  #limit output
                        try:
                            cycles_per_second = 1 / (end - start)
                            print(
                                "Thread{} {} @ {:.2f} cycles/second, difficulty: {}({}), iteration: {}"
                                .format(q, db_block_hash[:10],
                                        cycles_per_second, diff, diff_real,
                                        tries))
                        except:
                            pass
                    tries += 1

                    if mining_condition in mining_hash:
                        tries = 0

                        print("Thread {} found a good block hash in {} cycles".
                              format(q, tries))

                        # serialize txs

                        block_send = []
                        del block_send[:]  # empty
                        removal_signature = []
                        del removal_signature[:]  # empty

                        s_node = socks.socksocket()
                        if self.tor_conf == 1:
                            s_node.setproxy(socks.PROXY_TYPE_SOCKS5,
                                            "127.0.0.1", 9050)
                        s_node.connect(
                            (self.node_ip_conf,
                             int(self.port)))  # connect to config.txt node
                        connections.send(s_node, "mpget", 10)
                        data = connections.receive(s_node, 10)
                        s_node.close()

                        if data != "[]":
                            mempool = data

                            for mpdata in mempool:
                                transaction = (str(mpdata[0]),
                                               str(mpdata[1][:56]),
                                               str(mpdata[2][:56]),
                                               '%.8f' % float(mpdata[3]),
                                               str(mpdata[4]), str(mpdata[5]),
                                               str(mpdata[6]), str(mpdata[7])
                                               )  # create tuple
                                # print transaction
                                block_send.append(
                                    transaction
                                )  # append tuple to list for each run
                                removal_signature.append(
                                    str(mpdata[4])
                                )  # for removal after successful mining

                        # claim reward
                        block_timestamp = '%.2f' % time.time()
                        transaction_reward = (
                            str(block_timestamp), str(address[:56]),
                            str(address[:56]), '%.8f' % float(0), "0",
                            str(nonce))  # only this part is signed!
                        # print transaction_reward

                        h = SHA.new(str(transaction_reward).encode("utf-8"))
                        signer = PKCS1_v1_5.new(key)
                        signature = signer.sign(h)
                        signature_enc = base64.b64encode(signature)

                        if signer.verify(h, signature):
                            print("Signature valid")

                            block_send.append(
                                (str(block_timestamp), str(address[:56]),
                                 str(address[:56]), '%.8f' % float(0),
                                 str(signature_enc.decode("utf-8")),
                                 str(public_key_hashed.decode("utf-8")), "0",
                                 str(nonce)))  # mining reward tx
                            print("Block to send: {}".format(block_send))

                            if not any(
                                    isinstance(el, list) for el in block_send
                            ):  # if it's not a list of lists (only the mining tx and no others)
                                new_list = []
                                new_list.append(block_send)
                                block_send = new_list  # make it a list of lists

                            #  claim reward
                            # include data

                            tries = 0

                            # submit mined block to node

                            if self.sync_conf == 1:
                                self.check_uptodate(300)

                            if self.pool_conf == 1:
                                mining_condition = bin_convert(
                                    db_block_hash)[0:diff_real]
                                if mining_condition in mining_hash:
                                    print(
                                        "Miner: Submitting block to all nodes, because it satisfies real difficulty too"
                                    )
                                    self.nodes_block_submit(block_send)

                                try:
                                    s_pool = socks.socksocket()
                                    s_pool.settimeout(0.3)
                                    if self.tor_conf == 1:
                                        s_pool.setproxy(
                                            socks.PROXY_TYPE_SOCKS5,
                                            "127.0.0.1", 9050)
                                    s_pool.connect((self.pool_ip_conf,
                                                    8525))  # connect to pool
                                    print("Connected")

                                    print(
                                        "Miner: Proceeding to submit mined block to pool"
                                    )

                                    connections.send(s_pool, "block", 10)
                                    connections.send(s_pool, self_address, 10)
                                    connections.send(s_pool, block_send, 10)
                                    s_pool.close()

                                    print("Miner: Block submitted to pool")

                                except Exception as e:
                                    print(
                                        "Miner: Could not submit block to pool"
                                    )
                                    pass

                            if self.pool_conf == 0:
                                self.nodes_block_submit(block_send)
                        else:
                            print("Invalid signature")
                tries = 0

            except Exception as e:
                print(e)
                time.sleep(0.1)
                if self.debug_conf == 1:
                    raise
                else:
                    pass
Exemple #9
0
    def save(self, filepath = None, password = None, keyfile = None):
        """This method saves the database.

        It's possible to parse a data path to an alternative file.

        """
        
        if (password is None and keyfile is not None and keyfile != "" and
            type(keyfile) is str):
            self.keyfile = keyfile
        elif (keyfile is None and password is not None and password != "" and
              type(password is str)):
            self.password = password
        elif (keyfile is not None and password is not None and
              keyfile != "" and password != "" and type(keyfile) is str and
              type(password) is str):
            self.keyfile = keyfile
            self.password = password

        if self.read_only:
            raise KPError("The database has been opened read-only.")
        elif ((self.password is None and self.keyfile is None) or 
              (filepath is None and self.filepath is None) or 
              (keyfile == "" and password == "")):
            raise KPError("Need a password/keyfile and a filepath to save the "
                          "file.")
        elif ((type(self.filepath) is not str and self.filepath is not None) or
              (type(self.password) is not str and self.password is not None) or
              (type(self.keyfile) is not str and self.keyfile is not None)):
            raise KPError("filepath, password and keyfile  must be strings.")
        elif self._num_groups == 0:
            raise KPError("Need at least one group!")
        
        content = bytearray()

        # First, read out all groups
        for i in self.groups:
            # Get the packed bytes
            # j stands for a possible field type
            for j in range(1, 10):
                ret_save = self._save_group_field(j, i)
                # The field type and the size is always in front of the data
                if ret_save is not False:
                    content += struct.pack('<H', j)
                    content += struct.pack('<I', ret_save[0])
                    content += ret_save[1]
            # End of field
            content += struct.pack('<H', 0xFFFF)
            content += struct.pack('<I', 0) 

        # Same with entries
        for i in self.entries:
            for j in range(1, 15):
                ret_save = self._save_entry_field(j, i)
                if ret_save is not False:
                    content += struct.pack('<H', j)
                    content += struct.pack('<I', ret_save[0])
                    content += ret_save[1]
            content += struct.pack('<H', 0xFFFF)
            content += struct.pack('<I', 0)

        # Generate new seed and new vector; calculate the new hash
        Random.atfork()
        self._final_randomseed = Random.get_random_bytes(16)
        self._enc_iv = Random.get_random_bytes(16)
        sha_obj = SHA256.new()
        sha_obj.update(bytes(content))
        self._contents_hash = sha_obj.digest()
        del sha_obj

        # Pack the header
        header = bytearray()
        header += struct.pack('<I', 0x9AA2D903)
        header += struct.pack('<I', 0xB54BFB65)
        header += struct.pack('<I', self._enc_flag)
        header += struct.pack('<I', self._version)
        header += struct.pack('<16s', self._final_randomseed)
        header += struct.pack('<16s', self._enc_iv)
        header += struct.pack('<I', self._num_groups)
        header += struct.pack('<I', self._num_entries)
        header += struct.pack('<32s', self._contents_hash)
        header += struct.pack('<32s', self._transf_randomseed)
        if self._key_transf_rounds < 150000:
            self._key_transf_rounds = 150000
        header += struct.pack('<I', self._key_transf_rounds)

        # Finally encrypt everything...
        if self.password is None:
            masterkey = self._get_filekey()
        elif self.password is not None and self.keyfile is not None:
            passwordkey = self._get_passwordkey()
            filekey = self._get_filekey()
            sha = SHA256.new()
            sha.update(passwordkey+filekey)
            masterkey = sha.digest()
        else:
            masterkey = self._get_passwordkey()
        final_key = self._transform_key(masterkey)
        encrypted_content = self._cbc_encrypt(content, final_key)
        del content
        del masterkey
        del final_key
        
        # ...and write it out
        if filepath is not None:
            try:
                handler = open(filepath, "wb")
            except IOError:
                raise KPError("Can't open {0}".format(filepath))
            if self.filepath is None:
                self.filepath = filepath
        elif filepath is None and self.filepath is not None:
            try:
                handler = open(self.filepath, "wb")
            except IOError:
                raise KPError("Can't open {0}".format(self.filepath))
        else:
            raise KPError("Need a filepath.")

        try:
            handler.write(header+encrypted_content)
        except IOError:
            raise KPError("Can't write to file.")
        finally:
            handler.close()
        
        if not path.isfile(self.filepath+".lock"):
            try:
                lock = open(self.filepath+".lock", "w")
                lock.write('')
            except IOError:
                raise KPError("Can't create lock-file {0}".format(self.filepath
                                                                  +".lock"))
            else:
                lock.close()
        return True