#!/usr/bin/env python3
"""ScannerSend Network Plugin v1.1

Optional plugin for CryptoAnnihilator that reports detected miner wallet
addresses to the ScannerSend Network (net.scannersend.org).

CONSENT MODEL:
  Tier 1 (plugin installed): Reports wallet anonymously. No tracking.
  Tier 2 (--network-track):  Enables contributor tracking. Your reports
    get a contributor hash. You can check your history and see if your
    reported wallets got confirmed/burnt. Still no PII.

What gets reported (Tier 1 - default):
  - Wallet address and coin type
  - Pool host and port
  - Process name
  - Detection layer number
  - Timestamp

What is NEVER reported:
  - Your IP (discarded server-side in Tier 1)
  - Your hostname, system info, kernel, RAM
  - Usernames, file paths, cmdlines

Additional in Tier 2 (--network-track):
  - Contributor hash (SHA256 of your IP + salt - not reversible)
  - Receipt ID returned per report
  - You can query: GET /receipt/<id> to check status
  - You can query: GET /contributions/<hash> for your history

Disable: Remove this file, or run crypto_annihilator with --no-network
License: MIT
By: Rav-n-Vic
"""

__version__ = "1.1.0"
__author__ = "Rav-n-Vic"
__license__ = "MIT"

import json
import hashlib
import re
import urllib.request
import urllib.error
from datetime import datetime, timezone

NETWORK_API = "https://net.scannersend.org"
REPORT_SALT = "scannersend_v1_2026"
TIMEOUT = 10
VERSION = 1

# Tier 2: contribution tracking (set by main tool via enable_tracking())
_tracking_enabled = False


def enable_tracking():
    """Enable Tier 2 contribution tracking. Called by main tool with --network-track."""
    global _tracking_enabled
    _tracking_enabled = True


def _get_nonce():
    """Request a single-use nonce from the server."""
    try:
        url = NETWORK_API + "/nonce"
        req = urllib.request.Request(url, method="GET")
        req.add_header("User-Agent", "ScannerSend-Network/" + __version__)
        with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            return data.get("nonce")
    except Exception:
        return None


def _sign_payload(payload_dict, nonce):
    """Create SHA256 signature for the payload."""
    canonical = json.dumps(payload_dict, sort_keys=True, separators=(",", ":"))
    message = canonical + nonce + REPORT_SALT
    return hashlib.sha256(message.encode("utf-8")).hexdigest()


def _submit_report(payload):
    """Submit the signed forensic packet to the server.

    Returns dict with receipt info if accepted, None otherwise."""
    try:
        url = NETWORK_API + "/report"
        body = json.dumps(payload).encode("utf-8")
        req = urllib.request.Request(url, data=body, method="POST")
        req.add_header("Content-Type", "application/json")
        req.add_header("User-Agent", "ScannerSend-Network/" + __version__)
        # Tier 2: tell server to track contributions
        if _tracking_enabled:
            req.add_header("X-Track-Contributions", "1")
        with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            if result.get("status") == "accepted":
                return result
            return None
    except Exception:
        return None


def check_receipt(receipt_id):
    """Check the status of a previously submitted report."""
    try:
        url = NETWORK_API + "/receipt/" + str(receipt_id)
        req = urllib.request.Request(url, method="GET")
        req.add_header("User-Agent", "ScannerSend-Network/" + __version__)
        with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except Exception:
        return None


def report(wallet, wallet_type, pool_host="", pool_port=0, process_name="",
           detection_layer=0):
    """Report a detected miner wallet to the ScannerSend Network.

    Returns dict with receipt info if accepted (Tier 2), True if accepted
    (Tier 1), False otherwise."""
    wallet = str(wallet)[:200]
    wallet_type = str(wallet_type)[:10]
    pool_host = str(pool_host)[:128]
    pool_port = max(0, min(65535, int(pool_port) if isinstance(pool_port, (int, float)) else 0))
    process_name = re.sub(r"[^a-zA-Z0-9_.\-]", "", str(process_name)[:64])
    detection_layer = max(1, min(5, int(detection_layer) if isinstance(detection_layer, (int, float)) else 1))

    nonce = _get_nonce()
    if not nonce:
        return False

    payload = {
        "version": VERSION,
        "nonce": nonce,
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "wallet": wallet,
        "wallet_type": wallet_type,
        "pool_host": pool_host,
        "pool_port": pool_port,
        "process_name": process_name,
        "detection_layer": detection_layer,
    }

    signature = _sign_payload(payload, nonce)
    payload["hmac"] = signature

    result = _submit_report(payload)
    if result is None:
        return False

    if _tracking_enabled and "receipt" in result:
        return result  # Return full dict with receipt for Tier 2
    return True  # Simple True for Tier 1


if __name__ == "__main__":
    import sys
    print("ScannerSend Network Plugin v" + __version__)
    print("API: " + NETWORK_API)
    print()
    print("Consent Model:")
    print("  Tier 1 (default): Anonymous wallet reporting")
    print("  Tier 2 (--network-track): Contribution tracking with receipts")
    print()
    print("Testing connection...")
    nonce = _get_nonce()
    if nonce:
        print("  Server reachable (nonce: " + nonce[:8] + "...)")
    else:
        print("  Server unreachable (net.scannersend.org not responding)")
    print()
    # Check receipt if provided
    if len(sys.argv) > 1 and sys.argv[1] == "--check":
        if len(sys.argv) > 2:
            receipt = check_receipt(sys.argv[2])
            if receipt:
                print("Receipt status:")
                for k, v in receipt.items():
                    print("  " + str(k) + ": " + str(v))
            else:
                print("Receipt not found or server error")
        else:
            print("Usage: python3 scannersend_network.py --check <receipt_id>")
    else:
        print("This plugin is loaded automatically by crypto_annihilator.py")
        print("when placed in the same directory (/usr/local/bin/).")
