11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 
     | 
    
      # File 'lib/chef/monkey_patches/net-http.rb', line 11
def connect
  if use_ssl?
            @ssl_context = OpenSSL::SSL::SSLContext.new
  end
  if proxy?
    conn_addr = proxy_address
    conn_port = proxy_port
  else
    conn_addr = conn_address
    conn_port = port
  end
  Chef::Log.debug("opening connection to #{conn_addr}:#{conn_port}...")
  s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
    begin
      TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
    rescue => e
      raise e, "Failed to open TCP connection to " +
        "#{conn_addr}:#{conn_port} (#{e.message})"
    end
  }
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
  Chef::Log.debug("opened")
  if use_ssl?
    if proxy?
      plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
                                  write_timeout: @write_timeout,
                                  continue_timeout: @continue_timeout,
                                  debug_output: @debug_output)
      buf = "CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n"
      buf << "Host: #{@address}:#{@port}\r\n"
      if proxy_user
        credential = ["#{proxy_user}:#{proxy_pass}"].pack("m0")
        buf << "Proxy-Authorization: Basic #{credential}\r\n"
      end
      buf << "\r\n"
      plain_sock.write(buf)
      HTTPResponse.read_new(plain_sock).value
          end
    ssl_parameters = {}
    iv_list = instance_variables
    SSL_IVNAMES.each_with_index do |ivname, i|
      if iv_list.include?(ivname)
        value = instance_variable_get(ivname)
        unless value.nil?
          ssl_parameters[SSL_ATTRIBUTES[i]] = value
        end
      end
    end
    @ssl_context.set_params(ssl_parameters)
    unless @ssl_context.session_cache_mode.nil?       @ssl_context.session_cache_mode =
          OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
          OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
    end
    if @ssl_context.respond_to?(:session_new_cb)       @ssl_context.session_new_cb = proc { |sock, sess| @ssl_session = sess }
    end
            verify_hostname = @ssl_context.verify_hostname
            require "resolv" unless defined?(Resolv)
        case @address
    when ::Resolv::IPv4::Regex, ::Resolv::IPv6::Regex
            
            @ssl_context.verify_hostname = false
    else
      ssl_host_address = @address
    end
    Chef::Log.debug("starting SSL for #{conn_addr}:#{conn_port}...")
    s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
    s.sync_close = true
    s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
    if @ssl_session &&
        (Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout)
      s.session = @ssl_session
    end
    ssl_socket_connect(s, @open_timeout)
    if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
      s.post_connection_check(@address)
    end
    Chef::Log.debug("SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}")
  end
  @socket = BufferedIO.new(s, read_timeout: @read_timeout,
                          write_timeout: @write_timeout,
                          continue_timeout: @continue_timeout,
                          debug_output: @debug_output)
  @last_communicated = nil
  on_connect
rescue => exception
  if s
    Chef::Log.debug("Conn close because of connect error #{exception}")
    s.close
  end
  raise
end
     |