1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
require 'spec_helper'
require 'puppet/ssl/inventory'
describe Puppet::SSL::Inventory, :unless => Puppet.features.microsoft_windows? do
let(:cert_inventory) { File.expand_path("/inven/tory") }
# different UTF-8 widths
# 1-byte A
# 2-byte ۿ - http://www.fileformat.info/info/unicode/char/06ff/index.htm - 0xDB 0xBF / 219 191
# 3-byte ᚠ - http://www.fileformat.info/info/unicode/char/16A0/index.htm - 0xE1 0x9A 0xA0 / 225 154 160
# 4-byte - http://www.fileformat.info/info/unicode/char/2070E/index.htm - 0xF0 0xA0 0x9C 0x8E / 240 160 156 142
let (:mixed_utf8) { "A\u06FF\u16A0\u{2070E}" } # Aۿᚠ
before do
@class = Puppet::SSL::Inventory
end
describe "when initializing" do
it "should set its path to the inventory file" do
Puppet[:cert_inventory] = cert_inventory
expect(@class.new.path).to eq(cert_inventory)
end
end
describe "when managing an inventory" do
before do
Puppet[:cert_inventory] = cert_inventory
allow(Puppet::FileSystem).to receive(:exist?).with(cert_inventory).and_return(true)
@inventory = @class.new
@cert = double('cert')
end
describe "and creating the inventory file" do
it "re-adds all of the existing certificates" do
inventory_file = StringIO.new
allow(Puppet.settings.setting(:cert_inventory)).to receive(:open).and_yield(inventory_file)
cert1 = Puppet::SSL::Certificate.new("cert1")
cert1.content = double(
'cert1',
:serial => 2,
:not_before => Time.now,
:not_after => Time.now,
:subject => "/CN=smocking",
)
cert2 = Puppet::SSL::Certificate.new("cert2")
cert2.content = double(
'cert2',
:serial => 3,
:not_before => Time.now,
:not_after => Time.now,
:subject => "/CN=mocking bird",
)
expect(Puppet::SSL::Certificate.indirection).to receive(:search).with("*").and_return([cert1, cert2])
@inventory.rebuild
expect(inventory_file.string).to match(/\/CN=smocking/)
expect(inventory_file.string).to match(/\/CN=mocking bird/)
end
end
describe "and adding a certificate" do
it "should use the Settings to write to the file" do
expect(Puppet.settings.setting(:cert_inventory)).to receive(:open).with('a:UTF-8')
@inventory.add(@cert)
end
it "should add formatted certificate information to the end of the file" do
cert = Puppet::SSL::Certificate.new("mycert")
cert.content = @cert
fh = StringIO.new
expect(Puppet.settings.setting(:cert_inventory)).to receive(:open).with('a:UTF-8').and_yield(fh)
expect(@inventory).to receive(:format).with(@cert).and_return("myformat")
@inventory.add(@cert)
expect(fh.string).to eq("myformat")
end
it "can use UTF-8 in the CN per RFC 5280" do
cert = Puppet::SSL::Certificate.new("mycert")
cert.content = double(
'cert',
:serial => 1,
:not_before => Time.now,
:not_after => Time.now,
:subject => "/CN=#{mixed_utf8}",
)
fh = StringIO.new
expect(Puppet.settings.setting(:cert_inventory)).to receive(:open).with('a:UTF-8').and_yield(fh)
@inventory.add(cert)
expect(fh.string).to match(/\/CN=#{mixed_utf8}/)
end
end
describe "and formatting a certificate" do
before do
@cert = double('cert', :not_before => Time.now, :not_after => Time.now, :subject => "mycert", :serial => 15)
end
it "should print the serial number as a 4 digit hex number in the first field" do
expect(@inventory.format(@cert).split[0]).to eq("0x000f") # 15 in hex
end
it "should print the not_before date in '%Y-%m-%dT%H:%M:%S%Z' format in the second field" do
expect(@cert.not_before).to receive(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').and_return("before_time")
expect(@inventory.format(@cert).split[1]).to eq("before_time")
end
it "should print the not_after date in '%Y-%m-%dT%H:%M:%S%Z' format in the third field" do
expect(@cert.not_after).to receive(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').and_return("after_time")
expect(@inventory.format(@cert).split[2]).to eq("after_time")
end
it "should print the subject in the fourth field" do
expect(@inventory.format(@cert).split[3]).to eq("mycert")
end
it "should add a carriage return" do
expect(@inventory.format(@cert)).to match(/\n$/)
end
it "should produce a line consisting of the serial number, start date, expiration date, and subject" do
# Just make sure our serial and subject bracket the lines.
expect(@inventory.format(@cert)).to match(/^0x.+mycert$/)
end
end
describe "and finding serial numbers" do
it "should return an empty array if the inventory file is missing" do
expect(Puppet::FileSystem).to receive(:exist?).with(cert_inventory).and_return(false)
expect(@inventory.serials(:whatever)).to be_empty
end
it "should return the all the serial numbers from the lines matching the provided name" do
expect(File).to receive(:readlines).with(cert_inventory, :encoding => Encoding::UTF_8).and_return(["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n", "0x002 blah blah /CN=me\n"])
expect(@inventory.serials("me")).to eq([15, 2])
end
end
end
end
|