socksify 1.1.0 → 1.1.1

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.
Files changed (4) hide show
  1. data/doc/index.html +7 -18
  2. data/lib/socksify.rb +21 -21
  3. data/lib/socksify.rb.orig +244 -0
  4. metadata +9 -6
data/doc/index.html CHANGED
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml1-strict.dtd">
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
3
 
4
4
  <html xmlns="http://www.w3.org/1999/xhtml">
5
5
  <head>
@@ -77,10 +77,10 @@ rubyforge_www = TCPSocket.new("rubyforge.org", 80)
77
77
  <h2>Development</h2>
78
78
 
79
79
  <p>
80
- The <a href="http://cthulhu.c3d2.de/~astro/gitweb/?p=socksify-ruby.git">repository</a>
80
+ The <a href="http://github.com/astro/socksify-ruby/">repository</a>
81
81
  can be checked out with:
82
82
  </p>
83
- <pre>$ git-clone http://cthulhu.c3d2.de/~astro/git/socksify-ruby.git/</pre>
83
+ <pre>$ git-clone git://github.com/astro/socksify-ruby.git</pre>
84
84
  <p>
85
85
  Send patches via E-Mail.
86
86
  </p>
@@ -106,21 +106,10 @@ rubyforge_www = TCPSocket.new("rubyforge.org", 80)
106
106
 
107
107
  <h2>License</h2>
108
108
  <p>
109
- This program is free software: you can redistribute it and/or
110
- modify it under the terms of the GNU General Public License as
111
- published by the Free Software Foundation, either version 3 of
112
- the License, or (at your option) any later version.
113
- </p>
114
- <p>
115
- This program is distributed in the hope that it will be
116
- useful, but WITHOUT ANY WARRANTY; without even the implied
117
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
118
- PURPOSE. See the GNU General Public License for more details.
119
- </p>
120
- <p>
121
- You should have received a copy of the GNU General Public
122
- License along with this program. If not, see
123
- &lt;<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>&gt;.
109
+ SOCKSify Ruby is distributed under the terms of the GNU
110
+ General Public License version 3 (see
111
+ file <code>COPYING</code>) or the Ruby License (see
112
+ file <code>LICENSE</code>) at your option.
124
113
  </p>
125
114
  </div>
126
115
  </body>
data/lib/socksify.rb CHANGED
@@ -91,13 +91,13 @@ end
91
91
 
92
92
  class TCPSocket
93
93
  def self.socks_server
94
- @@socks_server
94
+ @@socks_server ||= nil
95
95
  end
96
96
  def self.socks_server=(host)
97
97
  @@socks_server = host
98
98
  end
99
99
  def self.socks_port
100
- @@socks_port
100
+ @@socks_port ||= nil
101
101
  end
102
102
  def self.socks_port=(port)
103
103
  @@socks_port = port
@@ -139,11 +139,11 @@ class TCPSocket
139
139
  write "\005\001\000"
140
140
  Socksify::debug_debug "Waiting for authentication reply"
141
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")
142
+ if auth_reply[0..0] != "\004" and auth_reply[0..0] != "\005"
143
+ raise SOCKSError.new("SOCKS version #{auth_reply[0..0]} not supported")
144
144
  end
145
- if auth_reply[1] != 0
146
- raise SOCKSError.new("SOCKS authentication method #{auth_reply[1]} neither requested nor supported")
145
+ if auth_reply[1..1] != "\000"
146
+ raise SOCKSError.new("SOCKS authentication method #{auth_reply[1..1]} neither requested nor supported")
147
147
  end
148
148
  end
149
149
 
@@ -173,30 +173,30 @@ class TCPSocket
173
173
  def socks_receive_reply
174
174
  Socksify::debug_debug "Waiting for SOCKS reply"
175
175
  connect_reply = recv(4)
176
- if connect_reply[0] != 5
177
- raise SOCKSError.new("SOCKS version #{connect_reply[0]} is not 5")
176
+ if connect_reply[0..0] != "\005"
177
+ raise SOCKSError.new("SOCKS version #{connect_reply[0..0]} is not 5")
178
178
  end
179
- if connect_reply[1] != 0
180
- raise SOCKSError.for_response_code(connect_reply[1])
179
+ if connect_reply[1..1] != "\000"
180
+ raise SOCKSError.for_response_code(connect_reply.bytes.to_a[1])
181
181
  end
182
182
  Socksify::debug_debug "Waiting for bind_addr"
183
- bind_addr_len = case connect_reply[3]
184
- when 1
183
+ bind_addr_len = case connect_reply[3..3]
184
+ when "\001"
185
185
  4
186
- when 3
187
- recv(1)[0]
188
- when 4
186
+ when "\003"
187
+ recv(1).bytes.first
188
+ when "\004"
189
189
  16
190
190
  else
191
- raise SOCKSError.for_response_code(connect_reply[3])
191
+ raise SOCKSError.for_response_code(connect_reply.bytes.to_a[3])
192
192
  end
193
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
194
+ bind_addr = case connect_reply[3..3]
195
+ when "\001"
196
+ bind_addr_s.bytes.to_a.join('.')
197
+ when "\003"
198
198
  bind_addr_s
199
- when 4 # Untested!
199
+ when "\004" # Untested!
200
200
  i = 0
201
201
  ip6 = ""
202
202
  bind_addr_s.each_byte do |b|
@@ -0,0 +1,244 @@
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: socksify
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephan Maka
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-04-17 00:00:00 +02:00
12
+ date: 2010-03-15 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,13 +25,16 @@ extra_rdoc_files:
25
25
  - COPYING
26
26
  files:
27
27
  - COPYING
28
- - lib/socksify.rb
29
28
  - lib/socksify_debug.rb
29
+ - lib/socksify.rb.orig
30
+ - lib/socksify.rb
30
31
  - bin/socksify_ruby
31
32
  - doc/index.css
32
33
  - doc/index.html
33
- has_rdoc: false
34
+ has_rdoc: true
34
35
  homepage: http://socksify.rubyforge.org/
36
+ licenses: []
37
+
35
38
  post_install_message:
36
39
  rdoc_options: []
37
40
 
@@ -52,9 +55,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
55
  requirements: []
53
56
 
54
57
  rubyforge_project: socksify
55
- rubygems_version: 1.1.1
58
+ rubygems_version: 1.3.5
56
59
  signing_key:
57
- specification_version: 2
60
+ specification_version: 3
58
61
  summary: Redirect all TCPSockets through a SOCKS5 proxy
59
62
  test_files: []
60
63