socksify 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/doc/index.html CHANGED
@@ -36,7 +36,9 @@
36
36
  </ul>
37
37
  <p>
38
38
  Additionally, <code>Socksify::resolve</code> can be used to
39
- resolve hostnames to IPv4 addresses via SOCKS.
39
+ resolve hostnames to IPv4 addresses via SOCKS. There is also
40
+ <code>socksify/http</code> enabling Net::HTTP to work
41
+ via SOCKS.
40
42
  </p>
41
43
 
42
44
  <h2>Installation</h2>
@@ -64,6 +66,39 @@ TCPSocket::socks_port = 9050
64
66
  rubyforge_www = TCPSocket.new("rubyforge.org", 80)
65
67
  # => #&lt;TCPSocket:0x...&gt;</pre>
66
68
 
69
+ <p>
70
+ Using block only:
71
+ <pre>require 'socksify'
72
+ require 'open-uri'
73
+ Socksify::proxy("127.0.0.1", 9050) {
74
+ open('http://rubyforge.org').read
75
+ # => #&lt;String: rubyforge's html&gt;
76
+ }
77
+ </pre>
78
+ </p>
79
+
80
+ <h3>Use Net::HTTP explicitly via SOCKS</h3>
81
+ <p>
82
+ Require the additional library <code>socksify/http</code>
83
+ and use the <code>Net::HTTP.SOCKSProxy</code> method. It
84
+ is similar to <code>Net:HTTP.Proxy</code> from the Ruby
85
+ standard library:
86
+ </p>
87
+ <pre>
88
+ require 'socksify/http'
89
+ uri = URI.parse('http://rubyforge.org/')
90
+ Net::HTTP.SOCKSProxy('127.0.0.1', 9050).start(uri.host, uri.port) do |http|
91
+ http.get(uri.path)
92
+ end
93
+ # => #&lt;Net::HTTPOK 200 OK readbody=true&gt;</pre>
94
+
95
+ <p>
96
+ Note that <code>Net::HTTP.SOCKSProxy</code> never relies
97
+ on <code>TCPSocket::socks_server</code>/<code>socks_port</code>.
98
+ You should either set <code>SOCKSProxy</code> arguments
99
+ explicitly or use <code>Net::HTTP</code> directly.
100
+ </p>
101
+
67
102
  <h3>Resolve addresses via SOCKS</h3>
68
103
  <pre>Socksify::resolve("spaceboyz.net")
69
104
  # => "87.106.131.203"</pre>
data/lib/socksify.rb CHANGED
@@ -298,4 +298,17 @@ module Socksify
298
298
  s.close
299
299
  end
300
300
  end
301
+
302
+ def self.proxy(server, port)
303
+ default_server = TCPSocket::socks_server
304
+ default_port = TCPSocket::socks_port
305
+ begin
306
+ TCPSocket::socks_server = server
307
+ TCPSocket::socks_port = port
308
+ yield
309
+ ensure
310
+ TCPSocket::socks_server = default_server
311
+ TCPSocket::socks_port = default_port
312
+ end
313
+ end
301
314
  end
metadata CHANGED
@@ -1,24 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: socksify
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
4
  prerelease: false
6
5
  segments:
7
6
  - 1
8
- - 3
7
+ - 4
9
8
  - 0
10
- version: 1.3.0
9
+ version: 1.4.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Stephan Maka
14
13
  - Andrey Kouznetsov
15
14
  - Christopher Thorpe
16
15
  - Musy Bite
16
+ - Yuichi Tateno
17
17
  autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-02-22 00:00:00 +01:00
21
+ date: 2011-03-31 00:00:00 +02:00
22
22
  default_executable:
23
23
  dependencies: []
24
24
 
@@ -34,10 +34,9 @@ extra_rdoc_files:
34
34
  - COPYING
35
35
  files:
36
36
  - COPYING
37
- - lib/socksify.rb.orig
38
- - lib/socksify.rb
39
37
  - lib/socksify/debug.rb
40
38
  - lib/socksify/http.rb
39
+ - lib/socksify.rb
41
40
  - bin/socksify_ruby
42
41
  - doc/index.css
43
42
  - doc/index.html
@@ -55,7 +54,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
54
  requirements:
56
55
  - - ">="
57
56
  - !ruby/object:Gem::Version
58
- hash: 3
59
57
  segments:
60
58
  - 0
61
59
  version: "0"
@@ -64,7 +62,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
62
  requirements:
65
63
  - - ">="
66
64
  - !ruby/object:Gem::Version
67
- hash: 3
68
65
  segments:
69
66
  - 0
70
67
  version: "0"
data/lib/socksify.rb.orig DELETED
@@ -1,244 +0,0 @@
1
- =begin
2
- Copyright (C) 2007 Stephan Maka <stephan@spaceboyz.net>
3
-
4
- This program is free software: you can redistribute it and/or modify
5
- it under the terms of the GNU General Public License as published by
6
- the Free Software Foundation, either version 3 of the License, or
7
- (at your option) any later version.
8
-
9
- This program is distributed in the hope that it will be useful,
10
- but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- GNU General Public License for more details.
13
-
14
- You should have received a copy of the GNU General Public License
15
- along with this program. If not, see <http://www.gnu.org/licenses/>.
16
- =end
17
-
18
- require 'socket'
19
- require 'socksify_debug'
20
-
21
- class SOCKSError < RuntimeError
22
- def initialize(msg)
23
- Socksify::debug_error("#{self.class}: #{msg}")
24
- super
25
- end
26
-
27
- class ServerFailure < SOCKSError
28
- def initialize
29
- super("general SOCKS server failure")
30
- end
31
- end
32
- class NotAllowed < SOCKSError
33
- def initialize
34
- super("connection not allowed by ruleset")
35
- end
36
- end
37
- class NetworkUnreachable < SOCKSError
38
- def initialize
39
- super("Network unreachable")
40
- end
41
- end
42
- class HostUnreachable < SOCKSError
43
- def initialize
44
- super("Host unreachable")
45
- end
46
- end
47
- class ConnectionRefused < SOCKSError
48
- def initialize
49
- super("Connection refused")
50
- end
51
- end
52
- class TTLExpired < SOCKSError
53
- def initialize
54
- super("TTL expired")
55
- end
56
- end
57
- class CommandNotSupported < SOCKSError
58
- def initialize
59
- super("Command not supported")
60
- end
61
- end
62
- class AddressTypeNotSupported < SOCKSError
63
- def initialize
64
- super("Address type not supported")
65
- end
66
- end
67
-
68
- def self.for_response_code(code)
69
- case code
70
- when 1
71
- ServerFailure
72
- when 2
73
- NotAllowed
74
- when 3
75
- NetworkUnreachable
76
- when 4
77
- HostUnreachable
78
- when 5
79
- ConnectionRefused
80
- when 6
81
- TTLExpired
82
- when 7
83
- CommandNotSupported
84
- when 8
85
- AddressTypeNotSupported
86
- else
87
- self
88
- end
89
- end
90
- end
91
-
92
- class TCPSocket
93
- def self.socks_server
94
- @@socks_server
95
- end
96
- def self.socks_server=(host)
97
- @@socks_server = host
98
- end
99
- def self.socks_port
100
- @@socks_port
101
- end
102
- def self.socks_port=(port)
103
- @@socks_port = port
104
- end
105
- def self.socks_ignores
106
- @@socks_ignores ||= []
107
- end
108
- def self.socks_ignores=(ignores)
109
- @@socks_ignores = ignores
110
- end
111
-
112
- alias :initialize_tcp :initialize
113
-
114
- # See http://tools.ietf.org/html/rfc1928
115
- def initialize(host=nil, port=0, local_host="0.0.0.0", local_port=0)
116
- socks_server = self.class.socks_server
117
- socks_port = self.class.socks_port
118
- socks_ignores = self.class.socks_ignores
119
-
120
- if socks_server and socks_port and not socks_ignores.include?(host)
121
- Socksify::debug_notice "Connecting to SOCKS server #{socks_server}:#{socks_port}"
122
- initialize_tcp socks_server, socks_port
123
-
124
- socks_authenticate
125
-
126
- if host
127
- socks_connect(host, port)
128
- end
129
- else
130
- Socksify::debug_notice "Connecting directly to #{host}:#{port}"
131
- initialize_tcp host, port, local_host, local_port
132
- Socksify::debug_debug "Connected to #{host}:#{port}"
133
- end
134
- end
135
-
136
- # Authentication
137
- def socks_authenticate
138
- Socksify::debug_debug "Sending no authentication"
139
- write "\005\001\000"
140
- Socksify::debug_debug "Waiting for authentication reply"
141
- auth_reply = recv(2)
142
- if auth_reply[0] != 4 and auth_reply[0] != 5
143
- raise SOCKSError.new("SOCKS version #{auth_reply[0]} not supported")
144
- end
145
- if auth_reply[1] != 0
146
- raise SOCKSError.new("SOCKS authentication method #{auth_reply[1]} neither requested nor supported")
147
- end
148
- end
149
-
150
- # Connect
151
- def socks_connect(host, port)
152
- Socksify::debug_debug "Sending destination address"
153
- write "\005\001\000"
154
- if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ # to IPv4 address
155
- write "\001" + [$1.to_i,
156
- $2.to_i,
157
- $3.to_i,
158
- $4.to_i
159
- ].pack('CCCC')
160
- elsif host =~ /^[:0-9a-f]+$/ # to IPv6 address
161
- raise "TCP/IPv6 over SOCKS is not yet supported (inet_pton missing in Ruby & not supported by Tor"
162
- write "\004"
163
- else # to hostname
164
- write "\003" + [host.size].pack('C') + host
165
- end
166
- write [port].pack('n')
167
-
168
- socks_receive_reply
169
- Socksify::debug_notice "Connected to #{host}:#{port} over SOCKS"
170
- end
171
-
172
- # returns [bind_addr: String, bind_port: Fixnum]
173
- def socks_receive_reply
174
- Socksify::debug_debug "Waiting for SOCKS reply"
175
- connect_reply = recv(4)
176
- if connect_reply[0] != 5
177
- raise SOCKSError.new("SOCKS version #{connect_reply[0]} is not 5")
178
- end
179
- if connect_reply[1] != 0
180
- raise SOCKSError.for_response_code(connect_reply[1])
181
- end
182
- Socksify::debug_debug "Waiting for bind_addr"
183
- bind_addr_len = case connect_reply[3]
184
- when 1
185
- 4
186
- when 3
187
- recv(1)[0]
188
- when 4
189
- 16
190
- else
191
- raise SOCKSError.for_response_code(connect_reply[3])
192
- end
193
- bind_addr_s = recv(bind_addr_len)
194
- bind_addr = case connect_reply[3]
195
- when 1
196
- "#{bind_addr_s[0]}.#{bind_addr_s[1]}.#{bind_addr_s[2]}.#{bind_addr_s[3]}"
197
- when 3
198
- bind_addr_s
199
- when 4 # Untested!
200
- i = 0
201
- ip6 = ""
202
- bind_addr_s.each_byte do |b|
203
- if i > 0 and i % 2 == 0
204
- ip6 += ":"
205
- end
206
- i += 1
207
-
208
- ip6 += b.to_s(16).rjust(2, '0')
209
- end
210
- end
211
- bind_port = recv(bind_addr_len + 2)
212
- [bind_addr, bind_port.unpack('n')]
213
- end
214
- end
215
-
216
- module Socksify
217
- def self.resolve(host)
218
- s = TCPSocket.new
219
-
220
- begin
221
- Socksify::debug_debug "Sending hostname to resolve: #{host}"
222
- s.write "\005"
223
- if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ # to IPv4 address
224
- s.write "\xF1\000\001" + [$1.to_i,
225
- $2.to_i,
226
- $3.to_i,
227
- $4.to_i
228
- ].pack('CCCC')
229
- elsif host =~ /^[:0-9a-f]+$/ # to IPv6 address
230
- raise "TCP/IPv6 over SOCKS is not yet supported (inet_pton missing in Ruby & not supported by Tor"
231
- s.write "\004"
232
- else # to hostname
233
- s.write "\xF0\000\003" + [host.size].pack('C') + host
234
- end
235
- s.write [0].pack('n') # Port
236
-
237
- addr, port = s.socks_receive_reply
238
- Socksify::debug_notice "Resolved #{host} as #{addr} over SOCKS"
239
- addr
240
- ensure
241
- s.close
242
- end
243
- end
244
- end