Merge branch 'master-oss' into pr-2495
This commit is contained in:
commit
d2e9e0b873
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,4 +1,12 @@
|
|||
## 0.7.0 (Unreleased)
|
||||
## 0.7.0 (Early Access; final release March 21th, 2017)
|
||||
|
||||
SECURITY:
|
||||
|
||||
* Common name not being validated when `exclude_cn_from_sans` option used in
|
||||
`pki` backend: When using a role in the `pki` backend that specified the
|
||||
`exclude_cn_from_sans` option, the common name would not then be properly
|
||||
validated against the role's constraints. This has been fixed. We recommend
|
||||
any users of this feature to upgrade to 0.7 as soon as feasible.
|
||||
|
||||
DEPRECATIONS/CHANGES:
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ func fetchCertBySerial(req *logical.Request, prefix, serial string) (*logical.St
|
|||
// Given a set of requested names for a certificate, verifies that all of them
|
||||
// match the various toggles set in the role for controlling issuance.
|
||||
// If one does not pass, it is returned in the string argument.
|
||||
func validateNames(req *logical.Request, names []string, role *roleEntry) (string, error) {
|
||||
func validateNames(req *logical.Request, names []string, role *roleEntry) string {
|
||||
for _, name := range names {
|
||||
sanitizedName := name
|
||||
emailDomain := name
|
||||
|
@ -233,7 +233,7 @@ func validateNames(req *logical.Request, names []string, role *roleEntry) (strin
|
|||
if strings.Contains(name, "@") {
|
||||
splitEmail := strings.Split(name, "@")
|
||||
if len(splitEmail) != 2 {
|
||||
return name, nil
|
||||
return name
|
||||
}
|
||||
sanitizedName = splitEmail[1]
|
||||
emailDomain = splitEmail[1]
|
||||
|
@ -250,7 +250,7 @@ func validateNames(req *logical.Request, names []string, role *roleEntry) (strin
|
|||
|
||||
// Email addresses using wildcard domain names do not make sense
|
||||
if isEmail && isWildcard {
|
||||
return name, nil
|
||||
return name
|
||||
}
|
||||
|
||||
// AllowAnyName is checked after this because EnforceHostnames still
|
||||
|
@ -259,7 +259,7 @@ func validateNames(req *logical.Request, names []string, role *roleEntry) (strin
|
|||
// wildcard prefix.
|
||||
if role.EnforceHostnames {
|
||||
if !hostnameRegex.MatchString(sanitizedName) {
|
||||
return name, nil
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,10 +368,10 @@ func validateNames(req *logical.Request, names []string, role *roleEntry) (strin
|
|||
}
|
||||
|
||||
//panic(fmt.Sprintf("\nName is %s\nRole is\n%#v\n", name, role))
|
||||
return name, nil
|
||||
return name
|
||||
}
|
||||
|
||||
return "", nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func generateCert(b *backend,
|
||||
|
@ -560,8 +560,10 @@ func generateCreationBundle(b *backend,
|
|||
var err error
|
||||
var ok bool
|
||||
|
||||
// Get the common name
|
||||
// Read in names -- CN, DNS and email addresses
|
||||
var cn string
|
||||
dnsNames := []string{}
|
||||
emailAddresses := []string{}
|
||||
{
|
||||
if csr != nil && role.UseCSRCommonName {
|
||||
cn = csr.Subject.CommonName
|
||||
|
@ -572,28 +574,7 @@ func generateCreationBundle(b *backend,
|
|||
return nil, errutil.UserError{Err: `the common_name field is required, or must be provided in a CSR with "use_csr_common_name" set to true`}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set OU (organizationalUnit) values if specified in the role
|
||||
ou := []string{}
|
||||
{
|
||||
if role.OU != "" {
|
||||
ou = strutil.ParseDedupAndSortStrings(role.OU, ",")
|
||||
}
|
||||
}
|
||||
|
||||
// Set O (organization) values if specified in the role
|
||||
organization := []string{}
|
||||
{
|
||||
if role.Organization != "" {
|
||||
organization = strutil.ParseDedupAndSortStrings(role.Organization, ",")
|
||||
}
|
||||
}
|
||||
|
||||
// Read in alternate names -- DNS and email addresses
|
||||
dnsNames := []string{}
|
||||
emailAddresses := []string{}
|
||||
{
|
||||
if csr != nil && role.UseCSRSANs {
|
||||
dnsNames = csr.DNSNames
|
||||
emailAddresses = csr.EmailAddresses
|
||||
|
@ -613,38 +594,38 @@ func generateCreationBundle(b *backend,
|
|||
}
|
||||
|
||||
if csr == nil || !role.UseCSRSANs {
|
||||
cnAltInt, ok := data.GetOk("alt_names")
|
||||
cnAltRaw, ok := data.GetOk("alt_names")
|
||||
if ok {
|
||||
cnAlt := cnAltInt.(string)
|
||||
if len(cnAlt) != 0 {
|
||||
for _, v := range strings.Split(cnAlt, ",") {
|
||||
if strings.Contains(v, "@") {
|
||||
emailAddresses = append(emailAddresses, v)
|
||||
} else {
|
||||
dnsNames = append(dnsNames, v)
|
||||
}
|
||||
cnAlt := strutil.ParseDedupAndSortStrings(cnAltRaw.(string), ",")
|
||||
for _, v := range cnAlt {
|
||||
if strings.Contains(v, "@") {
|
||||
emailAddresses = append(emailAddresses, v)
|
||||
} else {
|
||||
dnsNames = append(dnsNames, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for bad email and/or DNS names
|
||||
badName, err := validateNames(req, dnsNames, role)
|
||||
// Check the CN. This ensures that the CN is checked even if it's
|
||||
// excluded from SANs.
|
||||
badName := validateNames(req, []string{cn}, role)
|
||||
if len(badName) != 0 {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"name %s not allowed by this role", badName)}
|
||||
} else if err != nil {
|
||||
return nil, errutil.InternalError{Err: fmt.Sprintf(
|
||||
"error validating name %s: %s", badName, err)}
|
||||
"common name %s not allowed by this role", badName)}
|
||||
}
|
||||
|
||||
badName, err = validateNames(req, emailAddresses, role)
|
||||
// Check for bad email and/or DNS names
|
||||
badName = validateNames(req, dnsNames, role)
|
||||
if len(badName) != 0 {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"email %s not allowed by this role", badName)}
|
||||
} else if err != nil {
|
||||
return nil, errutil.InternalError{Err: fmt.Sprintf(
|
||||
"error validating name %s: %s", badName, err)}
|
||||
"subject alternate name %s not allowed by this role", badName)}
|
||||
}
|
||||
|
||||
badName = validateNames(req, emailAddresses, role)
|
||||
if len(badName) != 0 {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"email address %s not allowed by this role", badName)}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -680,6 +661,22 @@ func generateCreationBundle(b *backend,
|
|||
}
|
||||
}
|
||||
|
||||
// Set OU (organizationalUnit) values if specified in the role
|
||||
ou := []string{}
|
||||
{
|
||||
if role.OU != "" {
|
||||
ou = strutil.ParseDedupAndSortStrings(role.OU, ",")
|
||||
}
|
||||
}
|
||||
|
||||
// Set O (organization) values if specified in the role
|
||||
organization := []string{}
|
||||
{
|
||||
if role.Organization != "" {
|
||||
organization = strutil.ParseDedupAndSortStrings(role.Organization, ",")
|
||||
}
|
||||
}
|
||||
|
||||
// Get the TTL and very it against the max allowed
|
||||
var ttlField string
|
||||
var ttl time.Duration
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//-------------------------------------------------------------------
|
||||
|
||||
variable "download-url" {
|
||||
default = "https://releases.hashicorp.com/vault/0.6.5/vault_0.6.5_linux_amd64.zip"
|
||||
default = "https://releases.hashicorp.com/vault/0.7.0/vault_0.7.0_linux_amd64.zip"
|
||||
description = "URL to download Vault"
|
||||
}
|
||||
|
||||
|
|
|
@ -9,5 +9,5 @@ func init() {
|
|||
// A pre-release marker for the version. If this is "" (empty string)
|
||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||
// such as "dev" (in development), "beta", "rc1", etc.
|
||||
VersionPrerelease = "beta1"
|
||||
VersionPrerelease = ""
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ set :base_url, "https://www.vaultproject.io/"
|
|||
|
||||
activate :hashicorp do |h|
|
||||
h.name = "vault"
|
||||
h.version = "0.6.5"
|
||||
h.version = "0.7.0"
|
||||
h.github_slug = "hashicorp/vault"
|
||||
h.website_root = "website"
|
||||
end
|
||||
|
|
|
@ -12,4 +12,4 @@ description: |-
|
|||
The `listener` stanza configures the addresses and ports on which Vault will
|
||||
respond to requests. At this time, there is only one listener - [TCP][tcp].
|
||||
|
||||
[tcp]: /docs/configuration/listenger/tcp.html
|
||||
[tcp]: /docs/configuration/listener/tcp.html
|
||||
|
|
|
@ -56,5 +56,5 @@ storage "gcs" {
|
|||
```
|
||||
|
||||
[gcs]: https://cloud.google.com/storage/
|
||||
[gcs-service-account]: (https://cloud.google.com/compute/docs/access/service-accounts
|
||||
[gcs-service-account]: https://cloud.google.com/compute/docs/access/service-accounts
|
||||
[gcs-private-key]: https://cloud.google.com/storage/docs/authentication#generating-a-private-key
|
||||
|
|
|
@ -14,5 +14,9 @@ guidance to do them safely.
|
|||
|
||||
The following guides are available:
|
||||
|
||||
* [Generate Root](/docs/guides/generate-root.html) - This guide covers how to
|
||||
generate new root tokens using unseal keys.
|
||||
* [Generate a Root Token](/docs/guides/generate-root.html) - This guide covers
|
||||
how to generate new root tokens using unseal keys.
|
||||
|
||||
* [Setting Up and Managing Replication](/docs/guides/replication.html) - This
|
||||
guide covers how to set up and manage Vault Replication, a part of Vault
|
||||
Enterprise.
|
||||
|
|
|
@ -19,7 +19,11 @@ the [Vault Replication API documentation](/docs/http/system/replication.html)
|
|||
|
||||
### Activating the Primary
|
||||
|
||||
To activate the primary, run `vault write -f sys/replication/primary/enable`.
|
||||
To activate the primary, run:
|
||||
|
||||
|
||||
$ vault write -f sys/replication/primary/enable
|
||||
|
||||
|
||||
There is currently one optional argument: `primary_cluster_addr`. This can be
|
||||
used to override the cluster address that the primary advertises to the
|
||||
|
@ -28,18 +32,24 @@ members of a single cluster and primary/secondary clusters.
|
|||
|
||||
### Fetching a Secondary Token
|
||||
|
||||
To fetch a secondary bootstrap token, run `vault write
|
||||
sys/replication/primary/secondary-token id=<id>`.
|
||||
To fetch a secondary bootstrap token, run:
|
||||
|
||||
The value for ID is opaque to Vault and can be any identifying value you want;
|
||||
|
||||
$ vault write sys/replication/primary/secondary-token id=<id>
|
||||
|
||||
|
||||
The value for `id` is opaque to Vault and can be any identifying value you want;
|
||||
this can be used later to revoke the secondary and will be listed when you read
|
||||
replication status on the primary. You will get back a normal wrapped response,
|
||||
except that the token will be a JWT instead of UUID-formatted random bytes.
|
||||
|
||||
### Activating a Secondary
|
||||
|
||||
To activate a secondary, run `vault write sys/replication/secondary/enable
|
||||
token=<token>`.
|
||||
To activate a secondary using the fetched token, run:
|
||||
|
||||
|
||||
$ vault write sys/replication/secondary/enable token=<token>
|
||||
|
||||
|
||||
You must provide the full token value. Be very careful when running this
|
||||
command, as it will destroy all data currently stored in the secondary.
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
<a href="/docs/http/system/renew.html"><tt>/sys/renew</tt></a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-http-system-replication") %>>
|
||||
<a href="/docs/http/system/replication.html"><tt>/sys/replication</tt></a>
|
||||
<a href="/docs/http/system/replication.html">/sys/replication</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-http-system-revoke/") %>>
|
||||
<a href="/docs/http/system/revoke.html"><tt>/sys/revoke</tt></a>
|
||||
|
|
Loading…
Reference in New Issue