@@ -3,10 +3,23 @@ require "socket"
3
3
require " base64"
4
4
require " openssl"
5
5
6
+ {% if compare_versions(Crystal ::VERSION , " 1.0.1" ) < 0 % }
7
+ abstract class OpenSSL::SSL::Context
8
+ def add_x509_verify_flags (flags : OpenSSL ::SSL ::X509VerifyFlags )
9
+ param = LibSSL .ssl_ctx_get0_param(@handle )
10
+ ret = LibCrypto .x509_verify_param_set_flags(param, flags)
11
+ raise OpenSSL ::Error .new(" X509_VERIFY_PARAM_set_flags)" ) unless ret == 1
12
+ end
13
+ end
14
+ {% end % }
15
+
6
16
# Based on https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh/proxy/http.rb
7
17
class ConnectProxy
8
- PROXY_PASS = ENV [" PROXY_PASSWORD" ]?
9
- PROXY_USER = ENV [" PROXY_USERNAME" ]?
18
+ class_property username : String ? = ENV [" PROXY_USERNAME" ]?
19
+ class_property password : String ? = ENV [" PROXY_PASSWORD" ]?
20
+ class_property proxy_uri : String ? = ENV [" https_proxy" ]? || ENV [" http_proxy" ]? || ENV [" HTTPS_PROXY" ]? || ENV [" HTTP_PROXY" ]?
21
+ class_property verify_tls : Bool = ENV [" PROXY_VERIFY_TLS" ]? != " false"
22
+ class_property disable_crl_checks : Bool = ENV [" PROXY_DISABLE_CRL_CHECKS" ]? == " true"
10
23
11
24
# The hostname or IP address of the HTTP proxy.
12
25
getter proxy_host : String
@@ -21,17 +34,17 @@ class ConnectProxy
21
34
# Simple check for relevant environment
22
35
#
23
36
def self.behind_proxy ?
24
- !! ( ENV [ " https_proxy " ]? || ENV [ " http_proxy " ]? || ENV [ " HTTP_PROXY " ]? || ENV [ " HTTPS_PROXY " ]?)
37
+ !! proxy_uri
25
38
end
26
39
27
40
# Grab the host, port
28
41
#
29
42
def self.parse_proxy_url
30
- proxy_url = ENV [ " https_proxy " ]? || ENV [ " http_proxy " ]? || ENV [ " HTTP_PROXY " ]? || ENV [ " HTTPS_PROXY " ]
43
+ proxy_url = proxy_uri.not_nil!
31
44
32
45
uri = URI .parse(proxy_url)
33
- user = uri.user || PROXY_USER
34
- pass = uri.password || PROXY_PASS
46
+ user = uri.user || username
47
+ pass = uri.password || password
35
48
host = uri.host.not_nil!
36
49
port = uri.port || URI .default_port(uri.scheme.not_nil!).not_nil!
37
50
creds = {username: user, password: pass} if user && pass
@@ -48,7 +61,7 @@ class ConnectProxy
48
61
# * :user => the user name to use when authenticating to the proxy
49
62
# * :password => the password to use when authenticating
50
63
def initialize (host, port, auth : NamedTuple (username: String , password: String )? = nil )
51
- auth = {username: PROXY_USER . as(String ), password: PROXY_PASS . as(String )} if ! auth && PROXY_USER && PROXY_PASS
64
+ auth = {username: self .class.username. as(String ), password: self .class.password. as(String )} if ! auth && self .class.username && self .class.password
52
65
@credentials = Base64 .strict_encode(" #{ auth[:username ] } :#{ auth[:password ] } " ).gsub(/\s / , " " ) if auth
53
66
@proxy_host = host.gsub(/^http[s] ?\:\/\/ / , " " )
54
67
@proxy_port = port
@@ -129,6 +142,14 @@ class ConnectProxy
129
142
socket = {% if compare_versions(Crystal ::VERSION , " 0.36.0" ) < 0 % } @socket {% else % } @io {% end % }
130
143
return if socket && ! socket.closed?
131
144
145
+ if tls = @tls
146
+ if ! ConnectProxy .verify_tls
147
+ tls.verify_mode = OpenSSL ::SSL ::VerifyMode ::NONE
148
+ elsif ConnectProxy .disable_crl_checks
149
+ tls.add_x509_verify_flags OpenSSL ::SSL ::X509VerifyFlags ::IGNORE_CRITICAL
150
+ end
151
+ end
152
+
132
153
{% if compare_versions(Crystal ::VERSION , " 0.36.0" ) < 0 % }
133
154
begin
134
155
@socket = proxy.open(@host , @port , @tls , ** proxy_connection_options)
0 commit comments