Class: Tor::Controller

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

Overview

Tor Control Protocol (TC) client.

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



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/tor/control.rb', line 52

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



64
65
66
# File 'lib/tor/control.rb', line 64

def host
  @host
end

#portObject (readonly)

Since:

  • 0.1.1



64
65
66
# File 'lib/tor/control.rb', line 64

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



36
37
38
39
40
41
42
43
44
# File 'lib/tor/control.rb', line 36

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



191
192
193
194
195
196
197
198
199
# File 'lib/tor/control.rb', line 191

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



175
176
177
# File 'lib/tor/control.rb', line 175

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



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/tor/control.rb', line 148

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



101
102
103
104
105
# File 'lib/tor/control.rb', line 101

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



232
233
234
235
236
237
# File 'lib/tor/control.rb', line 232

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



249
250
251
252
253
254
255
256
257
258
259
# File 'lib/tor/control.rb', line 249

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



74
75
76
77
78
79
# File 'lib/tor/control.rb', line 74

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



90
91
92
# File 'lib/tor/control.rb', line 90

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



121
122
123
124
125
126
# File 'lib/tor/control.rb', line 121

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



268
269
270
271
# File 'lib/tor/control.rb', line 268

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



213
214
215
216
217
218
# File 'lib/tor/control.rb', line 213

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