Merge remote-tracking branch 'oss/master' into sys-tidy-leases

This commit is contained in:
Jeff Mitchell 2017-05-03 15:02:42 -04:00
commit 99884a8f13
17 changed files with 142 additions and 26 deletions

View File

@ -21,18 +21,21 @@ FEATURES:
IMPROVEMENTS:
* auth/cert: Support for constraints on subject common name, DNS names and
Email addresses in the certificate [GH-2595]
* auth/cert: Support for constraints on subject Common Name and DNS/email
Subject Alternate Names in certificates [GH-2595]
* auth/ldap: Use the binding credentials to search group membership rather
than the user credentials [GH-2534]
* cli/revoke: Add `-self` option to allow revoking the currently active token
[GH-2596]
* core: Randomizing x coordinate in Shamir shares [GH-2621]
* secret/pki: Add `no_store` option that allows certificates to be issued
without being stored. This removes the ability to look up and/or add to a
CRL but helps with scaling to very large numbers of certificates. [GH-2565]
* secret/pki: If used with a role parameter, the `sign-verbatim/<role>`
endpoint honors the values of `generate_lease`, `no_store`, `ttl` and
`max_ttl` from the given role [GH-2593]
* secret/pki: Add role parameter `allow_glob_domains` that enables defining
names in `allowed_domains` containing `*` glob patterns [GH-2517]
* storage/etcd3: Add `discovery_srv` option to query for SRV records to find
servers [GH-2521]
* storage/s3: Support `max_parallel` option to limit concurrent outstanding

View File

@ -104,7 +104,7 @@ func TestAppRole_RoleConstraints(t *testing.T) {
roleData["bind_secret_id"] = false
resp, err = b.HandleRequest(roleReq)
if resp != nil && resp.IsError() {
t.Fatalf("resp:%#v", err, resp)
t.Fatalf("err:%v, resp:%#v", err, resp)
}
if err == nil {
t.Fatalf("expected an error")
@ -433,7 +433,7 @@ func TestAppRole_RoleSecretIDAccessorReadDelete(t *testing.T) {
hmacReq.Operation = logical.ReadOperation
resp, err = b.HandleRequest(hmacReq)
if resp != nil && resp.IsError() {
t.Fatalf("error response:%#v", err, resp)
t.Fatalf("err:%v resp:%#v", err, resp)
}
if err == nil {
t.Fatalf("expected an error")

View File

@ -352,7 +352,7 @@ func (b *backend) nonLockedSecretIDStorageEntry(s logical.Storage, roleNameHMAC,
if persistNeeded {
if err := b.nonLockedSetSecretIDStorageEntry(s, roleNameHMAC, secretIDHMAC, &result); err != nil {
return nil, fmt.Errorf("failed to upgrade role storage entry", err)
return nil, fmt.Errorf("failed to upgrade role storage entry %s", err)
}
}

View File

@ -249,17 +249,18 @@ func TestBackend_pathIam(t *testing.T) {
// generate a second role, ensure we're able to list both
data["bound_ami_id"] = "ami-abcd123"
resp, err = b.HandleRequest(&logical.Request{
secondRole := &logical.Request{
Operation: logical.CreateOperation,
Path: "role/MyOtherRoleName",
Data: data,
Storage: storage,
})
}
resp, err = b.HandleRequest(secondRole)
if err != nil {
t.Fatal(err)
}
if resp != nil && resp.IsError() {
t.Fatalf("failed to create additional role: %s")
t.Fatalf("failed to create additional role: %v", *secondRole)
}
resp, err = b.HandleRequest(&logical.Request{

View File

@ -400,7 +400,7 @@ func (c *ConfigEntry) DialLDAP() (*ldap.Conn, error) {
}
conn, err = ldap.DialTLS("tcp", net.JoinHostPort(host, port), tlsConfig)
default:
retErr = multierror.Append(retErr, fmt.Errorf("invalid LDAP scheme in url %q"))
retErr = multierror.Append(retErr, fmt.Errorf("invalid LDAP scheme in url %q", net.JoinHostPort(host, port)))
continue
}
if err == nil {

View File

@ -1549,6 +1549,7 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep {
Wildcard bool `structs:"*.example.com"`
SubSubdomain bool `structs:"foo.bar.example.com"`
SubSubdomainWildcard bool `structs:"*.bar.example.com"`
GlobDomain bool `structs:"fooexample.com"`
NonHostname bool `structs:"daɪˈɛrɨsɨs"`
AnyHost bool `structs:"porkslap.beer"`
}
@ -1755,6 +1756,11 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep {
commonNames.BareDomain = true
addCnTests()
roleVals.AllowedDomains = "foobar.com,*example.com"
roleVals.AllowGlobDomains = true
commonNames.GlobDomain = true
addCnTests()
roleVals.AllowAnyName = true
roleVals.EnforceHostnames = true
commonNames.AnyHost = true

View File

@ -22,6 +22,7 @@ import (
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
"github.com/ryanuber/go-glob"
)
type certExtKeyUsage int
@ -362,6 +363,13 @@ func validateNames(req *logical.Request, names []string, role *roleEntry) string
break
}
}
if role.AllowGlobDomains &&
strings.Contains(currDomain, "*") &&
glob.Glob(currDomain, name) {
valid = true
break
}
}
if valid {
continue

View File

@ -84,6 +84,14 @@ including wildcard subdomains. See the documentation for
more information.`,
},
"allow_glob_domains": &framework.FieldSchema{
Type: framework.TypeBool,
Default: false,
Description: `If set, domains specified in "allowed_domains"
can include glob patterns, e.g. "ftp*.example.com". See
the documentation for more information.`,
},
"allow_any_name": &framework.FieldSchema{
Type: framework.TypeBool,
Default: false,
@ -380,6 +388,7 @@ func (b *backend) pathRoleCreate(
AllowedDomains: data.Get("allowed_domains").(string),
AllowBareDomains: data.Get("allow_bare_domains").(bool),
AllowSubdomains: data.Get("allow_subdomains").(bool),
AllowGlobDomains: data.Get("allow_glob_domains").(bool),
AllowAnyName: data.Get("allow_any_name").(bool),
EnforceHostnames: data.Get("enforce_hostnames").(bool),
AllowIPSANs: data.Get("allow_ip_sans").(bool),
@ -505,6 +514,7 @@ type roleEntry struct {
AllowBareDomains bool `json:"allow_bare_domains" structs:"allow_bare_domains" mapstructure:"allow_bare_domains"`
AllowTokenDisplayName bool `json:"allow_token_displayname" structs:"allow_token_displayname" mapstructure:"allow_token_displayname"`
AllowSubdomains bool `json:"allow_subdomains" structs:"allow_subdomains" mapstructure:"allow_subdomains"`
AllowGlobDomains bool `json:"allow_glob_domains" structs:"allow_glob_domains" mapstructure:"allow_glob_domains"`
AllowAnyName bool `json:"allow_any_name" structs:"allow_any_name" mapstructure:"allow_any_name"`
EnforceHostnames bool `json:"enforce_hostnames" structs:"enforce_hostnames" mapstructure:"enforce_hostnames"`
AllowIPSANs bool `json:"allow_ip_sans" structs:"allow_ip_sans" mapstructure:"allow_ip_sans"`

View File

@ -48,7 +48,7 @@ func (c *CredentialsConfig) GenerateCredentialChain() (*credentials.Credentials,
SecretAccessKey: c.SecretKey,
SessionToken: c.SessionToken,
}})
case c.AccessKey == "" && c.AccessKey == "":
case c.AccessKey == "" && c.SecretKey == "":
// Attempt to get credentials from the IAM instance role below
default: // Have one or the other but not both and not neither

View File

@ -248,7 +248,7 @@ func (lm *LockManager) getPolicyCommon(req PolicyRequest, lockType bool) (*Polic
case KeyType_ECDSA_P256:
if req.Derived || req.Convergent {
return nil, nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %s", KeyType_ECDSA_P256)
return nil, nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", KeyType_ECDSA_P256)
}
default:

View File

@ -95,7 +95,7 @@ func TestRouter_Mount(t *testing.T) {
}
if v := r.MatchingStorageView("prod/aws/foo"); v != view {
t.Fatalf("bad: %s", v)
t.Fatalf("bad: %v", v)
}
if path := r.MatchingMount("stage/aws/foo"); path != "" {
@ -103,7 +103,7 @@ func TestRouter_Mount(t *testing.T) {
}
if v := r.MatchingStorageView("stage/aws/foo"); v != nil {
t.Fatalf("bad: %s", v)
t.Fatalf("bad: %v", v)
}
mount, prefix, ok := r.MatchingStoragePrefix("logical/foo")

View File

@ -2232,7 +2232,7 @@ func (ts *TokenStore) tokenStoreRoleCreateUpdate(
}
resp.AddWarning(fmt.Sprintf(
"Given explicit max TTL of %d is greater than system/mount allowed value of %d seconds; until this is fixed attempting to create tokens against this role will result in an error",
entry.ExplicitMaxTTL.Seconds(), sysView.MaxLeaseTTL().Seconds()))
int64(entry.ExplicitMaxTTL.Seconds()), int64(sysView.MaxLeaseTTL().Seconds())))
}
}

View File

@ -336,7 +336,7 @@ role.
```json
{
"ttl": "5m"
"ttl": "15m"
}
```

View File

@ -490,7 +490,7 @@ based on the role named in the endpoint. The issuing CA certificate is returned
as well, so that only the root CA need be in a client's trust store.
**The private key is _not_ stored. If you do not save the private key, you will
**need to request a new certificate.**
need to request a new certificate.**
| Method | Path | Produces |
| :------- | :--------------------------- | :--------------------- |
@ -613,12 +613,13 @@ $ curl \
## Create/Update Role
This endpoint ceates or updates the role definition. Note that the
`allowed_domains`, `allow_subdomains`, and `allow_any_name` attributes are
additive; between them nearly and across multiple roles nearly any issuing
policy can be accommodated. `server_flag`, `client_flag`, and
`code_signing_flag` are additive as well. If a client requests a certificate
that is not allowed by the CN policy in the role, the request is denied.
This endpoint creates or updates the role definition. Note that the
`allowed_domains`, `allow_subdomains`, `allow_glob_domains`, and
`allow_any_name` attributes are additive; between them nearly and across
multiple roles nearly any issuing policy can be accommodated. `server_flag`,
`client_flag`, and `code_signing_flag` are additive as well. If a client
requests a certificate that is not allowed by the CN policy in the role, the
request is denied.
| Method | Path | Produces |
| :------- | :--------------------------- | :--------------------- |
@ -659,6 +660,11 @@ that is not allowed by the CN policy in the role, the request is denied.
allow `foo.example.com` and `bar.example.com` as well as `*.example.com`. This
is redundant when using the `allow_any_name` option.
- `allow_glob_domains` `(bool: false)` - Allows names specified in
`allowed_domains` to contain glob patterns (e.g. `ftp*.example.com`). Clients
will be allowed to request certificates with names matching the glob
patterns.
- `allow_any_name` `(bool: false)`  Specifies if clients can request any CN.
Useful in some circumstances, but make sure you understand whether it is
appropriate for your installation before enabling it.

View File

@ -97,9 +97,10 @@ to specify where the configuration is.
duration for tokens and secrets. This is specified using a label
suffix like `"30s"` or `"1h"`.
- `ui` `(bool: false, Enterprise-only)` Enables the built-in web UI. Once
enabled, the UI will be available to browsers at the standard Vault address.
This can also be provided via the environment variable `VAULT_UI`.
- `ui` `(bool: false, Enterprise-only)` Enables the built-in web UI, which is
available on all listeners (address + port) at the `/ui` path. Browsers accessing
the standard Vault API address will automatically redirect there. This can also
be provided via the environment variable `VAULT_UI`.
[storage-backend]: /docs/configuration/storage/index.html
[listener]: /docs/configuration/listener/index.html

View File

@ -0,0 +1,78 @@
---
layout: "docs"
page_title: "Vault Enterprise UI"
sidebar_current: "docs-vault-enterprise-ui"
description: |-
Vault Enterprise features a user interface for interacting with Vault. Easily
create, read, update, and delete secrets, authenticate, unseal, and more with
the Vault Enterprise UI.
---
# Vault UI
Vault Enterprise features a user interface for interacting with Vault. Easily
create, read, update, and delete secrets, authenticate, unseal, and more with
the Vault Enterprise UI.
To use the UI, you must have an active or trial license for Vault Enterprise or
Vault Pro. To start a trial, contact [HashiCorp sales](mailto:sales@hashicorp.com).
## Activating the Vault UI
The Vault Enterprise UI is not activated by default. To activate the UI, set the
`ui` configuration option in the Vault server configuration. Vault clients do
not need to set this option, since they will not be serving the UI.
```hcl
ui = true
listener "tcp" {
address = "10.0.1.35:8200"
}
storage "consul" {
# ...
}
```
For more information, please see the
[Vault configuration options](/docs/configuration/index.html).
## Accessing the Vault UI
The UI runs on the same port as the Vault listener. As such, you must configure
at least one `listener` stanza in order to access the UI.
```hcl
listener "tcp" {
address = "10.0.1.35:8200"
# If bound to localhost, the Vault UI is only
# accessible from the local machine!
# address = "127.0.0.1:8200"
}
```
In this case, the UI is accessible the following URL from any machine on the
subnet (provided no network firewalls are in place):
```text
https://10.0.1.35:8200/ui
```
It is also accessible at any DNS entry that resolves to that IP address, such as
the Consul service address (if using Consul):
```text
https://vault.service.consul:8200/ui
```
### Note on TLS
When using TLS (recommended), the certificate must be valid for all DNS entries
you will be accessing the Vault UI on, and any IP addresses on the SAN. If you
are running Vault with a self-signed certificate, any browsers that access the
Vault UI will need to have the root CA installed. Failure to do so may result in
the browser displaying a warning that the site is "untrusted". It is highly
recommended that client browsers accessing the Vault UI install the proper CA
root for validation to reduce the chance of a MITM attack.

View File

@ -356,6 +356,9 @@
</li>
</ul>
</li>
<li<%= sidebar_current("docs-vault-enterprise-ui") %>>
<a href="/docs/vault-enterprise/ui/index.html">UI (Web Interface)</a>
</li>
</ul>
</li>
</ul>