#!/usr/bin/env python3
import nmap
import argparse

def callbackFTP(host, result):
    try:
        script = result['scan'][host]['tcp'][21]['script']
        print("Polecenie: " + result['nmap']['command_line'])
        for key, value in script.items():
            print('Skrypt {0} --> {1}'.format(key, value))
    except KeyError:
        pass

class NmapScannerAsyncFTP:
    def __init__(self):
        self.portScanner = nmap.PortScanner()
        self.portScannerAsync = nmap.PortScannerAsync()

    def scanning(self):
        while self.portScannerAsync.still_scanning():
            print("Skanowanie >>>")
            self.portScannerAsync.wait(10)

    def nmapScanAsync(self, hostname, port):
        try:
            print("Skanowanie portu " + port + " ..........")
            self.portScanner.scan(hostname, port)
            self.state = self.portScanner[hostname]['tcp'][int(port)]['state']
            print(" [+] "+ hostname + " tcp/" + port + " " + self.state)
            if (port == '21') and self.portScanner[hostname]['tcp'][int(port)]['state'] == 'open':
                print('Sprawdzanie usługi FTP za pomocą skryptów Nmap......')
                print('Skrypt ftp-anon.nse .....')
                self.portScannerAsync.scan(hostname, arguments = "-A -sV -p21 --script ftp-anon.nse", callback = callbackFTP)
                self.scanning()
                print('Skrypt ftp-bounce.nse .....')
                self.portScannerAsync.scan(hostname, arguments = "-A -sV -p21 --script ftp-bounce.nse", callback = callbackFTP)
                self.scanning()
                print('Skrypt ftp-libopie.nse .....')
                self.portScannerAsync.scan(hostname, arguments = "-A -sV -p21 --script ftp-libopie.nse", callback = callbackFTP)
                self.scanning()
                print('Skrypt ftp-proftpd-backdoor.nse .....')
                self.portScannerAsync.scan(hostname, arguments = "-A -sV -p21 --script ftp-proftpd-backdoor.nse", callback = callbackFTP)
                self.scanning()
                print('Skrypt ftp-vsftpd-backdoor.nse .....')
                self.portScannerAsync.scan(hostname, arguments = "-A -sV -p21 --script ftp-vsftpd-backdoor.nse", callback = callbackFTP)
                self.scanning()
        except Exception as exception:
            print("Błąd połączenia z hostem " + hostname, str(exception))

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description = 'Asynchroniczny skaner Nmap')
    parser.add_argument("--host", dest = "host", help = "nazwa lub adres hosta", required = True)
    parser.add_argument("--ports", dest = "ports", help = "lista portów oddzielonych przecinkami (domyślnie 21)", default = "21")
    parsed_args = parser.parse_args()
    port_list = parsed_args.ports.split(',')
    ip_address = parsed_args.host
    for port in port_list:
        NmapScannerAsyncFTP().nmapScanAsync(ip_address, port)
