chef 18.1.0-x64-mingw-ucrt → 18.1.29-x64-mingw-ucrt

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: 448a7d27ab27f9a0c39566270e5d99dfa5717ba32bd893505fd3f1d9d50ad339
4
- data.tar.gz: be60df259d416a70dc1c6447edab19ec1d4b9fb32f1429a4fc09c62c4cb8e022
3
+ metadata.gz: 937611f440a583a253b01525212c4d6214da8f25aee63891ab928b9a3d53de67
4
+ data.tar.gz: 7d69aeb9e4df6f13d76b464c08178f9935bc9be01eed136539d5d123315f0fea
5
5
  SHA512:
6
- metadata.gz: 833f265e523ce7924016ee802f599548361c94ec5e837f85b1263a39935f5a8443953b06d9b753fe2cbc154d0d9a6f1d5fd363caaaf2a14ccab08f6d952344ee
7
- data.tar.gz: 25c72dc0a3d5e6e4a6c414ecea9260a363b033a657d1626cdf1cdd6be683a8f51968655715b5b693e643bbf44b605c99d27d98d6cdf6a58d0d1481f43e687300
6
+ metadata.gz: 2bc789e6367a7ba5277f905d460f7b5390854f62c98f0ba07270e6659e7e70bb92b2d4fc64c8d87e524a972da75657f64022d3f01305558e00f90348f8d6811a
7
+ data.tar.gz: dea177b817a903ef86d7b8bacef0aca894ca778c26615339a041186276da976eb23abede8c47c1a3b9ee459a392961ff75fbc8532475186a1d21d77a1a528fde
data/Gemfile CHANGED
@@ -37,9 +37,6 @@ group(:omnibus_package, :pry) do
37
37
  gem "pry-stack_explorer"
38
38
  end
39
39
 
40
- # proxifier gem is busted on ruby 3.1 and seems abandoned so use git fork of gem
41
- gem "proxifier", git: "https://github.com/chef/ruby-proxifier", branch: "lcg/ruby-3"
42
-
43
40
  # Everything except AIX and Windows
44
41
  group(:ruby_shadow) do
45
42
  # if ruby-shadow does a release that supports ruby-3.0 this can be removed
data/chef.gemspec CHANGED
@@ -49,7 +49,8 @@ Gem::Specification.new do |s|
49
49
  s.add_dependency "net-ftp" # remote_file resource
50
50
  s.add_dependency "erubis", "~> 2.7" # template resource / cookbook syntax check
51
51
  s.add_dependency "diff-lcs", ">= 1.2.4", "!= 1.4.0", "< 1.6.0" # 1.4 breaks output. Used in lib/chef/util/diff
52
- s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3" # archive_file resource
52
+ # s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3" # archive_file resource
53
+ s.add_dependency "ffi-libarchive", "~> 1.1", ">= 1.1.3"
53
54
  s.add_dependency "chef-zero", ">= 14.0.11"
54
55
  s.add_dependency "chef-vault" # chef-vault resources and helpers
55
56
 
@@ -61,7 +62,7 @@ Gem::Specification.new do |s|
61
62
  s.add_dependency "unf_ext", ">= 0.0.8.2" # This is ruby31 compatible ucrt gem version
62
63
  s.add_dependency "corefoundation", "~> 0.3.4" # macos_userdefaults resource
63
64
 
64
- s.add_dependency "proxifier", "~> 1.0"
65
+ s.add_dependency "proxifier2", "~> 1.1"
65
66
 
66
67
  s.add_dependency "aws-sdk-s3", "~> 1.91" # s3 recipe-url support
67
68
  s.add_dependency "aws-sdk-secretsmanager", "~> 1.46"
@@ -386,8 +386,10 @@ class Chef::Application::Base < Chef::Application
386
386
  elsif uri.scheme == "s3"
387
387
  require "aws-sdk-s3" unless defined?(Aws::S3)
388
388
 
389
- s3 = Aws::S3::Client.new
390
- object = s3.get_object(bucket: uri.hostname, key: uri.path[1..-1])
389
+ bucket_name = uri.hostname
390
+ s3 = Aws::S3::Client.new(region: s3_bucket_location(bucket_name))
391
+
392
+ object = s3.get_object(bucket: bucket_name, key: uri.path[1..-1])
391
393
  File.open(path, "wb") do |f|
392
394
  f.write(object.body.read)
393
395
  end
@@ -403,6 +405,20 @@ class Chef::Application::Base < Chef::Application
403
405
  end
404
406
  end
405
407
 
408
+ def s3_bucket_location(bucket_name)
409
+ s3 = Aws::S3::Client.new(region: aws_api_region)
410
+
411
+ resp = s3.get_bucket_location(bucket: bucket_name)
412
+ resp.location_constraint
413
+ rescue Aws::S3::Errors::AccessDenied => _e
414
+ Chef::Log.warn("Missing s3:GetBucketLocation privilege, trying currently configured region #{aws_api_region}")
415
+ aws_api_region
416
+ end
417
+
418
+ def aws_api_region
419
+ ENV["AWS_REGION"] || Aws.shared_config.region || Aws::EC2Metadata.new.get("/latest/meta-data/placement/region")
420
+ end
421
+
406
422
  def interval_run_chef_client
407
423
  if Chef::Config[:daemonize]
408
424
  Chef::Daemon.daemonize(ChefUtils::Dist::Infra::PRODUCT)
data/lib/chef/client.rb CHANGED
@@ -66,6 +66,15 @@ class Chef
66
66
  class Client
67
67
  CRYPT_EXPORTABLE = 0x00000001
68
68
 
69
+ # adding these
70
+ # certstore 65536 == 0x00010000 == CurrentUser
71
+ # certstore 131072 == 0x00020000 == LocalMachine
72
+ # Reference: https://github.com/chef/win32-certstore/blob/main/lib/win32/certstore/mixin/crypto.rb#L90
73
+ CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000
74
+ CERT_SYSTEM_STORE_CURRENT_USER = 0x00010000
75
+ CERT_SYSTEM_STORE_SERVICES = 0x00050000
76
+ CERT_SYSTEM_STORE_USERS = 0x00060000
77
+
69
78
  attr_reader :local_context
70
79
 
71
80
  extend Chef::Mixin::Deprecation
@@ -674,9 +683,15 @@ class Chef
674
683
 
675
684
  # In the brave new world of No Certs On Disk, we want to put the pem file into Keychain or the Certstore
676
685
  # But is it already there?
686
+ # We're solving the multi-user scenario where both a system/admin user can run on the box but also someone without
687
+ # admin rights can also run correctly locally.
677
688
  def check_certstore_for_key(cert_name)
678
689
  require "win32-certstore"
679
- win32certstore = ::Win32::Certstore.open("MY")
690
+ if Chef::Config[:auth_key_registry_type] == "user"
691
+ win32certstore = ::Win32::Certstore.open("MY", store_location: CERT_SYSTEM_STORE_CURRENT_USER)
692
+ else
693
+ win32certstore = ::Win32::Certstore.open("MY")
694
+ end
680
695
  win32certstore.search("#{cert_name}")
681
696
  end
682
697
 
@@ -783,8 +798,6 @@ class Chef
783
798
  require "time" unless defined?(Time)
784
799
  autoload :URI, "uri"
785
800
 
786
- # KeyMigration.instance.key_migrated = true
787
-
788
801
  node = Chef::Config[:node_name]
789
802
  d = Time.now
790
803
  if d.month == 10 || d.month == 11 || d.month == 12
@@ -818,9 +831,13 @@ class Chef
818
831
  require "win32-certstore"
819
832
  tempfile = Tempfile.new("#{Chef::Config[:node_name]}.pfx")
820
833
  File.open(tempfile, "wb") { |f| f.print new_pfx.to_der }
821
-
822
- store = ::Win32::Certstore.open("MY")
823
- store.add_pfx(tempfile, password, CRYPT_EXPORTABLE)
834
+ # Need to determine where to store the key
835
+ if Chef::Config[:auth_key_registry_type] == "user"
836
+ win32certstore = ::Win32::Certstore.open("MY", store_location: CERT_SYSTEM_STORE_CURRENT_USER)
837
+ else
838
+ win32certstore = ::Win32::Certstore.open("MY")
839
+ end
840
+ win32certstore.add_pfx(tempfile, password, CRYPT_EXPORTABLE)
824
841
  tempfile.unlink
825
842
  end
826
843
 
@@ -102,12 +102,12 @@ class Chef
102
102
  self.class.get_cert_password
103
103
  end
104
104
 
105
- def encrypt_pfx_pass
106
- self.class.encrypt_pfx_pass
105
+ def encrypt_pfx_pass_with_vector
106
+ self.class.encrypt_pfx_pass_with_vector
107
107
  end
108
108
 
109
- def decrypt_pfx_pass
110
- self.class.decrypt_pfx_pass
109
+ def decrypt_pfx_pass_with_vector
110
+ self.class.decrypt_pfx_pass_with_vector
111
111
  end
112
112
 
113
113
  # Detects if a private key exists in a certificate repository like Keychain (macOS) or Certificate Store (Windows)
@@ -123,9 +123,18 @@ class Chef
123
123
  end
124
124
  end
125
125
 
126
+ def self.get_cert_user
127
+ Chef::Config[:auth_key_registry_type] == "user" ? store = "CurrentUser" : store = "LocalMachine"
128
+ end
129
+
130
+ def self.get_registry_user
131
+ Chef::Config[:auth_key_registry_type] == "user" ? store = "HKEY_CURRENT_USER" : store = "HKEY_LOCAL_MACHINE"
132
+ end
133
+
126
134
  def self.check_certstore_for_key(client_name)
135
+ store = get_cert_user
127
136
  powershell_code = <<~CODE
128
- $cert = Get-ChildItem -path cert:\\LocalMachine\\My -Recurse -Force | Where-Object { $_.Subject -Match "chef-#{client_name}" } -ErrorAction Stop
137
+ $cert = Get-ChildItem -path cert:\\#{store}\\My -Recurse -Force | Where-Object { $_.Subject -Match "chef-#{client_name}" } -ErrorAction Stop
129
138
  if (($cert.HasPrivateKey -eq $true) -and ($cert.PrivateKey.Key.ExportPolicy -ne "NonExportable")) {
130
139
  return $true
131
140
  }
@@ -164,49 +173,86 @@ class Chef
164
173
  end
165
174
 
166
175
  def self.get_cert_password
176
+ store = get_registry_user
167
177
  @win32registry = Chef::Win32::Registry.new
168
- path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
178
+ path = "#{store}\\Software\\Progress\\Authentication"
169
179
  # does the registry key even exist?
170
- present = @win32registry.get_values(path)
171
- if present.nil? || present.empty?
180
+ # password_blob should be an array of hashes
181
+ password_blob = @win32registry.get_values(path)
182
+ if password_blob.nil? || password_blob.empty?
172
183
  raise Chef::Exceptions::Win32RegKeyMissing
173
184
  end
174
185
 
175
- present.each do |secret|
176
- if secret[:name] == "PfxPass"
177
- password = decrypt_pfx_pass(secret[:data])
178
- return password
186
+ # Did someone have just the password stored in the registry?
187
+ raw_data = password_blob.map { |x| x[:data] }
188
+ vector = raw_data[2]
189
+ if !!vector
190
+ decrypted_password = decrypt_pfx_pass_with_vector(password_blob)
191
+ else
192
+ decrypted_password = decrypt_pfx_pass_with_password(password_blob)
193
+ if !!decrypted_password
194
+ migrate_pass_to_use_vector(decrypted_password)
195
+ else
196
+ Chef::Log.error("Failed to retrieve certificate password")
179
197
  end
180
198
  end
181
-
182
- raise Chef::Exceptions::Win32RegKeyMissing
183
-
199
+ decrypted_password
184
200
  rescue Chef::Exceptions::Win32RegKeyMissing
185
201
  # if we don't have a password, log that and generate one
186
- Chef::Log.warn "Authentication Hive and values not present in registry, creating them now"
187
- new_path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
202
+ store = get_registry_user
203
+ new_path = "#{store}\\Software\\Progress\\Authentication"
188
204
  unless @win32registry.key_exists?(new_path)
189
205
  @win32registry.create_key(new_path, true)
190
206
  end
191
- require "securerandom" unless defined?(SecureRandom)
192
- size = 14
193
- password = SecureRandom.alphanumeric(size)
194
- encrypted_pass = encrypt_pfx_pass(password)
195
- values = { name: "PfxPass", type: :string, data: encrypted_pass }
196
- @win32registry.set_value(new_path, values)
197
- password
207
+ create_and_store_new_password
198
208
  end
199
209
 
200
- def self.encrypt_pfx_pass(password)
210
+ def self.encrypt_pfx_pass_with_vector(password)
201
211
  powershell_code = <<~CODE
202
- $encrypted_string = ConvertTo-SecureString "#{password}" -AsPlainText -Force
203
- $secure_string = ConvertFrom-SecureString $encrypted_string
204
- return $secure_string
212
+ $AES = [System.Security.Cryptography.Aes]::Create()
213
+ $key_temp = [System.Convert]::ToBase64String($AES.Key)
214
+ $iv_temp = [System.Convert]::ToBase64String($AES.IV)
215
+ $encryptor = $AES.CreateEncryptor()
216
+ [System.Byte[]]$Bytes = [System.Text.Encoding]::Unicode.GetBytes("#{password}")
217
+ $EncryptedBytes = $encryptor.TransformFinalBlock($Bytes,0,$Bytes.Length)
218
+ $EncryptedBase64String = [System.Convert]::ToBase64String($EncryptedBytes)
219
+ # create array of encrypted pass, key, iv
220
+ $password_blob = @($EncryptedBase64String, $key_temp, $iv_temp)
221
+ return $password_blob
205
222
  CODE
206
223
  powershell_exec!(powershell_code).result
207
224
  end
208
225
 
209
- def self.decrypt_pfx_pass(password)
226
+ def self.decrypt_pfx_pass_with_vector(password_blob)
227
+ raw_data = password_blob.map { |x| x[:data] }
228
+ password = raw_data[0]
229
+ key = raw_data[1]
230
+ vector = raw_data[2]
231
+
232
+ powershell_code = <<~CODE
233
+ $KeyBytes = [System.Convert]::FromBase64String("#{key}")
234
+ $IVBytes = [System.Convert]::FromBase64String("#{vector}")
235
+ $aes = [System.Security.Cryptography.Aes]::Create()
236
+ $aes.Key = $KeyBytes
237
+ $aes.IV = $IVBytes
238
+ $EncryptedBytes = [System.Convert]::FromBase64String("#{password}")
239
+ $Decryptor = $aes.CreateDecryptor()
240
+ $DecryptedBytes = $Decryptor.TransformFinalBlock($EncryptedBytes,0,$EncryptedBytes.Length)
241
+ $DecryptedString = [System.Text.Encoding]::Unicode.GetString($DecryptedBytes)
242
+ return $DecryptedString
243
+ CODE
244
+ results = powershell_exec!(powershell_code).result
245
+ end
246
+
247
+ def self.decrypt_pfx_pass_with_password(password_blob)
248
+ password = ""
249
+ password_blob.each do |secret|
250
+ if secret[:name] == "PfxPass"
251
+ password = secret[:data]
252
+ else
253
+ Chef::Log.error("Failed to retrieve a password for the private key")
254
+ end
255
+ end
210
256
  powershell_code = <<~CODE
211
257
  $secure_string = "#{password}" | ConvertTo-SecureString
212
258
  $string = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($secure_string))))
@@ -215,14 +261,49 @@ class Chef
215
261
  powershell_exec!(powershell_code).result
216
262
  end
217
263
 
218
- def self.retrieve_certificate_key(client_name)
219
- require "openssl" unless defined?(OpenSSL)
264
+ def self.migrate_pass_to_use_vector(password)
265
+ store = get_cert_user
266
+ corrected_store = (store == "CurrentUser" ? "HKCU" : "HKLM")
267
+ powershell_code = <<~CODE
268
+ Remove-ItemProperty -Path "#{corrected_store}:\\Software\\Progress\\Authentication" -Name "PfXPass"
269
+ CODE
270
+ powershell_exec!(powershell_code)
271
+ create_and_store_new_password(password)
272
+ end
220
273
 
274
+ # This method name is a bit of a misnomer. We call it to legit create a new password using the vector format.
275
+ # But we also call it with a password that needs to be migrated to use the vector format too.
276
+ def self.create_and_store_new_password(password = nil)
277
+ @win32registry = Chef::Win32::Registry.new
278
+ store = get_registry_user
279
+ path = "#{store}\\Software\\Progress\\Authentication"
280
+ if password.nil?
281
+ require "securerandom" unless defined?(SecureRandom)
282
+ size = 14
283
+ password = SecureRandom.alphanumeric(size)
284
+ end
285
+ encrypted_blob = encrypt_pfx_pass_with_vector(password)
286
+ encrypted_password = encrypted_blob[0]
287
+ key = encrypted_blob[1]
288
+ vector = encrypted_blob[2]
289
+ values = [
290
+ { name: "PfxPass", type: :string, data: encrypted_password },
291
+ { name: "PfxKey", type: :string, data: key },
292
+ { name: "PfxIV", type: :string, data: vector },
293
+ ]
294
+ values.each do |i|
295
+ @win32registry.set_value(path, i)
296
+ end
297
+ password
298
+ end
299
+
300
+ def self.retrieve_certificate_key(client_name)
221
301
  if ChefUtils.windows?
302
+ require "openssl" unless defined?(OpenSSL)
222
303
  password = get_cert_password
223
304
  return false unless password
224
305
 
225
- if check_certstore_for_key(client_name)
306
+ if !!check_certstore_for_key(client_name)
226
307
  ps_blob = powershell_exec!(get_the_key_ps(client_name, password)).result
227
308
  file_path = ps_blob["PSPath"].split("::")[1]
228
309
  pkcs = OpenSSL::PKCS12.new(File.binread(file_path), password)
@@ -252,10 +333,11 @@ class Chef
252
333
  end
253
334
 
254
335
  def self.get_the_key_ps(client_name, password)
336
+ store = get_cert_user
255
337
  powershell_code = <<~CODE
256
338
  Try {
257
339
  $my_pwd = ConvertTo-SecureString -String "#{password}" -Force -AsPlainText;
258
- $cert = Get-ChildItem -path cert:\\LocalMachine\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } -ErrorAction Stop;
340
+ $cert = Get-ChildItem -path cert:\\#{store}\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } -ErrorAction Stop;
259
341
  $tempfile = [System.IO.Path]::GetTempPath() + "export_pfx.pfx";
260
342
  Export-PfxCertificate -Cert $cert -Password $my_pwd -FilePath $tempfile;
261
343
  }
@@ -266,8 +348,9 @@ class Chef
266
348
  end
267
349
 
268
350
  def self.delete_old_key_ps(client_name)
351
+ store = get_cert_user
269
352
  powershell_code = <<~CODE
270
- Get-ChildItem -path cert:\\LocalMachine\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } | Remove-Item -ErrorAction Stop;
353
+ Get-ChildItem -path cert:\\#{store}\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } | Remove-Item -ErrorAction Stop;
271
354
  CODE
272
355
  end
273
356
 
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- require "proxifier"
18
+ require "proxifier2"
19
19
  require "chef-config/mixin/fuzzy_hostname_matcher"
20
20
 
21
21
  class Chef
@@ -187,6 +187,24 @@ class Chef
187
187
  end.compact
188
188
  end
189
189
 
190
+ # run the specified command and extract the public key ids
191
+ # accepts the command so it can be used to extract both the current keys
192
+ # and the new keys
193
+ # @param [Array<String>] cmd the command to run
194
+ #
195
+ # @return [Array] an array of key ids
196
+ def extract_public_keys_from_cmd(*cmd)
197
+ so = shell_out(*cmd)
198
+ # Sample output
199
+ # pub:-:4096:1:D94AA3F0EFE21092:1336774248:::-:::scSC::::::23::0:
200
+ so.stdout.split(/\n/).map do |t|
201
+ if t.match(/^pub:/)
202
+ f = t.split(":")
203
+ f.slice(0, 6).join(":")
204
+ end
205
+ end.compact
206
+ end
207
+
190
208
  # validate the key against the apt keystore to see if that version is expired
191
209
  # @param [String] key
192
210
  #
@@ -222,8 +240,8 @@ class Chef
222
240
  def no_new_keys?(file)
223
241
  # Now we are using the option --with-colons that works across old os versions
224
242
  # as well as the latest (16.10). This for both `apt-key` and `gpg` commands
225
- installed_keys = extract_fingerprints_from_cmd(*LIST_APT_KEY_FINGERPRINTS)
226
- proposed_keys = extract_fingerprints_from_cmd("gpg", "--with-fingerprint", "--with-colons", file)
243
+ installed_keys = extract_public_keys_from_cmd(*LIST_APT_KEY_FINGERPRINTS)
244
+ proposed_keys = extract_public_keys_from_cmd("gpg", "--with-fingerprint", "--with-colons", file)
227
245
  (installed_keys & proposed_keys).sort == proposed_keys.sort
228
246
  end
229
247
 
@@ -43,6 +43,19 @@ class Chef
43
43
  end
44
44
  ```
45
45
 
46
+ **Using escape characters in a string of code**
47
+
48
+ In the following example, the `find` command uses an escape character (`\`). Use a second escape character (`\\`) to preserve the escape character in the code string:
49
+
50
+ ```ruby
51
+ bash 'delete some archives ' do
52
+ code <<-EOH
53
+ find ./ -name "*.tar.Z" -mtime +180 -exec rm -f {} \\;
54
+ EOH
55
+ ignore_failure true
56
+ end
57
+ ```
58
+
46
59
  **Install a file from a remote location**
47
60
 
48
61
  The following is an example of how to install the foo123 module for Nginx. This module adds shell-style functionality to an Nginx configuration file and does the following:
@@ -34,7 +34,7 @@ class Chef
34
34
  resource in #{ChefUtils::Dist::Infra::PRODUCT}, such as the Archive resource, a custom DSC resource, an existing DSC script that performs an important
35
35
  task, and so on. Use the dsc_script resource to embed the code that defines a DSC configuration directly within a #{ChefUtils::Dist::Infra::PRODUCT} recipe.
36
36
 
37
- Warning: The **dsc_script** resource may not be used with the 32 bit Chef Infra client. It must be executed from a 64 bit Chef Infra client.
37
+ Warning: The **dsc_script** resource is only available on 64-bit Chef Infra Client.
38
38
  DESC
39
39
 
40
40
  default_action :run
@@ -21,7 +21,7 @@ require_relative "../resource"
21
21
  class Chef
22
22
  class Resource
23
23
  class Launchd < Chef::Resource
24
- provides :launchd
24
+ provides :launchd, os: "darwin"
25
25
 
26
26
  description "Use the **launchd** resource to manage system-wide services (daemons) and per-user services (agents) on the macOS platform."
27
27
  introduced "12.8"
@@ -129,7 +129,7 @@ class Chef
129
129
  property :abandon_process_group, [ TrueClass, FalseClass ],
130
130
  description: "If a job dies, all remaining processes with the same process ID may be kept running. Set to true to kill all remaining processes."
131
131
 
132
- property :associated_bundle_identifiers, Hash,
132
+ property :associated_bundle_identifiers, Array,
133
133
  description: "This optional key indicates which bundles the Login Items Added by Apps panel associates with the helper executable."
134
134
 
135
135
  property :debug, [ TrueClass, FalseClass ],
@@ -92,7 +92,7 @@ class Chef
92
92
 
93
93
  property :release,
94
94
  [Float, String],
95
- description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used with the `auto_attach` option, it may also be used with activation keys. For example, `release '6.4'` will append `--release=6.4` to the register command.",
95
+ description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used with the `auto_attach` or `activation_key` options. For example, `release '6.4'` will append `--release=6.4` to the register command.",
96
96
  introduced: "17.8"
97
97
 
98
98
  action :register, description: "Register the node with RHSM." do
@@ -22,7 +22,7 @@ class Chef
22
22
 
23
23
  provides :selinux_fcontext
24
24
 
25
- description "Use **selinux_fcontext** resource to set the SELinux context of files with semanage fcontext."
25
+ description "Use the **selinux_fcontext** resource to set the SELinux context of files using the `semanage fcontext` command."
26
26
  introduced "18.0"
27
27
  examples <<~DOC
28
28
  **Allow http servers (e.g. nginx/apache) to modify moodle files**:
@@ -20,7 +20,7 @@ class Chef
20
20
 
21
21
  provides :selinux_permissive
22
22
 
23
- description "Use **selinux_permissive** resource to allows some types to misbehave without stopping them. Not as good as specific policies, but better than disabling SELinux entirely."
23
+ description "Use the **selinux_permissive** resource to allow some domains to misbehave without stopping them. This is not as good as setting specific policies, but better than disabling SELinux entirely."
24
24
  introduced "18.0"
25
25
  examples <<~DOC
26
26
  **Disable enforcement on Apache**:
@@ -21,7 +21,7 @@ class Chef
21
21
 
22
22
  provides :selinux_port
23
23
 
24
- description "Use **selinux_port** resource to allows assigning a network port to a certain SELinux context, e.g. for running a webserver on a non-standard port."
24
+ description "Use the **selinux_port** resource to assign a network port to a specific SELinux context. For example, running a web server on a non-standard port."
25
25
  introduced "18.0"
26
26
  examples <<~DOC
27
27
  **Allow nginx/apache to bind to port 5678 by giving it the http_port_t context**:
@@ -56,7 +56,7 @@ class Chef
56
56
 
57
57
  property :persistent, [true, false],
58
58
  default: true,
59
- description: "Persist status update to the selinux configuration file."
59
+ description: "Set the status update in the SELinux configuration file."
60
60
 
61
61
  property :policy, String,
62
62
  default: lazy { default_policy_platform },
@@ -81,7 +81,7 @@ class Chef
81
81
  # specify overrides for the start_command, stop_command and
82
82
  # restart_command properties.
83
83
  property :init_command, String,
84
- description: "The path to the init script that is associated with the service. Use init_command to prevent the need to specify overrides for the start_command, stop_command, and restart_command properties. When this property is not specified, the #{ChefUtils::Dist::Infra::PRODUCT} will use the default init command for the service provider being used.",
84
+ description: "The path to the init script that is associated with the service. Use `init_command` to prevent the need to specify overrides for the `start_command`, `stop_command`, and `restart_command` properties. When this property is not specified, the #{ChefUtils::Dist::Infra::PRODUCT} will use the default init command for the service provider being used.",
85
85
  desired_state: false
86
86
 
87
87
  # if the service is enabled or not
@@ -74,12 +74,12 @@ class Chef
74
74
  alias_method :group, :gid
75
75
 
76
76
  property :expire_date, [ String, NilClass ],
77
- description: "(Linux) The date on which the user account will be disabled. The date is specified in the format YYYY-MM-DD.",
77
+ description: "(Linux) The date on which the user account will be disabled. The date is specified in YYYY-MM-DD format.",
78
78
  introduced: "18.0",
79
79
  desired_state: false
80
80
 
81
81
  property :inactive, [ String, Integer, NilClass ],
82
- description: "(Linux) The number of days after a password expires until the account is permanently disabled. A value of 0 disables the account as soon as the password has expired, and a value of -1 disables the feature.",
82
+ description: "(Linux) The number of days after a password expires until the account is permanently disabled. A value of `0` disables the account as soon as the password has expired, and a value of `-1` disables the feature.",
83
83
  introduced: "18.0",
84
84
  desired_state: false
85
85
  end
@@ -23,12 +23,14 @@ class Chef
23
23
  class WindowsUserPrivilege < Chef::Resource
24
24
 
25
25
  provides :windows_user_privilege
26
- description "The windows_user_privilege resource allows to add a privilege to a principal or (User/Group).\n Ref: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment"
26
+ description "Use the **windows_user_privilege** resource to set privileges for a principal, user, or group.\n See [Microsoft's user rights assignment documentation](https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment) for more information."
27
27
 
28
28
  introduced "16.0"
29
29
 
30
30
  examples <<~DOC
31
- **Set the SeNetworkLogonRight Privilege for the Builtin Administrators Group and Authenticated Users**:
31
+ **Set the SeNetworkLogonRight privilege for the Builtin Administrators and Authenticated Users groups**:
32
+
33
+ The `:set` action will add this privilege for these two groups and remove this privilege from all other groups or users.
32
34
 
33
35
  ```ruby
34
36
  windows_user_privilege 'Network Logon Rights' do
@@ -38,7 +40,9 @@ class Chef
38
40
  end
39
41
  ```
40
42
 
41
- **Provide only the Builtin Guests and Administrator Groups with the SeCreatePageFile Privilege**:
43
+ **Set the SeCreatePagefilePrivilege privilege for the Builtin Guests and Administrator groups**:
44
+
45
+ The `:set` action will add this privilege for these two groups and remove this privilege from all other groups or users.
42
46
 
43
47
  ```ruby
44
48
  windows_user_privilege 'Create Pagefile' do
@@ -48,7 +52,7 @@ class Chef
48
52
  end
49
53
  ```
50
54
 
51
- **Add the SeDenyRemoteInteractiveLogonRight Privilege to the 'Remote interactive logon' principal**:
55
+ **Add the SeDenyRemoteInteractiveLogonRight privilege to the 'Remote interactive logon' principal**:
52
56
 
53
57
  ```ruby
54
58
  windows_user_privilege 'Remote interactive logon' do
@@ -57,7 +61,7 @@ class Chef
57
61
  end
58
62
  ```
59
63
 
60
- **Add to the Builtin Guests Group the SeCreatePageFile Privilege**:
64
+ **Add the SeCreatePageFilePrivilege privilege to the Builtin Guests group**:
61
65
 
62
66
  ```ruby
63
67
  windows_user_privilege 'Guests add Create Pagefile' do
@@ -67,7 +71,7 @@ class Chef
67
71
  end
68
72
  ```
69
73
 
70
- **Remove the SeCreatePageFile Privilege from the Builtin Guests Group**:
74
+ **Remove the SeCreatePageFilePrivilege privilege from the Builtin Guests group**:
71
75
 
72
76
  ```ruby
73
77
  windows_user_privilege 'Create Pagefile' do
@@ -77,7 +81,7 @@ class Chef
77
81
  end
78
82
  ```
79
83
 
80
- **Clear all users from the SeDenyNetworkLogonRight Privilege**:
84
+ **Clear the SeDenyNetworkLogonRight privilege from all users**:
81
85
 
82
86
  ```ruby
83
87
  windows_user_privilege 'Allow any user the Network Logon right' do
@@ -135,15 +139,15 @@ class Chef
135
139
  }.freeze
136
140
 
137
141
  property :principal, String,
138
- description: "An optional property to add the privilege for given principal. Use only with add and remove action. Principal can either be a User/Group or one of special identities found here Ref: https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/special-identities",
142
+ description: "An optional property to add the privilege for given principal. Use only with add and remove action. Principal can either be a user, group, or [special identity](https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/special-identities).",
139
143
  name_property: true
140
144
 
141
145
  property :users, [Array, String],
142
- description: "An optional property to set the privilege for given users. Use only with set action.",
146
+ description: "An optional property to set the privilege for the specified users. Use only with `:set` action",
143
147
  coerce: proc { |v| Array(v) }
144
148
 
145
149
  property :privilege, [Array, String],
146
- description: "One or more privileges to set for principal or users/groups. For more information on what each privilege does Ref: https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment",
150
+ description: "One or more privileges to set for principal or users/groups. For more information, see [Microsoft's documentation on what each privilege does](https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment).",
147
151
  required: true,
148
152
  coerce: proc { |v| Array(v) },
149
153
  callbacks: {
data/lib/chef/version.rb CHANGED
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("18.1.0")
26
+ VERSION = Chef::VersionString.new("18.1.29")
27
27
  end
28
28
 
29
29
  #
@@ -35,14 +35,14 @@ describe "chef-client" do
35
35
  @server = @api = nil
36
36
  end
37
37
 
38
- def install_certificate_in_store(client_name)
38
+ def install_certificate_in_store(client_name, store_location)
39
39
  if ChefUtils.windows?
40
40
  powershell_exec! <<~EOH
41
41
  if (-not (($PSVersionTable.PSVersion.Major -ge 5) -and ($PSVersionTable.PSVersion.Build -ge 22000)) ) {
42
- New-SelfSignedCertificate -CertStoreLocation Cert:\\LocalMachine\\My -DnsName "#{client_name}"
42
+ New-SelfSignedCertificate -CertStoreLocation Cert:\\#{store_location}\\My -DnsName "#{client_name}"
43
43
  }
44
44
  else {
45
- New-SelfSignedCertificate -CertStoreLocation Cert:\\LocalMachine\\My -Subject "#{client_name}" -FriendlyName "#{client_name}" -KeyExportPolicy Exportable
45
+ New-SelfSignedCertificate -CertStoreLocation Cert:\\#{store_location}\\My -Subject "#{client_name}" -FriendlyName "#{client_name}" -KeyExportPolicy Exportable
46
46
  }
47
47
  EOH
48
48
  end
@@ -50,14 +50,6 @@ describe "chef-client" do
50
50
 
51
51
  def create_registry_key
52
52
  ::Chef::HTTP::Authenticator.get_cert_password
53
- # @win32registry = Chef::Win32::Registry.new
54
- # path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
55
- # unless @win32registry.key_exists?(path)
56
- # @win32registry.create_key(path, true)
57
- # end
58
- # password = SOME_CHARS.sample(1 + rand(SOME_CHARS.count)).join[0...14]
59
- # values = { name: "PfxPass", type: :string, data: password }
60
- # @win32registry.set_value(path, values)
61
53
  end
62
54
 
63
55
  def remove_certificate_from_store
@@ -111,6 +103,9 @@ describe "chef-client" do
111
103
  tempfile.close
112
104
  @path = tempfile.path
113
105
  Chef::Config.validation_key = @path
106
+ if ChefUtils.windows?
107
+ create_registry_key
108
+ end
114
109
 
115
110
  file "config/client.rb", <<~EOM
116
111
  local_mode true
@@ -201,17 +196,27 @@ describe "chef-client" do
201
196
 
202
197
  if ChefUtils.windows?
203
198
  context "and the private key is in the Windows CertStore" do
204
- before do
205
- install_certificate_in_store(client_name)
199
+
200
+ it "should verify that the cert is loaded in the \\LocalMachine\\My store" do
201
+ Chef::Config[:auth_key_registry_type] = "machine"
202
+ install_certificate_in_store(client_name, "LocalMachine")
206
203
  create_registry_key
204
+ expect(Chef::HTTP::Authenticator.check_certstore_for_key(hostname)).to eq(true)
207
205
  end
208
206
 
209
- after do
207
+ it "should verify that the export password for the pfx is loaded in the Registry" do
208
+ expect(verify_export_password_exists.result).to eq(true)
209
+ end
210
+
211
+ it "should verify that a private key is returned to me" do
212
+ expect(Chef::HTTP::Authenticator.retrieve_certificate_key(client_name)).not_to be nil
210
213
  remove_certificate_from_store
211
- remove_registry_key
212
214
  end
213
215
 
214
- it "should verify that the cert is loaded in the LocalMachine\\My" do
216
+ it "should verify that the cert is loaded in the \\CurrentUser\\My store" do
217
+ Chef::Config[:auth_key_registry_type] = "user"
218
+ install_certificate_in_store(client_name, "CurrentUser")
219
+ create_registry_key
215
220
  expect(Chef::HTTP::Authenticator.check_certstore_for_key(hostname)).to eq(true)
216
221
  end
217
222
 
@@ -221,6 +226,7 @@ describe "chef-client" do
221
226
 
222
227
  it "should verify that a private key is returned to me" do
223
228
  expect(Chef::HTTP::Authenticator.retrieve_certificate_key(client_name)).not_to be nil
229
+ remove_certificate_from_store
224
230
  end
225
231
  end
226
232
  end
data/spec/spec_helper.rb CHANGED
@@ -138,9 +138,9 @@ RSpec.configure do |config|
138
138
 
139
139
  config.filter_run_excluding skip_buildkite: true if ENV["BUILDKITE"]
140
140
 
141
- config.filter_run_excluding fips_mode: !fips_mode_build? unless opensuse?
142
- # RubyDistros OpenSUSE docker images have a broken fips
143
- config.filter_run_excluding :fips_mode if opensuse?
141
+ config.filter_run_excluding fips_mode: !fips_mode_build?
142
+ # Skip fips on windows
143
+ # config.filter_run_excluding :fips_mode if windows?
144
144
 
145
145
  config.filter_run_excluding windows_only: true unless windows?
146
146
  config.filter_run_excluding not_supported_on_windows: true if windows?
@@ -310,25 +310,49 @@ describe Chef::Client, :windows_only do
310
310
  end
311
311
 
312
312
  context "when the client intially boots the first time" do
313
- it "verfies that a certificate was correctly created and exists in the Cert Store" do
313
+ it "verfies that a certificate was correctly created and exists in the LocalMachine Cert Store" do
314
+ Chef::Config[:node_name] = "test"
314
315
  new_pfx = my_client.generate_pfx_package(cert_name, end_date)
315
316
  my_client.import_pfx_to_store(new_pfx)
316
317
  expect(my_client.check_certstore_for_key(cert_name)).not_to be false
318
+ delete_certificate(cert_name)
317
319
  end
318
320
 
319
321
  it "correctly returns a new Publc Key" do
320
322
  new_pfx = my_client.generate_pfx_package(cert_name, end_date)
321
323
  cert_object = new_pfx.certificate.public_key.to_pem
322
324
  expect(cert_object.to_s).to match(/PUBLIC KEY/)
325
+ delete_certificate(cert_name)
326
+ end
327
+
328
+ end
329
+
330
+ context "when the client intially boots the first time and auth_key_registry_type is set to 'user' " do
331
+ it "verfies that a certificate was correctly created and exists in the CurrentUser Cert Store" do
332
+ Chef::Config[:node_name] = "test"
333
+ Chef::Config[:auth_key_registry_type] = "user"
334
+ new_pfx = my_client.generate_pfx_package(cert_name, end_date)
335
+ my_client.import_pfx_to_store(new_pfx)
336
+ expect(my_client.check_certstore_for_key(cert_name)).not_to be false
337
+ delete_certificate(cert_name)
338
+ end
339
+
340
+ it "correctly returns a new Publc Key" do
341
+ Chef::Config[:auth_key_registry_type] = "user"
342
+ new_pfx = my_client.generate_pfx_package(cert_name, end_date)
343
+ cert_object = new_pfx.certificate.public_key.to_pem
344
+ expect(cert_object.to_s).to match(/PUBLIC KEY/)
345
+ delete_certificate(cert_name)
323
346
  end
324
347
 
325
348
  end
326
349
 
327
350
  def delete_certificate(cert_name)
351
+ Chef::Config[:auth_key_registry_type] == "user" ? store = "CurrentUser" : store = "LocalMachine"
328
352
  require "chef/mixin/powershell_exec"
329
353
  extend Chef::Mixin::PowershellExec
330
354
  powershell_code = <<~CODE
331
- Get-ChildItem -path cert:\\LocalMachine\\My -Recurse -Force | Where-Object { $_.Subject -Match "#{cert_name}" } | Remove-item
355
+ Get-ChildItem -path cert:\\#{store}\\My -Recurse -Force | Where-Object { $_.Subject -Match "#{cert_name}" } | Remove-item
332
356
  CODE
333
357
  powershell_exec!(powershell_code)
334
358
  end
@@ -49,6 +49,14 @@ describe Chef::Compliance::Runner do
49
49
  expect(runner).not_to be_enabled
50
50
  end
51
51
 
52
+ it "is false if the node attributes have audit profiles and the audit cookbook is present, and the complince mode attribute is false" do
53
+ stub_const("::Reporter::ChefAutomate", true)
54
+ node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
55
+ node.normal["audit"]["compliance_phase"] = false
56
+
57
+ expect(runner).not_to be_enabled
58
+ end
59
+
52
60
  it "is true if the node attributes have audit profiles and the audit cookbook is present, and the complince mode attribute is true" do
53
61
  stub_const("::Reporter::ChefAutomate", true)
54
62
  node.normal["audit"]["profiles"]["ssh"] = { 'compliance': "base/ssh" }
@@ -18,6 +18,9 @@
18
18
 
19
19
  require "spec_helper"
20
20
  require "chef/http/authenticator"
21
+ require "chef/mixin/powershell_exec"
22
+
23
+ require_relative "../../../lib/chef/win32/registry"
21
24
 
22
25
  describe Chef::HTTP::Authenticator, :windows_only do
23
26
  let(:class_instance) { Chef::HTTP::Authenticator.new(client_name: "test") }
@@ -28,7 +31,7 @@ describe Chef::HTTP::Authenticator, :windows_only do
28
31
  let(:node_name) { "test" }
29
32
  let(:passwrd) { "some_insecure_password" }
30
33
 
31
- before do
34
+ before(:each) do
32
35
  Chef::Config[:node_name] = node_name
33
36
  cert_name = "chef-#{node_name}"
34
37
  d = Time.now
@@ -36,6 +39,7 @@ describe Chef::HTTP::Authenticator, :windows_only do
36
39
  end_date = end_date.utc.iso8601
37
40
 
38
41
  my_client = Chef::Client.new
42
+ class_instance.get_cert_password
39
43
  pfx = my_client.generate_pfx_package(cert_name, end_date)
40
44
  my_client.import_pfx_to_store(pfx)
41
45
  end
@@ -47,10 +51,21 @@ describe Chef::HTTP::Authenticator, :windows_only do
47
51
  delete_certificate(cert_name)
48
52
  end
49
53
 
50
- context "when retrieving a certificate from the certificate store" do
54
+ context "when retrieving a certificate from the certificate store it" do
55
+ it "properly creates the password hive in the registry when it doesn't exist" do
56
+ delete_registry_hive
57
+ class_instance.get_cert_password
58
+ win32registry = Chef::Win32::Registry.new
59
+ expected_path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
60
+ path_created = win32registry.key_exists?(expected_path)
61
+ expect(path_created).to be(true)
62
+ end
63
+
51
64
  it "retrieves a certificate password from the registry when the hive does not already exist" do
52
65
  delete_registry_hive
66
+ password = class_instance.get_cert_password
53
67
  expect { class_instance.get_cert_password }.not_to raise_error
68
+ expect(password).not_to be(nil)
54
69
  end
55
70
 
56
71
  it "should return a password of at least 14 characters in length" do
@@ -58,7 +73,27 @@ describe Chef::HTTP::Authenticator, :windows_only do
58
73
  expect(password.length).to eql(14)
59
74
  end
60
75
 
61
- it "correctly retrieves a valid certificate in pem format from the certstore" do
76
+ it "will retrieve a password from a partial registry hive and upgrades it while using the old decryptor" do
77
+ delete_registry_hive
78
+ load_partial_registry_hive
79
+ password = class_instance.get_cert_password
80
+ expect(password).to eql(passwrd)
81
+ end
82
+
83
+ it "verifies that the new password is now using a vector" do
84
+ win32registry = Chef::Win32::Registry.new
85
+ path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
86
+ password_blob = win32registry.get_values(path)
87
+ if password_blob.nil? || password_blob.empty?
88
+ raise Chef::Exceptions::Win32RegKeyMissing
89
+ end
90
+
91
+ raw_data = password_blob.map { |x| x[:data] }
92
+ vector = raw_data[2]
93
+ expect(vector).not_to be(nil)
94
+ end
95
+
96
+ it "correctly retrieves a valid certificate in pem format from the LocalMachine certstore" do
62
97
  require "openssl"
63
98
  certificate = class_instance.retrieve_certificate_key(node_name)
64
99
  cert_object = OpenSSL::PKey::RSA.new(certificate)
@@ -66,21 +101,39 @@ describe Chef::HTTP::Authenticator, :windows_only do
66
101
  end
67
102
  end
68
103
 
69
- def delete_certificate(cert_name)
104
+ def load_partial_registry_hive
105
+ extend Chef::Mixin::PowershellExec
106
+ password = "some_insecure_password"
70
107
  powershell_code = <<~CODE
71
- Get-ChildItem -path cert:\\LocalMachine\\My -Recurse -Force | Where-Object { $_.Subject -Match "#{cert_name}" } | Remove-item
108
+ $encrypted_string = ConvertTo-SecureString "#{password}" -AsPlainText -Force
109
+ $secure_string = ConvertFrom-SecureString $encrypted_string
110
+ return $secure_string
72
111
  CODE
73
- powershell_exec!(powershell_code)
112
+ encrypted_pass = powershell_exec!(powershell_code).result
113
+ Chef::Config[:auth_key_registry_type] == "user" ? store = "HKEY_CURRENT_USER" : store = "HKEY_LOCAL_MACHINE"
114
+ hive_path = "#{store}\\Software\\Progress\\Authentication"
115
+ win32registry = Chef::Win32::Registry.new
116
+ unless win32registry.key_exists?(hive_path)
117
+ win32registry.create_key(hive_path, true)
118
+ end
119
+ values = { name: "PfxPass", type: :string, data: encrypted_pass }
120
+ win32registry.set_value(hive_path, values)
74
121
  end
75
122
 
76
123
  def delete_registry_hive
77
- @win32registry = Chef::Win32::Registry.new
78
- path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
79
- present = @win32registry.get_values(path)
80
- unless present.nil? || present.empty?
81
- @win32registry.delete_key(path, true)
124
+ win32registry = Chef::Win32::Registry.new
125
+ hive_path = "HKEY_LOCAL_MACHINE\\Software\\Progress"
126
+ if win32registry.key_exists?(hive_path)
127
+ win32registry.delete_key(hive_path, true)
82
128
  end
83
129
  end
130
+
131
+ def delete_certificate(cert_name)
132
+ powershell_code = <<~CODE
133
+ Get-ChildItem -path cert:\\LocalMachine\\My -Recurse -Force | Where-Object { $_.Subject -Match "#{cert_name}" } | Remove-item
134
+ CODE
135
+ powershell_exec!(powershell_code)
136
+ end
84
137
  end
85
138
 
86
139
  describe Chef::HTTP::Authenticator do
@@ -82,6 +82,15 @@ C5986B4F1257FFA86632CBA746181433FBB75451
82
82
  843938DF228D22F7B3742BC0D94AA3F0EFE21092}
83
83
  end
84
84
 
85
+ let(:apt_public_keys) do
86
+ %w{
87
+ pub:-:1024:17:40976EAF437D05B5:2004-09-12
88
+ pub:-:1024:17:46181433FBB75451:2004-12-30
89
+ pub:-:4096:1:3B4FE6ACC0B21F32:2012-05-11
90
+ pub:-:4096:1:D94AA3F0EFE21092:2012-05-11
91
+ }
92
+ end
93
+
85
94
  it "responds to load_current_resource" do
86
95
  expect(provider).to respond_to(:load_current_resource)
87
96
  end
@@ -113,6 +122,18 @@ C5986B4F1257FFA86632CBA746181433FBB75451
113
122
  end
114
123
  end
115
124
 
125
+ describe "#extract_public_keys_from_cmd" do
126
+ it "runs the desired command" do
127
+ expect(provider).to receive(:shell_out).and_return(apt_key_finger)
128
+ provider.extract_public_keys_from_cmd(*apt_key_finger_cmd)
129
+ end
130
+
131
+ it "returns a list of key fingerprints" do
132
+ expect(provider).to receive(:shell_out).and_return(apt_key_finger)
133
+ expect(provider.extract_public_keys_from_cmd(*apt_key_finger_cmd)).to eql(apt_public_keys)
134
+ end
135
+ end
136
+
116
137
  describe "#cookbook_name" do
117
138
  it "returns 'test' when the cookbook property is set" do
118
139
  new_resource.cookbook("test")
@@ -122,22 +143,22 @@ C5986B4F1257FFA86632CBA746181433FBB75451
122
143
 
123
144
  describe "#no_new_keys?" do
124
145
  before do
125
- allow(provider).to receive(:extract_fingerprints_from_cmd).with(*apt_key_finger_cmd).and_return(apt_fingerprints)
146
+ allow(provider).to receive(:extract_public_keys_from_cmd).with(*apt_key_finger_cmd).and_return(apt_public_keys)
126
147
  end
127
148
 
128
149
  let(:file) { "/tmp/remote-gpg-keyfile" }
129
150
 
130
151
  it "matches a set of keys" do
131
- allow(provider).to receive(:extract_fingerprints_from_cmd)
152
+ allow(provider).to receive(:extract_public_keys_from_cmd)
132
153
  .with("gpg", "--with-fingerprint", "--with-colons", file)
133
- .and_return(Array(apt_fingerprints.first))
154
+ .and_return([apt_public_keys.first])
134
155
  expect(provider.no_new_keys?(file)).to be_truthy
135
156
  end
136
157
 
137
158
  it "notices missing keys" do
138
- allow(provider).to receive(:extract_fingerprints_from_cmd)
159
+ allow(provider).to receive(:extract_public_keys_from_cmd)
139
160
  .with("gpg", "--with-fingerprint", "--with-colons", file)
140
- .and_return(%w{ F36A89E33CC1BD0F71079007327574EE02A818DD })
161
+ .and_return(%w{pub:-:4096:1:871920D1991BC93C:1537196506})
141
162
  expect(provider.no_new_keys?(file)).to be_falsey
142
163
  end
143
164
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 18.1.0
4
+ version: 18.1.29
5
5
  platform: x64-mingw-ucrt
6
6
  authors:
7
7
  - Adam Jacob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-05 00:00:00.000000000 Z
11
+ date: 2023-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-config
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 18.1.0
19
+ version: 18.1.29
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 18.1.0
26
+ version: 18.1.29
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: chef-utils
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 18.1.0
33
+ version: 18.1.29
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: 18.1.0
40
+ version: 18.1.29
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: train-core
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -336,20 +336,20 @@ dependencies:
336
336
  requirements:
337
337
  - - "~>"
338
338
  - !ruby/object:Gem::Version
339
- version: '1.0'
339
+ version: '1.1'
340
340
  - - ">="
341
341
  - !ruby/object:Gem::Version
342
- version: 1.0.3
342
+ version: 1.1.3
343
343
  type: :runtime
344
344
  prerelease: false
345
345
  version_requirements: !ruby/object:Gem::Requirement
346
346
  requirements:
347
347
  - - "~>"
348
348
  - !ruby/object:Gem::Version
349
- version: '1.0'
349
+ version: '1.1'
350
350
  - - ">="
351
351
  - !ruby/object:Gem::Version
352
- version: 1.0.3
352
+ version: 1.1.3
353
353
  - !ruby/object:Gem::Dependency
354
354
  name: chef-zero
355
355
  requirement: !ruby/object:Gem::Requirement
@@ -483,19 +483,19 @@ dependencies:
483
483
  - !ruby/object:Gem::Version
484
484
  version: 0.3.4
485
485
  - !ruby/object:Gem::Dependency
486
- name: proxifier
486
+ name: proxifier2
487
487
  requirement: !ruby/object:Gem::Requirement
488
488
  requirements:
489
489
  - - "~>"
490
490
  - !ruby/object:Gem::Version
491
- version: '1.0'
491
+ version: '1.1'
492
492
  type: :runtime
493
493
  prerelease: false
494
494
  version_requirements: !ruby/object:Gem::Requirement
495
495
  requirements:
496
496
  - - "~>"
497
497
  - !ruby/object:Gem::Version
498
- version: '1.0'
498
+ version: '1.1'
499
499
  - !ruby/object:Gem::Dependency
500
500
  name: aws-sdk-s3
501
501
  requirement: !ruby/object:Gem::Requirement