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, )
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)
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!"}, )
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, )
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)
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, )
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!"}, )
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, )
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)
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}, )
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
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
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.")
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}, )
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)})
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!"}, )
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)
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)
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
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, )
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)} )
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, )
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!"}, )
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, )
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)
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
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"))
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!"}, )
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
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)} )
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, )
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