コード例 #1
0
ファイル: user.py プロジェクト: kyonetca/indx
            def check_cb(rows, *args, **kw):
                logging.debug(
                    "IndxUser, generate_encryption_keys, connected_cb, check_cb"
                )

                exists = rows[0][0]
                if exists and not overwrite:
                    return_d.callback(False)
                    return  # already has keys, and we are not overwriting

                keys = generate_rsa_keypair(self.RSA_KEYSIZE)
                public_key = keys['public']
                private_key = keys[
                    'private']  # TODO FIXME XXX encrypt private key with password / client cert (decide mechanism)

                insert_q = "UPDATE tbl_users SET private_key_rsa_env = %s, public_key_rsa = %s WHERE username = %s"
                insert_p = [private_key, public_key, self.username]

                def insert_cb(empty):
                    logging.debug(
                        "IndxUser, generate_encryption_keys, insert_cb")
                    return_d.callback(True)

                conn.runOperation(insert_q, insert_p).addCallbacks(
                    insert_cb, return_d.errback)
コード例 #2
0
ファイル: user.py プロジェクト: imclab/indx
            def check_cb(rows, *args, **kw):
                logging.debug("IndxUser, generate_encryption_keys, connected_cb, check_cb")

                exists = rows[0][0]
                if exists and not overwrite:
                    return_d.callback(False)
                    return # already has keys, and we are not overwriting

                keys = generate_rsa_keypair(self.RSA_KEYSIZE)
                public_key = keys['public']
                private_key = keys['private'] # TODO FIXME XXX encrypt private key with password / client cert (decide mechanism)

                insert_q = "UPDATE tbl_users SET private_key_rsa_env = %s, public_key_rsa = %s WHERE username = %s"
                insert_p = [private_key, public_key, self.username]

                def insert_cb(empty):
                    logging.debug("IndxUser, generate_encryption_keys, insert_cb")
                    return_d.callback(True)

                conn.runOperation(insert_q, insert_p).addCallbacks(insert_cb, return_d.errback)
コード例 #3
0
ファイル: box.py プロジェクト: imclab/indx
    def generate_new_key(self, request, token):
        """ Generate a new key and store it in the keystore. Return the public and public-hash parts of the key. """
        if not token:
            return self.return_forbidden(request)
        BoxHandler.log(logging.DEBUG, "BoxHandler generate_new_key", extra = {"request": request, "token": token})

        is_linked = self.get_arg(request, "is-linked", default = False)

        remote_public = self.get_arg(request, "public")
        remote_hash = self.get_arg(request, "public-hash")
        remote_encpk2 = self.get_arg(request, "encpk2")
        remote_serverid = self.get_arg(request, "serverid")

        if not remote_public or not remote_hash or not remote_encpk2 or not remote_serverid:
            BoxHandler.log(logging.ERROR, "BoxHandler generate_new_key: public, public-hash, encpk2, or serverid was missing.", extra = {"request": request, "token": token})
            return self.remote_bad_request(request, "public, public-hash, encpk2 or serverid was missing.")

        def err_cb(failure):
            failure.trap(Exception)
            BoxHandler.log(logging.ERROR, "BoxHandler generate_new_key err_cb: {0}".format(failure), extra = {"request": request, "token": token})
            return self.return_internal_error(request)

        if type(remote_encpk2) != type(""):
            remote_encpk2 = json.dumps(remote_encpk2) 
        remote_encpk2_hsh = sha512_hash(remote_encpk2)

        local_keys = generate_rsa_keypair(3072)

        def store_cb(store):

            def setacl_cb(empty):

                def created_cb(empty):

                    def saved_cb(empty):
                        def servervar_cb(empty):

        #                    encpk2 = rsa_encrypt(load_key(local_keys['public']), token.password)
                            encpk2 = make_encpk2(local_keys, token.password)

                            self.return_created(request, {"data": {"public": local_keys['public'], "public-hash": local_keys['public-hash'], "encpk2": encpk2, "serverid": self.webserver.server_id}})

                        if is_linked:
                            self.database.save_linked_box(token.boxid).addCallbacks(servervar_cb, err_cb)
                        else:
                            servervar_cb(None)

                    self.database.save_encpk2(remote_encpk2_hsh, remote_encpk2, remote_serverid).addCallbacks(saved_cb, err_cb)

                def new_key_added_cb(empty):
                    self.webserver.keystore.put(local_keys, token.username, token.boxid).addCallbacks(created_cb, err_cb) # store in the local keystore

                remote_keys = {"public": remote_public, "public-hash": remote_hash, "private": ""}
                self.webserver.keystore.put(remote_keys, token.username, token.boxid).addCallbacks(new_key_added_cb, err_cb)

            user = IndxUser(self.database, token.username)
            user.set_acl(token.boxid, "@indx", {"read": True, "write": True, "control": False, "owner": False}).addCallbacks(setacl_cb, lambda failure: self.return_internal_error(request))

#            store.apply_diff(remote_diff['data'], remote_diff['@commits']).addCallbacks(applied_cb, lambda failure: self.return_internal_error(request))

        token.get_store().addCallbacks(store_cb, lambda failure: self.return_internal_error(request))
コード例 #4
0
ファイル: sync.py プロジェクト: kyonetca/indx
    def link_remote_box(self, local_user, local_pass, remote_address, remote_box, remote_token, server_id):
        """ Link a remote box with this local box (either a root box, or just a non-root synced box).

            Requires the credentials of the remote box, and will exchange keys using these credentials, store public keys of each box in the synced boxes, and then not require the credentials again in future to sync.
        """
        logging.debug("IndxSync link_remote_box, local: {0}, to remote: {1} @ {2}".format(self.root_store.boxid, remote_address, remote_box))
        return_d = Deferred()

        local_keys = generate_rsa_keypair(3072)
        local_encpk = make_encpk2(local_keys, local_pass)
#        local_encpk = rsa_encrypt(load_key(local_keys['public']), local_pass)

        def ver_cb(ver):

            def new_remote_key_cb(remote_keys):
                logging.debug("IndxSync link_remote_box, new_remote_key_cb, remote_keys: {0}".format(remote_keys))
                # NB: no "private" in remote_keys, that never leaves the remote box.
                remote_keys = remote_keys['data'] # remove the Indx HTTP response padding

                remote_encpk = remote_keys['encpk2']
                if type(remote_encpk) != type(""):
                    remote_encpk = json.dumps(remote_encpk) 

                remote_serverid = remote_keys['serverid']

                link_uid = uuid.uuid1()
                local_key_uid = uuid.uuid1()
                remote_key_uid = uuid.uuid1()
                status1_uid = uuid.uuid1()
                status2_uid = uuid.uuid1()

                link_uri = "link-{0}".format(link_uid)
                status1_uri = "status-{0}".format(status1_uid)
                status2_uri = "status-{0}".format(status2_uid)

                # objects get updated to local box, and then synced across to the other boxes once the syncing starts
                new_objs = [
                    {   "@id": link_uri,
                        "type": [ {"@value": NS_ROOT_BOX + "link"} ],
                        "boxes": [ {"@id": "box-{0}".format(local_key_uid)}, # links to the objs below
                                   {"@id": "box-{0}".format(remote_key_uid)}, # links to the objs below
                                 ],
                        "statuses": [ {"@id": status1_uri}, {"@id": status2_uri} ],
                    },
                    { "@id": status1_uri,
                      "type": [ {"@value": NS_ROOT_BOX + "status"} ],
                      "src-boxid": [ {"@value": remote_box} ],
                      "src-server-url": [ {"@value": remote_address} ],
                      "dst-boxid": [ {"@value": self.root_store.boxid} ],
                      "dst-server-url": [ {"@value": self.url} ],
                      "last-version-seen": [ {"@value": ver + 1} ], #we save this because we will push our whole box to it in a sec - it is incremented because the version is before we put this in
                    },
                    { "@id": status2_uri,
                      "type": [ {"@value": NS_ROOT_BOX + "status"} ],
                      "dst-boxid": [ {"@value": remote_box} ],
                      "dst-server-url": [ {"@value": remote_address} ],
                      "src-boxid": [ {"@value": self.root_store.boxid} ],
                      "src-server-url": [ {"@value": self.url} ],
                    },
                    {   "@id": "box-{0}".format(local_key_uid),
                        "type": [ {"@value": NS_ROOT_BOX + "box"} ],
                        "server-url": [ {"@value": self.url } ],
                        "server-id": [ {"@value": server_id } ],
                        "box": [ {"@value": self.root_store.boxid} ],
                        "key": [ {"@id": local_keys['public-hash']}], # links to the key objs below
                    },
                    {   "@id": "box-{0}".format(remote_key_uid),
                        "type": [ {"@value": NS_ROOT_BOX + "box"} ],
                        "server-url": [ {"@value": remote_address } ],
                        "server-id": [ {"@value": remote_serverid } ],
                        "box": [ {"@value": remote_box} ],
                        "key": [ {"@id": remote_keys['public-hash']}], # links to the key objs below
                    },
                    {   "@id": local_keys['public-hash'],
                        "type": [ {"@value": NS_ROOT_BOX + "key"} ],
                        "public-key": [ {"@value": local_keys['public']} ], # share the full public keys everywhere (private keys only in respective server's keystores)
                        "public-hash": [ {"@value": local_keys['public-hash']} ], # share the full public keys everywhere (private keys only in respective server's keystores)
                    },
                    {   "@id": remote_keys['public-hash'],
                        "type": [ {"@value": NS_ROOT_BOX + "key"} ],
                        "public-key": [ {"@value": remote_keys['public']} ], # share the full public keys everywhere
                        "public-hash": [ {"@value": remote_keys['public-hash']} ], # share the full public keys everywhere
                    },
                ]



                def update_cb(empty):

                    def diff_cb(diff):

                        def applied_cb(empty):

                            def encpk_cb(empty):

                                def remote_added_cb(empty):

                                    def local_added_cb(empty):
                                        logging.debug("IndxSync link_remote_box, local_added_cb")

                                        def added_indx_cb(empty):
                                            # start syncing/connecting using the new key
                                            self.sync_boxes([link_uri], include_push_all = True).addCallbacks(lambda empty: return_d.callback(remote_keys['public']), return_d.errback)

                                        self.database.save_linked_box(self.root_store.boxid).addCallbacks(added_indx_cb, return_d.errback)

                                    # add the local key to the local store
                                    self.keystore.put(local_keys, local_user, self.root_store.boxid).addCallbacks(local_added_cb, return_d.errback) # store in the local keystore

                                self.keystore.put({"public": remote_keys['public'], "private": "", "public-hash": remote_keys['public-hash']}, local_user, self.root_store.boxid).addCallbacks(remote_added_cb, return_d.errback)

                            # don't save the local encpk2 here, only give it to the remote server.
                            # save the remote encpk2
                            self.database.save_encpk2(sha512_hash(remote_encpk), remote_encpk, remote_serverid).addCallbacks(encpk_cb, return_d.errback)

                        client.apply_diff(diff).addCallbacks(applied_cb, return_d.errback)

                    self.root_store.diff(0, None, "diff").addCallbacks(diff_cb, return_d.errback)

                self.root_store.update(new_objs, ver, propagate = True).addCallbacks(update_cb, return_d.errback)

            client = IndxClient(remote_address, remote_box, self.APPID, token = remote_token)
            client.generate_new_key(local_keys, local_encpk, server_id).addCallbacks(new_remote_key_cb, return_d.errback)

        self.root_store._get_latest_ver().addCallbacks(ver_cb, return_d.errback)
        return return_d