Class: Tor::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/tormanager/control.rb

Overview

Tor Control Protocol (TC) client. pulled from tor.rb: github.com/dryruby/tor.rb/blob/master/lib/tor/control.rb because latest version was not pushed to rubygems and needed to bundle into my gem

The Tor control protocol is used by other programs (such as frontend user interfaces) to communicate with a locally running Tor process. It is not part of the Tor onion routing protocol.

Examples:

Establishing a controller connection (1)

tor = Tor::Controller.new

Establishing a controller connection (2)

tor = Tor::Controller.new(:host => '127.0.0.1', :port => 9051)

Authenticating the controller connection

tor.authenticate

Obtaining information about the Tor process

tor.version      #=> "0.2.1.25"
tor.config_file  #=> #<Pathname:/opt/local/etc/tor/torrc>

See Also:

Since:

  • 0.1.1

Defined Under Namespace

Classes: AuthenticationError

Constant Summary collapse

PROTOCOL_VERSION =

Since:

  • 0.1.1

1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &block) ⇒ Controller

Returns a new instance of Controller.

Parameters:

  • options (Hash{Symbol => Object}) (defaults to: {})

Options Hash (options):

  • :host (String, #to_s) — default: "127.0.0.1"
  • :port (Integer, #to_i) — default: 9051
  • :cookie (String, #to_s) — default: nil
  • :version (Integer, #to_i) — default: PROTOCOL_VERSION

Since:

  • 0.1.1



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/tormanager/control.rb', line 55

def initialize(options = {}, &block)
  @options = options.dup
  @host    = (@options.delete(:host)    || '127.0.0.1').to_s
  @port    = (@options.delete(:port)    || 9051).to_i
  @version = (@options.delete(:version) || PROTOCOL_VERSION).to_i
  connect
  if block_given?
    block.call(self)
    quit
  end
end

Instance Attribute Details

#hostObject (readonly)

Since:

  • 0.1.1



67
68
69
# File 'lib/tormanager/control.rb', line 67

def host
  @host
end

#portObject (readonly)

Since:

  • 0.1.1



67
68
69
# File 'lib/tormanager/control.rb', line 67

def port
  @port
end

Class Method Details

.connect(options = {}, &block) ⇒ Object

Parameters:

  • options (Hash{Symbol => Object}) (defaults to: {})

Options Hash (options):

  • :host (String, #to_s) — default: "127.0.0.1"
  • :port (Integer, #to_i) — default: 9051
  • :cookie (String, #to_s) — default: nil
  • :version (Integer, #to_i) — default: PROTOCOL_VERSION

Since:

  • 0.1.1



39
40
41
42
43
44
45
46
47
# File 'lib/tormanager/control.rb', line 39

def self.connect(options = {}, &block)
  if block_given?
    result = block.call(tor = self.new(options))
    tor.quit
    result
  else
    self.new(options)
  end
end

Instance Method Details

#authenticate(cookie = nil) ⇒ void

This method returns an undefined value.

Authenticates the controller connection.

Examples:

C: AUTHENTICATE
S: 250 OK
tor.authenticate

Raises:

Since:

  • 0.1.1



194
195
196
197
198
199
200
201
202
# File 'lib/tormanager/control.rb', line 194

def authenticate(cookie = nil)
  cookie ||= @options[:cookie]
  send(:send_line, cookie ? "AUTHENTICATE \"#{cookie}\"" : "AUTHENTICATE")
  case reply = read_reply
    when '250 OK' then @authenticated = true
    else raise AuthenticationError.new(reply)
  end
  self
end

#authenticated?Boolean

Returns true if the controller connection has been authenticated.

Examples:

tor.authenticated?         #=> false
tor.authenticate
tor.authenticated?         #=> true

Returns:

  • (Boolean)

Since:

  • 0.1.1



178
179
180
# File 'lib/tormanager/control.rb', line 178

def authenticated?
  @authenticated || false
end

#authentication_methodSymbol

Returns information about the authentication method required by the Tor process.

This command may be used before authenticating.

Examples:

C: PROTOCOLINFO
S: 250-PROTOCOLINFO 1
S: 250-AUTH METHODS=NULL
S: 250-VERSION Tor="0.2.1.25"
S: 250 OK
tor.authentication_method  #=> nil
tor.authentication_method  #=> :hashedpassword
tor.authentication_method  #=> :cookie

Returns:

  • (Symbol)

Since:

  • 0.1.2



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/tormanager/control.rb', line 151

def authentication_method
  @authentication_method ||= begin
    method = nil
    send_line('PROTOCOLINFO')
    loop do
      # TODO: support for reading multiple authentication methods
      case reply = read_reply
        when /^250-AUTH METHODS=(\w*)/
          method = $1.strip.downcase.to_sym
          method = method.eql?(:null) ? nil : method
        when /^250-/  then next
        when '250 OK' then break
      end
    end
    method
  end
end

#closevoid

This method returns an undefined value.

Closes the socket connection to the Tor process.

Examples:

tor.close

Since:

  • 0.1.1



104
105
106
107
108
# File 'lib/tormanager/control.rb', line 104

def close
  @socket.close if @socket
  @socket = nil
  self
end

#config_filePathname

Returns the path to the Tor configuration file.

Examples:

C: GETINFO config-file
S: 250-config-file=/opt/local/etc/tor/torrc
S: 250 OK
tor.config_file            #=> #<Pathname:/opt/local/etc/tor/torrc>

Returns:

  • (Pathname)

Since:

  • 0.1.1



235
236
237
238
239
240
# File 'lib/tormanager/control.rb', line 235

def config_file
  send_command(:getinfo, 'config-file')
  reply = read_reply.split('=').last
  read_reply # skip "250 OK"
  Pathname(reply)
end

#config_textObject

Returns the current (in-memory) Tor configuration. Response is terminated with a “.”

Examples:

C: GETINFO config-text
S: 250+config-text=
S: ControlPort 9051
S: RunAsDaemon 1
S: .

Since:

  • 0.1.1



252
253
254
255
256
257
258
259
260
261
262
# File 'lib/tormanager/control.rb', line 252

def config_text
  send_command(:getinfo, 'config-text')
  reply = ""
  read_reply # skip "250+config-text="
  while line = read_reply
    break unless line != "."
    reply.concat(line + "\n")
  end
  read_reply # skip "250 OK"
  return reply
end

#connectvoid

This method returns an undefined value.

Establishes the socket connection to the Tor process.

Examples:

tor.close
tor.connect

Since:

  • 0.1.1



77
78
79
80
81
82
# File 'lib/tormanager/control.rb', line 77

def connect
  close
  @socket = TCPSocket.new(@host, @port)
  @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
  self
end

#connected?Boolean

Returns true if the controller connection is active.

Examples:

tor.connected?             #=> true
tor.close
tor.connected?             #=> false

Returns:

  • (Boolean)

Since:

  • 0.1.1



93
94
95
# File 'lib/tormanager/control.rb', line 93

def connected?
  !!@socket
end

#quitvoid

This method returns an undefined value.

Tells the Tor process to hang up on this controller connection.

This command can be used before authenticating.

Examples:

C: QUIT
S: 250 closing connection
^D
tor.quit

Since:

  • 0.1.1



124
125
126
127
128
129
# File 'lib/tormanager/control.rb', line 124

def quit
  send_line('QUIT')
  reply = read_reply
  close
  reply
end

#signal(name) ⇒ String

Send a signal to the server

tor.signal(“newnym”)

Returns:

  • (String)

Since:

  • 0.1.1



271
272
273
274
# File 'lib/tormanager/control.rb', line 271

def signal(name)
  send_command(:signal, name)
  read_reply
end

#versionString

Returns the version number of the Tor process.

Examples:

C: GETINFO version
S: 250-version=0.2.1.25
S: 250 OK
tor.version                #=> "0.2.1.25"

Returns:

  • (String)

Since:

  • 0.1.1



216
217
218
219
220
221
# File 'lib/tormanager/control.rb', line 216

def version
  send_command(:getinfo, 'version')
  reply = read_reply.split('=').last
  read_reply # skip "250 OK"
  reply
end