puppet 8.1.0-x86-mingw32 → 8.3.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +30 -30
  4. data/ext/project_data.yaml +2 -2
  5. data/lib/puppet/application/doc.rb +1 -1
  6. data/lib/puppet/application/ssl.rb +42 -7
  7. data/lib/puppet/application.rb +5 -1
  8. data/lib/puppet/defaults.rb +17 -5
  9. data/lib/puppet/face/config.rb +1 -1
  10. data/lib/puppet/face/epp.rb +2 -2
  11. data/lib/puppet/face/module/list.rb +2 -2
  12. data/lib/puppet/face/parser.rb +1 -1
  13. data/lib/puppet/functions/split.rb +28 -1
  14. data/lib/puppet/http/client.rb +12 -5
  15. data/lib/puppet/http/service/ca.rb +25 -0
  16. data/lib/puppet/indirector/facts/facter.rb +1 -1
  17. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  18. data/lib/puppet/indirector/indirection.rb +1 -1
  19. data/lib/puppet/info_service/task_information_service.rb +1 -1
  20. data/lib/puppet/module_tool.rb +1 -1
  21. data/lib/puppet/network/formats.rb +3 -3
  22. data/lib/puppet/network/http/memory_response.rb +1 -1
  23. data/lib/puppet/node/environment.rb +6 -4
  24. data/lib/puppet/parameter/value_collection.rb +1 -1
  25. data/lib/puppet/parser/files.rb +4 -3
  26. data/lib/puppet/parser/functions.rb +1 -1
  27. data/lib/puppet/pops/evaluator/deferred_resolver.rb +20 -3
  28. data/lib/puppet/pops/loader/loader_paths.rb +4 -4
  29. data/lib/puppet/pops/lookup/explainer.rb +1 -1
  30. data/lib/puppet/pops/lookup/hiera_config.rb +1 -1
  31. data/lib/puppet/pops/model/factory.rb +1 -1
  32. data/lib/puppet/pops/model/tree_dumper.rb +1 -1
  33. data/lib/puppet/pops/parser/epp_support.rb +1 -1
  34. data/lib/puppet/pops/parser/evaluating_parser.rb +1 -1
  35. data/lib/puppet/pops/parser/pn_parser.rb +1 -1
  36. data/lib/puppet/pops/pn.rb +1 -1
  37. data/lib/puppet/pops/serialization/json_path.rb +1 -1
  38. data/lib/puppet/pops/time/timespan.rb +4 -4
  39. data/lib/puppet/pops/types/ruby_generator.rb +2 -2
  40. data/lib/puppet/pops/types/string_converter.rb +6 -6
  41. data/lib/puppet/pops/types/type_formatter.rb +2 -2
  42. data/lib/puppet/pops/types/types.rb +1 -1
  43. data/lib/puppet/provider/nameservice/directoryservice.rb +2 -2
  44. data/lib/puppet/provider/package/apt.rb +1 -1
  45. data/lib/puppet/provider/package/dnf.rb +1 -1
  46. data/lib/puppet/provider/package/yum.rb +1 -1
  47. data/lib/puppet/provider/user/directoryservice.rb +1 -1
  48. data/lib/puppet/reference/configuration.rb +1 -1
  49. data/lib/puppet/reference/indirection.rb +1 -1
  50. data/lib/puppet/reports.rb +1 -1
  51. data/lib/puppet/ssl/oids.rb +2 -0
  52. data/lib/puppet/ssl/ssl_provider.rb +1 -1
  53. data/lib/puppet/ssl/state_machine.rb +60 -9
  54. data/lib/puppet/transaction/report.rb +1 -1
  55. data/lib/puppet/type/filebucket.rb +1 -1
  56. data/lib/puppet/util/diff.rb +1 -1
  57. data/lib/puppet/util/execution.rb +9 -4
  58. data/lib/puppet/util/inifile.rb +2 -2
  59. data/lib/puppet/util/monkey_patches.rb +18 -0
  60. data/lib/puppet/util/package/version/rpm.rb +1 -1
  61. data/lib/puppet/util/provider_features.rb +1 -1
  62. data/lib/puppet/util/selinux.rb +1 -1
  63. data/lib/puppet/util/windows/access_control_entry.rb +1 -1
  64. data/lib/puppet/util/windows/access_control_list.rb +1 -1
  65. data/lib/puppet/util/windows/adsi.rb +9 -2
  66. data/lib/puppet/util/windows/error.rb +1 -1
  67. data/lib/puppet/util/windows/file.rb +2 -2
  68. data/lib/puppet/util/windows/process.rb +1 -1
  69. data/lib/puppet/util/windows/sid.rb +4 -2
  70. data/lib/puppet/util.rb +2 -3
  71. data/lib/puppet/version.rb +1 -1
  72. data/lib/puppet/x509/cert_provider.rb +13 -2
  73. data/locales/puppet.pot +106 -74
  74. data/man/man5/puppet.conf.5 +16 -2
  75. data/man/man8/puppet-agent.8 +1 -1
  76. data/man/man8/puppet-apply.8 +1 -1
  77. data/man/man8/puppet-catalog.8 +1 -1
  78. data/man/man8/puppet-config.8 +1 -1
  79. data/man/man8/puppet-describe.8 +1 -1
  80. data/man/man8/puppet-device.8 +1 -1
  81. data/man/man8/puppet-doc.8 +1 -1
  82. data/man/man8/puppet-epp.8 +1 -1
  83. data/man/man8/puppet-facts.8 +1 -1
  84. data/man/man8/puppet-filebucket.8 +1 -1
  85. data/man/man8/puppet-generate.8 +1 -1
  86. data/man/man8/puppet-help.8 +1 -1
  87. data/man/man8/puppet-lookup.8 +1 -1
  88. data/man/man8/puppet-module.8 +1 -1
  89. data/man/man8/puppet-node.8 +1 -1
  90. data/man/man8/puppet-parser.8 +1 -1
  91. data/man/man8/puppet-plugin.8 +1 -1
  92. data/man/man8/puppet-report.8 +1 -1
  93. data/man/man8/puppet-resource.8 +1 -1
  94. data/man/man8/puppet-script.8 +1 -1
  95. data/man/man8/puppet-ssl.8 +5 -1
  96. data/man/man8/puppet.8 +2 -2
  97. data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -107
  98. data/spec/fixtures/ssl/127.0.0.1.pem +52 -51
  99. data/spec/fixtures/ssl/bad-basic-constraints.pem +56 -56
  100. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +53 -53
  101. data/spec/fixtures/ssl/ca.pem +54 -54
  102. data/spec/fixtures/ssl/crl.pem +26 -26
  103. data/spec/fixtures/ssl/ec-key.pem +11 -11
  104. data/spec/fixtures/ssl/ec.pem +33 -32
  105. data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
  106. data/spec/fixtures/ssl/encrypted-key.pem +108 -108
  107. data/spec/fixtures/ssl/intermediate-agent-crl.pem +26 -26
  108. data/spec/fixtures/ssl/intermediate-agent.pem +56 -56
  109. data/spec/fixtures/ssl/intermediate-crl.pem +29 -29
  110. data/spec/fixtures/ssl/intermediate.pem +53 -53
  111. data/spec/fixtures/ssl/oid-key.pem +107 -107
  112. data/spec/fixtures/ssl/oid.pem +51 -50
  113. data/spec/fixtures/ssl/pluto-key.pem +107 -107
  114. data/spec/fixtures/ssl/pluto.pem +52 -51
  115. data/spec/fixtures/ssl/renewed.pem +67 -0
  116. data/spec/fixtures/ssl/request-key.pem +107 -107
  117. data/spec/fixtures/ssl/request.pem +50 -48
  118. data/spec/fixtures/ssl/revoked-key.pem +107 -107
  119. data/spec/fixtures/ssl/revoked.pem +51 -50
  120. data/spec/fixtures/ssl/signed-key.pem +107 -107
  121. data/spec/fixtures/ssl/signed.pem +49 -48
  122. data/spec/fixtures/ssl/tampered-cert.pem +51 -50
  123. data/spec/fixtures/ssl/tampered-csr.pem +50 -48
  124. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -107
  125. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -49
  126. data/spec/fixtures/ssl/unknown-ca-key.pem +107 -107
  127. data/spec/fixtures/ssl/unknown-ca.pem +54 -54
  128. data/spec/integration/application/agent_spec.rb +27 -27
  129. data/spec/integration/application/apply_spec.rb +14 -0
  130. data/spec/integration/http/client_spec.rb +16 -0
  131. data/spec/integration/type/exec_spec.rb +13 -0
  132. data/spec/lib/puppet/test_ca.rb +3 -10
  133. data/spec/lib/puppet_spec/verbose.rb +10 -1
  134. data/spec/unit/agent_spec.rb +2 -9
  135. data/spec/unit/application/ssl_spec.rb +49 -0
  136. data/spec/unit/defaults_spec.rb +2 -40
  137. data/spec/unit/file_system/path_pattern_spec.rb +15 -0
  138. data/spec/unit/functions/split_spec.rb +6 -0
  139. data/spec/unit/http/service/ca_spec.rb +71 -0
  140. data/spec/unit/info_service_spec.rb +1 -1
  141. data/spec/unit/ssl/certificate_signer_spec.rb +17 -0
  142. data/spec/unit/ssl/ssl_provider_spec.rb +21 -1
  143. data/spec/unit/ssl/state_machine_spec.rb +75 -3
  144. data/spec/unit/util/execution_spec.rb +1 -0
  145. data/spec/unit/util/monkey_patches_spec.rb +42 -0
  146. data/spec/unit/util/windows/adsi_spec.rb +25 -0
  147. data/spec/unit/x509/cert_provider_spec.rb +23 -0
  148. data/tasks/generate_cert_fixtures.rake +4 -0
  149. metadata +11 -13
@@ -258,7 +258,7 @@ module Puppet::Parser::Functions
258
258
  def self.functiondocs(environment = Puppet.lookup(:current_environment))
259
259
  autoloader.delegatee.loadall(environment)
260
260
 
261
- ret = String.new
261
+ ret = ''.dup
262
262
 
263
263
  merged_functions(environment).sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash|
264
264
  ret << "#{name}\n#{"-" * name.to_s.length}\n"
@@ -10,7 +10,13 @@ class DeferredValue
10
10
  end
11
11
 
12
12
  def resolve
13
- @proc.call
13
+ val = @proc.call
14
+ # Deferred sensitive values will be marked as such in resolve_futures()
15
+ if val.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
16
+ val.unwrap
17
+ else
18
+ val
19
+ end
14
20
  end
15
21
  end
16
22
 
@@ -88,8 +94,12 @@ class DeferredResolver
88
94
  #
89
95
  if resolved.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
90
96
  resolved = resolved.unwrap
91
- unless r.sensitive_parameters.include?(k.to_sym)
92
- r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze
97
+ mark_sensitive_parameters(r, k)
98
+ # If the value is a DeferredValue and it has an argument of type PSensitiveType, mark it as sensitive
99
+ # The DeferredValue.resolve method will unwrap it during catalog application
100
+ elsif resolved.is_a?(Puppet::Pops::Evaluator::DeferredValue)
101
+ if v.arguments.any? {|arg| arg.is_a?(Puppet::Pops::Types::PSensitiveType)}
102
+ mark_sensitive_parameters(r, k)
93
103
  end
94
104
  end
95
105
  overrides[ k ] = resolved
@@ -98,6 +108,13 @@ class DeferredResolver
98
108
  end
99
109
  end
100
110
 
111
+ def mark_sensitive_parameters(r, k)
112
+ unless r.sensitive_parameters.include?(k.to_sym)
113
+ r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze
114
+ end
115
+ end
116
+ private :mark_sensitive_parameters
117
+
101
118
  def resolve(x)
102
119
  if x.class == @deferred_class
103
120
  resolve_future(x)
@@ -88,7 +88,7 @@ module LoaderPaths
88
88
 
89
89
  def typed_name(type, name_authority, relative_path, module_name)
90
90
  # Module name is assumed to be included in the path and therefore not added here
91
- n = String.new
91
+ n = ''.dup
92
92
  unless extension.empty?
93
93
  # Remove extension
94
94
  relative_path = relative_path[0..-(extension.length+1)]
@@ -153,7 +153,7 @@ module LoaderPaths
153
153
  end
154
154
 
155
155
  def typed_name(type, name_authority, relative_path, module_name)
156
- n = String.new
156
+ n = ''.dup
157
157
  n << module_name unless module_name.nil?
158
158
  unless extension.empty?
159
159
  # Remove extension
@@ -249,7 +249,7 @@ module LoaderPaths
249
249
  end
250
250
 
251
251
  def typed_name(type, name_authority, relative_path, module_name)
252
- n = String.new
252
+ n = ''.dup
253
253
  n << module_name unless module_name.nil?
254
254
 
255
255
  # Remove the file extension, defined as everything after the *last* dot.
@@ -351,7 +351,7 @@ module LoaderPaths
351
351
  if @init_filenames.include?(relative_path) && !(module_name.nil? || module_name.empty?)
352
352
  TypedName.new(type, module_name, name_authority)
353
353
  else
354
- n = String.new
354
+ n = ''.dup
355
355
  n << module_name unless module_name.nil?
356
356
  ext = @extensions.find { |extension| relative_path.end_with?(extension) }
357
357
  relative_path = relative_path[0..-(ext.length+1)]
@@ -20,7 +20,7 @@ module Lookup
20
20
  end
21
21
 
22
22
  def explain
23
- io = String.new
23
+ io = ''.dup
24
24
  dump_on(io, '', '')
25
25
  io
26
26
  end
@@ -228,7 +228,7 @@ class HieraConfig
228
228
  line_number += 1
229
229
  next if line_number < start_line
230
230
  quote = nil
231
- stripped = String.new
231
+ stripped = ''.dup
232
232
  line.each_codepoint do |cp|
233
233
  if cp == 0x22 || cp == 0x27 # double or single quote
234
234
  if quote == cp
@@ -1112,7 +1112,7 @@ class Factory
1112
1112
  end
1113
1113
 
1114
1114
  def self.concat(*args)
1115
- result = String.new
1115
+ result = ''.dup
1116
1116
  args.each do |e|
1117
1117
  if e.instance_of?(Factory) && e.model_class <= LiteralString
1118
1118
  result << e[KEY_VALUE]
@@ -21,7 +21,7 @@ class Puppet::Pops::Model::TreeDumper
21
21
  end
22
22
 
23
23
  def format(x)
24
- result = String.new
24
+ result = ''.dup
25
25
  parts = format_r(x)
26
26
  parts.each_index do |i|
27
27
  if i > 0
@@ -183,7 +183,7 @@ module EppSupport
183
183
  @skip_leading = skip_leading
184
184
 
185
185
  return nil if scanner.eos?
186
- s = String.new
186
+ s = ''.dup
187
187
  until scanner.eos?
188
188
  part = @scanner.scan_until(/(<%)|\z/)
189
189
  if @skip_leading
@@ -125,7 +125,7 @@ class EvaluatingParser
125
125
  # @return [String] The quoted string
126
126
  #
127
127
  def self.quote(x)
128
- escaped = String.new('"')
128
+ escaped = '"'.dup
129
129
  p = nil
130
130
  x.each_char do |c|
131
131
  case p
@@ -218,7 +218,7 @@ class PNParser
218
218
 
219
219
  def consume_string
220
220
  s = @pos
221
- b = String.new
221
+ b = ''.dup
222
222
  loop do
223
223
  c = next_cp
224
224
  case c
@@ -20,7 +20,7 @@ module PN
20
20
  end
21
21
 
22
22
  def to_s
23
- s = String.new
23
+ s = ''.dup
24
24
  format(nil, s)
25
25
  s
26
26
  end
@@ -11,7 +11,7 @@ module JsonPath
11
11
  #
12
12
  # @api private
13
13
  def self.to_json_path(path)
14
- p = String.new('$')
14
+ p = '$'.dup
15
15
  path.each do |seg|
16
16
  if seg.nil?
17
17
  p << '[null]'
@@ -545,7 +545,7 @@ module Time
545
545
  end
546
546
 
547
547
  def format(timespan)
548
- bld = String.new(timespan.negative? ? '-' : '')
548
+ bld = timespan.negative? ? '-'.dup : ''.dup
549
549
  @segments.each { |segment| segment.append_to(bld, timespan) }
550
550
  bld
551
551
  end
@@ -575,7 +575,7 @@ module Time
575
575
  end
576
576
 
577
577
  def build_regexp
578
- bld = String.new('\A-?')
578
+ bld = '\A-?'.dup
579
579
  @segments.each { |segment| segment.append_regexp(bld) }
580
580
  bld << '\z'
581
581
  Regexp.new(bld)
@@ -613,7 +613,7 @@ module Time
613
613
 
614
614
  def append_literal(bld, codepoint)
615
615
  if bld.empty? || !bld.last.is_a?(Format::LiteralSegment)
616
- bld << Format::LiteralSegment.new(String.new.concat(codepoint))
616
+ bld << Format::LiteralSegment.new(''.dup.concat(codepoint))
617
617
  else
618
618
  bld.last.concat(codepoint)
619
619
  end
@@ -634,7 +634,7 @@ module Time
634
634
  position = -1
635
635
  fstart = 0
636
636
 
637
- str.codepoints do |codepoint|
637
+ str.each_codepoint do |codepoint|
638
638
  position += 1
639
639
  if state == STATE_LITERAL
640
640
  if codepoint == 0x25 # '%'
@@ -60,7 +60,7 @@ class RubyGenerator < TypeFormatter
60
60
  if cls.nil?
61
61
  rp = key.resolved_parent
62
62
  parent_class = rp.is_a?(PObjectType) ? rp.implementation_class : Object
63
- class_def = String.new
63
+ class_def = ''.dup
64
64
  class_body(key, EMPTY_ARRAY, class_def)
65
65
  cls = Class.new(parent_class)
66
66
  cls.class_eval(class_def)
@@ -109,7 +109,7 @@ class RubyGenerator < TypeFormatter
109
109
  end
110
110
 
111
111
  # Create class definition of all contained types
112
- bld = String.new
112
+ bld = ''.dup
113
113
  start_module(common_prefix, comment, bld)
114
114
  class_names = []
115
115
  names_by_prefix.each_pair do |seg_array, index_and_name_array|
@@ -701,7 +701,7 @@ class StringConverter
701
701
  # Performs post-processing of literals to apply width and precision flags
702
702
  def apply_string_flags(f, literal_str)
703
703
  if f.left || f.width || f.prec
704
- fmt = String.new('%')
704
+ fmt = '%'.dup
705
705
  fmt << '-' if f.left
706
706
  fmt << f.width.to_s if f.width
707
707
  fmt << '.' << f.prec.to_s if f.prec
@@ -853,7 +853,7 @@ class StringConverter
853
853
  end
854
854
 
855
855
  # Assume that the string can be single quoted
856
- bld = String.new('\'')
856
+ bld = "'".dup
857
857
  bld.force_encoding(str.encoding)
858
858
  escaped = false
859
859
  str.each_codepoint do |codepoint|
@@ -879,12 +879,12 @@ class StringConverter
879
879
  # If string ended with a backslash, then that backslash must be escaped
880
880
  bld << 0x5c if escaped
881
881
 
882
- bld << '\''
882
+ bld << "'"
883
883
  bld
884
884
  end
885
885
 
886
886
  def puppet_double_quote(str)
887
- bld = String.new('"')
887
+ bld = '"'.dup
888
888
  str.each_codepoint do |codepoint|
889
889
  case codepoint
890
890
  when 0x09
@@ -940,7 +940,7 @@ class StringConverter
940
940
 
941
941
  case format.format
942
942
  when :a, :s, :p
943
- buf = String.new
943
+ buf = ''.dup
944
944
  if indentation.breaks?
945
945
  buf << "\n"
946
946
  buf << indentation.padding
@@ -1055,7 +1055,7 @@ class StringConverter
1055
1055
 
1056
1056
  when :h, :s, :p
1057
1057
  indentation = indentation.indenting(format.alt? || indentation.is_indenting?)
1058
- buf = String.new
1058
+ buf = ''.dup
1059
1059
  if indentation.breaks?
1060
1060
  buf << "\n"
1061
1061
  buf << indentation.padding
@@ -50,7 +50,7 @@ class TypeFormatter
50
50
  # @api public
51
51
  #
52
52
  def string(t)
53
- @bld = String.new
53
+ @bld = ''.dup
54
54
  append_string(t)
55
55
  @bld
56
56
  end
@@ -64,7 +64,7 @@ class TypeFormatter
64
64
  #
65
65
  # @api public
66
66
  def indented_string(t, indent = 0, indent_width = 2)
67
- @bld = String.new
67
+ @bld = ''.dup
68
68
  append_indented_string(t, indent, indent_width)
69
69
  @bld
70
70
  end
@@ -1713,7 +1713,7 @@ class PRegexpType < PScalarType
1713
1713
  if options == 0
1714
1714
  rx_string
1715
1715
  else
1716
- bld = String.new('(?')
1716
+ bld = '(?'.dup
1717
1717
  bld << 'i' if (options & Regexp::IGNORECASE) != 0
1718
1718
  bld << 'm' if (options & Regexp::MULTILINE) != 0
1719
1719
  bld << 'x' if (options & Regexp::EXTENDED) != 0
@@ -218,8 +218,8 @@ class Puppet::Provider::NameService::DirectoryService < Puppet::Provider::NameSe
218
218
  password_hash_plist = users_plist['ShadowHashData'][0]
219
219
  converted_hash_plist = convert_binary_to_hash(password_hash_plist)
220
220
  else
221
- users_plist['ShadowHashData'] = String.new
222
- converted_hash_plist = {'SALTED-SHA512' => String.new}
221
+ users_plist['ShadowHashData'] = ''.dup
222
+ converted_hash_plist = {'SALTED-SHA512' => ''.dup}
223
223
  end
224
224
 
225
225
  # converted_hash_plist['SALTED-SHA512'] expects a Base64 encoded
@@ -13,7 +13,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
13
13
  These options should be specified as an array where each element is either a
14
14
  string or a hash."
15
15
 
16
- has_feature :versionable, :install_options, :virtual_packages
16
+ has_feature :versionable, :install_options, :virtual_packages, :version_ranges
17
17
 
18
18
  commands :aptget => "/usr/bin/apt-get"
19
19
  commands :aptcache => "/usr/bin/apt-cache"
@@ -10,7 +10,7 @@ Puppet::Type.type(:package).provide :dnf, :parent => :yum do
10
10
  These options should be specified as an array where each element is either
11
11
  a string or a hash."
12
12
 
13
- has_feature :install_options, :versionable, :virtual_packages, :install_only
13
+ has_feature :install_options, :versionable, :virtual_packages, :install_only, :version_ranges
14
14
 
15
15
  commands :cmd => "dnf", :rpm => "rpm"
16
16
 
@@ -16,7 +16,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
16
16
  This provider supports the `install_options` attribute, which allows command-line flags to be passed to yum.
17
17
  These options should be specified as an array where each element is either a string or a hash."
18
18
 
19
- has_feature :install_options, :versionable, :virtual_packages, :install_only
19
+ has_feature :install_options, :versionable, :virtual_packages, :install_only, :version_ranges
20
20
 
21
21
  RPM_VERSION = Puppet::Util::Package::Version::Rpm
22
22
  RPM_VERSION_RANGE = Puppet::Util::Package::Version::Range
@@ -637,7 +637,7 @@ Puppet::Type.type(:user).provide :directoryservice do
637
637
  def set_salted_sha512(users_plist, shadow_hash_data, value)
638
638
  unless shadow_hash_data
639
639
  shadow_hash_data = Hash.new
640
- shadow_hash_data['SALTED-SHA512'] = String.new
640
+ shadow_hash_data['SALTED-SHA512'] = ''.dup
641
641
  end
642
642
  shadow_hash_data['SALTED-SHA512'] = base64_decode_string(value)
643
643
  binary_plist = self.class.convert_hash_to_binary(shadow_hash_data)
@@ -5,7 +5,7 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
5
5
  docs[name] = object
6
6
  end
7
7
 
8
- str = String.new
8
+ str = ''.dup
9
9
  docs.sort { |a, b|
10
10
  a[0].to_s <=> b[0].to_s
11
11
  }.each do |name, object|
@@ -5,7 +5,7 @@ require_relative '../../puppet/file_serving/content'
5
5
  require_relative '../../puppet/file_serving/metadata'
6
6
 
7
7
  reference = Puppet::Util::Reference.newreference :indirection, :doc => "Indirection types and their terminus classes" do
8
- text = String.new
8
+ text = ''.dup
9
9
  Puppet::Indirector::Indirection.instances.sort_by(&:to_s).each do |indirection|
10
10
  ind = Puppet::Indirector::Indirection.instance(indirection)
11
11
  name = indirection.to_s.capitalize
@@ -71,7 +71,7 @@ class Puppet::Reports
71
71
  # Collects the docs for all reports.
72
72
  # @api private
73
73
  def self.reportdocs
74
- docs = String.new
74
+ docs = ''.dup
75
75
 
76
76
  # Use this method so they all get loaded
77
77
  instance_loader(:report).loadall(Puppet.lookup(:current_environment))
@@ -71,7 +71,9 @@ module Puppet::SSL::Oids
71
71
  ["1.3.6.1.4.1.34380.1.3", 'ppAuthCertExt', 'Puppet Certificate Authorization Extension'],
72
72
 
73
73
  ["1.3.6.1.4.1.34380.1.3.1", 'pp_authorization', 'Certificate Extension Authorization'],
74
+ ["1.3.6.1.4.1.34380.1.3.2", 'pp_auth_auto_renew', 'Auto-Renew Certificate Attribute'],
74
75
  ["1.3.6.1.4.1.34380.1.3.13", 'pp_auth_role', 'Puppet Node Role Name for Authorization'],
76
+ ["1.3.6.1.4.1.34380.1.3.39", 'pp_cli_auth', 'Puppetserver CA CLI Authorization'],
75
77
  ]
76
78
 
77
79
  @did_register_puppet_oids = false
@@ -225,7 +225,7 @@ class Puppet::SSL::SSLProvider
225
225
  ssl_context.crls.each do |crl|
226
226
  oid_values = Hash[crl.extensions.map { |ext| [ext.oid, ext.value] }]
227
227
  crlNumber = oid_values['crlNumber'] || 'unknown'
228
- authKeyId = (oid_values['authorityKeyIdentifier'] || 'unknown').chomp!
228
+ authKeyId = (oid_values['authorityKeyIdentifier'] || 'unknown').chomp
229
229
  Puppet.debug("Using CRL '#{crl.issuer.to_utf8}' authorityKeyIdentifier '#{authKeyId}' crlNumber '#{crlNumber }'")
230
230
  end
231
231
  end
@@ -59,9 +59,6 @@ class Puppet::SSL::StateMachine
59
59
  now = Time.now
60
60
  last_update = @cert_provider.ca_last_update
61
61
  if needs_refresh?(now, last_update)
62
- # set last updated time first, then make a best effort to refresh
63
- @cert_provider.ca_last_update = now
64
-
65
62
  # If we refresh the CA, then we need to force the CRL to be refreshed too,
66
63
  # since if there is a new CA in the chain, then we need its CRL to check
67
64
  # the full chain for revocation status.
@@ -114,7 +111,12 @@ class Puppet::SSL::StateMachine
114
111
  Puppet.info(_("Refreshing CA certificate"))
115
112
 
116
113
  # return the next_ctx containing the updated ca
117
- [download_ca(ssl_ctx, last_update), true]
114
+ next_ctx = [download_ca(ssl_ctx, last_update), true]
115
+
116
+ # After a successful refresh, update ca_last_update
117
+ @cert_provider.ca_last_update = Time.now
118
+
119
+ next_ctx
118
120
  rescue Puppet::HTTP::ResponseError => e
119
121
  if e.response.code == 304
120
122
  Puppet.info(_("CA certificate is unmodified, using existing CA certificate"))
@@ -171,8 +173,6 @@ class Puppet::SSL::StateMachine
171
173
  now = Time.now
172
174
  last_update = @cert_provider.crl_last_update
173
175
  if needs_refresh?(now, last_update)
174
- # set last updated time first, then make a best effort to refresh
175
- @cert_provider.crl_last_update = now
176
176
  next_ctx = refresh_crl(next_ctx, last_update)
177
177
  end
178
178
  else
@@ -209,7 +209,12 @@ class Puppet::SSL::StateMachine
209
209
  Puppet.info(_("Refreshing CRL"))
210
210
 
211
211
  # return the next_ctx containing the updated crl
212
- download_crl(ssl_ctx, last_update)
212
+ next_ctx = download_crl(ssl_ctx, last_update)
213
+
214
+ # After a successful refresh, update crl_last_update
215
+ @cert_provider.crl_last_update = Time.now
216
+
217
+ next_ctx
213
218
  rescue Puppet::HTTP::ResponseError => e
214
219
  if e.response.code == 304
215
220
  Puppet.info(_("CRL is unmodified, using existing CRL"))
@@ -257,7 +262,11 @@ class Puppet::SSL::StateMachine
257
262
  next_ctx = @ssl_provider.create_context(
258
263
  cacerts: @ssl_context.cacerts, crls: @ssl_context.crls, private_key: key, client_cert: cert
259
264
  )
260
- return Done.new(@machine, next_ctx)
265
+ if needs_refresh?(cert)
266
+ return NeedRenewedCert.new(@machine, next_ctx, key)
267
+ else
268
+ return Done.new(@machine, next_ctx)
269
+ end
261
270
  end
262
271
  else
263
272
  if Puppet[:key_type] == 'ec'
@@ -273,6 +282,15 @@ class Puppet::SSL::StateMachine
273
282
 
274
283
  NeedSubmitCSR.new(@machine, @ssl_context, key)
275
284
  end
285
+
286
+ private
287
+
288
+ def needs_refresh?(cert)
289
+ cert_ttl = Puppet[:hostcert_renewal_interval]
290
+ return false unless cert_ttl
291
+
292
+ Time.now.to_i >= (cert.not_after.to_i - cert_ttl)
293
+ end
276
294
  end
277
295
 
278
296
  # Base class for states with a private key.
@@ -344,6 +362,39 @@ class Puppet::SSL::StateMachine
344
362
  end
345
363
  end
346
364
 
365
+ # Class to renew a client/host certificate automatically.
366
+ #
367
+ class NeedRenewedCert < KeySSLState
368
+ def next_state
369
+ Puppet.debug(_("Renewing client certificate"))
370
+
371
+ route = @machine.session.route_to(:ca, ssl_context: @ssl_context)
372
+ cert = OpenSSL::X509::Certificate.new(
373
+ route.post_certificate_renewal(@ssl_context)[1]
374
+ )
375
+
376
+ # verify client cert before saving
377
+ next_ctx = @ssl_provider.create_context(
378
+ cacerts: @ssl_context.cacerts, crls: @ssl_context.crls, private_key: @private_key, client_cert: cert
379
+ )
380
+ @cert_provider.save_client_cert(Puppet[:certname], cert)
381
+
382
+ Puppet.info(_("Renewed client certificate: %{cert_digest}, not before '%{not_before}', not after '%{not_after}'") % { cert_digest: @machine.digest_as_hex(cert.to_pem), not_before: cert.not_before, not_after: cert.not_after })
383
+
384
+ Done.new(@machine, next_ctx)
385
+ rescue Puppet::HTTP::ResponseError => e
386
+ if e.response.code == 404
387
+ Puppet.info(_("Certificate autorenewal has not been enabled on the server."))
388
+ else
389
+ Puppet.warning(_("Failed to automatically renew certificate: %{code} %{reason}") % { code: e.response.code, reason: e.response.reason })
390
+ end
391
+ Done.new(@machine, @ssl_context)
392
+ rescue => e
393
+ Puppet.warning(_("Unable to automatically renew certificate: %{message}") % { message: e })
394
+ Done.new(@machine, @ssl_context)
395
+ end
396
+ end
397
+
347
398
  # We cannot make progress, so wait if allowed to do so, or exit.
348
399
  #
349
400
  class Wait < SSLState
@@ -495,7 +546,7 @@ class Puppet::SSL::StateMachine
495
546
  final_state.ssl_context
496
547
  end
497
548
 
498
- # Run the state machine for CA certs and CRLs.
549
+ # Run the state machine for client certs.
499
550
  #
500
551
  # @return [Puppet::SSL::SSLContext] initialized SSLContext
501
552
  # @raise [Puppet::Error] If we fail to generate an SSLContext
@@ -369,7 +369,7 @@ class Puppet::Transaction::Report
369
369
  def summary
370
370
  report = raw_summary
371
371
 
372
- ret = String.new
372
+ ret = ''.dup
373
373
  report.keys.sort_by(&:to_s).each do |key|
374
374
  ret += "#{Puppet::Util::Metric.labelize(key)}:\n"
375
375
 
@@ -4,7 +4,7 @@ module Puppet
4
4
 
5
5
  Type.newtype(:filebucket) do
6
6
  @doc = <<-EOT
7
- A repository for storing and retrieving file content by MD5 checksum. Can
7
+ A repository for storing and retrieving file content by cryptographic checksum. Can
8
8
  be local to each agent node, or centralized on a primary Puppet server. All
9
9
  puppet servers provide a filebucket service that agent nodes can access
10
10
  via HTTP, but you must declare a filebucket resource before any agents
@@ -34,7 +34,7 @@ module Puppet::Util::Diff
34
34
  data_old = data_old.split(/\n/).map! { |e| e.chomp }
35
35
  data_new = data_new.split(/\n/).map! { |e| e.chomp }
36
36
 
37
- output = String.new
37
+ output = ''.dup
38
38
 
39
39
  diffs = ::Diff::LCS.diff(data_old, data_new)
40
40
  return output if diffs.empty?
@@ -162,7 +162,7 @@ module Puppet::Util::Execution
162
162
  # do this after processing 'command' array or string
163
163
  command_str = '[redacted]' if options[:sensitive]
164
164
 
165
- user_log_s = String.new
165
+ user_log_s = ''.dup
166
166
  if options[:uid]
167
167
  user_log_s << " uid=#{options[:uid]}"
168
168
  end
@@ -202,7 +202,7 @@ module Puppet::Util::Execution
202
202
  stderr = options[:combine] ? stdout : Puppet::FileSystem.open(null_file, nil, 'w')
203
203
 
204
204
  exec_args = [command, options, stdin, stdout, stderr]
205
- output = String.new
205
+ output = ''.dup
206
206
 
207
207
  # We close stdin/stdout/stderr immediately after fork/exec as they're no longer needed by
208
208
  # this process. In most cases they could be closed later, but when `stdout` is the "writer"
@@ -223,8 +223,12 @@ module Puppet::Util::Execution
223
223
  # Use non-blocking read to check for data. After each attempt,
224
224
  # check whether the child is done. This is done in case the child
225
225
  # forks and inherits stdout, as happens in `foo &`.
226
-
227
- until results = Process.waitpid2(child_pid, Process::WNOHANG) #rubocop:disable Lint/AssignmentInCondition
226
+ # If we encounter EOF, though, then switch to a blocking wait for
227
+ # the child; after EOF, IO.select will never block and the loop
228
+ # below will use maximum CPU available.
229
+
230
+ wait_flags = Process::WNOHANG
231
+ until results = Process.waitpid2(child_pid, wait_flags) #rubocop:disable Lint/AssignmentInCondition
228
232
 
229
233
  # If not done, wait for data to read with a timeout
230
234
  # This timeout is selected to keep activity low while waiting on
@@ -235,6 +239,7 @@ module Puppet::Util::Execution
235
239
  output << reader.read_nonblock(4096) if ready
236
240
  rescue Errno::EAGAIN
237
241
  rescue EOFError
242
+ wait_flags = 0
238
243
  end
239
244
  end
240
245
 
@@ -79,7 +79,7 @@ module Puppet::Util::IniConfig
79
79
  # written to file
80
80
  def format
81
81
  if @destroy
82
- text = String.new
82
+ text = ''.dup
83
83
  else
84
84
  text = "[#{name}]\n"
85
85
  @entries.each do |entry|
@@ -208,7 +208,7 @@ module Puppet::Util::IniConfig
208
208
  end
209
209
 
210
210
  def format
211
- text = String.new
211
+ text = ''.dup
212
212
 
213
213
  @contents.each do |content|
214
214
  if content.is_a? Section
@@ -30,6 +30,24 @@ class Object
30
30
  end
31
31
  end
32
32
 
33
+ unless Dir.singleton_methods.include?(:exists?)
34
+ class Dir
35
+ def self.exists?(file_name)
36
+ warn("Dir.exists?('#{file_name}') is deprecated, use Dir.exist? instead") if $VERBOSE
37
+ Dir.exist?(file_name)
38
+ end
39
+ end
40
+ end
41
+
42
+ unless File.singleton_methods.include?(:exists?)
43
+ class File
44
+ def self.exists?(file_name)
45
+ warn("File.exists?('#{file_name}') is deprecated, use File.exist? instead") if $VERBOSE
46
+ File.exist?(file_name)
47
+ end
48
+ end
49
+ end
50
+
33
51
  require_relative '../../puppet/ssl/openssl_loader'
34
52
  unless Puppet::Util::Platform.jruby_fips?
35
53
  class OpenSSL::SSL::SSLContext