train-winrm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 12bed665790e51bd23cbe569c27f6a93c0300e8c
4
+ data.tar.gz: 599a6d141eb447d549ca3b511c15929401dea19d
5
+ SHA512:
6
+ metadata.gz: b12889e4dc8845c34c911e3856213eee6a8993d1d1e93488bd838a0ff0421722cba9256641b3c23bda1a7df9982e5c0ed3fdd805ee787f161edf57e34129f5a6
7
+ data.tar.gz: 82873a1ed8096c63b6c56f8a8acf0981168429af31fcb63f421af272664d8822142f7fab0e7627d6aa413f1639201c84c8e91b076f1cd7cd551c88d0d38cef37
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # This is a Gemfile, which is used by bundler
6
+ # to ensure a coherent set of gems is installed.
7
+ # This file lists dependencies needed when outside
8
+ # of a gem (the gemspec lists deps for gem deployment)
9
+
10
+ # Bundler should refer to the gemspec for any dependencies.
11
+ gemspec
12
+
13
+ # Remaining group is only used for development.
14
+ group :development do
15
+ gem 'bundler'
16
+ gem 'byebug'
17
+ gem 'm'
18
+ gem 'minitest'
19
+ gem 'mocha'
20
+ gem 'pry'
21
+ gem 'rake'
22
+ gem 'rubocop', '= 0.49.1' # Need to keep in sync with main InSpec project, so config files will work
23
+ end
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # train-winrm - Train Plugin for connecting to Windows via Remote Management
2
+
3
+ This plugin allows applications that rely on Train to communicate with the WinRM API. For example, you could use this to audit Windows Server 2016 machines.
4
+
5
+ TODO - details about underlying library
6
+
7
+ Train itself has no CLI, nor a sophisticated test harness. Chef InSpec does have such facilities, so installing Train plugins will require a Chef InSpec installation. You do not need to use or understand Chef InSpec.
8
+
9
+ Train plugins may be developed without a Chef InSpec installation.
10
+
11
+ ## To Install this as a User
12
+
13
+ Train plugins are distributed as gems. You may choose to manage the gem yourself, but if you are an Chef InSpec user, Chef InSpec can handle it for you.
14
+
15
+ You will need Chef InSpec v2.3 or later.
16
+
17
+ Simply run:
18
+
19
+ ```
20
+ $ inspec plugin install train-winrm
21
+ ```
22
+
23
+ You can then run:
24
+
25
+ ```
26
+ TODO - example
27
+ ```
28
+
29
+ ## Target Options for Train-WinRM
30
+
31
+ TODO
32
+
33
+ ## Reporting Issues
34
+
35
+ Bugs, typos, limitations, and frustrations are welcome to be reported through the [GitHub issues page for the train-winrm project](https://github.com/inspec/train-winrm/issues).
36
+
37
+ You may also ask questions in the #inspec channel of the Chef Community Slack team. However, for an issue to get traction, please report it as a github issue.
38
+
39
+ ## Development on this Plugin
40
+
41
+ ### Development Process
42
+
43
+ If you wish to contribute to this plugin, please use the usual fork-branch-push-PR cycle. All functional changes need new tests, and bugfixes are expected to include a new test that demonstrates the bug.
44
+
45
+ ### Reference Information
46
+
47
+ [Plugin Development](https://github.com/inspec/train/blob/master/docs/dev/plugins.md) is documented on the `train` project on GitHub.
48
+
49
+ ### Testing changes against a Windows Machine
50
+
51
+ TODO
@@ -0,0 +1,20 @@
1
+ # This file is known as the "entry point."
2
+ # This is the file Train will try to load if it
3
+ # thinks your plugin is needed.
4
+
5
+ # The *only* thing this file should do is setup the
6
+ # load path, then load plugin files.
7
+
8
+ # Next two lines simply add the path of the gem to the load path.
9
+ # This is not needed when being loaded as a gem; but when doing
10
+ # plugin development, you may need it. Either way, it's harmless.
11
+ libdir = File.dirname(__FILE__)
12
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
13
+
14
+ # It's traditonal to keep your gem version in a separate file, so CI can find it easier.
15
+ require 'train-winrm/version'
16
+
17
+ # A train plugin has three components: Transport, Connection, and (optionally) Platform.
18
+ # Transport acts as the glue.
19
+ require 'train-winrm/transport'
20
+ require 'train-winrm/connection'
@@ -0,0 +1,213 @@
1
+ # encoding: utf-8
2
+
3
+ #
4
+ # Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
5
+ # Author:: Matt Wrock (<matt@mattwrock.com>)
6
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
7
+ # Author:: Dominik Richter (<dominik.richter@gmail.com>)
8
+ # Author:: Christoph Hartmann (<chris@lollyrock.com>)
9
+ #
10
+ # Copyright (C) 2014, Salim Afiune
11
+ #
12
+ # Licensed under the Apache License, Version 2.0 (the "License");
13
+ # you may not use this file except in compliance with the License.
14
+ # You may obtain a copy of the License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the License is distributed on an "AS IS" BASIS,
20
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ # See the License for the specific language governing permissions and
22
+ # limitations under the License.
23
+
24
+ # Most of the work of a Train plugin happens in this file.
25
+ # Connections derive from Train::Plugins::Transport::BaseConnection,
26
+ # and provide a variety of services. Later generations of the plugin
27
+ # API will likely separate out these responsibilities, but for now,
28
+ # some of the responsibilities include:
29
+ # * authentication to the target
30
+ # * platform / release /family detection
31
+ # * caching
32
+ # * API execution
33
+ # * marshalling to / from JSON
34
+ # You don't have to worry about most of this.
35
+
36
+ require 'train'
37
+ require 'train/plugins'
38
+
39
+ module TrainPlugins
40
+ module WinRM
41
+ # @author Fletcher Nichol <fnichol@nichol.ca>
42
+ class Connection < Train::Plugins::Transport::BaseConnection # rubocop:disable Metrics/ClassLength
43
+ attr_reader :hostname
44
+ def initialize(options)
45
+ super(options)
46
+ @hostname = @options.delete(:hostname)
47
+ @rdp_port = @options.delete(:rdp_port)
48
+ @connection_retries = @options.delete(:connection_retries)
49
+ @connection_retry_sleep = @options.delete(:connection_retry_sleep)
50
+ @max_wait_until_ready = @options.delete(:max_wait_until_ready)
51
+ @operation_timeout = @options.delete(:operation_timeout)
52
+ end
53
+
54
+ # (see Base::Connection#close)
55
+ def close
56
+ return if @session.nil?
57
+ session.close
58
+ ensure
59
+ @session = nil
60
+ end
61
+
62
+ # (see Base::Connection#login_command)
63
+ def login_command
64
+ case RbConfig::CONFIG['host_os']
65
+ when /darwin/
66
+ login_command_for_mac
67
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
68
+ login_command_for_windows
69
+ when /linux/
70
+ login_command_for_linux
71
+ else
72
+ fail ActionFailed,
73
+ "Remote login not supported in #{self.class} " \
74
+ "from host OS '#{RbConfig::CONFIG['host_os']}'."
75
+ end
76
+ end
77
+
78
+ # (see Base::Connection#upload)
79
+ def upload(locals, remote)
80
+ file_manager.upload(locals, remote)
81
+ end
82
+
83
+ def download(remotes, local)
84
+ Array(remotes).each do |remote|
85
+ file_manager.download(remote, local)
86
+ end
87
+ end
88
+
89
+ # (see Base::Connection#wait_until_ready)
90
+ def wait_until_ready
91
+ delay = 3
92
+ session(
93
+ retry_limit: @max_wait_until_ready / delay,
94
+ retry_delay: delay,
95
+ )
96
+ run_command_via_connection(PING_COMMAND.dup)
97
+ end
98
+
99
+ def uri
100
+ "winrm://#{options[:user]}@#{options[:endpoint]}:#{@rdp_port}"
101
+ end
102
+
103
+ private
104
+
105
+ PING_COMMAND = "Write-Host '[WinRM] Established\n'".freeze
106
+
107
+ def file_via_connection(path)
108
+ Train::File::Remote::Windows.new(self, path)
109
+ end
110
+
111
+ def run_command_via_connection(command, &data_handler)
112
+ return if command.nil?
113
+ logger.debug("[WinRM] #{self} (#{command})")
114
+ out = ''
115
+
116
+ response = session.run(command) do |stdout, _|
117
+ yield(stdout) if data_handler && stdout
118
+ out << stdout if stdout
119
+ end
120
+
121
+ CommandResult.new(out, response.stderr, response.exitcode)
122
+ end
123
+
124
+ # Create a local RDP document and return it
125
+ #
126
+ # @param opts [Hash] configuration options
127
+ # @option opts [true,false] :mac whether or not the document is for a
128
+ # Mac system
129
+ # @api private
130
+ def rdp_doc(opts = {})
131
+ host = URI.parse(options[:endpoint]).host
132
+ content = [
133
+ "full address:s:#{host}:#{@rdp_port}",
134
+ 'prompt for credentials:i:1',
135
+ "username:s:#{options[:user]}",
136
+ ].join("\n")
137
+
138
+ content.prepend("drivestoredirect:s:*\n") if opts[:mac]
139
+
140
+ content
141
+ end
142
+
143
+ # @return [Winrm::FileManager] a file transporter
144
+ # @api private
145
+ def file_manager
146
+ @file_manager ||= begin
147
+ # Ensure @service is available:
148
+ wait_until_ready
149
+ WinRM::FS::FileManager.new(@service)
150
+ end
151
+ end
152
+
153
+ # Builds a `LoginCommand` for use by Linux-based platforms.
154
+ #
155
+ # TODO: determine whether or not `desktop` exists
156
+ #
157
+ # @return [LoginCommand] a login command
158
+ # @api private
159
+ def login_command_for_linux
160
+ args = %W(-u #{options[:user]})
161
+ args += %W(-p #{options[:pass]}) if options.key?(:pass)
162
+ args += %W(#{URI.parse(options[:endpoint]).host}:#{@rdp_port})
163
+ LoginCommand.new('rdesktop', args)
164
+ end
165
+
166
+ # Builds a `LoginCommand` for use by Mac-based platforms.
167
+ #
168
+ # @return [LoginCommand] a login command
169
+ # @api private
170
+ def login_command_for_mac
171
+ LoginCommand.new('open', rdp_doc(mac: true))
172
+ end
173
+
174
+ # Builds a `LoginCommand` for use by Windows-based platforms.
175
+ #
176
+ # @return [LoginCommand] a login command
177
+ # @api private
178
+ def login_command_for_windows
179
+ LoginCommand.new('mstsc', rdp_doc)
180
+ end
181
+
182
+ # Establishes a remote shell session, or establishes one when invoked
183
+ # the first time.
184
+ #
185
+ # @param retry_options [Hash] retry options for the initial connection
186
+ # @return [Winrm::CommandExecutor] the command executor session
187
+ # @api private
188
+ def session(retry_options = {})
189
+ @session ||= begin
190
+ opts = {
191
+ retry_limit: @connection_retries.to_i,
192
+ retry_delay: @connection_retry_sleep.to_i,
193
+ }.merge(retry_options)
194
+
195
+ opts[:operation_timeout] = @operation_timeout unless @operation_timeout.nil?
196
+ @service = ::WinRM::Connection.new(options.merge(opts))
197
+ @service.logger = logger
198
+ @service.shell(:powershell)
199
+ end
200
+ end
201
+
202
+ # String representation of object, reporting its connection details and
203
+ # configuration.
204
+ #
205
+ # @api private
206
+ def to_s
207
+ options_to_print = @options.clone
208
+ options_to_print[:password] = '<hidden>' if options_to_print.key?(:password)
209
+ "#{@username}@#{@hostname}<#{options_to_print.inspect}>"
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,216 @@
1
+ # encoding: utf-8
2
+
3
+ #
4
+ # Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
5
+ # Author:: Matt Wrock (<matt@mattwrock.com>)
6
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
7
+ # Author:: Dominik Richter (<dominik.richter@gmail.com>)
8
+ # Author:: Christoph Hartmann (<chris@lollyrock.com>)
9
+ #
10
+ # Copyright (C) 2014, Salim Afiune
11
+ #
12
+ # Licensed under the Apache License, Version 2.0 (the "License");
13
+ # you may not use this file except in compliance with the License.
14
+ # You may obtain a copy of the License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the License is distributed on an "AS IS" BASIS,
20
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ # See the License for the specific language governing permissions and
22
+ # limitations under the License.
23
+
24
+ require 'rbconfig'
25
+ require 'uri'
26
+ require 'train'
27
+ require 'train/errors'
28
+ require 'train/plugins'
29
+
30
+ # Train Plugins v1 are usually declared under the TrainPlugins namespace.
31
+ # Each plugin has three components: Transport, Connection, and (optionally) Platform.
32
+ # We'll only define the Transport here, but we'll refer to the others.
33
+
34
+ module TrainPlugins
35
+ module WinRM
36
+ # Wrapped exception for any internally raised WinRM-related errors.
37
+ #
38
+ # @author Fletcher Nichol <fnichol@nichol.ca>
39
+ class WinRMFailed < Train::TransportError; end
40
+
41
+ # A Transport which uses WinRM to execute commands and transfer files.
42
+ #
43
+ # @author Matt Wrock <matt@mattwrock.com>
44
+ # @author Salim Afiune <salim@afiunemaya.com.mx>
45
+ # @author Fletcher Nichol <fnichol@nichol.ca>
46
+ class Transport < Train.plugin(1) # rubocop:disable Metrics/ClassLength
47
+ name 'winrm'
48
+
49
+ require 'train-winrm/connection'
50
+
51
+ # ref: https://github.com/winrb/winrm#transports
52
+ SUPPORTED_WINRM_TRANSPORTS = %i(negotiate ssl plaintext kerberos).freeze
53
+
54
+ # common target configuration
55
+ option :host, required: true
56
+ option :port
57
+ option :user, default: 'administrator', required: true
58
+ option :password, nil
59
+ option :winrm_transport, default: :negotiate
60
+ option :winrm_disable_sspi, default: false
61
+ option :winrm_basic_auth_only, default: false
62
+ option :path, default: '/wsman'
63
+ option :ssl, default: false
64
+ option :self_signed, default: false
65
+
66
+ # additional winrm options
67
+ option :rdp_port, default: 3389
68
+ option :connection_retries, default: 5
69
+ option :connection_retry_sleep, default: 1
70
+ option :max_wait_until_ready, default: 600
71
+ option :ssl_peer_fingerprint, default: nil
72
+ option :kerberos_realm, default: nil
73
+ option :kerberos_service, default: nil
74
+ option :ca_trust_file, default: nil
75
+ # The amount of time in SECONDS for which each operation must get an ack
76
+ # from the winrm endpoint. Does not mean that the command has
77
+ # completed in this time, only that the server has ack'd the request.
78
+ option :operation_timeout, default: nil
79
+
80
+ def initialize(opts)
81
+ super(opts)
82
+ load_needed_dependencies!
83
+ end
84
+
85
+ # (see Base#connection)
86
+ def connection(state = nil, &block)
87
+ opts = merge_options(options, state || {})
88
+ validate_options(opts)
89
+ conn_opts = connection_options(opts)
90
+
91
+ if @connection && @connection_options == conn_opts
92
+ reuse_connection(&block)
93
+ else
94
+ create_new_connection(conn_opts, &block)
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def validate_options(opts)
101
+ super(opts)
102
+
103
+ # set scheme and port based on ssl activation
104
+ scheme = opts[:ssl] ? 'https' : 'http'
105
+ port = opts[:port]
106
+ port = (opts[:ssl] ? 5986 : 5985) if port.nil?
107
+ winrm_transport = opts[:winrm_transport].to_sym
108
+ unless SUPPORTED_WINRM_TRANSPORTS.include?(winrm_transport)
109
+ fail Train::ClientError, "Unsupported transport type: #{winrm_transport.inspect}"
110
+ end
111
+
112
+ # remove leading '/'
113
+ path = (opts[:path] || '').sub(%r{^/+}, '')
114
+
115
+ opts[:endpoint] = "#{scheme}://#{opts[:host]}:#{port}/#{path}"
116
+ end
117
+
118
+ WINRM_FS_SPEC_VERSION = '~> 1.0'.freeze
119
+
120
+ # Builds the hash of options needed by the Connection object on
121
+ # construction.
122
+ #
123
+ # @param data [Hash] merged configuration and mutable state data
124
+ # @return [Hash] hash of connection options
125
+ # @api private
126
+ def connection_options(opts)
127
+ {
128
+ logger: logger,
129
+ transport: opts[:winrm_transport].to_sym,
130
+ disable_sspi: opts[:winrm_disable_sspi],
131
+ basic_auth_only: opts[:winrm_basic_auth_only],
132
+ hostname: opts[:host],
133
+ endpoint: opts[:endpoint],
134
+ user: opts[:user],
135
+ password: opts[:password],
136
+ rdp_port: opts[:rdp_port],
137
+ connection_retries: opts[:connection_retries],
138
+ connection_retry_sleep: opts[:connection_retry_sleep],
139
+ max_wait_until_ready: opts[:max_wait_until_ready],
140
+ no_ssl_peer_verification: opts[:self_signed],
141
+ realm: opts[:kerberos_realm],
142
+ service: opts[:kerberos_service],
143
+ ca_trust_file: opts[:ca_trust_file],
144
+ ssl_peer_fingerprint: opts[:ssl_peer_fingerprint],
145
+ }
146
+ end
147
+
148
+ # Creates a new WinRM Connection instance and save it for potential
149
+ # future reuse.
150
+ #
151
+ # @param options [Hash] conneciton options
152
+ # @return [WinRM::Connection] a WinRM Connection instance
153
+ # @api private
154
+ def create_new_connection(options, &block)
155
+ if @connection
156
+ logger.debug("[WinRM] shutting previous connection #{@connection}")
157
+ @connection.close
158
+ end
159
+
160
+ @connection_options = options
161
+ @connection = Connection.new(options, &block)
162
+ end
163
+
164
+ # (see Base#load_needed_dependencies!)
165
+ def load_needed_dependencies!
166
+ spec_version = WINRM_FS_SPEC_VERSION.dup
167
+ logger.debug('winrm-fs requested,' \
168
+ " loading WinRM::FS gem (#{spec_version})")
169
+ gem 'winrm-fs', spec_version
170
+ first_load = require 'winrm-fs'
171
+ load_winrm_transport!
172
+
173
+ if first_load
174
+ logger.debug('WinRM::FS library loaded')
175
+ else
176
+ logger.debug('WinRM::FS previously loaded')
177
+ end
178
+ rescue LoadError => e
179
+ logger.fatal(
180
+ "The `winrm-fs' gem is missing and must" \
181
+ ' be installed or cannot be properly activated. Run' \
182
+ " `gem install winrm-fs --version '#{spec_version}'`" \
183
+ ' or add the following to your Gemfile if you are using Bundler:' \
184
+ " `gem 'winrm-fs', '#{spec_version}'`.",
185
+ )
186
+ raise Train::UserError,
187
+ "Could not load or activate WinRM::FS (#{e.message})"
188
+ end
189
+
190
+ # Load WinRM::Transport code.
191
+ #
192
+ # @api private
193
+ def load_winrm_transport!
194
+ silence_warnings { require 'winrm-fs' }
195
+ end
196
+
197
+ # Return the last saved WinRM connection instance.
198
+ #
199
+ # @return [Winrm::Connection] a WinRM Connection instance
200
+ # @api private
201
+ def reuse_connection
202
+ logger.debug("[WinRM] reusing existing connection #{@connection}")
203
+ yield @connection if block_given?
204
+ @connection
205
+ end
206
+
207
+ def silence_warnings
208
+ old_verbose = $VERBOSE
209
+ $VERBOSE = nil
210
+ yield
211
+ ensure
212
+ $VERBOSE = old_verbose
213
+ end
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,10 @@
1
+ # This file exists simply to record the version number of the plugin.
2
+ # It is kept in a separate file, so that your gemspec can load it and
3
+ # learn the current version without loading the whole plugin. Also,
4
+ # many CI servers can update this file when "version bumping".
5
+
6
+ module TrainPlugins
7
+ module WinRM
8
+ VERSION = '0.1.0'.freeze
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ # As plugins are usually packaged and distributed as a RubyGem,
2
+ # we have to provide a .gemspec file, which controls the gembuild
3
+ # and publish process. This is a fairly generic gemspec.
4
+
5
+ # It is traditional in a gemspec to dynamically load the current version
6
+ # from a file in the source tree. The next three lines make that happen.
7
+ lib = File.expand_path('../lib', __FILE__)
8
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
+ require 'train-winrm/version'
10
+
11
+ Gem::Specification.new do |spec|
12
+ # Importantly, all Train plugins must be prefixed with `train-`
13
+ spec.name = 'train-winrm'
14
+
15
+ # It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
16
+ spec.version = TrainPlugins::WinRM::VERSION
17
+ spec.authors = ['Chef InSpec Team']
18
+ spec.email = ['inspec@chef.io']
19
+ spec.summary = 'Windows WinRM API Transport for Train'
20
+ spec.description = 'Allows applictaions using Train to speak to Windows using Remote Management; handles authentication, cacheing, and SDK dependency management.'
21
+ spec.homepage = 'https://github.com/inspec/train-winrm'
22
+ spec.license = 'Apache-2.0'
23
+
24
+ # Though complicated-looking, this is pretty standard for a gemspec.
25
+ # It just filters what will actually be packaged in the gem (leaving
26
+ # out tests, etc)
27
+ spec.files = %w{
28
+ README.md train-winrm.gemspec Gemfile
29
+ } + Dir.glob(
30
+ 'lib/**/*', File::FNM_DOTMATCH
31
+ ).reject { |f| File.directory?(f) }
32
+ spec.require_paths = ['lib']
33
+
34
+ # If you rely on any other gems, list them here with any constraints.
35
+ # This is how `inspec plugin install` is able to manage your dependencies.
36
+
37
+ # If you only need certain gems during development or testing, list
38
+ # them in Gemfile, not here.
39
+
40
+ # Do not list inspec as a dependency of a train plugin.
41
+
42
+ spec.add_dependency 'train', '~> 2.0'
43
+ spec.add_dependency 'winrm', '~> 2.0'
44
+ spec.add_dependency 'winrm-fs', '~> 1.0'
45
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: train-winrm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chef InSpec Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: train
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: winrm
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: winrm-fs
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ description: Allows applictaions using Train to speak to Windows using Remote Management;
56
+ handles authentication, cacheing, and SDK dependency management.
57
+ email:
58
+ - inspec@chef.io
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - Gemfile
64
+ - README.md
65
+ - lib/train-winrm.rb
66
+ - lib/train-winrm/connection.rb
67
+ - lib/train-winrm/transport.rb
68
+ - lib/train-winrm/version.rb
69
+ - train-winrm.gemspec
70
+ homepage: https://github.com/inspec/train-winrm
71
+ licenses:
72
+ - Apache-2.0
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.6.14.3
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Windows WinRM API Transport for Train
94
+ test_files: []