Exemplo n.º 1
0
def get_all_request_msg(
    msg: GetRequestsMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> GetRequestsResponse:

    # Get Payload Content
    current_user_id = msg.content.get("current_user", None)

    users = node.users

    if not current_user_id:
        current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    allowed = users.can_triage_requests(user_id=current_user_id)

    if allowed:
        requests = node.data_requests
        requests = requests.all()
        requests_json = [model_to_json(requests) for requests in requests]
    else:
        raise AuthorizationError(
            "You're not allowed to get Request information!")

    return GetRequestsResponse(
        address=msg.reply_to,
        status_code=200,
        content=requests_json,
    )
Exemplo n.º 2
0
def get_all_roles_msg(
    msg: GetRolesMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> GetRolesResponse:
    try:
        _current_user_id = msg.content.get("current_user", None)
    except Exception:
        _current_user_id = None

    users = node.users

    if not _current_user_id:
        _current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    _allowed = users.can_edit_settings(user_id=_current_user_id)
    if _allowed:
        roles = node.roles.all()
        _msg = [model_to_json(role) for role in roles]
    else:
        raise AuthorizationError("You're not allowed to get Role information!")

    return GetRolesResponse(address=msg.reply_to,
                            status_code=200,
                            content=_msg)
Exemplo n.º 3
0
def del_role_msg(
    msg: DeleteRoleMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> DeleteRoleResponse:
    _role_id = msg.content.get("role_id", None)
    _current_user_id = msg.content.get("current_user", None)

    users = node.users

    if not _current_user_id:
        _current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    if not _role_id:
        raise MissingRequestKeyError

    _allowed = node.users.can_edit_settings(user_id=_current_user_id)
    if _allowed:
        node.roles.delete(id=_role_id)
    else:
        raise AuthorizationError("You're not authorized to delete this role!")

    return DeleteRoleResponse(
        address=msg.reply_to,
        status_code=200,
        content={"msg": "Role has been deleted!"},
    )
Exemplo n.º 4
0
def get_association_request_msg(
    msg: GetAssociationRequestMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> GetAssociationRequestResponse:

    # Get Payload Content
    association_request_id = msg.content.get("association_request_id", None)
    current_user_id = msg.content.get("current_user", None)

    users = node.users

    if not current_user_id:
        current_user_id = users.first(
            verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
        ).id

    allowed = node.users.can_manage_infrastructure(user_id=current_user_id)

    if allowed:
        association_requests = node.association_requests
        association_request = association_requests.first(id=association_request_id)
        association_request_json = model_to_json(association_request)
    else:
        raise AuthorizationError(
            "You're not allowed to get Association Request information!"
        )

    return GetAssociationRequestResponse(
        address=msg.reply_to,
        status_code=200,
        content=association_request_json,
    )
Exemplo n.º 5
0
    def invitation_success(self, sigkeypayload, cid, _debug_when_done):
        if not sigkeypayload.startswith("i0:"):
            raise ValueError("expected i0:, got '%r'" % sigkeypayload[:20])
        their_verfkey = VerifyKey(sigkeypayload[3:3+32])
        encoded_payload = their_verfkey.verify(sigkeypayload[3+32:])
        payload = json.loads(encoded_payload.decode("utf-8"))

        self.db.update(
            "UPDATE addressbook SET"
            " invitation_state=?, wormhole=?, wormhole_payload=?,"
            " when_accepted=?,"
            " acked=1,"  # TODO: faked. add a roundtrip?
            " latest_offered_mailbox_json=?,"
            " their_channel_record_json=?,"
            " they_used_new_channel_key=?, their_verfkey=?"
            " WHERE id=?",
            (invitation.INVITE_COMPLETE, None, None,
             time.time(),
             json.dumps(payload.get("mailbox")),
             json.dumps(payload["channel"]),
             0, their_verfkey.encode().encode("hex"),
             cid), "addressbook", cid)
        self.maybe_accept_mailbox(cid)
        self.db.commit()
        log.msg("addressbook entry added for petname=%r" %
                self.petname_for_cid(cid))
        if _debug_when_done:
            eventually(_debug_when_done.callback, cid)
Exemplo n.º 6
0
def get_setup(
    msg: GetSetUpMessage, node: AbstractNode, verify_key: VerifyKey
) -> GetSetUpResponse:

    _current_user_id = msg.content.get("current_user", None)

    users = node.users

    if not _current_user_id:
        try:
            _current_user_id = users.first(
                verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
            ).id
        except Exception:
            pass

    if users.role(user_id=_current_user_id).name != "Owner":
        raise AuthorizationError("You're not allowed to get setup configs!")
    else:
        _setup = model_to_json(node.setup.first(domain_name=node.name))

    return GetSetUpResponse(
        address=msg.reply_to,
        status_code=200,
        content=_setup,
    )
Exemplo n.º 7
0
def del_request_msg(
    msg: DeleteRequestMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> DeleteRequestResponse:

    # Get Payload Content
    request_id = msg.content.get("request_id", None)
    current_user_id = msg.content.get("current_user", None)

    users = node.users

    if not current_user_id:
        current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    requests = node.data_requests
    request = requests.first(id=request_id)

    # Only the creator of a request may delete their request.
    if request.user_id == current_user_id:
        requests.delete(id=request_id)
    else:
        raise AuthorizationError("You're not allowed to delete this Request!")

    return DeleteRequestResponse(
        address=msg.reply_to,
        status_code=200,
        content={"msg": "Request deleted!"},
    )
Exemplo n.º 8
0
def get_request_msg(
    msg: GetRequestMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> GetRequestResponse:

    # Get Payload Content
    request_id = msg.content.get("request_id", None)
    current_user_id = msg.content.get("current_user", None)

    users = node.users

    if not current_user_id:
        current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    requests = node.data_requests
    request = requests.first(id=request_id)

    # A user can get a request if he's the owner of that request
    # or has the can_triage_requests permission
    allowed = request.user_id == current_user_id or users.can_triage_requests(
        user_id=current_user_id)

    if allowed:
        request_json = model_to_json(request)
    else:
        raise AuthorizationError(
            "You're not allowed to get Request information!")

    return GetRequestResponse(
        address=msg.reply_to,
        status_code=200,
        content=request_json,
    )
Exemplo n.º 9
0
def verify_signature(*, message, signature, verify_key):
    """
    Verify block signature
    """

    verify_key = VerifyKey(verify_key.encode('utf-8'), encoder=HexEncoder)
    signature = bytes.fromhex(signature)
    verify_key.verify(message, signature)
Exemplo n.º 10
0
def send_association_request_msg(
    msg: SendAssociationRequestMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> SendAssociationRequestResponse:
    # Get Payload Content
    name = msg.content.get("name", None)
    target_address = msg.content.get("address", None)
    current_user_id = msg.content.get("current_user", None)
    sender_address = msg.content.get("sender_address", None)

    users = node.users

    if not current_user_id:
        current_user_id = users.first(
            verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
        ).id

    # Check if name/address fields are empty
    missing_paramaters = not name or not target_address
    if missing_paramaters:
        raise MissingRequestKeyError(
            message="Invalid request payload, empty fields (name/adress)!"
        )

    allowed = node.users.can_manage_infrastructure(user_id=current_user_id)

    if allowed:
        association_requests = node.association_requests
        association_request_obj = association_requests.create_association_request(
            name, target_address, sender_address
        )
        handshake_value = association_request_obj.handshake_value

        # Create POST request to the address recived in the body
        payload = {
            "name": name,
            "address": sender_address,
            "handshake": handshake_value,
            "sender_address": target_address,
        }
        url = target_address + "/association-requests/receive"

        response = post(url=url, json=payload)
        response_message = (
            "Association request sent!"
            if response.status_code == 200
            else "Association request could not be sent! Please, try again."
        )

    else:
        raise AuthorizationError("You're not allowed to create an Association Request!")

    return SendAssociationRequestResponse(
        address=msg.reply_to,
        status_code=response.status_code,
        content={"msg": response_message},
    )
Exemplo n.º 11
0
    def processM2(self, msg):
        #print "processM2", repr(msg[:10]), "...", self.petname
        assert self.theirTempPubkey
        nonce_and_ciphertext = msg
        my_privkey = self.getMyTempPrivkey()
        b = Box(my_privkey, self.theirTempPubkey)
        #nonce = msg[:Box.NONCE_SIZE]
        #ciphertext = msg[Box.NONCE_SIZE:]
        #print "DECRYPTING n+ct", len(msg), msg.encode("hex")
        body = b.decrypt(nonce_and_ciphertext)
        if not body.startswith("i0:m2a:"):
            raise ValueError("expected i0:m2a:, got '%r'" % body[:20])
        verfkey_and_signedBody = body[len("i0:m2a:"):]
        theirVerfkey = VerifyKey(verfkey_and_signedBody[:32])
        signedBody = verfkey_and_signedBody[32:]
        body = theirVerfkey.verify(signedBody)
        check_myTempPubkey = body[:32]
        check_theirTempPubkey = body[32:64]
        their_channel_record_json = body[64:].decode("utf-8")
        #print " binding checks:"
        #print " check_myTempPubkey", check_myTempPubkey.encode("hex")
        #print " my real tempPubkey", my_privkey.public_key.encode(Hex)
        #print " check_theirTempPubkey", check_theirTempPubkey.encode("hex")
        #print " first theirTempPubkey", self.theirTempPubkey.encode(Hex)
        if check_myTempPubkey != my_privkey.public_key.encode():
            raise ValueError("binding failure myTempPubkey")
        if check_theirTempPubkey != self.theirTempPubkey.encode():
            raise ValueError("binding failure theirTempPubkey")

        them = json.loads(their_channel_record_json)
        me = self.getMyPrivateChannelData()
        addressbook_id = self.db.insert(
            "INSERT INTO addressbook"
            " (petname, acked,"
            "  next_outbound_seqnum, my_signkey,"
            "  their_channel_record_json,"
            "  my_CID_key, next_CID_token,"
            "  highest_inbound_seqnum,"
            "  my_old_channel_privkey, my_new_channel_privkey,"
            "  they_used_new_channel_key, their_verfkey)"
            " VALUES (?,?, "
            "         ?,?,"
            "         ?,"
            "         ?,?,"  # my_CID_key, next_CID_token
            "         ?,"  # highest_inbound_seqnum
            "         ?,?,"
            "         ?,?)",
            (self.petname, 0, 1, me["my_signkey"], json.dumps(them),
             me["my_CID_key"], None, 0, me["my_old_channel_privkey"],
             me["my_new_channel_privkey"], 0, theirVerfkey.encode(Hex)),
            "addressbook")
        self.db.update("UPDATE invitations SET addressbook_id=?"
                       " WHERE id=?", (addressbook_id, self.iid),
                       "invitations", self.iid)

        msg3 = "i0:m3:ACK-" + os.urandom(16)
        self.send(msg3)
        self.nextExpectedMessage = 3
Exemplo n.º 12
0
    def request_signature(self, key: VerifyKey, digest: bytes):
        # Check digest is valid
        if (len(digest) != 64):
            raise ValueError("Digest must be a SHA512 hash")

        # Create a subject for the request
        subject = rx.subject.ReplaySubject()

        # Looking for peers
        subject.on_next(ProtocolEvent(ProtocolEvent.EVENT_SEARCHING_FOR_PEERS))

        # Prepare for response from peer
        def peer_responded(stream: IngressStream):
            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_RECEIVING_RESPONSE))

            # Read the time signature
            time_signature = TimeSignature.deserialise(
                self.read_response(stream))

            # Return the response
            subject.on_next(ProtocolResult(time_signature))
            subject.on_completed()

        # Prepare to connet to peer
        def peer_connected(stream: EgressStream):
            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_REQUESTING_FROM_PEER))

            # Subscribe to the reply
            stream.reply.subscribe(peer_responded)

            # Make the request
            stream.write(Protocol.REQUEST_SIGNATURE + key.encode() + digest)
            stream.close()

            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_AWAITING_RESPONSE))

        # Prepare to find peers
        def peer_found(peer):
            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_ESTABLISHING_CONNECTION))

            # Establish connection
            self.instance.establish_stream(peer).subscribe(peer_connected)

        # Find peer with the signing key
        self.instance.find_resource_peers(key.encode()).subscribe(peer_found)

        # Return the subject
        return subject
Exemplo n.º 13
0
def account_register(args):
    username = get_username(args)

    if not args.public:
        server_verifykey = get_server_advertised_verifykey(args.address)
    else:
        server_verifykey = VerifyKey(args.public, URLSafeBase64Encoder)
    print(f"Server verification key: {server_verifykey.encode(URLSafeBase64Encoder).decode()}")
    server_publickey = get_server_verified_publickey(args.address, server_verifykey)

    # step 1: check access to homeserver
    server_name = get_server_name(args.address, server_verifykey)
    print(f"Server name: {server_name}")

    device_storage = LocalStorage('device', readonly=True)
    user_storage = LocalStorage(username, readonly=False)
    with user_storage as us, device_storage as ds:
        print(f"Setting identity '{username}' homeserver...")
        us['homeserver'] = {
            "address": args.address,
            "verify": server_verifykey.encode(URLSafeBase64Encoder).decode(),
            "public": server_publickey.encode(URLSafeBase64Encoder).decode(),
            "timestamp": get_timestamp_seconds()
        }
        us.save() # write changes before profile block:
        pb = _build_profile_block(username)
        # pack it:
        packd = msgpack.packb(pb)
        # sign it:
        packd_withsig = _get_user_signingkey(username).sign(packd)
        # since the server might not know us yet, we have to SealedBox:
        sbox = SealedBox(server_publickey)
        encrypted = sbox.encrypt(packd_withsig)
        # generate a signature for the headers:
        request_signature = _get_user_signingkey(username).sign(encrypted).signature

        # ready to submit the request:
        r = requests.post(
            args.address + "/api/v1/account/register",
            data=encrypted,
            headers={
                "KF-Client-Verify": _get_user_verifykey(username).encode(URLSafeBase64Encoder).decode(),
                "KF-Client-Signature": base64.urlsafe_b64encode(request_signature),
            }
        )
        if not r.ok:
            print(f"Error registering:\n{r.text}")
            # r.raise_for_status()
            return

        # box is authenticated, no need to check server signature here
        s_box = _get_homeserver_box(username)
        response_bytes = s_box.decrypt(r.content)
        unpacked = msgpack.unpackb(response_bytes)
        print(f"Server good response: {unpacked}")
        print(f"Successfully registered with homeserver.")
Exemplo n.º 14
0
def respond_association_request_msg(
    msg: RespondAssociationRequestMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> RespondAssociationRequestResponse:

    # Get Payload Content
    address = msg.content.get("address", None)
    current_user_id = msg.content.get("current_user", None)
    handshake_value = msg.content.get("handshake", None)
    value = msg.content.get("value", None)
    sender_address = msg.content.get("sender_address", None)

    users = node.users

    if not current_user_id:
        current_user_id = users.first(
            verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
        ).id

    # Check if handshake/address/value fields are empty
    missing_paramaters = not address or not handshake_value or not value
    if missing_paramaters:
        raise MissingRequestKeyError(
            message="Invalid request payload, empty fields (adress/handshake/value)!"
        )

    allowed = node.users.can_manage_infrastructure(user_id=current_user_id)

    if allowed:
        # Set the status of the Association Request according to the "value" field recived
        association_requests = node.association_requests
        association_requests.set(handshake_value, value)

        # Create POST request to the address recived in the body
        payload = {
            "address": sender_address,
            "handshake": handshake_value,
            "value": value,
            "sender_address": address,
        }
        url = address + "/association-requests/receive"

        response = post(url=url, json=payload)
        response_message = (
            "Association request replied!"
            if response.status_code == 200
            else "Association request could not be replied! Please, try again."
        )
    else:
        raise AuthorizationError("You're not allowed to create an Association Request!")
    return RespondAssociationRequestResponse(
        address=msg.reply_to,
        status_code=response.status_code,
        content={"msg": response_message},
    )
Exemplo n.º 15
0
def get_worker_msg(msg: GetWorkerMessage, node: AbstractNode,
                   verify_key: VerifyKey) -> GetWorkerResponse:
    try:

        worker_id = msg.content.get("worker_id", None)
        _current_user_id = msg.content.get("current_user", None)

        users = node.users

        if not _current_user_id:
            _current_user_id = users.first(verify_key=verify_key.encode(
                encoder=HexEncoder).decode("utf-8")).id

        env_ids = [
            env.id for env in node.environments.get_environments(
                user=_current_user_id)
        ]
        is_admin = users.can_manage_infrastructure(user_id=_current_user_id)

        if (int(worker_id) in env_ids) or is_admin:
            worker = node.environments.first(id=int(worker_id))

            try:
                worker_client = connect(
                    url="http://" + worker.address,
                    conn_type=GridHTTPConnection,  # HTTP Connection Protocol
                )

                node.environments.set(
                    id=worker.id,
                    syft_address=serialize(
                        worker_client.address).SerializeToString().decode(
                            "ISO-8859-1"),
                )

                node.in_memory_client_registry[
                    worker_client.domain_id] = worker_client
            except Exception as e:
                return GetWorkerResponse(
                    address=msg.reply_to,
                    status_code=500,
                    content={"error": str(e)},
                )
            _msg = model_to_json(node.environments.first(id=int(worker_id)))
        else:
            _msg = {}

        return GetWorkerResponse(address=msg.reply_to,
                                 status_code=200,
                                 content=_msg)
    except Exception as e:
        return GetWorkerResponse(address=msg.reply_to,
                                 status_code=500,
                                 content={"error": str(e)})
Exemplo n.º 16
0
def create_role_msg(
    msg: CreateRoleMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> CreateRoleResponse:
    _name = msg.content.get("name", None)
    _can_triage_requests = msg.content.get("can_triage_requests", False)
    _can_edit_settings = msg.content.get("can_edit_settings", False)
    _can_create_users = msg.content.get("can_create_users", False)
    _can_create_groups = msg.content.get("can_create_groups", False)
    _can_edit_roles = msg.content.get("can_edit_roles", False)
    _can_manage_infrastructure = msg.content.get("can_manage_infrastructure",
                                                 False)
    _can_upload_data = msg.content.get("can_upload_data", False)
    _current_user_id = msg.content.get("current_user", False)

    users = node.users

    if not _current_user_id:
        _current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    __allowed = users.can_edit_roles(user_id=_current_user_id)

    if not _name:
        raise MissingRequestKeyError(
            message="Invalid request payload, empty fields (name)!")

    # Check if this role name was already registered
    try:
        node.roles.first(name=_name)
        raise RequestError(message="The role name already exists!")
    except RoleNotFoundError:
        pass

    if __allowed:
        node.roles.register(
            name=_name,
            can_triage_requests=_can_triage_requests,
            can_edit_settings=_can_edit_settings,
            can_create_users=_can_create_users,
            can_create_groups=_can_create_groups,
            can_edit_roles=_can_edit_roles,
            can_manage_infrastructure=_can_manage_infrastructure,
            can_upload_data=_can_upload_data,
        )
    else:
        raise AuthorizationError("You're not allowed to create a new Role!")

    return CreateRoleResponse(
        address=msg.reply_to,
        status_code=200,
        content={"msg": "Role created successfully!"},
    )
Exemplo n.º 17
0
    def get_trust_set(self, public_key: VerifyKey) -> TrustSet:
        # Read the trust set file
        file = open(
            os.path.join(self.location,
                         public_key.encode(Base32Encoder).decode("utf-8")),
            'rb')
        data = file.read()
        file.close()

        # Construct and return the trust set
        return TrustSet.deserialise(data, public_key)
Exemplo n.º 18
0
    def get_signing_key(self, public_key: VerifyKey) -> SigningKey:
        # Read the key file
        file = open(
            os.path.join(self.location,
                         public_key.encode(Base32Encoder).decode("utf-8")),
            'rb')
        data = file.read()
        file.close()

        # Construct and return the signing key
        return SigningKey(data)
Exemplo n.º 19
0
    def request_trust_set(self, key: VerifyKey):
        # Create a subject for the request
        subject = rx.subject.ReplaySubject()

        # Looking for peers
        subject.on_next(ProtocolEvent(ProtocolEvent.EVENT_SEARCHING_FOR_PEERS))

        # Prepare for response from peer
        def peer_responded(stream: IngressStream):
            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_RECEIVING_RESPONSE))

            # Read the trust set
            trust_set = TrustSet.deserialise(self.read_response(stream), key)

            # Update our local copy of it
            self.store.update_trust_set(key, trust_set)

            # Return the response
            subject.on_next(ProtocolResult(trust_set))

        # Prepare to connet to peer
        def peer_connected(stream: EgressStream):
            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_REQUESTING_FROM_PEER))

            # Subscribe to the reply
            stream.reply.subscribe(peer_responded)

            # Make the request
            stream.write(Protocol.REQUEST_TRUST_SET + key.encode())
            stream.close()

            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_AWAITING_RESPONSE))

        # Prepare to find peers
        def peer_found(peer):
            # Notify subject
            subject.on_next(
                ProtocolEvent(ProtocolEvent.EVENT_ESTABLISHING_CONNECTION))

            # Establish connection
            self.instance.establish_stream(peer).subscribe(peer_connected)

        # Find peers with the trust set
        self.instance.find_resource_peers(key.encode()).subscribe(peer_found)

        # Return the subject
        return subject
Exemplo n.º 20
0
def build_request_message(msg: RequestMessage, node: AbstractNode,
                          verify_key: VerifyKey):
    if verify_key is None:
        raise ValueError("Can't process Request service without a given "
                         "verification key")

    if msg.requester_verify_key != verify_key:
        raise Exception(
            "You tried to request access for a key that is not yours!"
            "You cannot do this! Whatever key you want to request access"
            "for must be the verify key that also verifies the message"
            "containing the request.")

    # since we reject/accept requests based on the ID, we don't want there to be
    # multiple requests with the same ID because this could cause security problems.
    _duplicate_request = node.data_requests.contain(
        object_id=str(msg.object_id.value),
        verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8"),
    )

    if _duplicate_request:
        raise DuplicateRequestException(
            f"You have already requested {msg.object_id} ",
            node.data_requests.all(),
            "My Requests",
        )

    current_user = node.users.first(verify_key=verify_key.encode(
        encoder=HexEncoder).decode("utf-8"))

    node.data_requests.create_request(
        user_id=current_user.id,
        user_name=current_user.email,
        object_id=str(msg.object_id.value),
        reason=msg.request_description,
        request_type="permissions",
        verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8"),
        object_type=msg.object_type,
        tags=node.store[msg.object_id]._tags,
    )
Exemplo n.º 21
0
def del_worker_msg(
    msg: DeleteWorkerMessage, node: AbstractNode, verify_key: VerifyKey
) -> DeleteWorkerResponse:
    try:
        # Get Payload Content
        worker_id = msg.content.get("worker_id", None)
        _current_user_id = msg.content.get("current_user", None)

        users = node.users
        if not _current_user_id:
            _current_user_id = users.first(
                verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
            ).id

        is_admin = users.can_manage_infrastructure(user_id=_current_user_id)

        envs = [
            int(env.id)
            for env in node.environments.get_environments(user=_current_user_id)
        ]
        created_by_current_user = int(worker_id) in envs

        # Owner / Admin
        if not is_admin and not created_by_current_user:
            raise AuthorizationError("You're not allowed to delete this worker!")

        env = node.environments.first(id=worker_id)
        _config = Config(provider=env.provider, app=Config(name="worker", id=worker_id))

        if env.state == states["success"]:
            worker_dir = os.path.join(
                "/home/ubuntu/.pygrid/apps/aws/workers/", str(worker_id)
            )
            success = Provider(worker_dir).destroy()
            if success:
                node.environments.set(
                    id=worker_id, state=states["destroyed"], destroyed_at=datetime.now()
                )

        if env.state == states["destroyed"]:
            return DeleteWorkerResponse(
                address=msg.reply_to,
                status_code=200,
                content={"message": "Worker was deleted successfully!"},
            )
        else:
            raise Exception("Worker deletion failed")

    except Exception as e:
        return DeleteWorkerResponse(
            address=msg.reply_to, status_code=False, content={"error": str(e)}
        )
Exemplo n.º 22
0
def search_users_msg(
    msg: SearchUsersMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> SearchUsersResponse:
    # Get Payload Content
    _current_user_id = msg.content.get("current_user", None)
    users = node.users
    users = node.users
    if not _current_user_id:
        _current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    user_parameters = {
        "email": msg.content.get("email", None),
        "role": msg.content.get("role", None),
    }
    _group = msg.content.get("group", None)

    filter_parameters = lambda key: user_parameters[key]
    filtered_parameters = filter(filter_parameters, user_parameters.keys())
    user_parameters = {
        key: user_parameters[key]
        for key in filtered_parameters
    }

    _allowed = users.can_triage_requests(user_id=_current_user_id)

    if _allowed:
        try:
            users = node.users.query(**user_parameters)
            if _group:
                filtered_users = filter(
                    lambda x: node.groups.contain_association(user=x.id,
                                                              group=_group),
                    users,
                )
                _msg = [model_to_json(user) for user in filtered_users]
            else:
                _msg = [model_to_json(user) for user in users]
        except UserNotFoundError:
            _msg = {}
    else:
        raise AuthorizationError("You're not allowed to get User information!")

    return SearchUsersResponse(
        address=msg.reply_to,
        status_code=200,
        content=_msg,
    )
Exemplo n.º 23
0
def update_role_msg(
    msg: UpdateRoleMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> UpdateRoleResponse:
    _role_id = msg.content.get("role_id", None)
    _current_user_id = msg.content.get("current_user", None)

    if not _current_user_id:
        _current_user_id = node.users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    params = {
        "name":
        msg.content.get("name", ""),
        "can_triage_requests":
        msg.content.get("can_triage_requests", None),
        "can_edit_settings":
        msg.content.get("can_edit_settings", None),
        "can_create_users":
        msg.content.get("can_create_users", None),
        "can_create_groups":
        msg.content.get("can_create_groups", None),
        "can_edit_roles":
        msg.content.get("can_edit_roles", None),
        "can_manage_infrastructure":
        msg.content.get("can_manage_infrastructure", None),
        "can_upload_data":
        msg.content.get("can_upload_data", None),
    }

    filter_parameters = lambda key: (params[key] != None)
    filtered_parameters = filter(filter_parameters, params.keys())
    role_parameters = {key: params[key] for key in filtered_parameters}

    if not _role_id:
        raise MissingRequestKeyError

    _allowed = node.users.can_edit_roles(user_id=_current_user_id)

    if _allowed:
        node.roles.set(role_id=_role_id, params=role_parameters)
    else:
        raise AuthorizationError("You're not authorized to edit this role!")

    return UpdateRoleResponse(
        address=msg.reply_to,
        status_code=200,
        content={"msg": "Role updated successfully!"},
    )
Exemplo n.º 24
0
def create_request_msg(
    msg: CreateRequestMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> CreateRequestResponse:
    # Get Payload Content
    current_user_id = msg.content.get("current_user", None)
    object_id = msg.content.get("object_id", None)
    reason = msg.content.get("reason", None)
    request_type = msg.content.get("request_type", None)

    users = node.users

    if not current_user_id:
        current_user = users.first(
            verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
        )
    else:
        current_user = users.first(id=current_user_id)

    # Check if object_id/reason/request_type fields are empty
    missing_paramaters = not object_id or not reason or not request_type
    if missing_paramaters:
        raise MissingRequestKeyError(
            message="Invalid request payload, empty fields (object_id/reason/request_type)!"
        )

    valid_paramaters = request_type == "permissions" or request_type == "budget"

    if not valid_paramaters:
        raise InvalidParameterValueError(
            message='Request type should be either "permissions” or “budget”.'
        )

    requests = node.data_requests
    request_obj = requests.create_request(
        user_id=current_user.id,
        user_name=current_user.email,
        object_id=object_id,
        reason=reason,
        request_type=request_type,
    )
    request_json = model_to_json(request_obj)

    return CreateRequestResponse(
        address=msg.reply_to,
        status_code=200,
        content=request_json,
    )
Exemplo n.º 25
0
def get_all_requests(msg: GetAllRequestsMessage, node: AbstractNode,
                     verify_key: VerifyKey):
    if verify_key is None:
        raise ValueError("Can't process Request service without a given "
                         "verification key")

    current_user = node.users.first(verify_key=verify_key.encode(
        encoder=HexEncoder).decode("utf-8"))
    _can_triage_request = node.users.can_triage_requests(
        user_id=current_user.id)

    _requests = node.data_requests.all()

    if _can_triage_request:
        _requests = node.data_requests.all()
    else:
        _requests = node.data_requests.query(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8"))

    data_requests = [
        RequestMessage(
            request_id=UID.from_string(req.id),
            request_description=req.reason,
            address=node.address,
            owner_address=node.address,
            object_id=UID.from_string(req.object_id),
            object_type=req.object_type,
            object_tags=req.tags,
            requester_verify_key=VerifyKey(req.verify_key.encode("utf-8"),
                                           encoder=HexEncoder),
            timeout_secs=None,
        ) for req in _requests
    ]

    return GetAllRequestsResponseMessage(requests=data_requests,
                                         address=msg.reply_to)
Exemplo n.º 26
0
def make_subkey(sk, subuser_pk: VerifyKey):
    # Typically we'll do this, though in theory we can generate any old 32-byte value for c:
    a = sodium.crypto_sign_ed25519_sk_to_curve25519(sk.encode() +
                                                    sk.verify_key.encode())
    c = blake2b(sk.verify_key.encode() + subuser_pk.encode(),
                digest_size=32,
                encoder=RawEncoder)
    d = sodium.crypto_core_ed25519_scalar_mul(
        a,
        sodium.crypto_core_ed25519_scalar_add(
            c,
            blake2b(c + sk.verify_key.encode(),
                    key=b'OxenSSSubkey',
                    digest_size=32,
                    encoder=RawEncoder)))
    D = sodium.crypto_scalarmult_ed25519_base_noclamp(d)
    return c, d, D
Exemplo n.º 27
0
def run_vouch(magic: str) -> None:
    try:
        vouch_data = base64.b64decode(magic.encode("utf-8"))
        verify_key = VerifyKey(vouch_data[:32])
        signed_nickname = vouch_data[32:]
        msg = verify_with_magic(b"NAME", verify_key, signed_nickname)
        nickname = msg.decode("utf-8")
    except Exception:
        print("Could not parse data!")
        sys.exit(1)

    try:
        config = read_config()
        port = connect(config)
        port.send_json(
            {
                "method": "vouch",
                "who": verify_key.encode(HexEncoder).decode("utf-8"),
                "signed_name": HexEncoder.encode(signed_nickname).decode("utf-8"),
            }
        )
        port.receive_json()
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)

    if not ask(f"Grant permuter server access to {nickname}", default=True):
        return

    try:
        port.send_json({})
        port.receive_json()
    except Exception as e:
        print(f"Failed to grant access: {e}")
        sys.exit(1)

    assert config.server_address, "checked by connect"
    assert config.server_verify_key, "checked by connect"
    data = config.server_verify_key.encode() + config.server_address.encode("utf-8")
    token = SealedBox(verify_key.to_curve25519_public_key()).encrypt(data)
    print("Granted!")
    print()
    print("Send them the following token:")
    print(base64.b64encode(token).decode("utf-8"))
Exemplo n.º 28
0
    def process(
        node: AbstractNode,
        msg: Union[
            LoadObjectMessage,
        ],
        verify_key: VerifyKey,
    ) -> Union[LoadObjectResponse, SaveObjectResponse,]:
        _worker_address = msg.content.get("address", None)
        _obj_id = msg.content.get("uid", None)
        _current_user_id = msg.content.get("current_user", None)

        users = node.users

        if not _current_user_id:
            _current_user_id = users.first(
                verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
            ).id

        addr_pb = Address_PB()
        addr_pb.ParseFromString(_worker_address.encode("ISO-8859-1"))
        _syft_address = _deserialize(blob=addr_pb)

        _syft_id = UID.from_string(value=_obj_id)

        _worker_client = node.in_memory_client_registry[_syft_address.domain_id]

        try:
            _obj = node.store[_syft_id]
        except Exception:
            raise Exception("Object Not Found!")

        _obj.data.send(
            _worker_client,
            searchable=True,
            tags=_obj.tags,
            description=_obj.description,
        )

        return LoadObjectResponse(
            address=msg.reply_to,
            status_code=200,
            content={"msg": "Object loaded successfully!"},
        )
Exemplo n.º 29
0
    def update_trust_set(self, public_key: VerifyKey,
                         trust_set: TrustSet) -> bool:
        # Does the path already exist?
        if (self.has_trust_set(public_key)):
            # Get the trust set
            current = self.get_trust_set(public_key)

            # If the current trust set is valid from a later date, don't update
            if (trust_set.valid_from < current.valid_from):
                return False

        # Replace/create the trust set
        file = open(
            os.path.join(self.location,
                         public_key.encode(Base32Encoder).decode("utf-8")),
            'wb')
        file.write(trust_set.serialise())
        file.close()
        return True
Exemplo n.º 30
0
def get_workers_msg(
    msg: GetWorkersMessage, node: AbstractNode, verify_key: VerifyKey
) -> GetWorkersResponse:
    try:
        _current_user_id = msg.content.get("current_user", None)
        include_all = msg.content.get("include_all", True)
        include_failed = msg.content.get("include_failed", False)
        include_destroyed = msg.content.get("include_destroyed", False)

        if not _current_user_id:
            _current_user_id = node.users.first(
                verify_key=verify_key.encode(encoder=HexEncoder).decode("utf-8")
            ).id

        envs = node.environments.get_environments(user=_current_user_id)

        workers = []
        print("Node environments: ", node.environments.all()[0].id)
        for env in envs:
            print("Here!", env.id)
            _env = node.environments.first(id=env.id)

            if (
                include_all
                or (_env.state == states["success"])
                or (include_failed and _env.state == states["failed"])
                or (include_destroyed and _env.state == states["destroyed"])
            ):
                worker = model_to_json(_env)
                del worker["syft_address"]
                workers.append(worker)

        _msg = workers

        return GetWorkersResponse(address=msg.reply_to, status_code=200, content=_msg)
    except Exception as e:
        return GetWorkersResponse(
            address=msg.reply_to, status_code=False, content={"error": str(e)}
        )
Exemplo n.º 31
0
def get_user_msg(
    msg: GetUserMessage,
    node: AbstractNode,
    verify_key: VerifyKey,
) -> GetUserResponse:
    # Get Payload Content
    _user_id = msg.content.get("user_id", None)
    _current_user_id = msg.content.get("current_user", None)

    users = node.users
    if not _current_user_id:
        _current_user_id = users.first(verify_key=verify_key.encode(
            encoder=HexEncoder).decode("utf-8")).id

    user = users.first(id=_user_id)
    _msg = model_to_json(user)

    return GetUserResponse(
        address=msg.reply_to,
        status_code=200,
        content=_msg,
    )
Exemplo n.º 32
0
    def processM2(self, msg):
        #print "processM2", repr(msg[:10]), "...", self.petname
        assert self.theirTempPubkey
        nonce_and_ciphertext = msg
        my_privkey = self.getMyTempPrivkey()
        b = Box(my_privkey, self.theirTempPubkey)
        #nonce = msg[:Box.NONCE_SIZE]
        #ciphertext = msg[Box.NONCE_SIZE:]
        #print "DECRYPTING n+ct", len(msg), msg.encode("hex")
        body = b.decrypt(nonce_and_ciphertext)
        if not body.startswith("i0:m2a:"):
            raise ValueError("expected i0:m2a:, got '%r'" % body[:20])
        verfkey_and_signedBody = body[len("i0:m2a:"):]
        theirVerfkey = VerifyKey(verfkey_and_signedBody[:32])
        signedBody = verfkey_and_signedBody[32:]
        body = theirVerfkey.verify(signedBody)
        check_myTempPubkey = body[:32]
        check_theirTempPubkey = body[32:64]
        their_channel_record_json = body[64:].decode("utf-8")
        #print " binding checks:"
        #print " check_myTempPubkey", check_myTempPubkey.encode("hex")
        #print " my real tempPubkey", my_privkey.public_key.encode(Hex)
        #print " check_theirTempPubkey", check_theirTempPubkey.encode("hex")
        #print " first theirTempPubkey", self.theirTempPubkey.encode(Hex)
        if check_myTempPubkey != my_privkey.public_key.encode():
            raise ValueError("binding failure myTempPubkey")
        if check_theirTempPubkey != self.theirTempPubkey.encode():
            raise ValueError("binding failure theirTempPubkey")

        them = json.loads(their_channel_record_json)
        me = self.getMyPrivateChannelData()
        addressbook_id = self.db.insert(
            "INSERT INTO addressbook"
            " (petname, acked,"
            "  next_outbound_seqnum, my_signkey,"
            "  their_channel_record_json,"
            "  my_CID_key, next_CID_token,"
            "  highest_inbound_seqnum,"
            "  my_old_channel_privkey, my_new_channel_privkey,"
            "  they_used_new_channel_key, their_verfkey)"
            " VALUES (?,?, "
            "         ?,?,"
            "         ?,"
            "         ?,?," # my_CID_key, next_CID_token
            "         ?,"   # highest_inbound_seqnum
            "         ?,?,"
            "         ?,?)",
            (self.petname, 0,
             1, me["my_signkey"],
             json.dumps(them),
             me["my_CID_key"], None,
             0,
             me["my_old_channel_privkey"],
             me["my_new_channel_privkey"],
             0, theirVerfkey.encode(Hex) ),
            "addressbook")
        self.db.update("UPDATE invitations SET addressbook_id=?"
                       " WHERE id=?", (addressbook_id, self.iid),
                       "invitations", self.iid)

        msg3 = "i0:m3:ACK-"+os.urandom(16)
        self.send(msg3)
        self.nextExpectedMessage = 3