proxifier-fork 1.0.4

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.
@@ -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: []