def __init__(self, node): self.authz_server_id = None self.node = node try: if 'authorization' in _sec_conf and 'procedure' in _sec_conf[ 'authorization']: if _sec_conf['authorization']['procedure'] == "local": self.pdp = PolicyDecisionPoint( self.node, _sec_conf['authorization'] if _sec_conf else None) try: self.prp = FilePolicyRetrievalPoint( _sec_conf['authorization']["policy_storage_path"]) except: self.prp = FilePolicyRetrievalPoint( os.path.join(os.path.expanduser("~"), ".calvin", "security", "policies")) self.authz_server_id = self.node.id elif 'server_uuid' in _sec_conf['authorization']: self.authz_server_id = _sec_conf['authorization'][ 'server_uuid'] else: self.authz_server_id = None except Exception: self.authz_server_id = None
def __init__(self, node): self.node = node try: if _sec_conf['authorization']['procedure'] == "local": self.pdp = PolicyDecisionPoint(self.node, _sec_conf['authorization'] if _sec_conf else None) try: self.prp = FilePolicyRetrievalPoint(_sec_conf['authorization']["policy_storage_path"]) except: self.prp = FilePolicyRetrievalPoint(os.path.join(os.path.expanduser("~"), ".calvin", "security", "policies")) self.authz_server_id = self.node.id else: self.authz_server_id = _sec_conf['authorization']['server_uuid'] except Exception: self.authz_server_id = None
class Authorization(object): """Authorization helper functions""" def __init__(self, node): self.node = node try: if _sec_conf['authorization']['procedure'] == "local": self.pdp = PolicyDecisionPoint(self.node, _sec_conf['authorization'] if _sec_conf else None) try: self.prp = FilePolicyRetrievalPoint(_sec_conf['authorization']["policy_storage_path"]) except: self.prp = FilePolicyRetrievalPoint(os.path.join(os.path.expanduser("~"), ".calvin", "security", "policies")) self.authz_server_id = self.node.id else: self.authz_server_id = _sec_conf['authorization']['server_uuid'] except Exception: self.authz_server_id = None def decode_request(self, data): """Decode the JSON Web Token in the data.""" return decode_jwt(data["jwt"], data["cert_name"], self.node.node_name, self.node.id) def encode_response(self, request, response, audience=None): """Encode the response to the request as a JSON Web Token.""" jwt_payload = { "iss": self.node.id, "aud": request["iss"] if audience is None else audience, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "response": response } if "sub" in request: jwt_payload["sub"] = request["sub"] # Create a JSON Web Token signed using the authorization server's private key. return encode_jwt(jwt_payload, self.node.node_name) def register_node(self): """Register node attributes for authorization.""" if _sec_conf and "authorization" in _sec_conf: # TODO: the node should contact the authz server regularly (once a day?), # otherwise it should be removed from the registered_nodes list on the authz server. try: if _sec_conf['authorization']['procedure'] == "external": if not HAS_JWT: _log.error("Security: Install JWT to use external server as authorization method.") return self.register_node_external() else: self.pdp.register_node(self.node.id, self.node.attributes.get_indexed_public_with_keys()) except Exception as e: _log.error("Node could not be registered for authorization - %s" % str(e)) def register_node_external(self): """Register node attributes for external authorization""" # FIXME: should this include certificate exchange? payload = { "iss": self.node.id, "aud": self.node.authorization.authz_server_id, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "attributes": self.node.attributes.get_indexed_public_with_keys() } # Create a JSON Web Token signed using the node's Elliptic Curve private key. jwt_request = encode_jwt(payload, self.node.node_name) # Send registration request to authorization server. self.node.proto.authorization_register(self.node.authorization.authz_server_id, CalvinCB(self._register_node_external_cb), jwt_request) def _register_node_external_cb(self, status): if not status or status.status != 200: _log.error("Node could not be registered for authorization")
class Authorization(object): """Authorization helper functions""" def __init__(self, node): _log.debug("Authorization::__init__") self.authz_server_id = None self.node = node try: if 'authorization' in _sec_conf and 'procedure' in _sec_conf['authorization']: if _sec_conf['authorization']['procedure'] == "local": self.pdp = PolicyDecisionPoint(self.node, _sec_conf['authorization'] if _sec_conf else None) try: self.prp = FilePolicyRetrievalPoint(_sec_conf['authorization']["policy_storage_path"]) except: self.prp = FilePolicyRetrievalPoint(os.path.join(os.path.expanduser("~"), ".calvin", "security", "policies")) self.authz_server_id = self.node.id elif 'server_uuid' in _sec_conf['authorization']: self.authz_server_id = _sec_conf['authorization']['server_uuid'] else: self.authz_server_id = None except Exception: self.authz_server_id = None def decode_request(self, data, callback): """Decode the JSON Web Token in the data.""" _log.debug("decode_request:\n\tdata={}\n\tcallback={}".format(data, callback)) decode_jwt(data["jwt"], data["cert_name"], self.node, callback=CalvinCB(self._decode_request_cb, callback=callback)) def _decode_request_cb(self, decoded, callback): _log.debug("_decode_request_cb\n\tDecoded={}\n\tCallback={}".format(decoded, callback)) callback(decoded=decoded) def encode_response(self, request, response, audience=None): """Encode the response to the request as a JSON Web Token.""" jwt_payload = { "iss": self.node.id, "aud": request["iss"] if audience is None else audience, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "response": response } if "sub" in request: jwt_payload["sub"] = request["sub"] # Create a JSON Web Token signed using the authorization server's private key. return encode_jwt(jwt_payload, self.node) def register_node(self): """Register node attributes for authorization.""" _log.debug("register_node") if _sec_conf and "authorization" in _sec_conf: # TODO: the node should contact the authz server regularly (once a day?), # otherwise it should be removed from the registered_nodes list on the authz server. try: if "procedure" in _sec_conf['authorization']: if _sec_conf['authorization']['procedure'] == "external": _log.debug("register_node: usage of external authorization server selected") if not HAS_JWT: _log.error("Install JWT to use external server as authorization method.") return if self.authz_server_id: _log.debug("Authorization server id configured in calvin config file, let's use it. authz_server_id={}".format(self.authz_server_id)) self.register_node_external() else: _log.debug("No authorization server configured, let's try to find one in storage") self.node.storage.get_index(['external_authorization_server'], cb=CalvinCB(self._register_node_cb, key='external_authorization_server')) else: _log.debug("register_node: usage of local authorization server selected\n\tself.node={}".format(self.node)) self.pdp.register_node(self.node.id, self.node.attributes.get_indexed_public_with_keys()) else: _log.error("Please configure an authorization procedure") raise("Please configure an authorization procedure") except Exception as e: _log.error("Node could not be registered for authorization - %s" % str(e)) else: _log.debug("No authorization enabled") def _register_node_cb(self, key, value): import random import time global registration_search_attempt _log.debug("_register_node_cb:\n\tkey={}\n\tvalue={}\n\tattempt={}".format(key,value, registration_search_attempt)) if value: nbr = len(value) #For loadbalanding of authorization server, randomly select # one of the found authorization servers #TODO: there is a risk that we end up in a never ending loop if none of the authorization servers # certificates is valid!! rand = random.randint(0, nbr-1) self.authz_server_id = value[rand] #Fetch authorization runtime certificate and verify that it is certified as an # authorization server index = ['certificate',self.authz_server_id] self.node.storage.get_index(index, cb=CalvinCB(self._check_authz_certificate_cb, key="/".join(index), authz_list_key=key, authz_list=value)) # self.register_node_external() elif registration_search_attempt<10: time_to_sleep = 1+registration_search_attempt*registration_search_attempt*registration_search_attempt _log.error("No authorization server found, try again after sleeping {} seconds".format(time_to_sleep)) #Wait for a while and try again time.sleep(time_to_sleep) registration_search_attempt = registration_search_attempt+1 self.node.storage.get_index(['external_authorization_server'], cb=CalvinCB(self._register_node_cb, key='external_authorization_server')) else: raise Exception("No athorization server accepting external clients can be found") def _check_authz_certificate_cb(self, key, value, authz_list_key=None, authz_list=None): """Register node attributes for external authorization""" # FIXME: should this include certificate exchange? _log.debug("_check_authz_certificate_cb" "\n\tkey={}" "\n\tvalue={}".format(key, value)) if value: certstr = value[0] try: certx509 = self.node.runtime_credentials.certificate.truststore_transport.verify_certificate_str(certstr) except Exception as err: _log.error("Failed to verify the authorization servers certificate from storage, err={}".format(err)) raise if not "authzserver" in certificate.cert_CN(certstr): _log.error("The runtime IS NOT certified by the CA as an authorization server, let's try another one.") self._register_node_cb(key=authz_list_key, value=authz_list) else: _log.info("The runtime IS certified by the CA as an authorization server") self.register_node_external() def register_node_external(self): """Register node attributes for external authorization""" # FIXME: should this include certificate exchange? _log.debug("register_node_external") payload = { "iss": self.node.id, "aud": self.node.authorization.authz_server_id, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "attributes": self.node.attributes.get_indexed_public_with_keys() } # Create a JSON Web Token signed using the node's Elliptic Curve private key. jwt_request = encode_jwt(payload, self.node) # Send registration request to authorization server. self.node.proto.authorization_register(self.node.authorization.authz_server_id, CalvinCB(self._register_node_external_cb), jwt_request) def _register_node_external_cb(self, status): import time global registration_attempt _log.debug("_register_node_external_cb, status={}".format(status)) if not status or status.status != 200: time_to_sleep = 1+registration_attempt*registration_attempt*registration_attempt _log.error("Node could not be registered for authorization, try again after sleeping {} seconds".format(time_to_sleep)) #Wait for a while and try again time.sleep(time_to_sleep) registration_attempt = registration_attempt+1 self.register_node_external() else: _log.debug("Successfully registered with authorization server")
class Authorization(object): """Authorization helper functions""" def __init__(self, node): self.authz_server_id = None self.node = node try: if 'authorization' in _sec_conf and 'procedure' in _sec_conf[ 'authorization']: if _sec_conf['authorization']['procedure'] == "local": self.pdp = PolicyDecisionPoint( self.node, _sec_conf['authorization'] if _sec_conf else None) try: self.prp = FilePolicyRetrievalPoint( _sec_conf['authorization']["policy_storage_path"]) except: self.prp = FilePolicyRetrievalPoint( os.path.join(os.path.expanduser("~"), ".calvin", "security", "policies")) self.authz_server_id = self.node.id elif 'server_uuid' in _sec_conf['authorization']: self.authz_server_id = _sec_conf['authorization'][ 'server_uuid'] else: self.authz_server_id = None except Exception: self.authz_server_id = None def decode_request(self, data, callback): """Decode the JSON Web Token in the data.""" _log.debug("decode_request:\n\tdata={}\n\tcallback={}".format( data, callback)) decode_jwt(data["jwt"], data["cert_name"], self.node, callback=CalvinCB(self._decode_request_cb, callback=callback)) def _decode_request_cb(self, decoded, callback): _log.debug("_decode_request_cb\n\tDecoded={}\n\tCallback={}".format( decoded, callback)) callback(decoded=decoded) def encode_response(self, request, response, audience=None): """Encode the response to the request as a JSON Web Token.""" jwt_payload = { "iss": self.node.id, "aud": request["iss"] if audience is None else audience, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "response": response } if "sub" in request: jwt_payload["sub"] = request["sub"] # Create a JSON Web Token signed using the authorization server's private key. return encode_jwt(jwt_payload, self.node) def register_node(self): """Register node attributes for authorization.""" _log.debug("register_node") if _sec_conf and "authorization" in _sec_conf: # TODO: the node should contact the authz server regularly (once a day?), # otherwise it should be removed from the registered_nodes list on the authz server. try: if "procedure" in _sec_conf['authorization']: if _sec_conf['authorization']['procedure'] == "external": _log.debug( "register_node: usage of external authorization server selected" ) if not HAS_JWT: _log.error( "Install JWT to use external server as authorization method." ) return if self.authz_server_id: _log.debug( "Authorization server id configured in calvin config file, let's use it. authz_server_id={}" .format(self.authz_server_id)) self.register_node_external() else: _log.debug( "No authorization server configured, let's try to find one in storage" ) self.node.storage.get_index( ['external_authorization_server'], CalvinCB(self._register_node_cb)) else: _log.debug( "register_node: usage of local authorization server selected\n\tself.node={}" .format(self.node)) self.pdp.register_node( self.node.id, self.node.attributes.get_indexed_public_with_keys( )) else: _log.error("Please configure a authorization procedure") raise ("Please configure a authorization procedure") except Exception as e: _log.error( "Node could not be registered for authorization - %s" % str(e)) else: _log.debug("No authorization enabled") def _register_node_cb(self, key, value): import random import time global registration_search_attempt _log.debug( "_register_node_cb:\n\tkey={}\n\tvalue={}\n\tattempt={}".format( key, value, registration_search_attempt)) if value: nbr = len(value) #For loadbalanding of authorization server, randomly select # one of the found authorization servers rand = random.randint(0, nbr - 1) self.authz_server_id = value[rand] self.register_node_external() elif registration_search_attempt < 10: time_to_sleep = 1 + registration_search_attempt * registration_search_attempt * registration_search_attempt _log.error( "No authorization server found, try again after sleeping {} seconds" .format(time_to_sleep)) #Wait for a while and try again time.sleep(time_to_sleep) registration_search_attempt = registration_search_attempt + 1 self.node.storage.get_index(['external_authorization_server'], CalvinCB(self._register_node_cb)) else: raise Exception( "No athorization server accepting external clients can be found" ) def register_node_external(self): """Register node attributes for external authorization""" # FIXME: should this include certificate exchange? _log.debug("register_node_external") payload = { "iss": self.node.id, "aud": self.node.authorization.authz_server_id, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "attributes": self.node.attributes.get_indexed_public_with_keys() } # Create a JSON Web Token signed using the node's Elliptic Curve private key. jwt_request = encode_jwt(payload, self.node) # Send registration request to authorization server. self.node.proto.authorization_register( self.node.authorization.authz_server_id, CalvinCB(self._register_node_external_cb), jwt_request) def _register_node_external_cb(self, status): global registration_attempt _log.debug("_register_node_external_cb, status={}".format(status)) if not status or status.status != 200: time_to_sleep = 1 + registration_attempt * registration_attempt * registration_attempt _log.error( "Node could not be registered for authorization, try again after sleeping {} seconds" .format(time_to_sleep)) #Wait for a while and try again time.sleep(time_to_sleep) registration_attempt = registration_attempt + 1 self.register_node_external() else: _log.debug("Successfully registered with authorization server")