From 2b337083f398ad900689e57c0debc8c779c7fb41 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 1 May 2017 10:37:35 -0400 Subject: [PATCH 1/8] changelog++ --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5af2f195..408d65240 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,8 +21,8 @@ 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 From 403efeb5ae3175b8adf93e3d65b2e8b83d61f426 Mon Sep 17 00:00:00 2001 From: Justin Gerace Date: Mon, 1 May 2017 07:40:18 -0700 Subject: [PATCH 2/8] Add globbing support to the PKI backend's allowed_domains list (#2517) --- builtin/logical/pki/backend_test.go | 6 ++++++ builtin/logical/pki/cert_util.go | 8 ++++++++ builtin/logical/pki/path_roles.go | 10 ++++++++++ website/source/api/secret/pki/index.html.md | 18 ++++++++++++------ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/builtin/logical/pki/backend_test.go b/builtin/logical/pki/backend_test.go index 6bb1b99c2..4fefc95c1 100644 --- a/builtin/logical/pki/backend_test.go +++ b/builtin/logical/pki/backend_test.go @@ -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 diff --git a/builtin/logical/pki/cert_util.go b/builtin/logical/pki/cert_util.go index e84e238c1..b47d8eaa1 100644 --- a/builtin/logical/pki/cert_util.go +++ b/builtin/logical/pki/cert_util.go @@ -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 diff --git a/builtin/logical/pki/path_roles.go b/builtin/logical/pki/path_roles.go index 2095fbde3..4d9e11567 100644 --- a/builtin/logical/pki/path_roles.go +++ b/builtin/logical/pki/path_roles.go @@ -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"` diff --git a/website/source/api/secret/pki/index.html.md b/website/source/api/secret/pki/index.html.md index 8f95a4d5b..ae234e938 100644 --- a/website/source/api/secret/pki/index.html.md +++ b/website/source/api/secret/pki/index.html.md @@ -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. From 0ed210c67f22928e203024455304e6cc6e8ca7cf Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 1 May 2017 10:42:41 -0400 Subject: [PATCH 3/8] changelog++ --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 408d65240..2cb3210c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ IMPROVEMENTS: * secret/pki: If used with a role parameter, the `sign-verbatim/` 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 From e94c7ef3d1d3851cd5f1b8648b2632e8303cc47a Mon Sep 17 00:00:00 2001 From: Chris Hoffman Date: Mon, 1 May 2017 12:32:14 -0400 Subject: [PATCH 4/8] changelog++ --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cb3210c8..d2a459ffb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ IMPROVEMENTS: 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] From 5630b0ad4bc76562aef4b19597ed4b0a1c9cb14e Mon Sep 17 00:00:00 2001 From: Marc Boudreau Date: Mon, 1 May 2017 14:41:49 -0400 Subject: [PATCH 5/8] Changing the ttl value in the Generate IAM with STS sample to a valid value (#2665) --- website/source/api/secret/aws/index.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/api/secret/aws/index.html.md b/website/source/api/secret/aws/index.html.md index ece445fcc..25dc26829 100644 --- a/website/source/api/secret/aws/index.html.md +++ b/website/source/api/secret/aws/index.html.md @@ -336,7 +336,7 @@ role. ```json { - "ttl": "5m" + "ttl": "15m" } ``` From 44e1c64cfdd4bf26d81c4c9365a18fdb96484bb8 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Mon, 1 May 2017 14:36:37 -0700 Subject: [PATCH 6/8] Add UI docs (#2664) --- .../source/docs/configuration/index.html.md | 9 ++- .../docs/vault-enterprise/ui/index.html.md | 78 +++++++++++++++++++ website/source/layouts/docs.erb | 3 + 3 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 website/source/docs/vault-enterprise/ui/index.html.md diff --git a/website/source/docs/configuration/index.html.md b/website/source/docs/configuration/index.html.md index 75a2b02ff..7c61eb75f 100644 --- a/website/source/docs/configuration/index.html.md +++ b/website/source/docs/configuration/index.html.md @@ -74,7 +74,7 @@ to specify where the configuration is. Disabling `mlock` is not recommended unless the systems running Vault only use encrypted swap or do not use swap at all. Vault only supports memory - locking on UNIX-like systems that support the mlock() syscall (Linux, FreeBSD, etc). + locking on UNIX-like systems that support the mlock() syscall (Linux, FreeBSD, etc). Non UNIX-like systems (e.g. Windows, NaCL, Android) lack the primitives to keep a process's entire memory address space from spilling to disk and is therefore automatically disabled on unsupported platforms. @@ -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 diff --git a/website/source/docs/vault-enterprise/ui/index.html.md b/website/source/docs/vault-enterprise/ui/index.html.md new file mode 100644 index 000000000..a628b8ce5 --- /dev/null +++ b/website/source/docs/vault-enterprise/ui/index.html.md @@ -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. diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index f6f07b86a..f5317171f 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -356,6 +356,9 @@ + > + UI (Web Interface) + From 537342f038f53175a081b3d2b306cb366117998b Mon Sep 17 00:00:00 2001 From: Ben Gadbois Date: Mon, 1 May 2017 20:34:10 -0700 Subject: [PATCH 7/8] Fixing printf (and similar) issues (#2666) --- builtin/credential/approle/path_role_test.go | 4 ++-- builtin/credential/approle/validation.go | 2 +- builtin/credential/aws/path_role_test.go | 7 ++++--- builtin/credential/ldap/path_config.go | 2 +- helper/awsutil/generate_credentials.go | 2 +- helper/keysutil/lock_manager.go | 2 +- vault/router_test.go | 4 ++-- vault/token_store.go | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/builtin/credential/approle/path_role_test.go b/builtin/credential/approle/path_role_test.go index c19338549..a40cbe10d 100644 --- a/builtin/credential/approle/path_role_test.go +++ b/builtin/credential/approle/path_role_test.go @@ -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") diff --git a/builtin/credential/approle/validation.go b/builtin/credential/approle/validation.go index 15b50bbaf..db668a825 100644 --- a/builtin/credential/approle/validation.go +++ b/builtin/credential/approle/validation.go @@ -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) } } diff --git a/builtin/credential/aws/path_role_test.go b/builtin/credential/aws/path_role_test.go index a52d4fa7b..52ff43574 100644 --- a/builtin/credential/aws/path_role_test.go +++ b/builtin/credential/aws/path_role_test.go @@ -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{ diff --git a/builtin/credential/ldap/path_config.go b/builtin/credential/ldap/path_config.go index b32aa1087..4fc772eaa 100644 --- a/builtin/credential/ldap/path_config.go +++ b/builtin/credential/ldap/path_config.go @@ -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 { diff --git a/helper/awsutil/generate_credentials.go b/helper/awsutil/generate_credentials.go index 7605c84bb..7399a5ca3 100644 --- a/helper/awsutil/generate_credentials.go +++ b/helper/awsutil/generate_credentials.go @@ -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 diff --git a/helper/keysutil/lock_manager.go b/helper/keysutil/lock_manager.go index 380c39af1..e0bdd648a 100644 --- a/helper/keysutil/lock_manager.go +++ b/helper/keysutil/lock_manager.go @@ -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: diff --git a/vault/router_test.go b/vault/router_test.go index 5ba274bc8..e5de72e97 100644 --- a/vault/router_test.go +++ b/vault/router_test.go @@ -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") diff --git a/vault/token_store.go b/vault/token_store.go index 4bd27ebfa..fed0088d0 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -2173,7 +2173,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()))) } } From df325288ac2cc3a6d094ef8deb4adceb9c2b35b7 Mon Sep 17 00:00:00 2001 From: mhristof Date: Tue, 2 May 2017 12:52:55 +0100 Subject: [PATCH 8/8] fix format for secret/pki (#2668) --- website/source/api/secret/pki/index.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/api/secret/pki/index.html.md b/website/source/api/secret/pki/index.html.md index ae234e938..37eadb0b8 100644 --- a/website/source/api/secret/pki/index.html.md +++ b/website/source/api/secret/pki/index.html.md @@ -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 | | :------- | :--------------------------- | :--------------------- |