Fix locking around config/client

This commit is contained in:
vishalnayak
2016-04-27 22:25:15 -04:00
parent 0b561d668b
commit c7bfdd7ed0
2 changed files with 30 additions and 32 deletions

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"math/big"
"github.com/fatih/structs"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
@@ -131,17 +132,23 @@ func decodePEMAndParseCertificate(certificate string) (*x509.Certificate, error)
// awsPublicCertificates returns a slice of all the parsed AWS public
// certificates, that were registered using `config/certificate/<cert_name>` endpoint.
// This method will also append two default certificates to the slice.
// This method will also append default certificate to the slice.
func (b *backend) awsPublicCertificates(s logical.Storage) ([]*x509.Certificate, error) {
// Get the list `cert_name`s of all the registered certificates.
var certs []*x509.Certificate
// Append the generic certificate provided in the AWS EC2 instance metadata documentation.
decodedCert, err := decodePEMAndParseCertificate(genericAWSPublicCertificate)
if err != nil {
return nil, err
}
certs = append(certs, decodedCert)
// Get the list of all the registered certificates.
registeredCerts, err := s.List("config/certificate/")
if err != nil {
return nil, err
}
var certs []*x509.Certificate
// Iterate through each certificate, parse and append it to a slice.
for _, cert := range registeredCerts {
certEntry, err := b.awsPublicCertificateEntry(s, cert)
@@ -158,13 +165,6 @@ func (b *backend) awsPublicCertificates(s logical.Storage) ([]*x509.Certificate,
certs = append(certs, decodedCert)
}
// Append the generic certificate provided in the documentation.
decodedCert, err := decodePEMAndParseCertificate(genericAWSPublicCertificate)
if err != nil {
return nil, err
}
certs = append(certs, decodedCert)
return certs, nil
}
@@ -178,7 +178,6 @@ func (b *backend) awsPublicCertificateEntry(s logical.Storage, certName string)
return nil, err
}
if entry == nil {
// Existence check depends on this being nil when the storage entry is not present.
return nil, nil
}
@@ -209,7 +208,6 @@ func (b *backend) pathConfigCertificateDelete(req *logical.Request, data *framew
// used to verify the PKCS#7 signature of the instance identity document.
func (b *backend) pathConfigCertificateRead(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
certName := data.Get("cert_name").(string)
if certName == "" {
return logical.ErrorResponse("missing cert_name"), nil
@@ -224,9 +222,7 @@ func (b *backend) pathConfigCertificateRead(
}
return &logical.Response{
Data: map[string]interface{}{
"aws_public_cert": certificateEntry.AWSPublicCert,
},
Data: structs.New(certificateEntry).Map(),
}, nil
}
@@ -234,7 +230,6 @@ func (b *backend) pathConfigCertificateRead(
// used to verify the PKCS#7 signature of the instance identity document.
func (b *backend) pathConfigCertificateCreateUpdate(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
certName := data.Get("cert_name").(string)
if certName == "" {
return logical.ErrorResponse("missing cert_name"), nil
@@ -303,12 +298,17 @@ Configure the AWS Public Key that is used to verify the PKCS#7 signature of the
`
const pathConfigCertificateDesc = `
AWS Public Key used to verify the PKCS#7 signature of the identity document
varies by region. It can be found in AWS's documentation. The default key that
is used to verify the signature is the one that is applicable for following regions:
US East (N. Virginia), US West (Oregon), US West (N. California), EU (Ireland),
EU (Frankfurt), Asia Pacific (Tokyo), Asia Pacific (Seoul), Asia Pacific (Singapore),
AWS Public Key which is used to verify the PKCS#7 signature of the identity document,
varies by region. The public key can be found in AWS EC2 instance metadata documentation.
The default key that is used to verify the signature is the one that is applicable for
following regions: US East (N. Virginia), US West (Oregon), US West (N. California),
EU (Ireland), EU (Frankfurt), Asia Pacific (Tokyo), Asia Pacific (Seoul), Asia Pacific (Singapore),
Asia Pacific (Sydney), and South America (Sao Paulo).
If the instances belongs to region other than the above, the public key for the corresponding
regions should be registered using this endpoint. PKCS#7 is verified using a collection
of certificates containing the default certificate and all the registered certificates
added using this endpoint.
`
const pathListCertificatesHelpSyn = `
Lists all the AWS public certificates that are registered with Vault.

View File

@@ -25,9 +25,9 @@ func pathConfigClient(b *backend) *framework.Path {
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.CreateOperation: b.pathConfigClientCreateUpdate,
logical.UpdateOperation: b.pathConfigClientCreateUpdate,
logical.DeleteOperation: b.pathConfigClientDelete,
logical.ReadOperation: b.pathConfigClientRead,
logical.UpdateOperation: b.pathConfigClientCreateUpdate,
},
HelpSynopsis: pathConfigClientHelpSyn,
@@ -39,9 +39,6 @@ func pathConfigClient(b *backend) *framework.Path {
// Returning 'true' forces an UpdateOperation, CreateOperation otherwise.
func (b *backend) pathConfigClientExistenceCheck(
req *logical.Request, data *framework.FieldData) (bool, error) {
b.configMutex.RLock()
defer b.configMutex.RUnlock()
entry, err := clientConfigEntry(req.Storage)
if err != nil {
return false, err
@@ -51,6 +48,9 @@ func (b *backend) pathConfigClientExistenceCheck(
// Fetch the client configuration required to access the AWS API.
func clientConfigEntry(s logical.Storage) (*clientConfig, error) {
b.configMutex.RLock()
defer b.configMutex.RUnlock()
entry, err := s.Get("config/client")
if err != nil {
return nil, err
@@ -68,9 +68,6 @@ func clientConfigEntry(s logical.Storage) (*clientConfig, error) {
func (b *backend) pathConfigClientRead(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
b.configMutex.RLock()
defer b.configMutex.RUnlock()
clientConfig, err := clientConfigEntry(req.Storage)
if err != nil {
return nil, err
@@ -88,6 +85,7 @@ func (b *backend) pathConfigClientRead(
func (b *backend) pathConfigClientDelete(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
b.configMutex.Lock()
defer b.configMutex.Unlock()
err := req.Storage.Delete("config/client")
if err != nil {
@@ -105,9 +103,6 @@ func (b *backend) pathConfigClientDelete(
// that can be used to interact with AWS EC2 API.
func (b *backend) pathConfigClientCreateUpdate(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
b.configMutex.Lock()
defer b.configMutex.Unlock()
configEntry, err := clientConfigEntry(req.Storage)
if err != nil {
return nil, err
@@ -139,6 +134,9 @@ func (b *backend) pathConfigClientCreateUpdate(
configEntry.SecretKey = data.Get("secret_key").(string)
}
b.configMutex.Lock()
defer b.configMutex.Unlock()
entry, err := logical.StorageEntryJSON("config/client", configEntry)
if err != nil {
return nil, err