Skip to content

Commit

Permalink
(choria-legacy#18) Add configuration flag to always overwrite the cache
Browse files Browse the repository at this point in the history
* Add configuration flag to filesec/puppetsec to tell the provider to
always overwrite the local cache of a certificate with the one one
that's been presented (defaults to false for existing environments)
* Implement tests around configuration flag
* Update test certificates to replicate an updated certificate being
seen later
  • Loading branch information
vjanelle committed Nov 15, 2018
1 parent 54bd44c commit b9e1be1
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 64 deletions.
34 changes: 20 additions & 14 deletions filesec/file_security.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ type Config struct {

// DisableTLSVerify disables TLS verify in HTTP clients etc
DisableTLSVerify bool

// Support always overwriting the local filesystem cache
AlwaysOverwriteCache bool
}

// Option is a function that can configure the File Security Provider
Expand All @@ -77,14 +80,15 @@ type Option func(*FileSecurity) error
// WithChoriaConfig optionally configures the File Security Provider from settings found in a typical Choria configuration
func WithChoriaConfig(c *config.Config) Option {
cfg := Config{
AllowList: c.Choria.CertnameWhitelist,
CA: c.Choria.FileSecurityCA,
Cache: c.Choria.FileSecurityCache,
Certificate: c.Choria.FileSecurityCertificate,
DisableTLSVerify: c.DisableTLSVerify,
Key: c.Choria.FileSecurityKey,
PrivilegedUsers: c.Choria.PrivilegedUsers,
Identity: c.Identity,
AllowList: c.Choria.CertnameWhitelist,
CA: c.Choria.FileSecurityCA,
Cache: c.Choria.FileSecurityCache,
Certificate: c.Choria.FileSecurityCertificate,
DisableTLSVerify: c.DisableTLSVerify,
Key: c.Choria.FileSecurityKey,
PrivilegedUsers: c.Choria.PrivilegedUsers,
Identity: c.Identity,
AlwaysOverwriteCache: c.Choria.SecurityAlwaysOverwriteCache,
}

if cn, ok := os.LookupEnv("MCOLLECTIVE_CERTNAME"); ok {
Expand Down Expand Up @@ -333,10 +337,12 @@ func (s *FileSecurity) CachePublicData(data []byte, identity string) error {
return err
}

_, err = os.Stat(certfile)
if err == nil {
s.log.Debugf("Already have a certificate in %s, refusing to overwrite with a new one", certfile)
return nil
if !s.conf.AlwaysOverwriteCache {
_, err = os.Stat(certfile)
if err == nil {
s.log.Debugf("Already have a certificate in %s, refusing to overwrite with a new one", certfile)
return nil
}
}

err = ioutil.WriteFile(certfile, []byte(data), os.FileMode(int(0644)))
Expand Down Expand Up @@ -430,9 +436,9 @@ func (s *FileSecurity) VerifyCertificate(certpem []byte, name string) error {
}

opts := x509.VerifyOptions{
Roots: roots,
Roots: roots,
Intermediates: intermediates,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}

if name != "" {
Expand Down
44 changes: 44 additions & 0 deletions filesec/file_security_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package filesec

import (
"bytes"
"crypto/tls"
"encoding/base64"
"encoding/pem"
Expand Down Expand Up @@ -56,6 +57,7 @@ var _ = Describe("FileSSL", func() {
setSSL(cfg, goodStub, "rip.mcollective")

l = logrus.New()

l.Out = ioutil.Discard

prov, err = New(WithConfig(cfg), WithLog(l.WithFields(logrus.Fields{})))
Expand Down Expand Up @@ -505,6 +507,48 @@ var _ = Describe("FileSSL", func() {
Expect(stat.Size()).To(Equal(int64(16)))
})

It("Should support always overwrite files", func() {
c, err := config.NewDefaultConfig()
Expect(err).ToNot(HaveOccurred())

identity := "rip.mcollective"

// These certs both have the same hostname. First we cache the first one, then we attempt to cache the second one.
// This should result in the caching layer storing the second certificate.
firstcert := filepath.Join("..", "testdata", "intermediate", "certs", identity+".pem")
secondcert := filepath.Join("..", "testdata", "intermediate", "certs", "second."+identity+".pem")

c.Choria.FileSecurityCertificate = firstcert
c.Choria.FileSecurityCA = filepath.Join("..", "testdata", "intermediate", "certs", "ca.pem")
c.Choria.FileSecurityCache = filepath.Join("..", "testdata", "intermediate", "certs")
c.Choria.SecurityAlwaysOverwriteCache = true

c.Choria.FileSecurityCache, err = ioutil.TempDir("", "cache-always")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(c.Choria.FileSecurityCache)

prov, err := New(WithChoriaConfig(c), WithLog(l.WithFields(logrus.Fields{})))
Expect(err).ToNot(HaveOccurred())

fpd, err := ioutil.ReadFile(firstcert)
Expect(err).ToNot(HaveOccurred())

err = prov.CachePublicData(fpd, identity)
Expect(err).ToNot(HaveOccurred())

spd, err := ioutil.ReadFile(secondcert)
Expect(err).ToNot(HaveOccurred())

err = prov.CachePublicData(spd, identity)
Expect(err).To(BeNil())

cpd, err := prov.CachedPublicData(identity)
Expect(err).ToNot(HaveOccurred())

res := bytes.Compare(spd, cpd)
Expect(res).To(BeZero())
})

It("Should fail cache validation if allow lists change", func() {
cfg.Cache = os.TempDir()
cfg.Cache = os.TempDir()
Expand Down
37 changes: 25 additions & 12 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 11 additions & 7 deletions puppetsec/puppet_security.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ type Config struct {

useFakeUID bool
fakeUID int

//Support always overwriting the local filesystem cache
AlwaysOverwriteCache bool
}

// Option is a function that can configure the Puppet Security Provider
Expand All @@ -83,13 +86,14 @@ type Option func(*PuppetSecurity) error
func WithChoriaConfig(c *config.Config) Option {
return func(p *PuppetSecurity) error {
cfg := Config{
AllowList: c.Choria.CertnameWhitelist,
DisableTLSVerify: c.DisableTLSVerify,
PrivilegedUsers: c.Choria.PrivilegedUsers,
SSLDir: c.Choria.SSLDir,
PuppetCAHost: c.Choria.PuppetCAHost,
PuppetCAPort: c.Choria.PuppetCAPort,
Identity: c.Identity,
AllowList: c.Choria.CertnameWhitelist,
DisableTLSVerify: c.DisableTLSVerify,
PrivilegedUsers: c.Choria.PrivilegedUsers,
SSLDir: c.Choria.SSLDir,
PuppetCAHost: c.Choria.PuppetCAHost,
PuppetCAPort: c.Choria.PuppetCAPort,
Identity: c.Identity,
AlwaysOverwriteCache: c.Choria.SecurityAlwaysOverwriteCache,
}

if c.HasOption("plugin.choria.puppetca_host") || c.HasOption("plugin.choria.puppetca_port") {
Expand Down
28 changes: 28 additions & 0 deletions testdata/intermediate/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
all:
@rm -f ${PWD}/*.csr ${PWD}/*.pem
cfssl genkey -initca root.json | cfssljson -bare ca
cfssl genkey -initca intermediate.json | cfssljson -bare intermediate
cfssl sign -profile ca-to-root -ca ca.pem -ca-key ca-key.pem -config config.json intermediate.csr | cfssljson -bare intermediate
cfssl genkey csr.json | cfssljson -bare rip.mcollective
cfssl gencsr -key rip.mcollective-key.pem csr.json | cfssljson -bare rip.mcollective
cfssl sign -ca intermediate.pem -ca-key intermediate-key.pem rip.mcollective.csr subject.json | cfssljson -bare rip.mcollective && openssl x509 -in rip.mcollective.pem -noout -text
cat rip.mcollective.pem intermediate.pem > chain-rip.mcollective.pem
openssl verify -CAfile ca.pem -untrusted chain-rip.mcollective.pem chain-rip.mcollective.pem
cp ca.pem certs/ca.pem
cp chain-rip.mcollective.pem certs/rip.mcollective.pem

second:
# Make second cert chain to test caching
cfssl gencsr -key rip.mcollective-key.pem csr.json | cfssljson -bare second-rip.mcollective
cfssl sign -ca intermediate.pem -ca-key intermediate-key.pem rip.mcollective.csr subject.json | cfssljson -bare second-rip.mcollective && openssl x509 -in second-rip.mcollective.pem -noout -text
cat second-rip.mcollective.pem intermediate.pem > second-chain-rip.mcollective.pem
openssl x509 -in second-rip.mcollective.pem -noout -text

deploy:
cp ca.pem certs/ca.pem
cp chain-rip.mcollective.pem certs/rip.mcollective.pem
cp second-chain-rip.mcollective.pem certs/second.rip.mcollective.pem


clean:
rm -f *.pem *.csr
16 changes: 8 additions & 8 deletions testdata/intermediate/certs/ca.pem
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICOTCCAd+gAwIBAgIUHcItm2WcJQd0By9Sg5Wqlt0sONIwCgYIKoZIzj0EAwIw
MIICOjCCAd+gAwIBAgIUSHvvZWWyM18ks49RZkbWkyLslH0wCgYIKoZIzj0EAwIw
eTELMAkGA1UEBhMCWFgxETAPBgNVBAgTCExvY2FsaXR5MQ0wCwYDVQQHEwRDaXR5
MQ8wDQYDVQQKEwZDaG9yaWExJTAjBgNVBAsTHFVuaXQgdGVzdGluZyBJbnRlcm1l
ZGlhdGUgQ0ExEDAOBgNVBAMTB1Jvb3QgQ0EwHhcNMTgxMTExMjEzMDAwWhcNNDgx
MTAzMjEzMDAwWjB5MQswCQYDVQQGEwJYWDERMA8GA1UECBMITG9jYWxpdHkxDTAL
ZGlhdGUgQ0ExEDAOBgNVBAMTB1Jvb3QgQ0EwHhcNMTgxMTEzMDEyMzAwWhcNNDgx
MTA1MDEyMzAwWjB5MQswCQYDVQQGEwJYWDERMA8GA1UECBMITG9jYWxpdHkxDTAL
BgNVBAcTBENpdHkxDzANBgNVBAoTBkNob3JpYTElMCMGA1UECxMcVW5pdCB0ZXN0
aW5nIEludGVybWVkaWF0ZSBDQTEQMA4GA1UEAxMHUm9vdCBDQTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABPt/emjXdaHwnClOeT4qCjjPgOy8P5+sWwkV7UvWqDGW
YozFo0J9Sy5zBDAEdw6vmFA9F1yqx4Huuip4M/yF6USjRTBDMA4GA1UdDwEB/wQE
AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBRT2Qng+4kiaIILKMQ1
n9xNF5Rj3DAKBggqhkjOPQQDAgNIADBFAiEA+4RpvLfS0zX5T/uPXr2vHX7Ws78J
P/EyAiAYha39SNwCIDuRVsoTy72UtQdSkUAhslporEUNkNtbphynP3DaLZdd
AgEGCCqGSM49AwEHA0IABKKemAj1QsoT3pXQCYK7DD94vNry5BL9OnCmaojzlBFZ
0n0vZJi7/GHtr/OVnUXBQOD7XOOWkHCwHDJq2O0+Am6jRTBDMA4GA1UdDwEB/wQE
AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBQ2M6o4bz7r8MgG9Q0/
7rN8OgoiETAKBggqhkjOPQQDAgNJADBGAiEA/Yxzoa8YLNzIyWQqHq7tJHnnk3qt
anWV8i+8LIDItw4CIQC6YnE5cNQSUYXtK9L5A8sB8ZcBdO0LIu/zlrbBHQo53A==
-----END CERTIFICATE-----
46 changes: 23 additions & 23 deletions testdata/intermediate/certs/rip.mcollective.pem
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIDBjCCAqygAwIBAgIUVH5ROCpcZSA1uKg3RUD4/+GdFskwCgYIKoZIzj0EAwIw
MIIDBzCCAqygAwIBAgIUGCd2Rj5pwjR9bGLD9BS6YpWw7SIwCgYIKoZIzj0EAwIw
gYExCzAJBgNVBAYTAlhYMREwDwYDVQQIEwhMb2NhbGl0eTENMAsGA1UEBxMEQ2l0
eTEPMA0GA1UEChMGQ2hvcmlhMSUwIwYDVQQLExxVbml0IHRlc3RpbmcgSW50ZXJt
ZWRpYXRlIENBMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwHhcNMTgxMTExMjEz
MDAwWhcNMTkxMTExMjEzMDAwWjAaMRgwFgYDVQQDEw9yaXAubWNvbGxlY3RpdmUw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLNagA3ZY7Ohu2MscPPUy1
Yp8960WQdGUjBCGbN6nFOofGChuTRZXwVLxONWQuXS3fcBFkLQ9gfGBFyGSaYcKq
A2nYAvsuS46xTa+SkDUFePwE+JY/TcQR1lOLr2iCTqcNOFVaEYPsqaGhSlWnxZ9d
1sA7enzOb9DnDeHc/SAJII7r3cY3TLzvNqbBLcmfOh3wdA2Eqvosd7/TXcTY2eHQ
k9a9PJWbFeuLELgnPNROkw/ul0Dl1Vg0wGlr7q6jQFg22N+zZiKRa2740coSyuZ9
ziWVhW3H+XeWJSQrsmkML7xfTjTNTpPJfh18DWdjJ6mTq8yVkACkAlu3LZZiKd6H
ZWRpYXRlIENBMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwHhcNMTgxMTEzMDEy
MzAwWhcNMTkxMTEzMDEyMzAwWjAaMRgwFgYDVQQDEw9yaXAubWNvbGxlY3RpdmUw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNN5jOHMOMISkSrwFLmxIS
bKoEuDAwlOSbhFHc89GVbPcHziIJPLqur+YdV0xLZht+ZXvSZDsgo4hjZqXsOCbi
WZkzN5xfSuZqai8NvfEXOjXYjofCh3/bZ7gVcEkSt3EclxbcZ2d1pcX1sjl8GyH5
pyHmfOJHrpXdVE10Z4QuA58UKZoQ3i9R7ohCVYoUaAJn6+5015x/mWhzuB8ebdjc
mqt/aYK/f1apIxIo909nkXz2BS94B/s6zUGG89sA47Pi13CNC5u7cJ7VEfAQYHWP
F8sXzi6u7+MvDVXRcBPsy1sT89+udANidAtxYhn5On/dDB5qMD77DvJcVN/8Qil5
AgMBAAGjgZwwgZkwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRD5gmqomK9pQOzUE6p
gbLgBP48JjAfBgNVHSMEGDAWgBTE9RmIwQ7C2pfp37E4djWmkQrMyzAaBgNVHREE
EzARgg9yaXAubWNvbGxlY3RpdmUwCgYIKoZIzj0EAwIDSAAwRQIgKNywnHJ4NExk
1w8iwrvGP8bP9oeyoRBqPJjcCPWdNYACIQCyOi4N9N5vMK8QSSEJ2vRizq9neWhX
Y11phu0xsBIBPQ==
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTmgrLpFNVMbh1C5UsF
xVDjd549xzAfBgNVHSMEGDAWgBSlQrdE6JCCk8azRsWXnRuk2ctF+jAaBgNVHREE
EzARgg9yaXAubWNvbGxlY3RpdmUwCgYIKoZIzj0EAwIDSQAwRgIhAIDvVp0fzmEK
ULH79CDG3TqcCDiGRPwWMyRUFjazykNuAiEAypPXG9z+/MgGIO2lsYyhQR/Kd+ao
18XVjuUb3P2egYE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICYzCCAgmgAwIBAgIUM0jKjSKTjq5eO7N1jAHG+pVH3FUwCgYIKoZIzj0EAwIw
MIICZDCCAgmgAwIBAgIUMHE90peOTHN6Iv2S2R2astND6lswCgYIKoZIzj0EAwIw
eTELMAkGA1UEBhMCWFgxETAPBgNVBAgTCExvY2FsaXR5MQ0wCwYDVQQHEwRDaXR5
MQ8wDQYDVQQKEwZDaG9yaWExJTAjBgNVBAsTHFVuaXQgdGVzdGluZyBJbnRlcm1l
ZGlhdGUgQ0ExEDAOBgNVBAMTB1Jvb3QgQ0EwHhcNMTgxMTExMjEzMDAwWhcNNDgx
MTAzMjEzMDAwWjCBgTELMAkGA1UEBhMCWFgxETAPBgNVBAgTCExvY2FsaXR5MQ0w
ZGlhdGUgQ0ExEDAOBgNVBAMTB1Jvb3QgQ0EwHhcNMTgxMTEzMDEyMzAwWhcNNDgx
MTA1MDEyMzAwWjCBgTELMAkGA1UEBhMCWFgxETAPBgNVBAgTCExvY2FsaXR5MQ0w
CwYDVQQHEwRDaXR5MQ8wDQYDVQQKEwZDaG9yaWExJTAjBgNVBAsTHFVuaXQgdGVz
dGluZyBJbnRlcm1lZGlhdGUgQ0ExGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTBZ
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABLrrCCE1cvyKEHwmmKu5x2/eCnR8Qgkk
/TGi3eygp671u0G9kZOy2MdvgCecHCF/zR/YUPozEILZE9QldXVQWg+jZjBkMA4G
A1UdDwEB/wQEAwIBpjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTE9RmI
wQ7C2pfp37E4djWmkQrMyzAfBgNVHSMEGDAWgBRT2Qng+4kiaIILKMQ1n9xNF5Rj
3DAKBggqhkjOPQQDAgNIADBFAiEAtH7hxZ7QcPlFnM+YJuptChhGox7fSwwPbnyH
z7YMKygCIGn4lC2hIXRTk9FHPPCcZSPi8bJ9j5ZgKJO08xh3UGkb
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABNGtHy1coQANdtEj/OK8JjgVxQ+owXlq
X3PWtohIhx1dlD4MS78sPoEblHcU5NAfSPTN23gPw2kalFjV5NJH3I+jZjBkMA4G
A1UdDwEB/wQEAwIBpjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSlQrdE
6JCCk8azRsWXnRuk2ctF+jAfBgNVHSMEGDAWgBQ2M6o4bz7r8MgG9Q0/7rN8Ogoi
ETAKBggqhkjOPQQDAgNJADBGAiEAueRTGMy56l9024iI0tE+huS5E0wEu1ZyQfpI
AnqVQ70CIQCqVCe23uL3Po9THrXrmpVF7n+CJLQnKdpM3uxxsPWAIg==
-----END CERTIFICATE-----
Loading

0 comments on commit b9e1be1

Please sign in to comment.