class TorManager::TorProcess

Attributes

settings[RW]

Public Class Methods

new(params={}) click to toggle source
# File lib/tormanager/tor_process.rb, line 16
def initialize params={}
  @settings = {}
  @settings[:tor_port] = params.fetch(:tor_port, 9050)
  @settings[:control_port] = params.fetch(:control_port, 50500)
  @settings[:pid_dir] = params.fetch(:pid_dir, '/tmp'.freeze)
  @settings[:log_dir] = params.fetch(:log_dir, '/tmp'.freeze)
  @settings[:tor_data_dir] = params.fetch(:tor_data_dir, nil)
  @settings[:tor_new_circuit_period] = params.fetch(:tor_new_circuit_period, 60)
  @settings[:max_tor_memory_usage_mb] = params.fetch(:max_tor_memory_usage, 200)
  @settings[:max_tor_cpu_percentage] = params.fetch(:max_tor_cpu_percentage, 10)
  @settings[:eye_tor_config_template] =
      params.fetch(:eye_tor_config_template,
        File.join(File.dirname(__dir__),'tormanager/eye/tor.template.eye.rb'))
  @settings[:parent_pid] = Process.pid
  @settings[:control_password] = params.fetch(:control_password, random_password)
  @settings[:hashed_control_password] =
      tor_hash_password_from(@settings[:control_password])
  @settings[:tor_log_switch] = params.fetch(:tor_log_switch, nil)
  @settings[:eye_logging] = params.fetch(:eye_logging, nil)
  @settings[:tor_logging] = params.fetch(:tor_logging, nil)
  @settings[:dont_remove_tor_config] = params.fetch(:dont_remove_tor_config, nil)
end
stop_obsolete_processes() click to toggle source
# File lib/tormanager/tor_process.rb, line 50
def stop_obsolete_processes
  (EyeManager.list_apps || []).each do |app|
    EyeManager.stop(application: app, process: 'tor') unless
        ProcessHelper.process_pid_running? pid_of_tor_eye_process(app)
  end
end
tor_running_on?(params={}) click to toggle source
# File lib/tormanager/tor_process.rb, line 57
def tor_running_on? params={}
  is_running = false
  (EyeManager.list_apps || []).each do |app|
    if port_and_or_pid_matches_eye_tor_name?(app, params) &&
       EyeManager.status(application: app,
                         process: 'tor') == 'up'
      is_running = true
      break
    end
  end
  is_running
end

Private Class Methods

pid_of_tor_eye_process(app) click to toggle source
# File lib/tormanager/tor_process.rb, line 78
def pid_of_tor_eye_process app
  app.to_s.split('-').last
end
port_and_or_pid_matches_eye_tor_name?(app, params={}) click to toggle source
# File lib/tormanager/tor_process.rb, line 72
def port_and_or_pid_matches_eye_tor_name? app, params={}
  (params[:port] || params[:parent_pid]) &&
  (!params[:port] || port_of_tor_eye_process(app).to_i == params[:port].to_i) &&
  (!params[:parent_pid] || pid_of_tor_eye_process(app).to_i == params[:parent_pid].to_i)
end
port_of_tor_eye_process(app) click to toggle source
# File lib/tormanager/tor_process.rb, line 82
def port_of_tor_eye_process app
  app_name_split = app.to_s.split('-')
  app_name_split.length >= 3 ?
      app_name_split[2].to_i : nil
end

Public Instance Methods

start() click to toggle source
# File lib/tormanager/tor_process.rb, line 39
def start
  prepare_tor_start_and_monitor if tor_ports_are_open?
end
stop() click to toggle source
# File lib/tormanager/tor_process.rb, line 43
def stop
  EyeManager.stop application: eye_app_name, process: 'tor'
  remove_eye_tor_config unless @settings[:dont_remove_tor_config]
  ensure_tor_is_down
end

Private Instance Methods

control_port_is_open?() click to toggle source
# File lib/tormanager/tor_process.rb, line 103
def control_port_is_open?
  raise TorControlPortInUse, "Cannot spawn Tor process as control port " +
            "#{@settings[:control_port]} is in use" unless
      ProcessHelper.port_is_open?(@settings[:control_port])
  true
end
ensure_tor_is_down() click to toggle source
# File lib/tormanager/tor_process.rb, line 155
def ensure_tor_is_down
  10.times do |i|
    tor_status = EyeManager.status(
        application: eye_app_name,
        process: 'tor')
    break if ['unknown','unmonitored'].include?(tor_status)
    sleep 2
    raise TorFailedToStop,
          "Tor didnt stop after 20 seconds! Last status: #{tor_status} See log: " +
              "#{File.join(@settings[:log_dir],
                           eye_app_name + ".log")}" if i >= 9
  end
end
ensure_tor_is_up() click to toggle source
# File lib/tormanager/tor_process.rb, line 142
def ensure_tor_is_up
  10.times do |i|
    break if
        EyeManager.status(
            application: eye_app_name,
            process: 'tor') == 'up'
    sleep 2
    raise TorFailedToStart, "Tor didnt start up after 20 seconds! See log: " +
              "#{File.join(@settings[:log_dir],
                           eye_app_name + ".log")}" if i >= 9
  end
end
eye_app_name() click to toggle source
# File lib/tormanager/tor_process.rb, line 125
def eye_app_name
  @eye_app_name || "tormanager-tor-#{@settings[:tor_port]}-#{Process.pid}"
end
eye_config_filename() click to toggle source
# File lib/tormanager/tor_process.rb, line 120
def eye_config_filename
  @eye_config_filename || File.join(@settings[:log_dir],
            "tormanager.tor.#{@settings[:tor_port]}.#{Process.pid}.eye.rb")
end
make_dirs() click to toggle source
# File lib/tormanager/tor_process.rb, line 129
def make_dirs
  [@settings[:log_dir], @settings[:pid_dir],
   @settings[:tor_data_dir]].each do |path|
    FileUtils.mkpath(path) if path && !File.exists?(path)
  end
end
prepare_tor_start_and_monitor() click to toggle source
# File lib/tormanager/tor_process.rb, line 110
def prepare_tor_start_and_monitor
  #build_eye_config_from_template
  eye_config = CreateEyeConfig.new(
      @settings.merge(
          eye_tor_config_path: eye_config_filename))
  eye_config.create
  make_dirs
  start_tor_and_monitor
end
random_password() click to toggle source
# File lib/tormanager/tor_process.rb, line 173
def random_password
  SecureRandom.random_number(36**12).to_s(36).rjust(12, "0")
end
remove_eye_tor_config() click to toggle source
# File lib/tormanager/tor_process.rb, line 169
def remove_eye_tor_config
  File.delete(eye_config_filename) if File.exists?(eye_config_filename)
end
start_tor_and_monitor() click to toggle source
# File lib/tormanager/tor_process.rb, line 136
def start_tor_and_monitor
  EyeManager.start config: eye_config_filename,
                   application: eye_app_name
  ensure_tor_is_up
end
tor_hash_password_from(password) click to toggle source
# File lib/tormanager/tor_process.rb, line 177
def tor_hash_password_from password
  `tor --quiet --hash-password '#{password}'`.strip
end
tor_port_is_open?() click to toggle source
# File lib/tormanager/tor_process.rb, line 96
def tor_port_is_open?
  raise TorPortInUse, "Cannot spawn Tor process as port " +
            "#{@settings[:tor_port]} is in use" unless
      ProcessHelper.port_is_open?(@settings[:tor_port])
  true
end
tor_ports_are_open?() click to toggle source
# File lib/tormanager/tor_process.rb, line 91
def tor_ports_are_open?
  tor_port_is_open? &&
  control_port_is_open?
end