#!/usr/bin/python3
#   Filename: subhunter.py
#   Module: SubHunter
#   Author: Andreas Georgiou (@superhedgy)

# Standard Libraries
import time
import colorama
import ipaddress
# External Libraries
import requests
from colorama import Fore, Style
from validator_collection import checkers

from modules import subbrute
from subprocess import STDOUT, check_output

class TargetIP:
    def __init__(self, addr):
        self.address = addr
        self.hostname = []
        self.ports = []
        self.asn = ""
        self.asn_name = ""
        self.server = ""
        self.vulns = []
        self.cidr = ""
        self.location = ""
        self.country = ""

def cprint(type, msg, reset):
    colorama.init()
    message = {
        "action": Fore.YELLOW,
        "positive": Fore.GREEN + Style.BRIGHT,
        "info": Fore.YELLOW,
        "reset": Style.RESET_ALL,
        "red": Fore.RED,
        "white": Fore.WHITE,
        "green": Fore.GREEN,
        "yellow": Fore.YELLOW
    }
    style = message.get(type.lower())

    if type == "error":
        print("{0}\n[*] Error: {1}".format(Fore.RED + Style.BRIGHT, Style.RESET_ALL + Fore.WHITE + msg))
    else:
        print(style + msg, end="")
    if (reset == 1):
        print(Style.RESET_ALL)


def passive_query(hostx, key):
    par = {'apikey': key, 'domain': hostx.primary_domain}
    try:
        response = requests.get("https://www.virustotal.com/vtapi/v2/domain/report", params=par, timeout=4)
        tv_api = response.json()

        try:
            for sibling in tv_api["domain_siblings"]:
                if (sibling in hostx.subdomains) or (sibling == ""):
                    pass
                else:
                    hostx.subdomains.append(sibling)
        except:
            pass

        try:
            for subdomain in tv_api["subdomains"]:
                if (subdomain in hostx.subdomains) or (subdomain == ""):
                    pass
                else:
                    hostx.subdomains.append(subdomain)
        except:
            pass
    except:
        cprint("error", "[*] Error: connecting with VirusTotal API", 1)


def active(mswitch, hostx, wordlist, subwordlist, recursive=False):
    results=subbrute.run(hostx.primary_domain, subdomains=wordlist)
    for d in results:
        if mswitch.debug is True:
            current_time = time.strftime("%H:%M:%S", time.localtime())
            print("[DEBUG]["+str(current_time)+"][Item Discovered]: ",d)
        added_ips = []
        if (d[0] in hostx.subdomains) or (d[0] is hostx.primary_domain) or ("REFUSED" in d[1]) or ("NOERROR" in d[1]) or ("NXDOMAIN" in d[1]) or ("HINFO" in d[1]):
            pass
        else:
            # Verbose Mode
            if mswitch.verbose is True:
                print(d[0] + "," + d[1] + "," + d[2])
            hostx.subdomains.append(d[0])
            if d[1] is "A" or d[1] is "MX":
                if checkers.is_ipv4(d[2]) and (ipaddress.ip_address(d[2]) is False):
                    tmp = TargetIP(d[2])
                    tmp.hostname.append(d[0])
                    if not d[2] in added_ips:
                        hostx.resolved_ips.append(tmp)
                        cprint("white", "	|", 1)
                        cprint("white", "  [{0}]".format(d[2]), 1)
                        if mswitch.verbose is True:
                            cprint("info", "[i] Adding target IPv4:" + d[2], 1)
    return True

    if recursive is True:
        for sub in hostx.subdomains:
            cprint("info", "[i] Enumerating: xxx." + sub, 1)
            for item in subbrute.run(sub, query_type="A", subdomains=subwordlist, process_count=60):
                if item[0] in hostx.subdomains or ("REFUSED" in item[1]) or ("NOERROR" in item[1]) or ("NXDOMAIN" in d[1]) or ("HINFO" in item[1]):
                    pass
                else:
                    # Verbose Mode
                    if mswitch.verbose is True:
                        print(item[0] + "," + item[1] + "," + item[2])
                    hostx.subdomains.append(item[0])
                    # print (d[0]) # [Debug] Prints succesfully resolved domain
