tormanager 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/lib/tormanager/control.rb +313 -0
- data/lib/tormanager/ip_address_control.rb +0 -1
- data/lib/tormanager/version.rb +1 -1
- data/lib/tormanager.rb +1 -2
- data/tormanager.gemspec +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4f5f15e6d06ba9f2ea927a1a09e492cb06fcdb8
|
4
|
+
data.tar.gz: fcffe0b51611f91a85c4bd17407de5ee364acd98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f781d354d3d9a0ecc9740568c58fe308ae540b18ad63e6162dc46ea92e2dba5d71a0e9a789a79bf4c074c7b9019699ba69a8d034a122ffb33fe6dbd80a385b18
|
7
|
+
data.tar.gz: 09b546d6a5ce6f314b2de9972a283ae8043167e78988521346c67ea6de6333b0e653308fba1611d5a73366b1416b2b35ea9e687feb362087199c1cff5db216fa
|
data/Gemfile
CHANGED
@@ -3,8 +3,6 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in tormanager.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem 'tor', :git => 'https://github.com/bendiken/tor-ruby.git', :ref => '08e589d17196a5dc640e7b38cb1acc5b4c5ced05'
|
7
|
-
#gem 'tor', :git => 'https://github.com/dryruby/tor.rb.git'
|
8
6
|
group :development, :test do
|
9
7
|
gem "rb-fsevent", :require => false if RUBY_PLATFORM =~ /darwin/i
|
10
8
|
gem "guard-rspec"
|
@@ -0,0 +1,313 @@
|
|
1
|
+
require 'socket' unless defined?(Socket)
|
2
|
+
|
3
|
+
module Tor
|
4
|
+
##
|
5
|
+
# Tor Control Protocol (TC) client.
|
6
|
+
# pulled from tor.rb:
|
7
|
+
# https://github.com/dryruby/tor.rb/blob/master/lib/tor/control.rb
|
8
|
+
# because latest version was not pushed to rubygems and needed to bundle into my gem
|
9
|
+
#
|
10
|
+
# The Tor control protocol is used by other programs (such as frontend
|
11
|
+
# user interfaces) to communicate with a locally running Tor process. It
|
12
|
+
# is not part of the Tor onion routing protocol.
|
13
|
+
#
|
14
|
+
# @example Establishing a controller connection (1)
|
15
|
+
# tor = Tor::Controller.new
|
16
|
+
#
|
17
|
+
# @example Establishing a controller connection (2)
|
18
|
+
# tor = Tor::Controller.new(:host => '127.0.0.1', :port => 9051)
|
19
|
+
#
|
20
|
+
# @example Authenticating the controller connection
|
21
|
+
# tor.authenticate
|
22
|
+
#
|
23
|
+
# @example Obtaining information about the Tor process
|
24
|
+
# tor.version #=> "0.2.1.25"
|
25
|
+
# tor.config_file #=> #<Pathname:/opt/local/etc/tor/torrc>
|
26
|
+
#
|
27
|
+
# @see http://gitweb.torproject.org/tor.git?a=blob_plain;hb=HEAD;f=doc/spec/control-spec.txt
|
28
|
+
# @see http://www.thesprawl.org/memdump/?entry=8
|
29
|
+
# @since 0.1.1
|
30
|
+
class Controller
|
31
|
+
PROTOCOL_VERSION = 1
|
32
|
+
|
33
|
+
##
|
34
|
+
# @param [Hash{Symbol => Object}] options
|
35
|
+
# @option options [String, #to_s] :host ("127.0.0.1")
|
36
|
+
# @option options [Integer, #to_i] :port (9051)
|
37
|
+
# @option options [String, #to_s] :cookie (nil)
|
38
|
+
# @option options [Integer, #to_i] :version (PROTOCOL_VERSION)
|
39
|
+
def self.connect(options = {}, &block)
|
40
|
+
if block_given?
|
41
|
+
result = block.call(tor = self.new(options))
|
42
|
+
tor.quit
|
43
|
+
result
|
44
|
+
else
|
45
|
+
self.new(options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# @param [Hash{Symbol => Object}] options
|
51
|
+
# @option options [String, #to_s] :host ("127.0.0.1")
|
52
|
+
# @option options [Integer, #to_i] :port (9051)
|
53
|
+
# @option options [String, #to_s] :cookie (nil)
|
54
|
+
# @option options [Integer, #to_i] :version (PROTOCOL_VERSION)
|
55
|
+
def initialize(options = {}, &block)
|
56
|
+
@options = options.dup
|
57
|
+
@host = (@options.delete(:host) || '127.0.0.1').to_s
|
58
|
+
@port = (@options.delete(:port) || 9051).to_i
|
59
|
+
@version = (@options.delete(:version) || PROTOCOL_VERSION).to_i
|
60
|
+
connect
|
61
|
+
if block_given?
|
62
|
+
block.call(self)
|
63
|
+
quit
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_reader :host, :port
|
68
|
+
|
69
|
+
##
|
70
|
+
# Establishes the socket connection to the Tor process.
|
71
|
+
#
|
72
|
+
# @example
|
73
|
+
# tor.close
|
74
|
+
# tor.connect
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
def connect
|
78
|
+
close
|
79
|
+
@socket = TCPSocket.new(@host, @port)
|
80
|
+
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Returns `true` if the controller connection is active.
|
86
|
+
#
|
87
|
+
# @example
|
88
|
+
# tor.connected? #=> true
|
89
|
+
# tor.close
|
90
|
+
# tor.connected? #=> false
|
91
|
+
#
|
92
|
+
# @return [Boolean]
|
93
|
+
def connected?
|
94
|
+
!!@socket
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Closes the socket connection to the Tor process.
|
99
|
+
#
|
100
|
+
# @example
|
101
|
+
# tor.close
|
102
|
+
#
|
103
|
+
# @return [void]
|
104
|
+
def close
|
105
|
+
@socket.close if @socket
|
106
|
+
@socket = nil
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Tells the Tor process to hang up on this controller connection.
|
112
|
+
#
|
113
|
+
# This command can be used before authenticating.
|
114
|
+
#
|
115
|
+
# @example
|
116
|
+
# C: QUIT
|
117
|
+
# S: 250 closing connection
|
118
|
+
# ^D
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# tor.quit
|
122
|
+
#
|
123
|
+
# @return [void]
|
124
|
+
def quit
|
125
|
+
send_line('QUIT')
|
126
|
+
reply = read_reply
|
127
|
+
close
|
128
|
+
reply
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Returns information about the authentication method required by the
|
133
|
+
# Tor process.
|
134
|
+
#
|
135
|
+
# This command may be used before authenticating.
|
136
|
+
#
|
137
|
+
# @example
|
138
|
+
# C: PROTOCOLINFO
|
139
|
+
# S: 250-PROTOCOLINFO 1
|
140
|
+
# S: 250-AUTH METHODS=NULL
|
141
|
+
# S: 250-VERSION Tor="0.2.1.25"
|
142
|
+
# S: 250 OK
|
143
|
+
#
|
144
|
+
# @example
|
145
|
+
# tor.authentication_method #=> nil
|
146
|
+
# tor.authentication_method #=> :hashedpassword
|
147
|
+
# tor.authentication_method #=> :cookie
|
148
|
+
#
|
149
|
+
# @return [Symbol]
|
150
|
+
# @since 0.1.2
|
151
|
+
def authentication_method
|
152
|
+
@authentication_method ||= begin
|
153
|
+
method = nil
|
154
|
+
send_line('PROTOCOLINFO')
|
155
|
+
loop do
|
156
|
+
# TODO: support for reading multiple authentication methods
|
157
|
+
case reply = read_reply
|
158
|
+
when /^250-AUTH METHODS=(\w*)/
|
159
|
+
method = $1.strip.downcase.to_sym
|
160
|
+
method = method.eql?(:null) ? nil : method
|
161
|
+
when /^250-/ then next
|
162
|
+
when '250 OK' then break
|
163
|
+
end
|
164
|
+
end
|
165
|
+
method
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Returns `true` if the controller connection has been authenticated.
|
171
|
+
#
|
172
|
+
# @example
|
173
|
+
# tor.authenticated? #=> false
|
174
|
+
# tor.authenticate
|
175
|
+
# tor.authenticated? #=> true
|
176
|
+
#
|
177
|
+
# @return [Boolean]
|
178
|
+
def authenticated?
|
179
|
+
@authenticated || false
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# Authenticates the controller connection.
|
184
|
+
#
|
185
|
+
# @example
|
186
|
+
# C: AUTHENTICATE
|
187
|
+
# S: 250 OK
|
188
|
+
#
|
189
|
+
# @example
|
190
|
+
# tor.authenticate
|
191
|
+
#
|
192
|
+
# @return [void]
|
193
|
+
# @raise [AuthenticationError] if authentication failed
|
194
|
+
def authenticate(cookie = nil)
|
195
|
+
cookie ||= @options[:cookie]
|
196
|
+
send(:send_line, cookie ? "AUTHENTICATE \"#{cookie}\"" : "AUTHENTICATE")
|
197
|
+
case reply = read_reply
|
198
|
+
when '250 OK' then @authenticated = true
|
199
|
+
else raise AuthenticationError.new(reply)
|
200
|
+
end
|
201
|
+
self
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Returns the version number of the Tor process.
|
206
|
+
#
|
207
|
+
# @example
|
208
|
+
# C: GETINFO version
|
209
|
+
# S: 250-version=0.2.1.25
|
210
|
+
# S: 250 OK
|
211
|
+
#
|
212
|
+
# @example
|
213
|
+
# tor.version #=> "0.2.1.25"
|
214
|
+
#
|
215
|
+
# @return [String]
|
216
|
+
def version
|
217
|
+
send_command(:getinfo, 'version')
|
218
|
+
reply = read_reply.split('=').last
|
219
|
+
read_reply # skip "250 OK"
|
220
|
+
reply
|
221
|
+
end
|
222
|
+
|
223
|
+
##
|
224
|
+
# Returns the path to the Tor configuration file.
|
225
|
+
#
|
226
|
+
# @example
|
227
|
+
# C: GETINFO config-file
|
228
|
+
# S: 250-config-file=/opt/local/etc/tor/torrc
|
229
|
+
# S: 250 OK
|
230
|
+
#
|
231
|
+
# @example
|
232
|
+
# tor.config_file #=> #<Pathname:/opt/local/etc/tor/torrc>
|
233
|
+
#
|
234
|
+
# @return [Pathname]
|
235
|
+
def config_file
|
236
|
+
send_command(:getinfo, 'config-file')
|
237
|
+
reply = read_reply.split('=').last
|
238
|
+
read_reply # skip "250 OK"
|
239
|
+
Pathname(reply)
|
240
|
+
end
|
241
|
+
|
242
|
+
##
|
243
|
+
# Returns the current (in-memory) Tor configuration.
|
244
|
+
# Response is terminated with a "."
|
245
|
+
#
|
246
|
+
# @example
|
247
|
+
# C: GETINFO config-text
|
248
|
+
# S: 250+config-text=
|
249
|
+
# S: ControlPort 9051
|
250
|
+
# S: RunAsDaemon 1
|
251
|
+
# S: .
|
252
|
+
def config_text
|
253
|
+
send_command(:getinfo, 'config-text')
|
254
|
+
reply = ""
|
255
|
+
read_reply # skip "250+config-text="
|
256
|
+
while line = read_reply
|
257
|
+
break unless line != "."
|
258
|
+
reply.concat(line + "\n")
|
259
|
+
end
|
260
|
+
read_reply # skip "250 OK"
|
261
|
+
return reply
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# Send a signal to the server
|
266
|
+
#
|
267
|
+
# @example
|
268
|
+
# tor.signal("newnym")
|
269
|
+
#
|
270
|
+
# @return [String]
|
271
|
+
def signal(name)
|
272
|
+
send_command(:signal, name)
|
273
|
+
read_reply
|
274
|
+
end
|
275
|
+
|
276
|
+
protected
|
277
|
+
|
278
|
+
##
|
279
|
+
# Sends a command line over the socket.
|
280
|
+
#
|
281
|
+
# @param [Symbol, #to_s] command
|
282
|
+
# @param [Array<String>] args
|
283
|
+
# @return [void]
|
284
|
+
def send_command(command, *args)
|
285
|
+
authenticate unless authenticated?
|
286
|
+
send_line(["#{command.to_s.upcase}", *args].join(' '))
|
287
|
+
end
|
288
|
+
|
289
|
+
##
|
290
|
+
# Sends a text line over the socket.
|
291
|
+
#
|
292
|
+
# @param [String, #to_s] line
|
293
|
+
# @return [void]
|
294
|
+
def send_line(line)
|
295
|
+
@socket.write(line.to_s + "\r\n")
|
296
|
+
@socket.flush
|
297
|
+
end
|
298
|
+
|
299
|
+
##
|
300
|
+
# Reads a reply line from the socket.
|
301
|
+
#
|
302
|
+
# @return [String]
|
303
|
+
def read_reply
|
304
|
+
@socket.readline.chomp
|
305
|
+
end
|
306
|
+
|
307
|
+
##
|
308
|
+
# Used to signal an authentication error.
|
309
|
+
#
|
310
|
+
# @see Tor::Controller#authenticate
|
311
|
+
class AuthenticationError < StandardError; end
|
312
|
+
end
|
313
|
+
end
|
data/lib/tormanager/version.rb
CHANGED
data/lib/tormanager.rb
CHANGED
data/tormanager.gemspec
CHANGED
@@ -25,9 +25,9 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
26
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
27
|
spec.add_development_dependency "rspec-rails", "~> 3.5"
|
28
|
+
spec.add_development_dependency "gem-release"
|
28
29
|
spec.add_dependency "rest-client"
|
29
30
|
spec.add_dependency "eye"
|
30
31
|
spec.add_dependency "eyemanager"
|
31
|
-
spec.add_dependency "gem-release"
|
32
32
|
spec.add_dependency "socksify"
|
33
33
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tormanager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- joshweir
|
@@ -67,13 +67,13 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.5'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: gem-release
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
|
-
type: :
|
76
|
+
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rest-client
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: eye
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: eyemanager
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- bin/console
|
155
155
|
- bin/setup
|
156
156
|
- lib/tormanager.rb
|
157
|
+
- lib/tormanager/control.rb
|
157
158
|
- lib/tormanager/eye/eye.tor.test.rb
|
158
159
|
- lib/tormanager/eye/sugar.rb
|
159
160
|
- lib/tormanager/eye/tor.god.rb
|