proxifier-fork 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 62f6989420dada48d1a8ab2907bc9190f5219bb3
4
+ data.tar.gz: 0aa7b212e7f3c58c37a60a399732113359469c01
5
+ SHA512:
6
+ metadata.gz: 02b51fda9b4e7e9074a5c861b51353d18a24aed5ac3c33a130626b0db08a0c806e2c07887bc1dc41f9f68f608fc8a9d5a43af84b15fdf433854c10577227b386
7
+ data.tar.gz: 41541fd236088f779f93b8742299b8dc9e918fee26844dc8a97541211ed5fbbe4af03e7793d6208ffd2a5d3a6e223b0e5d7494ebbb83de6a31a23177a44c19d0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Samuel Kadolph
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,120 @@
1
+ # ruby-proxifier
2
+
3
+ ## Installing
4
+
5
+ ### Recommended
6
+
7
+ ```
8
+ gem install proxifier
9
+ ```
10
+
11
+ ### Edge
12
+
13
+ ```
14
+ git clone https://github.com/samuelkadolph/ruby-proxifier
15
+ cd ruby-proxifier && rake install
16
+ ```
17
+
18
+ ## Rationale
19
+
20
+ This gem was created for 2 purposes.
21
+
22
+ First is to enable ruby programmers to use HTTP or SOCKS proxies
23
+ interchangeably when using TCPSockets. Either manually with
24
+ `Proxifier::Proxy#open` or by `require "proxifier/env"`.
25
+
26
+ The second purpose is to use ruby code that doesn't use proxies for users that
27
+ have to use proxies.<br>The pruby and pirb executables are simple wrappers for
28
+ their respective ruby executables that support proxies from environment
29
+ variables.
30
+
31
+ ## Usage
32
+
33
+ ### Executable Wrappers & Environment Variables
34
+
35
+ proxifier provides two executables: `pruby` and `pirb`. They are simple
36
+ wrappers for your current `ruby` and `irb` executables that requires the
37
+ `"proxifier/env"` script which installs hooks into `TCPSocket` which will use
38
+ the proxy environment variables to proxy any `TCPSocket`.
39
+
40
+ The environment variables that proxifier will check are (in order of descending
41
+ precedence):
42
+
43
+ <table>
44
+ <tr>
45
+ <th>Variable Name</th>
46
+ <th>Alternatives</th>
47
+ <th>Notes</th>
48
+ </tr>
49
+ <tr>
50
+ <td>proxy</td>
51
+ <td>PROXY</td>
52
+ <td>Requires the proxy scheme to be present.</td>
53
+ </tr>
54
+ <tr>
55
+ <td>socks_proxy</td>
56
+ <td>SOCKS_PROXY<br>socks5_proxy<br>SOCKS5_PROXY</td>
57
+ <td>Implies the SOCKS5 proxy scheme.</td>
58
+ </tr>
59
+ <tr>
60
+ <td>socks4a_proxy</td>
61
+ <td>SOCKS4A_PROXY</td>
62
+ <td>Implies the SOCKS4A proxy scheme.</td>
63
+ </tr>
64
+ <tr>
65
+ <td>socks4_proxy</td>
66
+ <td>PROXY</td>
67
+ <td>Implies the SOCKS4 proxy scheme.</td>
68
+ </tr>
69
+ <tr>
70
+ <td>http_proxy</td>
71
+ <td>HTTP_PROXY</td>
72
+ <td>Implies the HTTP proxy scheme.</td>
73
+ </tr>
74
+ </table>
75
+
76
+ ### Ruby
77
+
78
+ ```ruby
79
+ require "proxifier/proxy"
80
+
81
+ proxy = Proxifier::Proxy("socks://localhost")
82
+ socket = proxy.open("www.google.com", 80)
83
+ socket << "GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"
84
+ socket.gets # => "HTTP/1.1 200 OK\r\n"
85
+ ```
86
+
87
+ ## Supported Proxies
88
+
89
+ <table>
90
+ <tr>
91
+ <th>Protocol</th>
92
+ <th>Formats</th>
93
+ <th>Notes</th>
94
+ </tr>
95
+ <tr>
96
+ <td>HTTP</td>
97
+ <td><pre>http://[username[:password]@]host[:port][?tunnel=false]</pre></td>
98
+ <td>
99
+ The port defaults to 80. This is currently a limitation that may be solved in the future.<br>
100
+ Appending <code>?tunnel=false</code> forces the proxy to not use <code>CONNECT</code>.</td>
101
+ </tr>
102
+ <tr>
103
+ <td>SOCKS5</td>
104
+ <td><pre>socks://[username[:password]@]host[:port]
105
+ socks5://[username[:password]@]host[:port]</pre></td>
106
+ <td>
107
+ Port defaults to 1080.
108
+ </td>
109
+ </tr>
110
+ <tr>
111
+ <td>SOCKS4A</td>
112
+ <td><pre>socks4a://[username@]host[:port]</pre></td>
113
+ <td>Not yet implemented.</td>
114
+ </tr>
115
+ <tr>
116
+ <td>SOCKS4</td>
117
+ <td><pre>socks4://[username@]host[:port]</pre></td>
118
+ <td>Currently hangs. Not sure if the problem is with code or server.</td>
119
+ </tr>
120
+ </table>
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ executable = File.expand_path("../" + Gem.default_exec_format % "irb", Gem.ruby)
4
+ full_gem_path = Gem.loaded_specs["proxifier"].full_gem_path
5
+ load_paths = Gem.loaded_specs["proxifier"].require_paths.map { |p| "-I#{File.join(full_gem_path, p)}" }
6
+ # TODO: support argument switches
7
+
8
+ exec(executable, *load_paths, "-rproxifier/env", *ARGV)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ executable = Gem.ruby
4
+ full_gem_path = Gem.loaded_specs["proxifier"].full_gem_path
5
+ load_paths = Gem.loaded_specs["proxifier"].require_paths.map { |p| "-I#{File.join(full_gem_path, p)}" }
6
+ # TODO: support argument switches
7
+
8
+ exec(executable, *load_paths, "-rproxifier/env", *ARGV)
@@ -0,0 +1,25 @@
1
+ require "uri"
2
+ require "uri/socks"
3
+
4
+ module Proxifier
5
+ require "proxifier/version"
6
+
7
+ autoload :HTTPProxy, "proxifier/proxies/http"
8
+ autoload :SOCKSProxy, "proxifier/proxies/socks"
9
+ autoload :SOCKS5Proxy, "proxifier/proxies/socks"
10
+ autoload :SOCKS4Proxy, "proxifier/proxies/socks4"
11
+ autoload :SOCKS4AProxy, "proxifier/proxies/socks4a"
12
+
13
+ def self.Proxy(url, options = {})
14
+ url = URI.parse(url)
15
+
16
+ raise(ArgumentError, "proxy url has no scheme") unless url.scheme
17
+ begin
18
+ klass = const_get("#{url.scheme.upcase}Proxy")
19
+ rescue NameError
20
+ raise(ArgumentError, "unknown proxy scheme `#{url.scheme}'")
21
+ end
22
+
23
+ klass.new(url, options)
24
+ end
25
+ end
@@ -0,0 +1,113 @@
1
+ require "socket"
2
+ require "proxifier"
3
+
4
+ module Proxifier
5
+ class Proxy
6
+ def open(host, port, local_host = nil, local_port = nil)
7
+ return TCPSocket.new(host, port, local_host, local_port, :proxy => nil) unless proxify?(host)
8
+
9
+ socket = TCPSocket.new(self.host, self.port, local_host, local_port, :proxy => nil)
10
+
11
+ begin
12
+ proxify(socket, host, port)
13
+ rescue
14
+ socket.close
15
+ raise
16
+ end
17
+
18
+ socket
19
+ end
20
+ end
21
+
22
+ module Proxify
23
+ def self.included(klass)
24
+ klass.class_eval do
25
+ alias_method :initialize_without_proxy, :initialize
26
+ alias_method :initialize, :initialize_with_proxy
27
+ end
28
+ end
29
+
30
+ def initialize_with_proxy(host, port, options_or_local_host = {}, local_port = nil, options_if_local_host = {})
31
+ if options_or_local_host.is_a?(Hash)
32
+ local_host = nil
33
+ options = options_or_local_host
34
+ else
35
+ local_host = options_or_local_host
36
+ options = options_if_local_host
37
+ end
38
+
39
+ if options[:proxy] && (proxy = Proxifier::Proxy(options.delete(:proxy), options)) && proxy.proxify?(host)
40
+ initialize_without_proxy(proxy.host, proxy.port, local_host, local_port)
41
+ begin
42
+ proxy.proxify(self, host, port)
43
+ rescue
44
+ close
45
+ raise
46
+ end
47
+ else
48
+ initialize_without_proxy(host, port, local_host, local_port)
49
+ end
50
+ end
51
+ end
52
+
53
+ module EnvironmentProxify
54
+ def self.included(klass)
55
+ klass.class_eval do
56
+ extend ClassMethods
57
+ alias_method :initialize_without_environment_proxy, :initialize
58
+ alias_method :initialize, :initialize_with_environment_proxy
59
+ end
60
+ end
61
+
62
+ def initialize_with_environment_proxy(host, port, options_or_local_host = {}, local_port = nil, options_if_local_host = {})
63
+ if options_or_local_host.is_a?(Hash)
64
+ local_host = nil
65
+ options = options_or_local_host
66
+ else
67
+ local_host = options_or_local_host
68
+ options = options_if_local_host
69
+ end
70
+
71
+ options = { :proxy => environment_proxy, :no_proxy => environment_no_proxy }.merge(options)
72
+ initialize_without_environment_proxy(host, port, local_host, local_port, options)
73
+ end
74
+
75
+ def environment_proxy
76
+ self.class.environment_proxy
77
+ end
78
+
79
+ def environment_no_proxy
80
+ self.class.environment_no_proxy
81
+ end
82
+
83
+ module ClassMethods
84
+ def environment_proxy
85
+ ENV["proxy"] || ENV["PROXY"] || specific_environment_proxy
86
+ end
87
+
88
+ def environment_no_proxy
89
+ ENV["no_proxy"] || ENV["NO_PROXY"]
90
+ end
91
+
92
+ private
93
+ def specific_environment_proxy
94
+ %w(socks socks5 socks4a socks4 http).each do |type|
95
+ if proxy = ENV["#{type}_proxy"] || ENV["#{type.upcase}_PROXY"]
96
+ scheme = "#{type}://"
97
+
98
+ proxy = proxy.dup
99
+ proxy.insert(0, scheme) unless proxy.index(scheme) == 0
100
+ return proxy
101
+ end
102
+ end
103
+
104
+ nil
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ class TCPSocket
111
+ include Proxifier::Proxify
112
+ include Proxifier::EnvironmentProxify
113
+ end
@@ -0,0 +1,20 @@
1
+ require "net/http"
2
+ require "proxifier/proxy"
3
+
4
+ module Proxifier
5
+ class HTTPProxy < Proxy
6
+ def do_proxify(socket, host, port)
7
+ return if query_options["tunnel"] == "false"
8
+
9
+ socket << "CONNECT #{host}:#{port} HTTP/1.1\r\n"
10
+ socket << "Host: #{host}:#{port}\r\n"
11
+ socket << "Proxy-Authorization: Basic #{["#{user}:#{password}"].pack("m").chomp}\r\n" if user
12
+ socket << "User-Agent: #{user_agent}\r\n" if user_agent
13
+ socket << "\r\n"
14
+
15
+ buffer = Net::BufferedIO.new(socket)
16
+ response = Net::HTTPResponse.read_new(buffer)
17
+ response.error! unless response.is_a?(Net::HTTPOK)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,103 @@
1
+ require "ipaddr"
2
+ require "proxifier/proxy"
3
+
4
+ module Proxifier
5
+ class SOCKSProxy < Proxy
6
+ VERSION = 0x05
7
+
8
+ def do_proxify(socket, host, port)
9
+ authenticaton_method = greet(socket)
10
+ authenticate(socket, authenticaton_method)
11
+ connect(socket, host, port)
12
+ end
13
+
14
+ protected
15
+ def greet(socket)
16
+ methods = authentication_methods
17
+
18
+ socket << [VERSION, methods.size, *methods].pack("CCC#{methods.size}")
19
+ version, authentication_method = socket.read(2).unpack("CC")
20
+ check_version(version)
21
+
22
+ authentication_method
23
+ end
24
+
25
+ def authenticate(socket, method)
26
+ case method
27
+ when 0x00 # NO AUTHENTICATION REQUIRED
28
+ when 0x02 # USERNAME/PASSWORD
29
+ user &&= user[0, 0xFF]
30
+ password &&= password[0, 0xFF]
31
+
32
+ socket << [user.size, user, password.size, password].pack("CA#{user.size}CA#{password.size}")
33
+ version, status = socket.read(2).unpack("CC")
34
+ check_version(version)
35
+
36
+ case status
37
+ when 0x00 # SUCCESS
38
+ else
39
+ raise "SOCKS5 username/password authentication failed"
40
+ end
41
+ else
42
+ raise "no acceptable SOCKS5 authentication methods"
43
+ end
44
+ end
45
+
46
+ def connect(socket, host, port)
47
+ host = host[0, 0xFF]
48
+ socket << [VERSION, 0x01, 0x00, 0x03, host.size, host, port].pack("CCCCCA#{host.size}n")
49
+ version, status, _, type = socket.read(4).unpack("CCCC")
50
+ check_version(version)
51
+
52
+ case status
53
+ when 0x00 # succeeded
54
+ when 0x01 # general SOCKS server failure
55
+ raise "general SOCKS server failure"
56
+ when 0x02 # connection not allowed by ruleset
57
+ raise "connection not allowed by ruleset"
58
+ when 0x03 # Network unreachable
59
+ raise "network unreachable"
60
+ when 0x04 # Host unreachable
61
+ raise "host unreachable"
62
+ when 0x05 # Connection refused
63
+ raise "connection refused"
64
+ when 0x06 # TTL expired
65
+ raise "TTL expired"
66
+ when 0x07 # Command not supported
67
+ raise "command not supported"
68
+ when 0x08 # Address type not supported
69
+ raise "address type not supported"
70
+ else # unassigned
71
+ raise "unknown SOCKS error"
72
+ end
73
+
74
+ case type
75
+ when 0x01 # IP V4 address
76
+ destination = IPAddr.ntop(socket.read(4))
77
+ when 0x03 # DOMAINNAME
78
+ length = socket.read(1).unpack("C").first
79
+ destination = socket.read(length).unpack("A#{length}")
80
+ when 0x04 # IP V6 address
81
+ destination = IPAddr.ntop(socket.read(16))
82
+ else
83
+ raise "unsupported SOCKS5 address type"
84
+ end
85
+
86
+ port = socket.read(2).unpack("n").first
87
+ end
88
+
89
+ def check_version(version, should_be = VERSION)
90
+ raise "mismatched SOCKS version" unless version == should_be
91
+ end
92
+
93
+ private
94
+ def authentication_methods
95
+ methods = []
96
+ methods << 0x00 # NO AUTHENTICATION REQUIRED
97
+ methods << 0x02 if user # USERNAME/PASSWORD
98
+ methods
99
+ end
100
+ end
101
+
102
+ SOCKS5Proxy = SOCKSProxy
103
+ end
@@ -0,0 +1,44 @@
1
+ require "proxifier/proxies/socks"
2
+
3
+ module Proxifier
4
+ class SOCKS4Proxy < SOCKSProxy
5
+ VERSION = 0x04
6
+
7
+ protected
8
+ def greet(socket)
9
+ # noop
10
+ end
11
+
12
+ def authenticate(socket, method)
13
+ # noop
14
+ end
15
+
16
+ def connect(socket, host, port)
17
+ begin
18
+ ip = IPAddr.new(host)
19
+ rescue ArgumentError
20
+ ip = IPAddr.new(Socket.getaddrinfo(host, nil, :INET, :STREAM).first)
21
+ end
22
+
23
+ socket << [VERSION, 0x01, port].pack("CCn") << ip.hton
24
+ socket << user if user
25
+ socket << 0x00
26
+
27
+ version, status, port = socket.read(4).unpack("CCn")
28
+ check_version(version, 0x00)
29
+ ip = IPAddr.ntop(socket.read(4))
30
+
31
+ case status
32
+ when 0x5A # request granted
33
+ when 0x5B # request rejected or failed
34
+ raise "request rejected or failed"
35
+ when 0x5C # request rejected becasue SOCKS server cannot connect to identd on the client
36
+ raise "request rejected becasue SOCKS server cannot connect to identd on the client"
37
+ when 0x5D # request rejected because the client program and identd report different user-ids
38
+ raise "request rejected because the client program and identd report different user-ids"
39
+ else
40
+ raise "unknown SOCKS error"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ require "proxifier/proxies/socks"
2
+
3
+ module Proxifier
4
+ class SOCKS4AProxy < SOCKSProxy
5
+ def do_proxify(*)
6
+ raise NotImplementedError, "SOCKS4A is not yet implemented"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ require "socket"
2
+ require "uri"
3
+ require "uri/socks"
4
+
5
+ module Proxifier
6
+ class Proxy
7
+ class << self
8
+ def proxify?(host, no_proxy = nil)
9
+ return true unless no_proxy
10
+
11
+ dont_proxy = no_proxy.split(",")
12
+ dont_proxy.none? { |h| host =~ /#{h}\Z/ }
13
+ end
14
+ end
15
+
16
+ attr_reader :url, :options
17
+
18
+ def initialize(url, options = {})
19
+ url = URI.parse(uri) unless url.is_a?(URI::Generic)
20
+ @url, @options = url, options
21
+ end
22
+
23
+ def open(host, port, local_host = nil, local_port = nil)
24
+ return TCPSocket.new(host, port, local_host, local_port) unless proxify?(host)
25
+
26
+ socket = TCPSocket.new(self.host, self.port, local_host, local_port)
27
+
28
+ begin
29
+ proxify(socket, host, port)
30
+ rescue
31
+ socket.close
32
+ raise
33
+ end
34
+
35
+ socket
36
+ end
37
+
38
+ def proxify?(host)
39
+ self.class.proxify?(host, options[:no_proxy])
40
+ end
41
+
42
+ def proxify(socket, host, port)
43
+ do_proxify(socket, host, port)
44
+ end
45
+
46
+ %w(host port user password query version).each do |attr|
47
+ class_eval "def #{attr}; url.#{attr} end"
48
+ end
49
+
50
+ def query_options
51
+ @query_options ||= query ? Hash[query.split("&").map { |q| q.split("=") }] : {}
52
+ end
53
+
54
+ %w(no_proxy user_agent).each do |option|
55
+ class_eval "def #{option}; options[:#{option}] end"
56
+ end
57
+
58
+ protected
59
+ def do_proxify(socket, host, port)
60
+ raise NotImplementedError, "#{self} must implement do_proxify"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module Proxifier
2
+ VERSION = "1.0.4"
3
+ end
@@ -0,0 +1,18 @@
1
+ require "uri/generic"
2
+
3
+ module URI
4
+ class SOCKS < Generic
5
+ DEFAULT_PORT = 1080
6
+ COMPONENT = [:scheme, :userinfo, :host, :port, :query].freeze
7
+ end
8
+ @@schemes["SOCKS"] = SOCKS
9
+ @@schemes["SOCKS5"] = SOCKS
10
+
11
+ class SOCKS4 < SOCKS
12
+ end
13
+ @@schemes["SOCKS4"] = SOCKS4
14
+
15
+ class SOCKS4A < SOCKS
16
+ end
17
+ @@schemes["SOCKS4A"] = SOCKS4A
18
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: proxifier-fork
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Kadolph
8
+ - Andy Brody
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-02-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ description: Proxifier adds support for HTTP or SOCKS proxies and lets you force TCPSocket
29
+ to use proxies.
30
+ email:
31
+ - samuel@kadolph.com
32
+ - git@abrody.com
33
+ executables:
34
+ - pirb
35
+ - pruby
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - LICENSE
40
+ - README.md
41
+ - bin/pirb
42
+ - bin/pruby
43
+ - lib/proxifier.rb
44
+ - lib/proxifier/env.rb
45
+ - lib/proxifier/proxies/http.rb
46
+ - lib/proxifier/proxies/socks.rb
47
+ - lib/proxifier/proxies/socks4.rb
48
+ - lib/proxifier/proxies/socks4a.rb
49
+ - lib/proxifier/proxy.rb
50
+ - lib/proxifier/version.rb
51
+ - lib/uri/socks.rb
52
+ homepage: https://github.com/ab/ruby-proxifier
53
+ licenses: []
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 2.4.5.1
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: Proxifier is a gem to force ruby to use a proxy.
75
+ test_files: []