Class: WinRM::HTTP::HttpTransport

Inherits:
Object
  • Object
show all
Defined in:
lib/winrm/http/transport.rb

Overview

A generic HTTP transport that utilized HTTPClient to send messages back and forth. This backend will maintain state for every WinRMWebService instance that is instantiated so it is possible to use GSSAPI with Keep-Alive.

Constant Summary collapse

DEFAULT_RECEIVE_TIMEOUT =

Set this to an unreasonable amount because WinRM has its own timeouts

3600

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(endpoint) ⇒ HttpTransport

Returns a new instance of HttpTransport.



30
31
32
33
34
35
# File 'lib/winrm/http/transport.rb', line 30

def initialize(endpoint)
  @endpoint = endpoint.is_a?(String) ? URI.parse(endpoint) : endpoint
  @httpcli = HTTPClient.new(agent_name: 'Ruby WinRM Client')
  @httpcli.receive_timeout = DEFAULT_RECEIVE_TIMEOUT
  @logger = Logging.logger[self]
end

Instance Attribute Details

#endpointObject (readonly)

Returns the value of attribute endpoint.



28
29
30
# File 'lib/winrm/http/transport.rb', line 28

def endpoint
  @endpoint
end

Instance Method Details

#basic_auth_only!Object

We’ll need this to force basic authentication if desired



60
61
62
63
# File 'lib/winrm/http/transport.rb', line 60

def basic_auth_only!
  auths = @httpcli.www_auth.instance_variable_get('@authenticator')
  auths.delete_if { |i| i.scheme !~ /basic/i }
end

#no_ssl_peer_verification!Object

Disable SSL Peer Verification



72
73
74
# File 'lib/winrm/http/transport.rb', line 72

def no_ssl_peer_verification!
  @httpcli.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

#no_sspi_auth!Object

Disable SSPI Auth



66
67
68
69
# File 'lib/winrm/http/transport.rb', line 66

def no_sspi_auth!
  auths = @httpcli.www_auth.instance_variable_get('@authenticator')
  auths.delete_if { |i| i.is_a? HTTPClient::SSPINegotiateAuth }
end

#receive_timeoutObject



117
118
119
# File 'lib/winrm/http/transport.rb', line 117

def receive_timeout
  @httpcli.receive_timeout
end

#receive_timeout=(sec) ⇒ Object

HTTP Client receive timeout. How long should a remote call wait for a for a response from WinRM?



113
114
115
# File 'lib/winrm/http/transport.rb', line 113

def receive_timeout=(sec)
  @httpcli.receive_timeout = sec
end

#send_request(message) ⇒ Object

Sends the SOAP payload to the WinRM service and returns the service’s SOAP response. If an error occurrs an appropriate error is raised.

Parameters:

  • The (String)

    XML SOAP message



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/winrm/http/transport.rb', line 42

def send_request(message)
  ssl_peer_fingerprint_verification!
  log_soap_message(message)
  hdr = { 'Content-Type' => 'application/soap+xml;charset=UTF-8',
          'Content-Length' => message.bytesize }
  # We need to add this header if using Client Certificate authentication
  unless @httpcli.ssl_config.client_cert.nil?
    hdr['Authorization'] = 'http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual'
  end

  resp = @httpcli.post(@endpoint, message, hdr)
  log_soap_message(resp.http_body.content)
  verify_ssl_fingerprint(resp.peer_cert)
  handler = WinRM::ResponseHandler.new(resp.http_body.content, resp.status)
  handler.parse_to_xml
end

#ssl_peer_fingerprint_verification!Object

SSL Peer Fingerprint Verification prior to connecting



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/winrm/http/transport.rb', line 77

def ssl_peer_fingerprint_verification!
  return unless @ssl_peer_fingerprint && ! @ssl_peer_fingerprint_verified

  with_untrusted_ssl_connection do |connection|
    connection_cert = connection.peer_cert_chain.last
    verify_ssl_fingerprint(connection_cert)
  end
  @logger.info("initial ssl fingerprint #{@ssl_peer_fingerprint} verified\n")
  @ssl_peer_fingerprint_verified = true
  no_ssl_peer_verification!
end

#verify_ssl_fingerprint(cert) ⇒ Object

compare @ssl_peer_fingerprint to current ssl context



104
105
106
107
108
109
# File 'lib/winrm/http/transport.rb', line 104

def verify_ssl_fingerprint(cert)
  return unless @ssl_peer_fingerprint
  conn_fingerprint = OpenSSL::Digest::SHA1.new(cert.to_der).to_s
  return unless @ssl_peer_fingerprint.casecmp(conn_fingerprint) != 0
  fail "ssl fingerprint mismatch!!!!\n"
end

#with_untrusted_ssl_connectionObject

Connect without verification to retrieve untrusted ssl context



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/winrm/http/transport.rb', line 90

def with_untrusted_ssl_connection
  noverify_peer_context = OpenSSL::SSL::SSLContext.new
  noverify_peer_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
  tcp_connection = TCPSocket.new(@endpoint.host, @endpoint.port)
  begin
    ssl_connection = OpenSSL::SSL::SSLSocket.new(tcp_connection, noverify_peer_context)
    ssl_connection.connect
    yield ssl_connection
  ensure
    tcp_connection.close
  end
end