mixlib-shellout 3.1.4-universal-mingw32 → 3.2.5-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15cf083a72ce549add81eded313d884cd178385d8fe28c5e3d7d93b40a728b21
4
- data.tar.gz: 619c1ffb3a1c8e78215c97acbf850e5908106e187b4cabc42b0132a4d94a86b7
3
+ metadata.gz: 2e870a84527d0b8d21a6b04199710a7fa5a1588821789070606f86cc177244ad
4
+ data.tar.gz: b0f00885654a4146864a9a2355502dbfbe5d2e145fef00307d49a3ab757a3882
5
5
  SHA512:
6
- metadata.gz: 0c973fdde62a84ab9a62a37f66ec022aed6ca32011e8855e7d9d6a54e4970ded0d59537dd147c3b830428745dfa60ac546edc63cd99f5f2dc6e8cf565a592cba
7
- data.tar.gz: 9771450ddf8fca070cb8013d623e605fb35476a2472d7d2ac1a5b8ed6e6cd00b19b4c13b284e5f6d435c901bfbed5f8f1952076131966196b1484f6279706ad5
6
+ metadata.gz: 6184480579532ea1659623681c1d22aa8b04f584304c843a1a68a8327ca8f5bee957219370b8967a94895e92b1ceadfb5d074407ced2e3f6aeef1df9f975c47a
7
+ data.tar.gz: 10f80539b427d7fda40f45250e49396a27d1d720651e2c6a561c4226c2c7c1fe03e8f8ff0f2e127ca3f01cbf3a595417bd7df3fba6359929e9c6c8d1686c4ddf
@@ -1,6 +1,6 @@
1
1
  #--
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
- # Copyright:: Copyright (c) 2010-2016 Chef Software, Inc.
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -248,7 +248,7 @@ module Mixlib
248
248
  # running or died without setting an exit status (e.g., terminated by
249
249
  # `kill -9`).
250
250
  def exitstatus
251
- @status && @status.exitstatus
251
+ @status&.exitstatus
252
252
  end
253
253
 
254
254
  # Run the command, writing the command's standard out and standard error
@@ -157,7 +157,7 @@ module Mixlib
157
157
  end
158
158
 
159
159
  def __io_for_live_stream
160
- if STDOUT.tty? && !__config[:daemon] && __log.debug?
160
+ if !STDOUT.closed? && __log.trace?
161
161
  STDOUT
162
162
  else
163
163
  nil
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
- # Copyright:: Copyright (c) 2010-2016 Chef Software, Inc.
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -370,11 +370,11 @@ module Mixlib
370
370
  return if attempt_reap
371
371
 
372
372
  @terminate_reason = "Command exceeded allowed execution time, process terminated"
373
- logger.error("Command exceeded allowed execution time, sending TERM") if logger
373
+ logger&.error("Command exceeded allowed execution time, sending TERM")
374
374
  Process.kill(:TERM, child_pgid)
375
375
  sleep 3
376
376
  attempt_reap
377
- logger.error("Command exceeded allowed execution time, sending KILL") if logger
377
+ logger&.error("Command exceeded allowed execution time, sending KILL")
378
378
  Process.kill(:KILL, child_pgid)
379
379
  reap
380
380
 
@@ -1,5 +1,5 @@
1
1
  module Mixlib
2
2
  class ShellOut
3
- VERSION = "3.1.4".freeze
3
+ VERSION = "3.2.5".freeze
4
4
  end
5
5
  end
@@ -2,7 +2,7 @@
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
3
  # Author:: John Keiser (<jkeiser@chef.io>)
4
4
  # Author:: Ho-Sheng Hsiao (<hosh@chef.io>)
5
- # Copyright:: Copyright (c) 2011-2019, Chef Software Inc.
5
+ # Copyright:: Copyright (c) Chef Software Inc.
6
6
  # License:: Apache License, Version 2.0
7
7
  #
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -89,7 +89,7 @@ module Mixlib
89
89
  # Start the process
90
90
  #
91
91
  process, profile, token = Process.create3(create_process_args)
92
- logger.debug(format_process(process, app_name, command_line, timeout)) if logger
92
+ logger&.debug(format_process(process, app_name, command_line, timeout))
93
93
  begin
94
94
  # Start pushing data into input
95
95
  stdin_write << input if input
@@ -124,7 +124,7 @@ module Mixlib
124
124
  kill_process_tree(process.process_id, wmi, logger)
125
125
  Process.kill(:KILL, process.process_id)
126
126
  rescue SystemCallError
127
- logger.warn("Failed to kill timed out process #{process.process_id}") if logger
127
+ logger&.warn("Failed to kill timed out process #{process.process_id}")
128
128
  end
129
129
 
130
130
  raise Mixlib::ShellOut::CommandTimeout, [
@@ -398,20 +398,16 @@ module Mixlib
398
398
 
399
399
  def kill_process(instance, logger)
400
400
  child_pid = instance.wmi_ole_object.processid
401
- if logger
402
- logger.debug([
401
+ logger&.debug([
403
402
  "killing child process #{child_pid}::",
404
403
  "#{instance.wmi_ole_object.Name} of parent #{pid}",
405
404
  ].join)
406
- end
407
405
  Process.kill(:KILL, instance.wmi_ole_object.processid)
408
406
  rescue SystemCallError
409
- if logger
410
- logger.debug([
407
+ logger&.debug([
411
408
  "Failed to kill child process #{child_pid}::",
412
409
  "#{instance.wmi_ole_object.Name} of parent #{pid}",
413
410
  ].join)
414
- end
415
411
  end
416
412
 
417
413
  def format_process(process, app_name, command_line, timeout)
@@ -1,7 +1,7 @@
1
- #--
1
+ #
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
3
  # Author:: John Keiser (<jkeiser@chef.io>)
4
- # Copyright:: Copyright (c) 2011-2016 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) Chef Software Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,10 +18,10 @@
18
18
  #
19
19
 
20
20
  require "win32/process"
21
+ require "ffi/win32/extensions"
21
22
 
22
23
  # Add new constants for Logon
23
24
  module Process::Constants
24
- private
25
25
 
26
26
  LOGON32_LOGON_INTERACTIVE = 0x00000002
27
27
  LOGON32_LOGON_BATCH = 0x00000004
@@ -45,6 +45,8 @@ module Process::Constants
45
45
  WIN32_PROFILETYPE_PT_MANDATORY = 0x04
46
46
  WIN32_PROFILETYPE_PT_ROAMING_PREEXISTING = 0x08
47
47
 
48
+ # The environment block list ends with two nulls (\0\0).
49
+ ENVIRONMENT_BLOCK_ENDS = "\0\0".freeze
48
50
  end
49
51
 
50
52
  # Structs required for data handling
@@ -78,6 +80,12 @@ module Process::Functions
78
80
  attach_pfunc :UnloadUserProfile,
79
81
  %i{handle handle}, :bool
80
82
 
83
+ attach_pfunc :CreateEnvironmentBlock,
84
+ %i{pointer ulong bool}, :bool
85
+
86
+ attach_pfunc :DestroyEnvironmentBlock,
87
+ %i{pointer}, :bool
88
+
81
89
  ffi_lib :advapi32
82
90
 
83
91
  attach_pfunc :LogonUserW,
@@ -148,15 +156,13 @@ module Process
148
156
  si_hash = {}
149
157
 
150
158
  # If the startup_info key is present, validate its subkeys
151
- if hash["startup_info"]
152
- hash["startup_info"].each do |key, val|
153
- key = key.to_s.downcase
154
- unless valid_si_keys.include?(key)
155
- raise ArgumentError, "invalid startup_info key '#{key}'"
156
- end
157
-
158
- si_hash[key] = val
159
+ hash["startup_info"]&.each do |key, val|
160
+ key = key.to_s.downcase
161
+ unless valid_si_keys.include?(key)
162
+ raise ArgumentError, "invalid startup_info key '#{key}'"
159
163
  end
164
+
165
+ si_hash[key] = val
160
166
  end
161
167
 
162
168
  # The +command_line+ key is mandatory unless the +app_name+ key
@@ -172,9 +178,25 @@ module Process
172
178
 
173
179
  env = nil
174
180
 
181
+ # Retrieve the environment variables for the specified user.
182
+ if hash["with_logon"]
183
+ logon, passwd, domain = format_creds_from_hash(hash)
184
+ logon_type = hash["elevated"] ? LOGON32_LOGON_BATCH : LOGON32_LOGON_INTERACTIVE
185
+ token = logon_user(logon, domain, passwd, logon_type)
186
+ logon_ptr = FFI::MemoryPointer.from_string(logon)
187
+ profile = PROFILEINFO.new.tap do |dat|
188
+ dat[:dwSize] = dat.size
189
+ dat[:dwFlags] = 1
190
+ dat[:lpUserName] = logon_ptr
191
+ end
192
+
193
+ load_user_profile(token, profile.pointer)
194
+ env_list = retrieve_environment_variables(token)
195
+ end
196
+
175
197
  # The env string should be passed as a string of ';' separated paths.
176
198
  if hash["environment"]
177
- env = hash["environment"]
199
+ env = env_list.nil? ? hash["environment"] : merge_env_variables(env_list, hash["environment"])
178
200
 
179
201
  unless env.respond_to?(:join)
180
202
  env = hash["environment"].split(File::PATH_SEPARATOR)
@@ -396,6 +418,33 @@ module Process
396
418
  true
397
419
  end
398
420
 
421
+ # Retrieves the environment variables for the specified user.
422
+ #
423
+ # @param env_pointer [Pointer] The environment block is an array of null-terminated Unicode strings.
424
+ # @param token [Integer] User token handle.
425
+ # @return [Boolean] true if successfully retrieves the environment variables for the specified user.
426
+ #
427
+ def create_environment_block(env_pointer, token)
428
+ unless CreateEnvironmentBlock(env_pointer, token, false)
429
+ raise SystemCallError.new("CreateEnvironmentBlock", FFI.errno)
430
+ end
431
+
432
+ true
433
+ end
434
+
435
+ # Frees environment variables created by the CreateEnvironmentBlock function.
436
+ #
437
+ # @param env_pointer [Pointer] The environment block is an array of null-terminated Unicode strings.
438
+ # @return [Boolean] true if successfully frees environment variables created by the CreateEnvironmentBlock function.
439
+ #
440
+ def destroy_environment_block(env_pointer)
441
+ unless DestroyEnvironmentBlock(env_pointer)
442
+ raise SystemCallError.new("DestroyEnvironmentBlock", FFI.errno)
443
+ end
444
+
445
+ true
446
+ end
447
+
399
448
  def create_process_as_user(token, app, cmd, process_security,
400
449
  thread_security, inherit, creation_flags, env, cwd, startinfo, procinfo)
401
450
 
@@ -530,5 +579,51 @@ module Process
530
579
  [ logon, passwd, domain ]
531
580
  end
532
581
 
582
+ # Retrieves the environment variables for the specified user.
583
+ #
584
+ # @param token [Integer] User token handle.
585
+ # @return env_list [Array<String>] Environment variables of specified user.
586
+ #
587
+ def retrieve_environment_variables(token)
588
+ env_list = []
589
+ env_pointer = FFI::MemoryPointer.new(:pointer)
590
+ create_environment_block(env_pointer, token)
591
+ str_ptr = env_pointer.read_pointer
592
+ offset = 0
593
+ loop do
594
+ new_str_pointer = str_ptr + offset
595
+ break if new_str_pointer.read_string(2) == ENVIRONMENT_BLOCK_ENDS
596
+
597
+ environment = new_str_pointer.read_wstring
598
+ env_list << environment
599
+ offset = offset + environment.length * 2 + 2
600
+ end
601
+
602
+ # To free the buffer when we have finished with the environment block
603
+ destroy_environment_block(str_ptr)
604
+ env_list
605
+ end
606
+
607
+ # Merge environment variables of specified user and current environment variables.
608
+ #
609
+ # @param fetched_env [Array<String>] environment variables of specified user.
610
+ # @param current_env [Array<String>] current environment variables.
611
+ # @return [Array<String>] Merged environment variables.
612
+ #
613
+ def merge_env_variables(fetched_env, current_env)
614
+ env_hash_1 = environment_list_to_hash(fetched_env)
615
+ env_hash_2 = environment_list_to_hash(current_env)
616
+ merged_env = env_hash_2.merge(env_hash_1)
617
+ merged_env.map { |k, v| "#{k}=#{v}" }
618
+ end
619
+
620
+ # Convert an array to a hash.
621
+ #
622
+ # @param env_var [Array<String>] Environment variables.
623
+ # @return [Hash] Converted an array to hash.
624
+ #
625
+ def environment_list_to_hash(env_var)
626
+ Hash[ env_var.map { |pair| pair.split("=", 2) } ]
627
+ end
533
628
  end
534
629
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-shellout
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.4
4
+ version: 3.2.5
5
5
  platform: universal-mingw32
6
6
  authors:
7
7
  - Chef Software Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-13 00:00:00.000000000 Z
11
+ date: 2021-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-utils
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.8.2
33
+ version: '0.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.8.2
40
+ version: '0.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: wmi-lite
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ffi-win32-extensions
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.3
55
69
  description: Run external commands on Unix or Windows
56
70
  email: info@chef.io
57
71
  executables: []
@@ -67,7 +81,8 @@ files:
67
81
  - lib/mixlib/shellout/windows.rb
68
82
  - lib/mixlib/shellout/windows/core_ext.rb
69
83
  homepage: https://github.com/chef/mixlib-shellout
70
- licenses: []
84
+ licenses:
85
+ - Apache-2.0
71
86
  metadata: {}
72
87
  post_install_message:
73
88
  rdoc_options: []
@@ -84,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
99
  - !ruby/object:Gem::Version
85
100
  version: '0'
86
101
  requirements: []
87
- rubygems_version: 3.0.3
102
+ rubygems_version: 3.1.4
88
103
  signing_key:
89
104
  specification_version: 4
90
105
  summary: Run external commands on Unix or Windows