#!/usr/bin/env python3
# For authorized penetration testing and educational environments only.
# Usage against targets without prior mutual consent is illegal.
# It is the end user's responsibility to obey all applicable local, state and federal laws.
"""Agent for performing open source intelligence (OSINT) gathering."""

import json
import argparse
import re

try:
    import requests
except ImportError:
    requests = None

try:
    import dns.resolver
    HAS_DNS = True
except ImportError:
    HAS_DNS = False


def whois_lookup(domain):
    """Perform WHOIS lookup for domain registration info."""
    try:
        import whois
        w = whois.whois(domain)
        return {
            "domain": domain, "registrar": w.registrar,
            "creation_date": str(w.creation_date),
            "expiration_date": str(w.expiration_date),
            "name_servers": w.name_servers if isinstance(w.name_servers, list) else [w.name_servers],
            "status": w.status if isinstance(w.status, list) else [w.status],
            "registrant": w.get("org", w.get("name", "")),
        }
    except ImportError:
        return {"error": "python-whois not installed — pip install python-whois"}
    except Exception as e:
        return {"domain": domain, "error": str(e)}


def dns_enumeration(domain):
    """Enumerate DNS records for intelligence gathering."""
    if not HAS_DNS:
        return {"error": "dnspython not installed — pip install dnspython"}
    records = {}
    for rtype in ["A", "AAAA", "MX", "NS", "TXT", "SOA", "CNAME"]:
        try:
            answers = dns.resolver.resolve(domain, rtype)
            records[rtype] = [str(r) for r in answers]
        except Exception:
            pass
    subs = ["www", "mail", "ftp", "vpn", "api", "dev", "staging", "admin",
            "portal", "test", "owa", "remote", "webmail", "autodiscover", "sip"]
    found = []
    for sub in subs:
        try:
            answers = dns.resolver.resolve(f"{sub}.{domain}", "A")
            found.append({"subdomain": f"{sub}.{domain}", "ips": [str(r) for r in answers]})
        except Exception:
            pass
    return {"domain": domain, "records": records, "subdomains": found}


def email_harvest(domain):
    """Search for email addresses associated with a domain."""
    if not requests:
        return {"error": "requests not installed"}
    emails = set()
    try:
        resp = requests.get(f"https://api.hunter.io/v2/domain-search?domain={domain}&api_key=demo", timeout=15)
        if resp.status_code == 200:
            data = resp.json()
            for email in data.get("data", {}).get("emails", []):
                emails.add(email.get("value", ""))
    except Exception:
        pass
    pattern = re.compile(rf"[a-zA-Z0-9._%+-]+@{re.escape(domain)}", re.I)
    search_urls = [f"https://www.google.com/search?q=%22%40{domain}%22&num=20"]
    return {
        "domain": domain,
        "emails_found": list(emails)[:20],
        "email_count": len(emails),
        "search_pattern": f"*@{domain}",
    }


def technology_fingerprint(url):
    """Fingerprint web technologies from HTTP response headers."""
    if not requests:
        return {"error": "requests not installed"}
    try:
        resp = requests.get(url, timeout=10, allow_redirects=True)
        headers = dict(resp.headers)
        technologies = []
        server = headers.get("Server", "")
        if server:
            technologies.append({"category": "Web Server", "value": server})
        powered = headers.get("X-Powered-By", "")
        if powered:
            technologies.append({"category": "Framework", "value": powered})
        if "wp-content" in resp.text or "wordpress" in resp.text.lower():
            technologies.append({"category": "CMS", "value": "WordPress"})
        if "drupal" in resp.text.lower():
            technologies.append({"category": "CMS", "value": "Drupal"})
        security_headers = {}
        for h in ["Strict-Transport-Security", "Content-Security-Policy", "X-Frame-Options",
                   "X-Content-Type-Options", "X-XSS-Protection", "Referrer-Policy"]:
            security_headers[h] = headers.get(h, "MISSING")
        return {
            "url": url, "status": resp.status_code,
            "technologies": technologies,
            "security_headers": security_headers,
            "cookies": [{"name": c.name, "secure": c.secure, "httponly": "HttpOnly" in str(c._rest)}
                        for c in resp.cookies][:10],
        }
    except Exception as e:
        return {"url": url, "error": str(e)}


def social_media_search(target_name):
    """Generate social media profile URLs for a target name."""
    username = target_name.lower().replace(" ", "")
    platforms = {
        "linkedin": f"https://www.linkedin.com/in/{username}",
        "twitter": f"https://twitter.com/{username}",
        "github": f"https://github.com/{username}",
        "facebook": f"https://www.facebook.com/{username}",
        "instagram": f"https://www.instagram.com/{username}",
    }
    results = []
    for platform, url in platforms.items():
        if requests:
            try:
                resp = requests.head(url, timeout=5, allow_redirects=True)
                exists = resp.status_code == 200
                results.append({"platform": platform, "url": url, "exists": exists})
            except Exception:
                results.append({"platform": platform, "url": url, "exists": "unknown"})
        else:
            results.append({"platform": platform, "url": url, "exists": "unchecked"})
    return {"target": target_name, "profiles": results}


def main():
    parser = argparse.ArgumentParser(description="OSINT Gathering Agent")
    sub = parser.add_subparsers(dest="command")
    w = sub.add_parser("whois", help="WHOIS lookup")
    w.add_argument("--domain", required=True)
    d = sub.add_parser("dns", help="DNS enumeration")
    d.add_argument("--domain", required=True)
    e = sub.add_parser("email", help="Email harvesting")
    e.add_argument("--domain", required=True)
    t = sub.add_parser("tech", help="Technology fingerprinting")
    t.add_argument("--url", required=True)
    s = sub.add_parser("social", help="Social media search")
    s.add_argument("--name", required=True)
    args = parser.parse_args()
    if args.command == "whois":
        result = whois_lookup(args.domain)
    elif args.command == "dns":
        result = dns_enumeration(args.domain)
    elif args.command == "email":
        result = email_harvest(args.domain)
    elif args.command == "tech":
        result = technology_fingerprint(args.url)
    elif args.command == "social":
        result = social_media_search(args.name)
    else:
        parser.print_help()
        return
    print(json.dumps(result, indent=2, default=str))


if __name__ == "__main__":
    main()
