From e78e7661115c78f78616fa24f8ad292ce7c3cdfd Mon Sep 17 00:00:00 2001 From: Jeff Wolak Date: Fri, 30 Oct 2020 19:36:13 -0700 Subject: [PATCH 1/2] support multiple encoded blocks --- lib/puppet-syntax/hiera.rb | 36 +++++++++++++--------------- spec/fixtures/hiera/hiera_bad.eyaml | 17 ++++++------- spec/fixtures/hiera/hiera_good.eyaml | 9 +++++++ spec/puppet-syntax/hiera_spec.rb | 12 ++++++++-- 4 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 spec/fixtures/hiera/hiera_good.eyaml diff --git a/lib/puppet-syntax/hiera.rb b/lib/puppet-syntax/hiera.rb index 6c9fb8b..ff5a8ee 100644 --- a/lib/puppet-syntax/hiera.rb +++ b/lib/puppet-syntax/hiera.rb @@ -42,30 +42,28 @@ def check_eyaml_data(name, val) end def check_eyaml_blob(val) - return unless val =~ /^ENC\[/ - - val.sub!('ENC[', '') + # strip newlines and extra spaces + val.gsub!(/\n/, '') val.gsub!(/\s+/, '') - if val !~ /\]$/ - return "has unterminated eyaml value" - else - val.sub!(/\]$/, '') - method, base64 = val.split(/,/) - if base64 == nil - base64 = method - method = 'PKCS7' - end + + encodes = val.scan(/ENC\[.*?\]/) - return "has unknown eyaml method #{method}" unless ['PKCS7','GPG','GKMS','KMS'].include? method - return "has unpadded or truncated base64 data" unless base64.length % 4 == 0 + # Return if there's no encoded material + return if encodes.length == 0 - # Base64#decode64 will silently ignore characters outside the alphabet, - # so we check resulting length of binary data instead - pad_length = base64.gsub(/[^=]/, '').length - if Base64.decode64(base64).length != base64.length * 3/4 - pad_length - return "has corrupt base64 data" + encodes.each do |n| + match = n.match(/ENC\[(.+),(.+)\]/) + if match == nil + return "has invalid eyaml encoded format" end + + return "has unknown eyaml method #{match[1]}" unless ['PKCS7','GPG','GKMS','KMS'].include? match[1] + + return "has unpadded or truncated base64 data" unless match[2].length % 4 == 0 + + return "has corrupt base64 data" unless match[2].match?(/^[a-zA-Z0-9+\/=]+$/) end + return end def check(filelist) diff --git a/spec/fixtures/hiera/hiera_bad.eyaml b/spec/fixtures/hiera/hiera_bad.eyaml index 14f4247..52eb7a1 100644 --- a/spec/fixtures/hiera/hiera_bad.eyaml +++ b/spec/fixtures/hiera/hiera_bad.eyaml @@ -1,11 +1,11 @@ --- -acme::warning1: ENC[unknown-method,aGVsbG8sIHdvcmxk] -acme::warning2: ENC[PKCS7,aGVsbG8sIHdvcmxk -acme::warning3: ENC[PKCS7,aGVsbG8sIHdvcmxk==] -acme::warning4: ENC[PKCS7,aGVs!!!!bG8sIHdvcmxk] +acme::warning1: ENC[unknown-method,aGVsbG8sIHdvcmxk] # unknown method +acme::warning2: ENC[PKCS7,aGV&&&sbG8sIHdvcmxk] # unpadded or truncated base64 data +acme::warning3: ENC[PKCS7,aGVsbG8sIHdvcmxk==] # unpadded or truncated base64 data +acme::warning4: ENC[PKCS7,aGVsbG8sf&IHdvcmxk==] # corrupt base64 data acme::warning5: key1: foo - key2: ENC[PKCS7,aGVs!!!!bG8sIHdvcmxk] + key2: ENC[PKCS7,aGVs!!!!bG8sIHdvcmxk] # corrupt base64 data acme::warning6: hash_key: - element1 @@ -17,8 +17,5 @@ acme::warning6: ENC[PKCS7, aGVs!!!!bG8sIHdvcmxk ] -acme::good1: > - ENC[PKCS7, - aGVsbG8sIHdvcmxk] -acme::good2: ENC[GPG,aGVsbG8sIHdvcmxkIQ==] -acme::good3: ENC[GPG,aGVsbG8sIHdvcmxkISE=] + # corrupt base64 data +acme::warning7: ENC[KMSaGVsbG8sIdGHdvcmxk==] # has invalid eyaml encoded format \ No newline at end of file diff --git a/spec/fixtures/hiera/hiera_good.eyaml b/spec/fixtures/hiera/hiera_good.eyaml new file mode 100644 index 0000000..2f260d9 --- /dev/null +++ b/spec/fixtures/hiera/hiera_good.eyaml @@ -0,0 +1,9 @@ +--- +acme::good1: ENC[KMS,aGVsbG8sIdGHdvcmxk==] +acme::good2: ENC[PKCS7,aGVsbG8sf3IHdvcmxk==] +acme::good3: ENC[KMS,aGVsbG8sIdGHdvcmxk==]ENC[KMS,aGVsbG8sIdGHdvcmxk==] +acme::good4: > + ENC[PKCS7, + aGVsbG8sIHdvcmxk] +acme::good5: ENC[GPG,aGVsbG8sIHdvcmxkIQ==] +acme::good6: ENC[GPG,aGVsbG8sIHdvcmxkISE=] diff --git a/spec/puppet-syntax/hiera_spec.rb b/spec/puppet-syntax/hiera_spec.rb index a4cd299..d9307fc 100644 --- a/spec/puppet-syntax/hiera_spec.rb +++ b/spec/puppet-syntax/hiera_spec.rb @@ -13,6 +13,13 @@ expect(res).to be == [] end + it "should return nothing from valid EYAML" do + files = fixture_hiera('hiera_good.eyaml') + res = subject.check(files) + expect(res).to be == [] + end + + it "should return an error from invalid YAML" do hiera_yaml = RUBY_VERSION =~ /1.8/ ? 'hiera_bad_18.yaml' : 'hiera_bad.yaml' files = fixture_hiera(hiera_yaml) @@ -45,7 +52,7 @@ it "should return warnings for bad eyaml values" do hiera_yaml = 'hiera_bad.eyaml' - examples = 6 + examples = 7 files = fixture_hiera(hiera_yaml) res = subject.check(files) (1..examples).each do |n| @@ -53,11 +60,12 @@ end expect(res.size).to be == examples expect(res[0]).to match('Key acme::warning1 has unknown eyaml method unknown-method') - expect(res[1]).to match('Key acme::warning2 has unterminated eyaml value') + expect(res[1]).to match('Key acme::warning2 has unpadded or truncated base64 data') expect(res[2]).to match('Key acme::warning3 has unpadded or truncated base64 data') expect(res[3]).to match('Key acme::warning4 has corrupt base64 data') expect(res[4]).to match('Key acme::warning5\[\'key2\'\] has corrupt base64 data') expect(res[5]).to match('Key acme::warning6\[\'hash_key\'\]\[2\] has corrupt base64 data') + expect(res[6]).to match('Key acme::warning7 has invalid eyaml encoded format') end it "should handle empty files" do From ee7fcb8c6508852c8b43beaad7b088ab0553f444 Mon Sep 17 00:00:00 2001 From: Jeff Wolak Date: Sat, 31 Oct 2020 19:33:48 -0700 Subject: [PATCH 2/2] add missing newline --- spec/fixtures/hiera/hiera_bad.eyaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/fixtures/hiera/hiera_bad.eyaml b/spec/fixtures/hiera/hiera_bad.eyaml index 52eb7a1..f0d5375 100644 --- a/spec/fixtures/hiera/hiera_bad.eyaml +++ b/spec/fixtures/hiera/hiera_bad.eyaml @@ -18,4 +18,4 @@ acme::warning6: aGVs!!!!bG8sIHdvcmxk ] # corrupt base64 data -acme::warning7: ENC[KMSaGVsbG8sIdGHdvcmxk==] # has invalid eyaml encoded format \ No newline at end of file +acme::warning7: ENC[KMSaGVsbG8sIdGHdvcmxk==] # has invalid eyaml encoded format