|
@@ -0,0 +1,178 @@
|
|
|
|
|
+import subprocess
|
|
|
|
|
+import sys
|
|
|
|
|
+import importlib
|
|
|
|
|
+import base64
|
|
|
|
|
+import json
|
|
|
|
|
+
|
|
|
|
|
+def check_and_install_dependencies():
|
|
|
|
|
+ """
|
|
|
|
|
+ Checks if required libraries are installed. If not, installs them automatically.
|
|
|
|
|
+ """
|
|
|
|
|
+ dependencies = [
|
|
|
|
|
+ ("requests", "requests"),
|
|
|
|
|
+ ("urllib3", "urllib3"),
|
|
|
|
|
+ ("questionary", "questionary"),
|
|
|
|
|
+ ("rich", "rich")
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ missing_packages = []
|
|
|
|
|
+
|
|
|
|
|
+ for import_name, pip_name in dependencies:
|
|
|
|
|
+ try:
|
|
|
|
|
+ importlib.import_module(import_name)
|
|
|
|
|
+ except ImportError:
|
|
|
|
|
+ missing_packages.append(pip_name)
|
|
|
|
|
+
|
|
|
|
|
+ if missing_packages:
|
|
|
|
|
+ print(f"Missing dependencies detected: {', '.join(missing_packages)}")
|
|
|
|
|
+ print("Attempting to install automatically...")
|
|
|
|
|
+ try:
|
|
|
|
|
+ # subprocess.check_call([sys.executable, "-m", "pip", "install"] + missing_packages)
|
|
|
|
|
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "--user"] + missing_packages)
|
|
|
|
|
+ print("\nDependencies installed successfully.\n")
|
|
|
|
|
+ except subprocess.CalledProcessError as e:
|
|
|
|
|
+ print(f"\n[ERROR] Failed to install dependencies automatically: {e}")
|
|
|
|
|
+ print("Please install them manually using: pip install " + " ".join(missing_packages))
|
|
|
|
|
+ sys.exit(1)
|
|
|
|
|
+
|
|
|
|
|
+# Run the dependency check before importing the rest
|
|
|
|
|
+check_and_install_dependencies()
|
|
|
|
|
+
|
|
|
|
|
+# --- Imports (Safe to run now) ---
|
|
|
|
|
+import requests
|
|
|
|
|
+import urllib3
|
|
|
|
|
+import questionary
|
|
|
|
|
+from questionary import Separator
|
|
|
|
|
+from rich.console import Console
|
|
|
|
|
+from rich.panel import Panel
|
|
|
|
|
+
|
|
|
|
|
+# Disable the "InsecureRequestWarning"
|
|
|
|
|
+urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
|
|
|
+
|
|
|
|
|
+# Configuration
|
|
|
|
|
+URL = "https://starwars.citrite.net/las_update/api"
|
|
|
|
|
+
|
|
|
|
|
+# --- Security Configuration ---
|
|
|
|
|
+VALID_UNLOCK_KEY_B64 = "dW5sb2NrbmV0c2NhbGVy"
|
|
|
|
|
+
|
|
|
|
|
+def print_banner():
|
|
|
|
|
+ """Prints a nice banner for the TUI."""
|
|
|
|
|
+ console = Console()
|
|
|
|
|
+ banner_text = (
|
|
|
|
|
+ "[bold cyan]NS-VPX LAS Activator[/bold cyan]\n"
|
|
|
|
|
+ "[dim]Build By Parv Ashwani[/dim]"
|
|
|
|
|
+ )
|
|
|
|
|
+ console.print(Panel(banner_text, expand=False, border_style="green"))
|
|
|
|
|
+
|
|
|
|
|
+def main():
|
|
|
|
|
+ print_banner()
|
|
|
|
|
+ console = Console()
|
|
|
|
|
+
|
|
|
|
|
+ # 1. Collect User Input via TUI
|
|
|
|
|
+
|
|
|
|
|
+ device_ip = questionary.text(
|
|
|
|
|
+ "Enter Device IP / Hostname:",
|
|
|
|
|
+ validate=lambda text: True if text else "Please enter a valid IP or hostname."
|
|
|
|
|
+ ).ask()
|
|
|
|
|
+
|
|
|
|
|
+ username = questionary.text(
|
|
|
|
|
+ "Enter Username:",
|
|
|
|
|
+ validate=lambda text: True if text else "Username cannot be empty."
|
|
|
|
|
+ ).ask()
|
|
|
|
|
+
|
|
|
|
|
+ password = questionary.password(
|
|
|
|
|
+ "Enter Password:"
|
|
|
|
|
+ ).ask()
|
|
|
|
|
+
|
|
|
|
|
+ # Selection for request_ed (Edition)
|
|
|
|
|
+ request_ed = questionary.select(
|
|
|
|
|
+ "Select Request Edition (request_ed):",
|
|
|
|
|
+ choices=[
|
|
|
|
|
+ "Standard",
|
|
|
|
|
+ "Advance",
|
|
|
|
|
+ "Premium"
|
|
|
|
|
+ ]
|
|
|
|
|
+ ).ask()
|
|
|
|
|
+
|
|
|
|
|
+ # Selection for request_pem (License Server)
|
|
|
|
|
+ request_pem = questionary.select(
|
|
|
|
|
+ "Select License Server (request_pem):",
|
|
|
|
|
+ choices=[
|
|
|
|
|
+ "CNS_V10_SERVER",
|
|
|
|
|
+ "CNS_V25_SERVER",
|
|
|
|
|
+ "CNS_V200_SERVER",
|
|
|
|
|
+ "CNS_V1000_SERVER",
|
|
|
|
|
+ "CNS_V3000_SERVER",
|
|
|
|
|
+ "CNS_V5000_SERVER",
|
|
|
|
|
+ "CNS_V10000_SERVER",
|
|
|
|
|
+ "CNS_V25000_SERVER"
|
|
|
|
|
+ ]
|
|
|
|
|
+ ).ask()
|
|
|
|
|
+
|
|
|
|
|
+ # 2. Security Check for High Capacity Licenses
|
|
|
|
|
+ # Restricted list: Anything strictly greater than CNS_V1000_SERVER
|
|
|
|
|
+ restricted_servers = [
|
|
|
|
|
+ "CNS_V3000_SERVER",
|
|
|
|
|
+ "CNS_V5000_SERVER",
|
|
|
|
|
+ "CNS_V10000_SERVER",
|
|
|
|
|
+ "CNS_V25000_SERVER"
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ if request_pem in restricted_servers:
|
|
|
|
|
+ console.print("\n[bold yellow]High Capacity License Selected.[/bold yellow]")
|
|
|
|
|
+ console.print("[yellow]Authorization required to proceed.[/yellow]")
|
|
|
|
|
+
|
|
|
|
|
+ unlock_input = questionary.password("Enter Unlock Password:").ask()
|
|
|
|
|
+
|
|
|
|
|
+ # Decode the Base64 key from the code and compare
|
|
|
|
|
+ try:
|
|
|
|
|
+ decoded_key = base64.b64decode(VALID_UNLOCK_KEY_B64).decode("utf-8")
|
|
|
|
|
+ if unlock_input != decoded_key:
|
|
|
|
|
+ console.print("[bold red]Incorrect Unlock Password. Exiting.[/bold red]")
|
|
|
|
|
+ sys.exit(1)
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+ console.print("[bold red]Security check failed. Exiting.[/bold red]")
|
|
|
|
|
+ sys.exit(1)
|
|
|
|
|
+
|
|
|
|
|
+ console.print("[green]Unlock successful. Proceeding...[/green]")
|
|
|
|
|
+
|
|
|
|
|
+ # 3. Construct the Payload
|
|
|
|
|
+ payload = {
|
|
|
|
|
+ "product": "NS-VPX",
|
|
|
|
|
+ "deviceip": device_ip,
|
|
|
|
|
+ "username": username,
|
|
|
|
|
+ "password": password,
|
|
|
|
|
+ "request_pem": request_pem,
|
|
|
|
|
+ "request_ed": request_ed
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.print("\n[yellow]Sending request...[/yellow]")
|
|
|
|
|
+
|
|
|
|
|
+ # 4. Send the Request
|
|
|
|
|
+ try:
|
|
|
|
|
+ response = requests.post(
|
|
|
|
|
+ URL,
|
|
|
|
|
+ data=payload,
|
|
|
|
|
+ verify=False,
|
|
|
|
|
+ timeout=30
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ # 5. Output the Response
|
|
|
|
|
+ console.print(f"[bold green]Status Code:[/bold green] {response.status_code}")
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ json_resp = response.json()
|
|
|
|
|
+ console.print("[bold blue]Response Body:[/bold blue]")
|
|
|
|
|
+ console.print(json.dumps(json_resp, indent=4))
|
|
|
|
|
+ except ValueError:
|
|
|
|
|
+ console.print("[bold blue]Response Body:[/bold blue]")
|
|
|
|
|
+ console.print(response.text)
|
|
|
|
|
+
|
|
|
|
|
+ except requests.exceptions.RequestException as e:
|
|
|
|
|
+ console.print(f"\n[bold red]An error occurred:[/bold red] {e}")
|
|
|
|
|
+
|
|
|
|
|
+if __name__ == "__main__":
|
|
|
|
|
+ try:
|
|
|
|
|
+ main()
|
|
|
|
|
+ except KeyboardInterrupt:
|
|
|
|
|
+ print("\nExiting...")
|