socksify 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/socksify_ruby +9 -3
  2. data/lib/socksify.rb.orig +244 -0
  3. metadata +6 -4
data/bin/socksify_ruby CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- if ARGV.size < 3
4
- puts "Usage: #{$0} <SOCKS host> <SOCKS port> <ruby script> [args ...]"
3
+ if ARGV.size < 2
4
+ puts "Usage: #{$0} <SOCKS host> <SOCKS port> [script args ...]"
5
5
  exit
6
6
  end
7
7
 
@@ -9,4 +9,10 @@ require 'socksify'
9
9
 
10
10
  TCPSocket.socks_server = ARGV.shift
11
11
  TCPSocket.socks_port = ARGV.shift.to_i
12
- load ARGV.shift
12
+ if ARGV.size >= 1
13
+ load ARGV.shift
14
+ else
15
+ require 'irb'
16
+ IRB.start(__FILE__)
17
+ end
18
+
@@ -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,22 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: socksify
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 1
9
8
  - 2
10
- version: 1.1.2
9
+ - 0
10
+ version: 1.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Stephan Maka
14
14
  - Andrey Kouznetsov
15
+ - Christopher Thorpe
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2010-10-20 00:00:00 +02:00
20
+ date: 2010-12-14 00:00:00 +01:00
20
21
  default_executable:
21
22
  dependencies: []
22
23
 
@@ -33,6 +34,7 @@ extra_rdoc_files:
33
34
  files:
34
35
  - COPYING
35
36
  - lib/socksify_debug.rb
37
+ - lib/socksify.rb.orig
36
38
  - lib/socksify.rb
37
39
  - bin/socksify_ruby
38
40
  - doc/index.css