def search_authorization_full(graph: Graph, principal: Node, action_to_check: str, resource_to_check: str, condition_keys_to_check: _UODict, resource_policy: Optional[dict] = None, resource_owner: Optional[str] = None, service_control_policies: List[List[Policy]] = None, session_policy: Optional[dict] = None) -> QueryResult: """Determines if the passed principal, or any principals it can access, can perform a given action for a given resource/condition. Handles an optional resource policy, an optional SCP list, and an optional session policy. SCPs are considered in the full search list, but the session policy is discarded after checking if the passed principal has access (we assume it is discarded after each pivot, and that it does NOT affect the accessibility of the edges). In `local_check_authorization` we usually throw up our hands if the given principal is an admin. But, because of how SCPs work (even blocking the root user), we force the full search to give more accurate results. If the SCPs param is None, we assume no SCPs are in place and can make the same assumption as in `local_check_authorization`. If the resource_owner param is not None, and the resource_owner param is None, the `local_check_authorization_full` function that gets called will throw a ValueError, so make sure the resource ownership is sorted before calling this method.""" if local_check_authorization_full(principal, action_to_check, resource_to_check, condition_keys_to_check, resource_policy, resource_owner, service_control_policies, session_policy): return QueryResult(True, [], principal) if service_control_policies is None and principal.is_admin: return QueryResult(True, principal, principal) for edge_list in query_utils.get_search_list(graph, principal): if local_check_authorization_full(edge_list[-1].destination, action_to_check, resource_to_check, condition_keys_to_check, resource_policy, resource_owner, service_control_policies, None): return QueryResult(True, edge_list, principal) return QueryResult(False, [], principal)
def is_connected(graph: Graph, source_node: Node, dest_node: Node) -> (bool, List[Edge]): """Method for determining if a source node can reach a destination node through edges. The return value is a bool, List[Edge] tuple indicating if there's a connection and the path the source node would need to take. """ edge_lists = get_search_list(graph, source_node) for edge_list in edge_lists: final_node = edge_list[-1].destination if final_node == dest_node: return True, edge_list return False, None
def search_authorization_for(graph: Graph, principal: Node, action_to_check: str, resource_to_check: str, condition_keys_to_check: _UODict) -> QueryResult: """Determines if the passed principal, or any principals it can access, can perform a given action for a given resource/condition.""" if local_check_authorization(principal, action_to_check, resource_to_check, condition_keys_to_check): return QueryResult(True, [], principal) # Invoke special-case if admin node is not directly authorized to call the given action for the given resource if principal.is_admin: return QueryResult(True, principal, principal) for edge_list in query_utils.get_search_list(graph, principal): if local_check_authorization(edge_list[-1].destination, action_to_check, resource_to_check, condition_keys_to_check): return QueryResult(True, edge_list, principal) return QueryResult(False, [], principal)
def can_privesc(graph: Graph, node: Node, debug: bool = False) -> (bool, List[Edge]): """Method for determining if a given Node in a Graph can escalate privileges. Returns a bool, List[Edge] tuple. The bool indicates if there is a privesc risk, and the List[Edge] component describes the path of edges the node would have to take to gain access to the admin node. """ edge_lists = get_search_list(graph, node) searched_nodes = [] for edge_list in edge_lists: # check if the node at the end of the list has been looked at yet, skip if so end_of_list = edge_list[-1].destination if end_of_list in searched_nodes: continue # add end of list to the searched nodes and do the privesc check searched_nodes.append(end_of_list) if end_of_list.is_admin: return True, edge_list return False, None
def search_authorization_for(graph: Graph, principal: Node, action_to_check: str, resource_to_check: str, condition_keys_to_check: dict, debug: bool = False) -> QueryResult: """Determines if the passed principal, or any principals it can access, can perform a given action for a given resource/condition.""" if principal.is_admin: return QueryResult(True, [], principal) if local_check_authorization(principal, action_to_check, resource_to_check, condition_keys_to_check, debug): return QueryResult(True, [], principal) for edge_list in query_utils.get_search_list(graph, principal): if local_check_authorization(edge_list[-1].destination, action_to_check, resource_to_check, condition_keys_to_check, debug): return QueryResult(True, edge_list, principal) return QueryResult(False, [], principal)