def add_adresse(self, value): """ Ajoute une Adresse au reseau. Si ce n'est pas un objet Adresse, il faut le creer Si la nouvelle adresse existe deja :param value : list, Adresse, IPAddress, IPInterface, str :return: None """ if not value: return if isinstance(value, list): for val in value: self.add_adresse(val) return if isinstance(value, Adresse): new_addr = value else: try: new_addr = Adresse(adresse=value) except SyntaxError: tools.error("add_adresse : Echec de l'ajout {}".format(value)) return if new_addr not in self: self._adresses.append(new_addr)
def add_nic(self, new_nic): """ Ajoute une interface reseau. Controle si l'interface n'est pas deja dans la liste des interface de cette machine. Controle de la collision d'adresse IP. Deux interfaces reseau ne doivent pas avoir la meme adresse :param new_nic: Nic, la nouvelle interface :return: Bool, True si l'interface a ete ajoutee. (utilise par PCAdmin) """ if not isinstance(new_nic, Nic): tools.error( "add_nic: Impossible d'ajouter {} aux interfaces de {}".format( new_nic, self.label)) return False if new_nic in self.nics: tools.debug("add_nic: '{}' deja presente sur '{}'".format( new_nic, self.label)) return False for new_ip in new_nic.ls_online_ip(): if new_ip in self.ls_online_ip(): tools.debug( "add_nic: {} deja utilise par une autre interface".format( new_ip)) return False self.nics.append(new_nic) return True
def get_public_ip(ip): """ Recupere l'adresse IP public de l'hote en utilisant la requete du moteur de recherche duckduckgo On recherche dans la page web le texte : Your IP address is ([0-9]{1,3}\.){3}[0-9]{1,3} in <a href=.*>.*</a> :param ip: str, adresse IP :return str, str, Public IP et localisation """ query = "https://duckduckgo.com/?q=whats++my+ip&t=canonical&ia=answer" try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.bind((ip, 65432)) context = ssl.create_default_context() context.wrap_socket(sock, server_hostname="duckduckgo.com") r = urllib.request.urlopen(query, context=context) page = r.read().decode() regex = re.compile( r"Your IP address is (?P<myip>(\d{1,3}\.){3}\d{1,3}) in <a (.)*>(?P<geoloc>(.)+)</a>" ) match = re.search(regex, page) if match: return match.group('myip'), match.group('geoloc') except OSError: tools.debug("Get public ip: OS erreur") except ssl.CertificateError: tools.error("Get public ip: Erreur de certificat") return None, None
def find_neigh(netw): """ Trouver les couples MAC/IP des voisins :param netw: String, netaddr avec son masque 192.168.0.0/24 :return une liste de tuples (IP, MAC) """ if isinstance(netw, ipaddress.IPv4Interface): netw = netw.with_prefixlen elif isinstance(netw, ipaddress.IPv4Network): netw = netw.with_prefixlen elif isinstance(netw, str): try: ipaddress.ip_interface(netw) except ValueError: tools.error( "Fonction find_neigh : '{}' Adresse invalide".format(netw)) return None else: return NotImplemented try: reponse, perdu = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=netw), timeout=5) return [(p[1].psrc, p[1].hwsrc) for p in reponse] except PermissionError: tools.error("Fonction find_neigh : Operation non permise") return None
def etat(self, value): """ Setter de l'etat d'utilisation de l'adresse IP True si elle est utilisee False si elle ne l'est pas :param value: bool, :return: None """ if isinstance(value, bool): self._etat = value else: tools.error("Adresse etat: Invalide, bool attendu") self._etat = False
def import_machine(data): """ Importation d'une machine a partir des information JSON :param data: les donnees de la machine :return: Machine """ try: machine = Machine(label=data['label'], nic=import_nics(data=data['nics']), desc=data['desc']) return machine except KeyError: tools.error('Importation, machine KeyError') exit(1)
def machine_from_nic(self, nic): """ Retourne une machine dans une reseau qui possede une interface nic :param nic: Nic, l'interface reseau :return: Machine, la machine si elle est dans le reseau """ if not isinstance(nic, Nic): tools.error("machine_form_nic : Interface reseau invalide") return None for machine in self.machines: if machine.nic_from_mac(nic.mac): return machine return None
def l_port(self, value): """ Setter des ports en ecoutes :param value: list, [0] : Port TCP, [1] Ports UDP :return: None """ self._l_port = {SOCK_STREAM: [], SOCK_DGRAM: []} if not value: return if isinstance(value, list) and (len(value) == 2): self.add_port(SOCK_STREAM, value[0]) self.add_port(SOCK_DGRAM, value[1]) else: tools.error("Setter Adresse l_ports : {} Invalide".format(value))
def import_adresses(data): """ Importation d'une adresse a partir d'informations json :param data: dict, donnees d'adresses :return: list, Adresse """ try: adrs = [] for entry in data: adresse = Adresse(adresse=entry['adresse'], etat=entry['etat'], l_port=[entry['port']['TCP'], entry['port']['UDP']]) adrs.append(adresse) return adrs except KeyError: tools.error('Importation, adresse KeyError') exit(1)
def import_nics(data): """ Importation d'une interface nic :param data: dict, les donnees des interfaces :return: list, Nic """ try: nics = [] for entry in data: nic = Nic(mac=entry['mac'], nom=entry['nom'], adresse=import_adresses(entry['adresses']), etat=entry['etat']) nics.append(nic) return nics except KeyError: tools.error('Importation, nics KeyError') exit(1)
def import_pcadmin(data): """ Importation d'une machine PcAdmin a partir des informations au format json. L'objet PcAdmin recupere plusieurs type de donnees automatiquement a la creation. On ecrase les donnees initiales. :param data: dict, les donnees du pcadmin :return: PcAdmin """ try: pca = PcAdmin() pca._label = data['label'] pca._nics = import_nics(data=data['nics']) pca._desc = data['desc'] pca._rzo = {'L2': [], 'L3': []} return pca except KeyError: tools.error('Importation, pcadmin KeyError') exit(1)
def import_json(file): """ Importation des donnees a partir d'un fichier json 1. Ouverture du fichier 2. Recuperation des donnees Json, controle des deux labels 3. Separation des donnees, machines et reseaux 4. Importation des machines, point particulier pour le PcAdmin 5. Importation des donnees reseaux :param file: str, le chemin vers le fichier json avec les donnees :return: PcAdmin """ try: with open(file, 'r') as f: data = f.read() if not data: tools.info("Aucunes donnees dans {}".format_map(file)) exit(0) except FileNotFoundError: tools.error("Importation: {} non trouve".format(file)) exit(1) except PermissionError: tools.error("Importation: {} lecture non autorisee".format(file)) exit(1) data = json.loads(data) if ('machines' not in data) or ('reseaux' not in data): tools.error("Importation: format de donnees invalide") exit(1) json_machines = data['machines'] json_reseau = data['reseaux'] d_machine = dict() # Importation des machines pca = None for key, data_machine in json_machines.items(): if 'rzo' in data_machine: pca = import_pcadmin(data_machine) d_machine[key] = pca else: machine = import_machine(data_machine) d_machine[key] = machine if not pca: tools.error("Importation: creation du PcAdmin non realisee") exit(1) for key, data_rzo in json_reseau.items(): import_rzo(data=data_rzo, pca=pca, d_machine=d_machine) return pca
def add_port(self, t_sock, valeur): """ Ajoute un ou plusieurs port dans la bonne liste :param t_sock: int, SOCK_STREAM or SOCK_DGRAM :param valeur: int ou list :return: None """ if t_sock not in [SOCK_STREAM, SOCK_DGRAM]: tools.error("Adresse add_l_port : {} type invalide".format(t_sock)) return lp = self.l_port[t_sock] if isinstance(valeur, list): for val in valeur: self.add_port(t_sock, val) elif isinstance(valeur, int): if valeur not in lp: lp.append(valeur) lp.sort() else: tools.error("Adresse add_l_port : {} port invalide".format(valeur)) return