\section{Méthodes} \subsection{route} La méthode "route" retourne la route (\Colorbox{light-gray}{\lstinline|Route|}), utilisée par l'équipement (\Colorbox{light-gray}{\lstinline|Device|}) pour atteindre le réseau spécifié. C'est une mise en application de ce qui est expliqué dans la section \ref{subsec:network:ip:routing}. Pour y arriver, il faut donc obtenir celles dont les adresses limites du réseau comprennent celle du réseau voulu. \vspace{3mm} \begin{lstlisting}[language=Ruby, title="app/model/routing\_table.rb"] # Params: # * network: an IPv4 network to test def route(network) ip_net = IPAddr.new network ip = ip_net.to_i candidate_routes = routes.where(:start_ip.lte => ip, :end_ip.gte => ip) choosed_route(candidate_routes) end \end{lstlisting} \vspace{3mm} Une fois les routes possibles obtenues, il faut encore isoler celle qui est la plus précise. Pour cela, il suffit de calculer le nombre d'adresses disponibles dans le réseau et de choisir celle qui en a le moins. \vspace{3mm} \begin{lstlisting}[language=Ruby, title="app/model/routing\_table.rb"] # Params: # * candidate_routes: a list of Route def choosed_route(candidate_routes) network_length = 4_294_967_296 choose_route = nil candidate_routes.each do |candidate| network = IPAddr.new candidate.network network_size = network.to_range.last.to_i - network.to_range.first.to_i if network_size < network_length network_length = network_size choose_route = candidate end end choose_route end \end{lstlisting} \vspace{3mm} \subsection{crossed?} \label{sec:methodes:crossed} La méthode "crossed?" est un élément essentiel pour l'analyse des règles de sécurité (\Colorbox{light-gray}{\lstinline|Policy|}). Elle permet de déterminer si un équipement (\Colorbox{light-gray}{\lstinline|Device|}) est traversé par un flux définit par deux réseaux. Pour cela, il faut utiliser la méthode "route" de la table de routage (\Colorbox{light-gray}{\lstinline|RoutingTable|}) de l'équipement en question et comparer l'interface de sortie des deux routes obtenues. Si elles sont différentes, cela signifique que le flux traverse ce firewall. \begin{lstlisting}[language=Ruby, title="app/model/device.rb"] # Params: # * network1: the *source* network # * network2: the *destination* network def crossed?(network1, network2) return false unless routing_table route1 = routing_table.route(network1) route2 = routing_table.route(network2) return false unless route1 && route2 route1.interface != route2.interface end \end{lstlisting} \subsection{matched\_policies} \label{sec:methodes:matched_policies} Cette méthode permet de gérer la fonctionnalité principale de l'application, soit de rechercher une règle spécifique en précisant une réseau source et distination, un protocole et un numéro de port. \begin{lstlisting}[language=Ruby, title="app/model/device.rb"] # Params: # * request: the PolicyRequest with all the required informations def matched_policies(request) policies = [] policies_found = find_policies(request) if !policies_found.empty? && request.include_all policies += policies_found elsif !policies_found.empty? policies << policies_found.first else policies << implicit_policy end policies end \end{lstlisting} Le but ici est de faire la requête de recherche et de retourner toutes les règles de sécurité obtenues ou bien uniquement la première en fonction de ce qui a été demandé dans la requête. Si aucune règle de sécurité n'est trouvée, la méthode va retourner une règle qui correspond à une règle implicite de blocage (par défaut sur firewall, ce qui n'est pas explicitement autorisé est bloqué). \begin{lstlisting}[language=Ruby, title="app/model/device.rb"] # Params: # * request: the PolicyRequest with all the required informations def find_policies(request) source = matched_addresses(request.source) source += matched_address_groups(source) destination = matched_addresses(request.destination) destination += matched_address_groups(destination) service = matched_services(request.protocol, request.port) service += matched_service_groups(service) source_interface = zone_name( routing_table.route(request.source).interface ) destination_interface = zone_name( routing_table.route(request.destination).interface ) policies.where( source_interface: source_interface, destination_interface: destination_interface ).any_in( source: source, destination: destination, service: service ) end \end{lstlisting} La requête sur la base de donnée qui permet d'obtenir les règles de sécurité voulues est définie dans la fonction ci-dessus. Pour cela, il faut commencer par isoler les adresses source et destination ainsi que les services. On cherche ici à comparer des tableaux de String entre eux et à savoir si au moins un des éléments de ce tableau se retrouvent dans l'autre tableau. La méthode utilisée pour cela est "any\_in"\cite{stackanyin} en lui précisant les paramètres.