class WinRM::HTTP::HttpTransport
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.
Attributes
endpoint[R]
Public Class Methods
new(endpoint, options)
click to toggle source
# File lib/winrm/http/transport.rb, line 26 def initialize(endpoint, options) @endpoint = endpoint.is_a?(String) ? URI.parse(endpoint) : endpoint @httpcli = HTTPClient.new(agent_name: 'Ruby WinRM Client') @logger = Logging.logger[self] @httpcli.receive_timeout = options[:receive_timeout] end
Public Instance Methods
basic_auth_only!()
click to toggle source
We’ll need this to force basic authentication if desired
# File lib/winrm/http/transport.rb, line 56 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!()
click to toggle source
Disable SSL Peer Verification
# File lib/winrm/http/transport.rb, line 68 def no_ssl_peer_verification! @httpcli.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE end
no_sspi_auth!()
click to toggle source
Disable SSPI Auth
# File lib/winrm/http/transport.rb, line 62 def no_sspi_auth! auths = @httpcli.www_auth.instance_variable_get('@authenticator') auths.delete_if { |i| i.is_a? HTTPClient::SSPINegotiateAuth } end
send_request(message)
click to toggle source
Sends the SOAP payload to the WinRM
service and returns the service’s SOAP response. If an error occurrs an appropriate error is raised.
@param [String] The XML SOAP message @returns [REXML::Document] The parsed response body
# File lib/winrm/http/transport.rb, line 38 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!()
click to toggle source
SSL Peer Fingerprint Verification prior to connecting
# File lib/winrm/http/transport.rb, line 73 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 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)
click to toggle source
compare @ssl_peer_fingerprint to current ssl context
# File lib/winrm/http/transport.rb, line 100 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 raise "ssl fingerprint mismatch!!!!\n" end
with_untrusted_ssl_connection() { |ssl_connection| ... }
click to toggle source
Connect without verification to retrieve untrusted ssl context
# File lib/winrm/http/transport.rb, line 86 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
Protected Instance Methods
body(message, length, type = 'application/HTTP-SPNEGO-session-encrypted')
click to toggle source
# File lib/winrm/http/transport.rb, line 111 def body(message, length, type = 'application/HTTP-SPNEGO-session-encrypted') [ '--Encrypted Boundary', "Content-Type: #{type}", "OriginalContent: type=application/soap+xml;charset=UTF-8;Length=#{length}", '--Encrypted Boundary', 'Content-Type: application/octet-stream', "#{message}--Encrypted Boundary--" ].join("\r\n").concat("\r\n") end
log_soap_message(message)
click to toggle source
# File lib/winrm/http/transport.rb, line 122 def log_soap_message(message) return unless @logger.debug? xml_msg = REXML::Document.new(message) formatter = REXML::Formatters::Pretty.new(2) formatter.compact = true formatter.write(xml_msg, @logger) @logger.debug("\n") rescue StandardError => e @logger.debug("Couldn't log SOAP request/response: #{e.message} - #{message}") end