a qqe)>@sddlZddlZddlmZddlmZmZmZmZm Z m Z z ddl Z ddl mZmZmZWn"ey~eedYn0ddlmZmZddlmZdd lmZmZmZmZd gZed Z Gd d d Z!Gd d d Z"dS)N)suppress)castIterableListMappingOptionalUnion) NetworkXErrorNetworkXNoPath NodeNotFoundzNetworkX failed to import.)EdgeAttrIntMax EdgeAttrList) PermissionMap)AVRule SELinuxPolicy TERuletypeTypeInfoFlowAnalysis InfoFlowStepc @seZdZUdZeeed<eed<eed<d.e eee e e ee fe ee efdddd Zeed d d Zejedd dd Zeed ddZejeddddZeeed ddZeje e e ee fddddZeee edddZd/e ee fe ee fee edddZe ee fe ee fe edddZd0e ee fee d!d"d#d$Ze d d%d&Zeeed'd(d)Zdd d*d+Zdd d,d-ZdS)1rzInformation flow analysis._exclude _min_weight _perm_mapr N)policyperm_map min_weightexcludebooleansreturncCstt|_||_||_||_||_||_d|_ d|_ zt |_ |j |_Wn,ty||jd|jdYn0dS)a Parameters: policy The policy to analyze. perm_map The permission map or path to the permission map file. minweight The minimum permission weight to include in the analysis. (default is 1) exclude The types excluded from the information flow analysis. (default is none) booleans If None, all rules will be added to the analysis (default). otherwise it should be set to a dict with keys corresponding to boolean names and values of True/False. Any unspecified booleans will use the policy's default values. TzKNetworkX is not available. This is requried for Information Flow Analysis.z2This is typically in the python3-networkx package.N)logging getLogger__name__logrrrrr rebuildgraphrebuildsubgraphnxZDiGraphGcopysubG NameErrorZcritical)selfrrrrrr+6/usr/lib64/python3.9/site-packages/setools/infoflow.py__init__!s     zInfoFlowAnalysis.__init__)rcCs|jSN)rr*r+r+r,rEszInfoFlowAnalysis.min_weight)weightrcCs.d|krdksntd||_d|_dS)Nr z4Min information flow weight must be an integer 1-10.T) ValueErrorrr$)r*r0r+r+r,rIs cCs|jSr.)rr/r+r+r,rRszInfoFlowAnalysis.perm_map)rrcCs||_d|_d|_dS)NT)rr#r$)r*rr+r+r,rVscCs|jSr.)rr/r+r+r,r\szInfoFlowAnalysis.exclude)typesrcs*|rfdd|D_ng_d_dS)Ncsg|]}j|qSr+)r lookup_type).0tr/r+r, cz,InfoFlowAnalysis.exclude..T)rr$)r*r3r+r/r,r`s)sourcetargetrccs|j|}|j|}|jr&||jd||ttt *| t j |j ||dVWdn1st0YdS)a Generator which yields one shortest path between the source and target types (there may be more). Parameters: source The source type. target The target type. Yield: generator(steps) steps Yield: tuple(source, target, rules) source The source type for this step of the information flow. target The target type for this step of the information flow. rules The list of rules creating this information flow step. z@Generating one shortest information flow path from {0} to {1}...)r9r:N)rr4r$_build_subgraphr"infoformatrr r !_InfoFlowAnalysis__generate_stepsr% shortest_pathr()r*r9r:sr6r+r+r,r?is    zInfoFlowAnalysis.shortest_path)r9r:maxlenrccs|dkrtd|j|}|j|}|jr6||jd|||tt t 4t |j |||D]}||VqjWdn1s0YdS)a Generator which yields all paths between the source and target up to the specified maximum path length. This algorithm tends to get very expensive above 3-5 steps, depending on the policy complexity. Parameters: source The source type. target The target type. maxlen Maximum length of paths. Yield: generator(steps) steps Yield: tuple(source, target, rules) source The source type for this step of the information flow. target The target type for this step of the information flow. rules The list of rules creating this information flow step. r z%Maximum path length must be positive.zHGenerating all information flow paths from {0} to {1}, max length {2}...N)r2rr4r$r;r"r<r=rr r r%Zall_simple_pathsr(r>)r*r9r:rBr@r6pathr+r+r, all_pathss    zInfoFlowAnalysis.all_pathsccs|j|}|j|}|jr&||jd||ttt 2t |j ||D]}| |VqVWdn1s|0YdS)a Generator which yields all shortest paths between the source and target types. Parameters: source The source type. target The target type. Yield: generator(steps) steps Yield: tuple(source, target, rules) source The source type for this step of the information flow. target The target type for this step of the information flow. rules The list of rules creating this information flow step. zAGenerating all shortest information flow paths from {0} to {1}...N)rr4r$r;r"r<r=rr r r%all_shortest_pathsr(r>)r*r9r:r@r6rCr+r+r,rEs    z#InfoFlowAnalysis.all_shortest_pathsTr)type_outrccs|j|}|jr||jd|r,dnd|ttL|rR|j |}n |j |}|D]\}}t |j ||VqbWdn1s0YdS)a( Generator which yields all information flows in/out of a specified source type. Parameters: source The starting type. Keyword Parameters: out If true, information flows out of the type will be returned. If false, information flows in to the type will be returned. Default is true. Yield: generator(steps) steps A generator that returns the tuple of source, target, and rules for each information flow. z(Generating all information flows {0} {1}zout ofZintoN) rr4r$r;r"r<r=rr r(Z out_edgesZin_edgesr)r*rFrGr@Zflowsr9r:r+r+r, infoflowss      zInfoFlowAnalysis.infoflowscCs.|jr|dt|jdt|jS)zQ Get the information flow graph statistics. Return: str z Graph nodes: z Graph edges: )r# _build_graphr%number_of_nodesr&number_of_edgesr/r+r+r, get_statss  zInfoFlowAnalysis.get_stats)rCrccs4tdt|D] }t|j||d||VqdS)a Generator which returns the source, target, and associated rules for each information flow step. Parameter: path A list of graph node names representing an information flow path. Yield: tuple(source, target, rules) source The source type for this step of the information flow. target The target type for this step of the information flow. rules The list of rules creating this information flow step. r N)rangelenrr()r*rCr@r+r+r,Z__generate_stepssz!InfoFlowAnalysis.__generate_stepscCs*|jd|j|j_|j|j|jd|j|j D]}|j t j krXqF|j tt|\}}t|j|jD]`\}}||kr|rt|j||dd}|j|||_|rt|j||dd}|j|||_qqFd|_d|_|jd|jdt|jt|jdS)NzInformation flow graph for {0}.z+Building information flow graph from {0}...T)createFz*Completed building information flow graph.z$Graph stats: nodes: {0}, edges: {1}.)r&clearr=rnamerZ map_policyr"r<ZterulesZruletyperZallowZ rule_weightrr itertoolsproductr9expandr:rrulesappendr0r#r$debugr%rJrK)r*ruleZrweightZwweightr@r6edger+r+r,rI.s2          zInfoFlowAnalysis._build_graphc sjrjdjdjjdjjdjdufddj D}j | _ jdkrg}j D],\}}tj ||}|jjkr||qj |jdurg}j D]\}}tj ||}g}|jD]$}|jfijs||qg}|D]&}||vr>|j|||q>|js||qj |d_jd jd tj tj dS) Nz%Building information flow subgraph...zExcluding {0!r}zMin weight {0}z(Exclude disabled conditional policy: {0}csg|]}|jvr|qSr+)r)r5nr/r+r,r7\r8z4InfoFlowAnalysis._build_subgraph..r Fz-Completed building information flow subgraph.z'Subgraph stats: nodes: {0}, edges: {1}.)r#rIr"r<rWr=rrrr&nodesZsubgraphr'r(Zedgesrr0rVZremove_edges_fromrUZenabledremover$r%rJrK) r*r[Z delete_listr@r6rYZ rule_listrXZ deleted_rulesr+r/r,r;QsN                z InfoFlowAnalysis._build_subgraph)r NN)rA)T)r! __module__ __qualname____doc__rr__annotations__intrrrrrstrrboolr-propertyrsetterrr InfoFlowPathr?rDrErHrLr>rIr;r+r+r+r,rsF   $"" ) # ' #c@sFeZdZdZedZedZd eee ddddZ d d Z d d Z dS)raR A graph edge. Also used for returning information flow steps. Parameters: graph The NetworkX graph. source The source type of the edge. target The target type of the edge. Keyword Parameters: create (T/F) create the edge if it does not exist. The default is False. rUZcapacityFN)r9r:rOrcCsP||_||_||_|j||sL|rD|jj||ddd|_d|_ntddS)Nr )r0z$InfoFlowStep does not exist in graph)r&r9r:Zhas_edgeZadd_edgerUr0r2)r*Zgraphr9r:rOr+r+r,r-szInfoFlowStep.__init__cs4t|tr&fddt|dDS|SdS)Ncsg|]}|qSr+)_index_to_item)r5ir/r+r,r7r8z,InfoFlowStep.__getitem__..rA) isinstanceslicerMindicesrg)r*keyr+r/r, __getitem__s zInfoFlowStep.__getitem__cCs.|dkr|jS|dkr|jStd|dS)z'Return source or target based on index.rr z,Invalid index (edges only have 2 items): {0}N)r9r: IndexErrorr=)r*indexr+r+r,rgs zInfoFlowStep._index_to_item)F) r!r]r^r_rrUr r0rrcr-rmrgr+r+r+r,rs   )#rRr contextlibrtypingrrrrrrZnetworkxr%Znetworkx.exceptionr r r ImportErrorr r!rWZ descriptorsr rZpermmaprZ policyreprrrr__all__rfrrr+r+r+r,s"    r