socksify 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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