winrm 1.3.0.dev.3 → 1.3.0

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.
@@ -1,11 +1,13 @@
1
+ # encoding: UTF-8
2
+ #
1
3
  # Copyright 2014 Shawn Neal <sneal@sneal.net>
2
- #
4
+ #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
4
6
  # you may not use this file except in compliance with the License.
5
7
  # You may obtain a copy of the License at
6
- #
8
+ #
7
9
  # http://www.apache.org/licenses/LICENSE-2.0
8
- #
10
+ #
9
11
  # Unless required by applicable law or agreed to in writing, software
10
12
  # distributed under the License is distributed on an "AS IS" BASIS,
11
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +20,6 @@ module WinRM
18
20
  # Handles the raw WinRM HTTP response. Returns the body as an XML doc
19
21
  # or raises the appropriate WinRM error if the response is an error.
20
22
  class ResponseHandler
21
-
22
23
  # @param [String] The raw unparsed response body, if any
23
24
  # @param [Integer] The HTTP response status code
24
25
  def initialize(response_body, status_code)
@@ -30,53 +31,52 @@ module WinRM
30
31
  # doc or raises an appropriate error.
31
32
  #
32
33
  # @returns [REXML::Document] The parsed response body
33
- def parse_to_xml()
34
- raise_if_error()
34
+ def parse_to_xml
35
+ raise_if_error
35
36
  response_xml
36
37
  end
37
38
 
38
39
  private
39
40
 
40
- def response_xml()
41
+ def response_xml
41
42
  @response_xml ||= REXML::Document.new(@response_body)
42
43
  rescue REXML::ParseException => e
43
- raise WinRMHTTPTransportError.new("Unable to parse WinRM response: #{e.message}", @status_code)
44
+ raise WinRMHTTPTransportError.new(
45
+ "Unable to parse WinRM response: #{e.message}", @status_code)
44
46
  end
45
47
 
46
- def raise_if_error()
47
- return if @status_code == 200
48
- raise_if_auth_error()
49
- raise_if_wsman_fault()
50
- raise_if_wmi_error()
51
- raise_transport_error()
48
+ def raise_if_error
49
+ return if @status_code == 200
50
+ raise_if_auth_error
51
+ raise_if_wsman_fault
52
+ raise_if_wmi_error
53
+ raise_transport_error
52
54
  end
53
55
 
54
- def raise_if_auth_error()
55
- raise WinRMAuthorizationError.new if @status_code == 401
56
+ def raise_if_auth_error
57
+ fail WinRMAuthorizationError if @status_code == 401
56
58
  end
57
59
 
58
- def raise_if_wsman_fault()
60
+ def raise_if_wsman_fault
59
61
  soap_errors = REXML::XPath.match(response_xml, "//#{NS_SOAP_ENV}:Body/#{NS_SOAP_ENV}:Fault/*")
60
- if !soap_errors.empty?
61
- fault = REXML::XPath.first(soap_errors, "//#{NS_WSMAN_FAULT}:WSManFault")
62
- raise WinRMWSManFault.new(fault.to_s, fault.attributes['Code']) unless fault.nil?
63
- end
62
+ return if soap_errors.empty?
63
+ fault = REXML::XPath.first(soap_errors, "//#{NS_WSMAN_FAULT}:WSManFault")
64
+ fail WinRMWSManFault.new(fault.to_s, fault.attributes['Code']) unless fault.nil?
64
65
  end
65
66
 
66
- def raise_if_wmi_error()
67
+ def raise_if_wmi_error
67
68
  soap_errors = REXML::XPath.match(response_xml, "//#{NS_SOAP_ENV}:Body/#{NS_SOAP_ENV}:Fault/*")
68
- if !soap_errors.empty?
69
- error = REXML::XPath.first(soap_errors, "//#{NS_WSMAN_MSFT}:MSFT_WmiError")
70
- if !error.nil?
71
- error_code = REXML::XPath.first(error, "//#{NS_WSMAN_MSFT}:error_Code").text
72
- raise WinRMWMIError.new(error.to_s, error_code)
73
- end
74
- end
75
- end
69
+ return if soap_errors.empty?
76
70
 
77
- def raise_transport_error()
78
- raise WinRMHTTPTransportError.new('Bad HTTP response returned from server', @status_code)
71
+ error = REXML::XPath.first(soap_errors, "//#{NS_WSMAN_MSFT}:MSFT_WmiError")
72
+ return if error.nil?
73
+
74
+ error_code = REXML::XPath.first(error, "//#{NS_WSMAN_MSFT}:error_Code").text
75
+ fail WinRMWMIError.new(error.to_s, error_code)
79
76
  end
80
77
 
78
+ def raise_transport_error
79
+ fail WinRMHTTPTransportError.new('Bad HTTP response returned from server', @status_code)
80
+ end
81
81
  end
82
82
  end
@@ -1,11 +1,13 @@
1
+ # encoding: UTF-8
2
+ #
1
3
  # Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
2
- #
4
+ #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
4
6
  # you may not use this file except in compliance with the License.
5
7
  # You may obtain a copy of the License at
6
- #
8
+ #
7
9
  # http://www.apache.org/licenses/LICENSE-2.0
8
- #
10
+ #
9
11
  # Unless required by applicable law or agreed to in writing, software
10
12
  # distributed under the License is distributed on an "AS IS" BASIS,
11
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,20 +18,18 @@ require_relative 'response_handler'
16
18
 
17
19
  module WinRM
18
20
  module HTTP
19
-
20
21
  # A generic HTTP transport that utilized HTTPClient to send messages back and forth.
21
22
  # This backend will maintain state for every WinRMWebService instance that is instantiated so it
22
23
  # is possible to use GSSAPI with Keep-Alive.
23
24
  class HttpTransport
24
-
25
25
  # Set this to an unreasonable amount because WinRM has its own timeouts
26
- DEFAULT_RECEIVE_TIMEOUT = 3600
26
+ DEFAULT_RECEIVE_TIMEOUT = 3600
27
27
 
28
28
  attr_reader :endpoint
29
29
 
30
30
  def initialize(endpoint)
31
31
  @endpoint = endpoint.is_a?(String) ? URI.parse(endpoint) : endpoint
32
- @httpcli = HTTPClient.new(:agent_name => 'Ruby WinRM Client')
32
+ @httpcli = HTTPClient.new(agent_name: 'Ruby WinRM Client')
33
33
  @httpcli.receive_timeout = DEFAULT_RECEIVE_TIMEOUT
34
34
  @logger = Logging.logger[self]
35
35
  end
@@ -41,23 +41,25 @@ module WinRM
41
41
  # @returns [REXML::Document] The parsed response body
42
42
  def send_request(message)
43
43
  log_soap_message(message)
44
- hdr = {'Content-Type' => 'application/soap+xml;charset=UTF-8', 'Content-Length' => message.length}
44
+ hdr = {
45
+ 'Content-Type' => 'application/soap+xml;charset=UTF-8',
46
+ 'Content-Length' => message.length }
45
47
  resp = @httpcli.post(@endpoint, message, hdr)
46
48
  log_soap_message(resp.http_body.content)
47
49
  handler = WinRM::ResponseHandler.new(resp.http_body.content, resp.status)
48
- handler.parse_to_xml()
50
+ handler.parse_to_xml
49
51
  end
50
52
 
51
53
  # We'll need this to force basic authentication if desired
52
54
  def basic_auth_only!
53
55
  auths = @httpcli.www_auth.instance_variable_get('@authenticator')
54
- auths.delete_if {|i| i.scheme !~ /basic/i}
56
+ auths.delete_if { |i| i.scheme !~ /basic/i }
55
57
  end
56
58
 
57
59
  # Disable SSPI Auth
58
60
  def no_sspi_auth!
59
61
  auths = @httpcli.www_auth.instance_variable_get('@authenticator')
60
- auths.delete_if {|i| i.is_a? HTTPClient::SSPINegotiateAuth }
62
+ auths.delete_if { |i| i.is_a? HTTPClient::SSPINegotiateAuth }
61
63
  end
62
64
 
63
65
  # Disable SSL Peer Verification
@@ -71,7 +73,7 @@ module WinRM
71
73
  @httpcli.receive_timeout = sec
72
74
  end
73
75
 
74
- def receive_timeout()
76
+ def receive_timeout
75
77
  @httpcli.receive_timeout
76
78
  end
77
79
 
@@ -79,7 +81,7 @@ module WinRM
79
81
 
80
82
  def log_soap_message(message)
81
83
  return unless @logger.debug?
82
-
84
+
83
85
  xml_msg = REXML::Document.new(message)
84
86
  formatter = REXML::Formatters::Pretty.new(2)
85
87
  formatter.compact = true
@@ -90,7 +92,7 @@ module WinRM
90
92
  end
91
93
  end
92
94
 
93
-
95
+ # Plain text, insecure, HTTP transport
94
96
  class HttpPlaintext < HttpTransport
95
97
  def initialize(endpoint, user, pass, opts)
96
98
  super(endpoint)
@@ -114,12 +116,15 @@ module WinRM
114
116
  end
115
117
 
116
118
  # Uses Kerberos/GSSAPI to authenticate and encrypt messages
119
+ # rubocop:disable Metrics/ClassLength
117
120
  class HttpGSSAPI < HttpTransport
118
121
  # @param [String,URI] endpoint the WinRM webservice endpoint
119
122
  # @param [String] realm the Kerberos realm we are authenticating to
120
123
  # @param [String<optional>] service the service name, default is HTTP
121
124
  # @param [String<optional>] keytab the path to a keytab file if you are using one
125
+ # rubocop:disable Lint/UnusedMethodArgument
122
126
  def initialize(endpoint, realm, service = nil, keytab = nil, opts)
127
+ # rubocop:enable Lint/UnusedMethodArgument
123
128
  super(endpoint)
124
129
  # Remove the GSSAPI auth from HTTPClient because we are doing our own thing
125
130
  no_sspi_auth!
@@ -137,18 +142,20 @@ module WinRM
137
142
  resp = send_kerberos_request(message)
138
143
 
139
144
  if resp.status == 401
140
- @logger.debug "Got 401 - reinitializing Kerberos and retrying one more time"
145
+ @logger.debug 'Got 401 - reinitializing Kerberos and retrying one more time'
141
146
  init_krb
142
147
  resp = send_kerberos_request(message)
143
148
  end
144
149
 
145
150
  handler = WinRM::ResponseHandler.new(winrm_decrypt(resp.http_body.content), resp.status)
146
- handler.parse_to_xml()
151
+ handler.parse_to_xml
147
152
  end
148
153
 
149
-
150
154
  private
151
155
 
156
+ # rubocop:disable Metrics/MethodLength
157
+ # rubocop:disable Metrics/AbcSize
158
+
152
159
  # Sends the SOAP payload to the WinRM service and returns the service's
153
160
  # HTTP response.
154
161
  #
@@ -159,8 +166,11 @@ module WinRM
159
166
  original_length = message.length
160
167
  pad_len, emsg = winrm_encrypt(message)
161
168
  hdr = {
162
- "Connection" => "Keep-Alive",
163
- "Content-Type" => "multipart/encrypted;protocol=\"application/HTTP-Kerberos-session-encrypted\";boundary=\"Encrypted Boundary\""
169
+ 'Connection' => 'Keep-Alive',
170
+ 'Content-Type' =>
171
+ 'multipart/encrypted;' \
172
+ 'protocol="application/HTTP-Kerberos-session-encrypted";' \
173
+ 'boundary="Encrypted Boundary"'
164
174
  }
165
175
 
166
176
  body = <<-EOF
@@ -183,13 +193,14 @@ Content-Type: application/octet-stream\r
183
193
  token = @gsscli.init_context
184
194
  auth = Base64.strict_encode64 token
185
195
 
186
- hdr = {"Authorization" => "Kerberos #{auth}",
187
- "Connection" => "Keep-Alive",
188
- "Content-Type" => "application/soap+xml;charset=UTF-8"
196
+ hdr = {
197
+ 'Authorization' => "Kerberos #{auth}",
198
+ 'Connection' => 'Keep-Alive',
199
+ 'Content-Type' => 'application/soap+xml;charset=UTF-8'
189
200
  }
190
- @logger.debug "Sending HTTP POST for Kerberos Authentication"
201
+ @logger.debug 'Sending HTTP POST for Kerberos Authentication'
191
202
  r = @httpcli.post(@endpoint, '', hdr)
192
- itok = r.header["WWW-Authenticate"].pop
203
+ itok = r.header['WWW-Authenticate'].pop
193
204
  itok = itok.split.last
194
205
  itok = Base64.strict_decode64(itok)
195
206
  @gsscli.init_context(itok)
@@ -202,19 +213,30 @@ Content-Type: application/octet-stream\r
202
213
  iov = FFI::MemoryPointer.new(GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * iov_cnt)
203
214
 
204
215
  iov0 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address))
205
- iov0[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_HEADER | GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
216
+ iov0[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_HEADER | \
217
+ GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
206
218
 
207
- iov1 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 1)))
219
+ iov1 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(
220
+ FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 1)))
208
221
  iov1[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_DATA)
209
222
  iov1[:buffer].value = str
210
223
 
211
- iov2 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 2)))
212
- iov2[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_PADDING | GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
224
+ iov2 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(
225
+ FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 2)))
226
+ iov2[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_PADDING | \
227
+ GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
213
228
 
214
229
  conf_state = FFI::MemoryPointer.new :uint32
215
230
  min_stat = FFI::MemoryPointer.new :uint32
216
231
 
217
- maj_stat = GSSAPI::LibGSSAPI.gss_wrap_iov(min_stat, @gsscli.context, 1, GSSAPI::LibGSSAPI::GSS_C_QOP_DEFAULT, conf_state, iov, iov_cnt)
232
+ GSSAPI::LibGSSAPI.gss_wrap_iov(
233
+ min_stat,
234
+ @gsscli.context,
235
+ 1,
236
+ GSSAPI::LibGSSAPI::GSS_C_QOP_DEFAULT,
237
+ conf_state,
238
+ iov,
239
+ iov_cnt)
218
240
 
219
241
  token = [iov0[:buffer].length].pack('L')
220
242
  token += iov0[:buffer].value
@@ -224,7 +246,6 @@ Content-Type: application/octet-stream\r
224
246
  [pad_len, token]
225
247
  end
226
248
 
227
-
228
249
  # @return [String] the unencrypted response string
229
250
  def winrm_decrypt(str)
230
251
  @logger.debug "Decrypting SOAP message:\n#{str}"
@@ -232,18 +253,21 @@ Content-Type: application/octet-stream\r
232
253
  iov = FFI::MemoryPointer.new(GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * iov_cnt)
233
254
 
234
255
  iov0 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address))
235
- iov0[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_HEADER | GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
256
+ iov0[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_HEADER | \
257
+ GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_FLAG_ALLOCATE)
236
258
 
237
- iov1 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 1)))
259
+ iov1 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(
260
+ FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 1)))
238
261
  iov1[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_DATA)
239
262
 
240
- iov2 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 2)))
263
+ iov2 = GSSAPI::LibGSSAPI::GssIOVBufferDesc.new(
264
+ FFI::Pointer.new(iov.address + (GSSAPI::LibGSSAPI::GssIOVBufferDesc.size * 2)))
241
265
  iov2[:type] = (GSSAPI::LibGSSAPI::GSS_IOV_BUFFER_TYPE_DATA)
242
266
 
243
267
  str.force_encoding('BINARY')
244
268
  str.sub!(/^.*Content-Type: application\/octet-stream\r\n(.*)--Encrypted.*$/m, '\1')
245
269
 
246
- len = str.unpack("L").first
270
+ len = str.unpack('L').first
247
271
  iov_data = str.unpack("LA#{len}A*")
248
272
  iov0[:buffer].value = iov_data[1]
249
273
  iov1[:buffer].value = iov_data[2]
@@ -254,13 +278,17 @@ Content-Type: application/octet-stream\r
254
278
  qop_state = FFI::MemoryPointer.new :uint32
255
279
  qop_state.write_int(0)
256
280
 
257
- maj_stat = GSSAPI::LibGSSAPI.gss_unwrap_iov(min_stat, @gsscli.context, conf_state, qop_state, iov, iov_cnt)
281
+ maj_stat = GSSAPI::LibGSSAPI.gss_unwrap_iov(
282
+ min_stat, @gsscli.context, conf_state, qop_state, iov, iov_cnt)
258
283
 
259
- @logger.debug "SOAP message decrypted (MAJ: #{maj_stat}, MIN: #{min_stat.read_int}):\n#{iov1[:buffer].value}"
284
+ @logger.debug "SOAP message decrypted (MAJ: #{maj_stat}, " \
285
+ "MIN: #{min_stat.read_int}):\n#{iov1[:buffer].value}"
260
286
 
261
287
  iov1[:buffer].value
262
288
  end
263
-
289
+ # rubocop:enable Metrics/MethodLength
290
+ # rubocop:enable Metrics/AbcSize
264
291
  end
292
+ # rubocop:enable Metrics/ClassLength
265
293
  end
266
294
  end # WinRM
data/lib/winrm/output.rb CHANGED
@@ -1,3 +1,19 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2014 Max Lincoln <max@devopsy.com>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
1
17
  module WinRM
2
18
  # This class holds raw output as a hash, and has convenience methods to parse.
3
19
  class Output < Hash
@@ -1,11 +1,13 @@
1
+ # encoding: UTF-8
2
+ #
1
3
  # Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
2
- #
4
+ #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
4
6
  # you may not use this file except in compliance with the License.
5
7
  # You may obtain a copy of the License at
6
- #
8
+ #
7
9
  # http://www.apache.org/licenses/LICENSE-2.0
8
- #
10
+ #
9
11
  # Unless required by applicable law or agreed to in writing, software
10
12
  # distributed under the License is distributed on an "AS IS" BASIS,
11
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,18 +20,19 @@ require 'gyoku'
18
20
  require 'uuidtools'
19
21
  require 'base64'
20
22
 
23
+ # SOAP constants for WinRM
21
24
  module WinRM
22
- NS_SOAP_ENV ='s' # http://www.w3.org/2003/05/soap-envelope
23
- NS_ADDRESSING ='a' # http://schemas.xmlsoap.org/ws/2004/08/addressing
24
- NS_CIMBINDING ='b' # http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd
25
- NS_ENUM ='n' # http://schemas.xmlsoap.org/ws/2004/09/enumeration
26
- NS_TRANSFER ='x' # http://schemas.xmlsoap.org/ws/2004/09/transfer
27
- NS_WSMAN_DMTF ='w' # http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
28
- NS_WSMAN_MSFT ='p' # http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd
29
- NS_SCHEMA_INST ='xsi' # http://www.w3.org/2001/XMLSchema-instance
30
- NS_WIN_SHELL ='rsp' # http://schemas.microsoft.com/wbem/wsman/1/windows/shell
31
- NS_WSMAN_FAULT = 'f' # http://schemas.microsoft.com/wbem/wsman/1/wsmanfault
32
- NS_WSMAN_CONF = 'cfg'# http://schemas.microsoft.com/wbem/wsman/1/config
25
+ NS_SOAP_ENV = 's' # http://www.w3.org/2003/05/soap-envelope
26
+ NS_ADDRESSING = 'a' # http://schemas.xmlsoap.org/ws/2004/08/addressing
27
+ NS_CIMBINDING = 'b' # http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd
28
+ NS_ENUM = 'n' # http://schemas.xmlsoap.org/ws/2004/09/enumeration
29
+ NS_TRANSFER = 'x' # http://schemas.xmlsoap.org/ws/2004/09/transfer
30
+ NS_WSMAN_DMTF = 'w' # http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
31
+ NS_WSMAN_MSFT = 'p' # http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd
32
+ NS_SCHEMA_INST = 'xsi' # http://www.w3.org/2001/XMLSchema-instance
33
+ NS_WIN_SHELL = 'rsp' # http://schemas.microsoft.com/wbem/wsman/1/windows/shell
34
+ NS_WSMAN_FAULT = 'f' # http://schemas.microsoft.com/wbem/wsman/1/wsmanfault
35
+ NS_WSMAN_CONF = 'cfg' # http://schemas.microsoft.com/wbem/wsman/1/config
33
36
  end
34
37
 
35
38
  require 'winrm/exceptions/exceptions'
@@ -1,11 +1,13 @@
1
+ # encoding: UTF-8
2
+ #
1
3
  # Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
2
- #
4
+ #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
4
6
  # you may not use this file except in compliance with the License.
5
7
  # You may obtain a copy of the License at
6
- #
8
+ #
7
9
  # http://www.apache.org/licenses/LICENSE-2.0
8
- #
10
+ #
9
11
  # Unless required by applicable law or agreed to in writing, software
10
12
  # distributed under the License is distributed on an "AS IS" BASIS,
11
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,10 +19,9 @@ require 'rexml/document'
17
19
  require_relative 'helpers/powershell_script'
18
20
 
19
21
  module WinRM
20
- # This is the main class that does the SOAP request/response logic. There are a few helper classes, but pretty
21
- # much everything comes through here first.
22
+ # This is the main class that does the SOAP request/response logic. There are a few helper
23
+ # classes, but pretty much everything comes through here first.
22
24
  class WinRMWebService
23
-
24
25
  DEFAULT_TIMEOUT = 'PT60S'
25
26
  DEFAULT_MAX_ENV_SIZE = 153600
26
27
  DEFAULT_LOCALE = 'en-US'
@@ -249,6 +250,13 @@ module WinRM
249
250
  output[:exitcode] = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:ExitCode").text.to_i
250
251
  end
251
252
  output
253
+ rescue WinRMWSManFault => e
254
+ # If no output is available before the wsman:OperationTimeout expires,
255
+ # the server MUST return a WSManFault with the Code attribute equal to
256
+ # 2150858793. When the client receives this fault, it SHOULD issue
257
+ # another Receive request.
258
+ # http://msdn.microsoft.com/en-us/library/cc251676.aspx
259
+ retry if e.fault_code == '2150858793'
252
260
  end
253
261
 
254
262
  # Clean-up after a command.