/ tor_api_setup.py
tor_api_setup.py
  1  import sys
  2  import os
  3  import subprocess
  4  import requests
  5  import socket
  6  import time
  7  from PyQt6.QtCore import QThread, pyqtSignal
  8  
  9  class TORAPISetup(QThread):
 10      """Thread to handle API setup through TOR"""
 11      output_signal = pyqtSignal(str)
 12      finished_signal = pyqtSignal(bool)
 13      
 14      def __init__(self, tor_port=9050, control_port=9051, tor_password=None):
 15          super().__init__()
 16          self.tor_port = tor_port
 17          self.control_port = control_port
 18          self.tor_password = tor_password
 19          self.process = None
 20      
 21      def enable_tor(self):
 22          """Enable and test TOR connection"""
 23          try:
 24              session = requests.Session()
 25              session.proxies = {
 26                  'http': f'socks5h://127.0.0.1:{self.tor_port}',
 27                  'https': f'socks5h://127.0.0.1:{self.tor_port}'
 28              }
 29              
 30              response = session.get('http://httpbin.org/ip', timeout=30)
 31              if response.status_code == 200:
 32                  self.output_signal.emit(f"🔒 TOR connected - IP: {response.json()['origin']}")
 33                  return True
 34          except Exception as e:
 35              self.output_signal.emit(f"❌ TOR connection failed: {e}")
 36              return False
 37  
 38      def renew_tor_ip(self):
 39          """Get fresh TOR IP with configurable authentication"""
 40          try:
 41              # Use socket-based authentication to match tor_spoofing.py
 42              sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 43              sock.settimeout(10)
 44              sock.connect(('127.0.0.1', self.control_port))
 45              
 46              # Authenticate with password if provided
 47              if self.tor_password:
 48                  auth_cmd = f'AUTHENTICATE "{self.tor_password}"\r\n'
 49                  sock.send(auth_cmd.encode())
 50                  response = sock.recv(1024).decode()
 51                  
 52                  if '250 OK' in response:
 53                      self.output_signal.emit("🔐 Authenticated with password")
 54                  else:
 55                      # Try without password
 56                      auth_cmd = 'AUTHENTICATE\r\n'
 57                      sock.send(auth_cmd.encode())
 58                      response = sock.recv(1024).decode()
 59              else:
 60                  # Try without password
 61                  auth_cmd = 'AUTHENTICATE\r\n'
 62                  sock.send(auth_cmd.encode())
 63                  response = sock.recv(1024).decode()
 64              
 65              if '250 OK' not in response:
 66                  self.output_signal.emit(f"❌ Authentication failed: {response}")
 67                  sock.close()
 68                  return False
 69              
 70              # Send NEWNYM signal
 71              sock.send(b'SIGNAL NEWNYM\r\n')
 72              response = sock.recv(1024).decode()
 73              
 74              if '250 OK' not in response:
 75                  self.output_signal.emit(f"❌ NEWNYM failed: {response}")
 76                  sock.close()
 77                  return False
 78              
 79              self.output_signal.emit("🔄 Renewed TOR circuit - New IP address")
 80              sock.send(b'QUIT\r\n')
 81              sock.close()
 82              
 83              # Wait for circuit to establish
 84              time.sleep(3)
 85              return True
 86                  
 87          except Exception as e:
 88              self.output_signal.emit(f"❌ TOR renewal failed: {e}")
 89              return True  # Don't fail the setup, continue with current IP
 90      
 91      def run(self):
 92          """Execute API setup through TOR"""
 93          self.output_signal.emit("🚀 Starting API setup through TOR...")
 94          
 95          # Enable TOR
 96          if not self.enable_tor():
 97              self.finished_signal.emit(False)
 98              return
 99          
100          # Renew to get fresh IP for registration
101          self.renew_tor_ip()
102          
103          # Set up environment for TOR
104          env = os.environ.copy()
105          env['ALL_PROXY'] = f'socks5h://127.0.0.1:{self.tor_port}'
106          env['HTTP_PROXY'] = f'socks5h://127.0.0.1:{self.tor_port}'
107          env['HTTPS_PROXY'] = f'socks5h://127.0.0.1:{self.tor_port}'
108          
109          try:
110              # Run blackbird setup through TOR
111              self.process = subprocess.Popen(
112                  ['python', 'blackbird.py', '--setup-ai'],
113                  stdout=subprocess.PIPE,
114                  stderr=subprocess.STDOUT,
115                  stdin=subprocess.PIPE,
116                  text=True,
117                  env=env,
118                  bufsize=1
119              )
120              
121              # Handle the interactive prompt
122              confirmation_sent = False
123              for line in self.process.stdout:
124                  text = line.strip()
125                  self.output_signal.emit(text)
126                  
127                  # Auto-confirm the IP registration prompt
128                  if not confirmation_sent and ('ip is registered' in text.lower() or '[y/n]' in text.lower()):
129                      try:
130                          self.process.stdin.write('Y\n')
131                          self.process.stdin.flush()
132                          confirmation_sent = True
133                          self.output_signal.emit("✅ Automatically confirmed IP registration through TOR")
134                      except Exception as e:
135                          self.output_signal.emit(f"❌ Confirmation failed: {e}")
136              
137              self.process.stdout.close()
138              self.process.wait()
139              self.finished_signal.emit(True)
140              
141          except Exception as e:
142              self.output_signal.emit(f"❌ Setup failed: {e}")
143              self.finished_signal.emit(False)
144      
145      def stop(self):
146          """Stop the setup process"""
147          if self.process:
148              self.process.terminate()
149              self.process.wait()