From 85a560abbad27e8072282cbff4b556cbed43a50a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 30 Jan 2019 16:23:28 -0500 Subject: [PATCH] Refactor common token fields and operations into a helper (#5953) --- audit/format.go | 4 + audit/format_json_test.go | 24 +- audit/format_jsonx_test.go | 26 +- builtin/credential/app-id/path_login.go | 3 - builtin/credential/approle/path_login.go | 5 +- builtin/credential/aws/path_login.go | 10 +- builtin/credential/cert/backend_test.go | 68 ++++ builtin/credential/cert/path_certs.go | 200 +++++----- builtin/credential/cert/path_login.go | 45 +-- builtin/credential/github/path_config.go | 77 ++-- builtin/credential/github/path_login.go | 40 +- builtin/credential/ldap/path_config.go | 11 +- builtin/credential/ldap/path_login.go | 25 +- builtin/credential/okta/path_config.go | 62 ++-- builtin/credential/okta/path_login.go | 14 +- builtin/credential/radius/path_config.go | 36 +- builtin/credential/radius/path_login.go | 21 +- builtin/credential/userpass/backend_test.go | 60 +++ builtin/credential/userpass/path_login.go | 28 +- builtin/credential/userpass/path_users.go | 96 +++-- .../logical/database/dbplugin/database.pb.go | 114 +++--- helper/forwarding/types.pb.go | 3 +- helper/identity/mfa/types.pb.go | 3 +- helper/identity/types.pb.go | 3 +- helper/ldaputil/config.go | 13 +- helper/storagepacker/types.pb.go | 3 +- helper/strutil/strutil.go | 6 + helper/tokenhelper/tokenhelper.go | 210 +++++++++++ logical/auth.go | 5 + logical/identity.pb.go | 3 +- logical/plugin.pb.go | 3 +- logical/plugin/pb/backend.pb.go | 342 +++++++++--------- logical/plugin/pb/backend.proto | 3 + logical/plugin/pb/translation.go | 2 + physical/types.pb.go | 3 +- .../external_tests/policy/no_default_test.go | 85 +++++ vault/request_forwarding_service.pb.go | 84 ++--- vault/request_handling.go | 6 +- vault/token_store.go | 148 ++++---- .../plugin/path_config.go | 2 +- 40 files changed, 1139 insertions(+), 757 deletions(-) create mode 100644 helper/tokenhelper/tokenhelper.go create mode 100644 vault/external_tests/policy/no_default_test.go diff --git a/audit/format.go b/audit/format.go index 76f81bf2a..caa912913 100644 --- a/audit/format.go +++ b/audit/format.go @@ -131,6 +131,7 @@ func (f *AuditFormatter) FormatRequest(ctx context.Context, w io.Writer, config TokenPolicies: auth.TokenPolicies, IdentityPolicies: auth.IdentityPolicies, ExternalNamespacePolicies: auth.ExternalNamespacePolicies, + NoDefaultPolicy: auth.NoDefaultPolicy, Metadata: auth.Metadata, EntityID: auth.EntityID, RemainingUses: req.ClientTokenRemainingUses, @@ -303,6 +304,7 @@ func (f *AuditFormatter) FormatResponse(ctx context.Context, w io.Writer, config TokenPolicies: resp.Auth.TokenPolicies, IdentityPolicies: resp.Auth.IdentityPolicies, ExternalNamespacePolicies: resp.Auth.ExternalNamespacePolicies, + NoDefaultPolicy: resp.Auth.NoDefaultPolicy, Metadata: resp.Auth.Metadata, NumUses: resp.Auth.NumUses, EntityID: resp.Auth.EntityID, @@ -344,6 +346,7 @@ func (f *AuditFormatter) FormatResponse(ctx context.Context, w io.Writer, config TokenPolicies: auth.TokenPolicies, IdentityPolicies: auth.IdentityPolicies, ExternalNamespacePolicies: auth.ExternalNamespacePolicies, + NoDefaultPolicy: auth.NoDefaultPolicy, Metadata: auth.Metadata, RemainingUses: req.ClientTokenRemainingUses, EntityID: auth.EntityID, @@ -437,6 +440,7 @@ type AuditAuth struct { TokenPolicies []string `json:"token_policies,omitempty"` IdentityPolicies []string `json:"identity_policies,omitempty"` ExternalNamespacePolicies map[string][]string `json:"external_namespace_policies,omitempty"` + NoDefaultPolicy bool `json:"no_default_policy,omitempty"` Metadata map[string]string `json:"metadata"` NumUses int `json:"num_uses,omitempty"` RemainingUses int `json:"remaining_uses,omitempty"` diff --git a/audit/format_json_test.go b/audit/format_json_test.go index 42f177306..d1aa45988 100644 --- a/audit/format_json_test.go +++ b/audit/format_json_test.go @@ -38,11 +38,12 @@ func TestFormatJSON_formatRequest(t *testing.T) { }{ "auth, request": { &logical.Auth{ - ClientToken: "foo", - Accessor: "bar", - DisplayName: "testtoken", - Policies: []string{"root"}, - TokenType: logical.TokenTypeService, + ClientToken: "foo", + Accessor: "bar", + DisplayName: "testtoken", + NoDefaultPolicy: true, + Policies: []string{"root"}, + TokenType: logical.TokenTypeService, }, &logical.Request{ Operation: logical.UpdateOperation, @@ -63,11 +64,12 @@ func TestFormatJSON_formatRequest(t *testing.T) { }, "auth, request with prefix": { &logical.Auth{ - ClientToken: "foo", - Accessor: "bar", - DisplayName: "testtoken", - Policies: []string{"root"}, - TokenType: logical.TokenTypeService, + ClientToken: "foo", + Accessor: "bar", + DisplayName: "testtoken", + NoDefaultPolicy: true, + Policies: []string{"root"}, + TokenType: logical.TokenTypeService, }, &logical.Request{ Operation: logical.UpdateOperation, @@ -139,5 +141,5 @@ func TestFormatJSON_formatRequest(t *testing.T) { } } -const testFormatJSONReqBasicStrFmt = `{"time":"2015-08-05T13:45:46Z","type":"request","auth":{"client_token":"%s","accessor":"bar","display_name":"testtoken","policies":["root"],"metadata":null,"entity_id":"","token_type":"service"},"request":{"operation":"update","path":"/foo","data":null,"wrap_ttl":60,"remote_address":"127.0.0.1","headers":{"foo":["bar"]}},"error":"this is an error"} +const testFormatJSONReqBasicStrFmt = `{"time":"2015-08-05T13:45:46Z","type":"request","auth":{"client_token":"%s","accessor":"bar","display_name":"testtoken","policies":["root"],"no_default_policy":true,"metadata":null,"entity_id":"","token_type":"service"},"request":{"operation":"update","path":"/foo","data":null,"wrap_ttl":60,"remote_address":"127.0.0.1","headers":{"foo":["bar"]}},"error":"this is an error"} ` diff --git a/audit/format_jsonx_test.go b/audit/format_jsonx_test.go index 1fc37e904..70a850f87 100644 --- a/audit/format_jsonx_test.go +++ b/audit/format_jsonx_test.go @@ -37,11 +37,12 @@ func TestFormatJSONx_formatRequest(t *testing.T) { }{ "auth, request": { &logical.Auth{ - ClientToken: "foo", - Accessor: "bar", - DisplayName: "testtoken", - Policies: []string{"root"}, - TokenType: logical.TokenTypeService, + ClientToken: "foo", + Accessor: "bar", + DisplayName: "testtoken", + Policies: []string{"root"}, + NoDefaultPolicy: true, + TokenType: logical.TokenTypeService, }, &logical.Request{ Operation: logical.UpdateOperation, @@ -59,16 +60,17 @@ func TestFormatJSONx_formatRequest(t *testing.T) { errors.New("this is an error"), "", "", - fmt.Sprintf(`bar%stesttokenrootservicethis is an errorbarrootupdate/foofalse127.0.0.160request`, + fmt.Sprintf(`bar%stesttokentruerootservicethis is an errorbarrootupdate/foofalse127.0.0.160request`, fooSalted), }, "auth, request with prefix": { &logical.Auth{ - ClientToken: "foo", - Accessor: "bar", - DisplayName: "testtoken", - Policies: []string{"root"}, - TokenType: logical.TokenTypeService, + ClientToken: "foo", + Accessor: "bar", + DisplayName: "testtoken", + NoDefaultPolicy: true, + Policies: []string{"root"}, + TokenType: logical.TokenTypeService, }, &logical.Request{ Operation: logical.UpdateOperation, @@ -86,7 +88,7 @@ func TestFormatJSONx_formatRequest(t *testing.T) { errors.New("this is an error"), "", "@cee: ", - fmt.Sprintf(`bar%stesttokenrootservicethis is an errorbarrootupdate/foofalse127.0.0.160request`, + fmt.Sprintf(`bar%stesttokentruerootservicethis is an errorbarrootupdate/foofalse127.0.0.160request`, fooSalted), }, } diff --git a/builtin/credential/app-id/path_login.go b/builtin/credential/app-id/path_login.go index ec744b283..a9e447cda 100644 --- a/builtin/credential/app-id/path_login.go +++ b/builtin/credential/app-id/path_login.go @@ -116,9 +116,6 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, data *fra DisplayName: displayName, Policies: policies, Metadata: metadata, - LeaseOptions: logical.LeaseOptions{ - Renewable: true, - }, Alias: &logical.Alias{ Name: appId, }, diff --git a/builtin/credential/approle/path_login.go b/builtin/credential/approle/path_login.go index e8c9ad7e9..4e44d1b63 100644 --- a/builtin/credential/approle/path_login.go +++ b/builtin/credential/approle/path_login.go @@ -294,9 +294,8 @@ func (b *backend) pathLoginUpdate(ctx context.Context, req *logical.Request, dat Metadata: metadata, Policies: role.Policies, LeaseOptions: logical.LeaseOptions{ - Renewable: true, - TTL: role.TokenTTL, - MaxTTL: role.TokenMaxTTL, + TTL: role.TokenTTL, + MaxTTL: role.TokenMaxTTL, }, Alias: &logical.Alias{ Name: role.RoleID, diff --git a/builtin/credential/aws/path_login.go b/builtin/credential/aws/path_login.go index f08357b9f..0d92d5a7c 100644 --- a/builtin/credential/aws/path_login.go +++ b/builtin/credential/aws/path_login.go @@ -825,9 +825,8 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, "ami_id": identityDocParsed.AmiID, }, LeaseOptions: logical.LeaseOptions{ - Renewable: true, - TTL: roleEntry.TTL, - MaxTTL: shortestMaxTTL, + TTL: roleEntry.TTL, + MaxTTL: shortestMaxTTL, }, Alias: &logical.Alias{ Name: identityAlias, @@ -1338,9 +1337,8 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request, }, DisplayName: entity.FriendlyName, LeaseOptions: logical.LeaseOptions{ - Renewable: true, - TTL: roleEntry.TTL, - MaxTTL: roleEntry.MaxTTL, + TTL: roleEntry.TTL, + MaxTTL: roleEntry.MaxTTL, }, Alias: &logical.Alias{ Name: identityAlias, diff --git a/builtin/credential/cert/backend_test.go b/builtin/credential/cert/backend_test.go index a6f3693be..3c4871452 100644 --- a/builtin/credential/cert/backend_test.go +++ b/builtin/credential/cert/backend_test.go @@ -21,14 +21,17 @@ import ( "testing" "time" + "github.com/go-test/deep" cleanhttp "github.com/hashicorp/go-cleanhttp" log "github.com/hashicorp/go-hclog" + sockaddr "github.com/hashicorp/go-sockaddr" "github.com/hashicorp/vault/api" vaulthttp "github.com/hashicorp/vault/http" rootcerts "github.com/hashicorp/go-rootcerts" "github.com/hashicorp/vault/builtin/logical/pki" "github.com/hashicorp/vault/helper/certutil" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" logicaltest "github.com/hashicorp/vault/logical/testing" @@ -1788,3 +1791,68 @@ func Test_Renew(t *testing.T) { t.Fatal("expected error") } } + +func TestBackend_CertUpgrade(t *testing.T) { + s := &logical.InmemStorage{} + + config := logical.TestBackendConfig() + config.StorageView = s + + ctx := context.Background() + + b := Backend() + if b == nil { + t.Fatalf("failed to create backend") + } + if err := b.Setup(ctx, config); err != nil { + t.Fatal(err) + } + + type B struct { + Policies []string + TTL time.Duration + MaxTTL time.Duration + Period time.Duration + BoundCIDRs []*sockaddr.SockAddrMarshaler + } + + foo := &B{ + Policies: []string{"foo"}, + TTL: time.Second, + MaxTTL: time.Second, + Period: time.Second, + BoundCIDRs: []*sockaddr.SockAddrMarshaler{&sockaddr.SockAddrMarshaler{SockAddr: sockaddr.MustIPAddr("127.0.0.1")}}, + } + + entry, err := logical.StorageEntryJSON("cert/foo", foo) + if err != nil { + t.Fatal(err) + } + err = s.Put(ctx, entry) + if err != nil { + t.Fatal(err) + } + + certEntry, err := b.Cert(ctx, s, "foo") + if err != nil { + t.Fatal(err) + } + + exp := &CertEntry{ + TokenParams: tokenhelper.TokenParams{ + Policies: []string{"foo"}, + TTL: time.Second, + MaxTTL: time.Second, + Period: time.Second, + BoundCIDRs: []*sockaddr.SockAddrMarshaler{&sockaddr.SockAddrMarshaler{SockAddr: sockaddr.MustIPAddr("127.0.0.1")}}, + }, + OldPolicies: nil, + OldTTL: 0, + OldMaxTTL: 0, + OldPeriod: 0, + OldBoundCIDRs: nil, + } + if diff := deep.Equal(certEntry, exp); diff != nil { + t.Fatal(diff) + } +} diff --git a/builtin/credential/cert/path_certs.go b/builtin/credential/cert/path_certs.go index 292b3cedb..0bdad4ee6 100644 --- a/builtin/credential/cert/path_certs.go +++ b/builtin/credential/cert/path_certs.go @@ -4,12 +4,11 @@ import ( "context" "crypto/x509" "fmt" - "strings" "time" sockaddr "github.com/hashicorp/go-sockaddr" - "github.com/hashicorp/vault/helper/parseutil" - "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/consts" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -28,11 +27,11 @@ func pathListCerts(b *backend) *framework.Path { } func pathCerts(b *backend) *framework.Path { - return &framework.Path{ + path := &framework.Path{ Pattern: "certs/" + framework.GenericNameRegex("name"), Fields: map[string]*framework.FieldSchema{ "name": &framework.FieldSchema{ - Type: framework.TypeString, + Type: framework.TypeLowerCaseString, Description: "The name of the certificate", }, @@ -93,42 +92,11 @@ All values much match. Supports globbing on "value".`, certificate.`, }, - "policies": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: "Comma-separated list of policies.", - }, - "lease": &framework.FieldSchema{ Type: framework.TypeInt, Description: `Deprecated: use "ttl" instead. TTL time in seconds. Defaults to system/backend default TTL.`, }, - - "ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: `TTL for tokens issued by this backend. -Defaults to system/backend default TTL time.`, - }, - - "max_ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: `Duration in either an integer number of seconds (3600) or -an integer time unit (60m) after which the -issued token can no longer be renewed.`, - }, - - "period": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: `If set, indicates that the token generated using this role -should never expire. The token should be renewed within the -duration specified by this value. At each renewal, the token's -TTL will be set to the value of this parameter.`, - }, - "bound_cidrs": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: `Comma separated string or list of CIDR blocks. If set, specifies the blocks of -IP addresses which can perform the login operation.`, - }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -140,10 +108,13 @@ IP addresses which can perform the login operation.`, HelpSynopsis: pathCertHelpSyn, HelpDescription: pathCertHelpDesc, } + tokenhelper.AddTokenFields(path.Fields) + + return path } func (b *backend) Cert(ctx context.Context, s logical.Storage, n string) (*CertEntry, error) { - entry, err := s.Get(ctx, "cert/"+strings.ToLower(n)) + entry, err := s.Get(ctx, "cert/"+n) if err != nil { return nil, err } @@ -155,11 +126,48 @@ func (b *backend) Cert(ctx context.Context, s logical.Storage, n string) (*CertE if err := entry.DecodeJSON(&result); err != nil { return nil, err } + + var needsUpgrade bool + if result.OldTTL != 0 { + needsUpgrade = true + result.TTL = result.OldTTL + result.OldTTL = 0 + } + if result.OldMaxTTL != 0 { + needsUpgrade = true + result.MaxTTL = result.OldMaxTTL + result.OldMaxTTL = 0 + } + if result.OldPeriod != 0 { + needsUpgrade = true + result.Period = result.OldPeriod + result.OldPeriod = 0 + } + if len(result.OldPolicies) > 0 { + needsUpgrade = true + result.Policies = result.OldPolicies + result.OldPolicies = nil + } + if len(result.OldBoundCIDRs) > 0 { + needsUpgrade = true + result.BoundCIDRs = result.OldBoundCIDRs + result.OldBoundCIDRs = nil + } + if needsUpgrade && (b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary|consts.ReplicationPerformanceStandby)) { + entry, err := logical.StorageEntryJSON("cert/"+n, result) + if err != nil { + return nil, err + } + if err := s.Put(ctx, entry); err != nil { + return nil, err + } + } + return &result, nil } func (b *backend) pathCertDelete(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { - err := req.Storage.Delete(ctx, "cert/"+strings.ToLower(d.Get("name").(string))) + err := req.Storage.Delete(ctx, "cert/"+d.Get("name").(string)) if err != nil { return nil, err } @@ -175,7 +183,7 @@ func (b *backend) pathCertList(ctx context.Context, req *logical.Request, d *fra } func (b *backend) pathCertRead(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { - cert, err := b.Cert(ctx, req.Storage, strings.ToLower(d.Get("name").(string))) + cert, err := b.Cert(ctx, req.Storage, d.Get("name").(string)) if err != nil { return nil, err } @@ -183,30 +191,27 @@ func (b *backend) pathCertRead(ctx context.Context, req *logical.Request, d *fra return nil, nil } + data := map[string]interface{}{ + "certificate": cert.Certificate, + "display_name": cert.DisplayName, + "allowed_names": cert.AllowedNames, + "allowed_common_names": cert.AllowedCommonNames, + "allowed_dns_sans": cert.AllowedDNSSANs, + "allowed_email_sans": cert.AllowedEmailSANs, + "allowed_uri_sans": cert.AllowedURISANs, + "allowed_organizational_units": cert.AllowedOrganizationalUnits, + "required_extensions": cert.RequiredExtensions, + } + cert.PopulateTokenData(data) return &logical.Response{ - Data: map[string]interface{}{ - "certificate": cert.Certificate, - "display_name": cert.DisplayName, - "policies": cert.Policies, - "ttl": cert.TTL / time.Second, - "max_ttl": cert.MaxTTL / time.Second, - "period": cert.Period / time.Second, - "allowed_names": cert.AllowedNames, - "allowed_common_names": cert.AllowedCommonNames, - "allowed_dns_sans": cert.AllowedDNSSANs, - "allowed_email_sans": cert.AllowedEmailSANs, - "allowed_uri_sans": cert.AllowedURISANs, - "allowed_organizational_units": cert.AllowedOrganizationalUnits, - "required_extensions": cert.RequiredExtensions, - }, + Data: data, }, nil } func (b *backend) pathCertWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { - name := strings.ToLower(d.Get("name").(string)) + name := d.Get("name").(string) certificate := d.Get("certificate").(string) displayName := d.Get("display_name").(string) - policies := policyutil.ParsePolicies(d.Get("policies")) allowedNames := d.Get("allowed_names").([]string) allowedCommonNames := d.Get("allowed_common_names").([]string) allowedDNSSANs := d.Get("allowed_dns_sans").([]string) @@ -215,45 +220,32 @@ func (b *backend) pathCertWrite(ctx context.Context, req *logical.Request, d *fr allowedOrganizationalUnits := d.Get("allowed_organizational_units").([]string) requiredExtensions := d.Get("required_extensions").([]string) + certEntry := &CertEntry{} var resp logical.Response + if err := certEntry.ParseTokenFields(req, d); err != nil { + return logical.ErrorResponse(err.Error()), nil + } + // Parse the ttl (or lease duration) systemDefaultTTL := b.System().DefaultLeaseTTL() - ttl := time.Duration(d.Get("ttl").(int)) * time.Second - if ttl == 0 { - ttl = time.Duration(d.Get("lease").(int)) * time.Second - } - if ttl > systemDefaultTTL { - resp.AddWarning(fmt.Sprintf("Given ttl of %d seconds is greater than current mount/system default of %d seconds", ttl/time.Second, systemDefaultTTL/time.Second)) - } - - if ttl < time.Duration(0) { - return logical.ErrorResponse("ttl cannot be negative"), nil + if certEntry.TTL > systemDefaultTTL { + resp.AddWarning(fmt.Sprintf("Given ttl of %d seconds is greater than current mount/system default of %d seconds", certEntry.TTL/time.Second, systemDefaultTTL/time.Second)) } // Parse max_ttl systemMaxTTL := b.System().MaxLeaseTTL() - maxTTL := time.Duration(d.Get("max_ttl").(int)) * time.Second - if maxTTL > systemMaxTTL { - resp.AddWarning(fmt.Sprintf("Given max_ttl of %d seconds is greater than current mount/system default of %d seconds", maxTTL/time.Second, systemMaxTTL/time.Second)) + if certEntry.MaxTTL > systemMaxTTL { + resp.AddWarning(fmt.Sprintf("Given max_ttl of %d seconds is greater than current mount/system default of %d seconds", certEntry.MaxTTL/time.Second, systemMaxTTL/time.Second)) } - if maxTTL < time.Duration(0) { - return logical.ErrorResponse("max_ttl cannot be negative"), nil - } - - if maxTTL != 0 && ttl > maxTTL { + if certEntry.MaxTTL != 0 && certEntry.TTL > certEntry.MaxTTL { return logical.ErrorResponse("ttl should be shorter than max_ttl"), nil } // Parse period - period := time.Duration(d.Get("period").(int)) * time.Second - if period > systemMaxTTL { - resp.AddWarning(fmt.Sprintf("Given period of %d seconds is greater than the backend's maximum TTL of %d seconds", period/time.Second, systemMaxTTL/time.Second)) - } - - if period < time.Duration(0) { - return logical.ErrorResponse("period cannot be negative"), nil + if certEntry.Period > systemMaxTTL { + resp.AddWarning(fmt.Sprintf("Given period of %d seconds is greater than the backend's maximum TTL of %d seconds", certEntry.Period/time.Second, systemMaxTTL/time.Second)) } // Default the display name to the certificate name if not given @@ -280,28 +272,16 @@ func (b *backend) pathCertWrite(ctx context.Context, req *logical.Request, d *fr } } - parsedCIDRs, err := parseutil.ParseAddrs(d.Get("bound_cidrs")) - if err != nil { - return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest - } - - certEntry := &CertEntry{ - Name: name, - Certificate: certificate, - DisplayName: displayName, - Policies: policies, - AllowedNames: allowedNames, - AllowedCommonNames: allowedCommonNames, - AllowedDNSSANs: allowedDNSSANs, - AllowedEmailSANs: allowedEmailSANs, - AllowedURISANs: allowedURISANs, - AllowedOrganizationalUnits: allowedOrganizationalUnits, - RequiredExtensions: requiredExtensions, - TTL: ttl, - MaxTTL: maxTTL, - Period: period, - BoundCIDRs: parsedCIDRs, - } + certEntry.Name = name + certEntry.Certificate = certificate + certEntry.DisplayName = displayName + certEntry.AllowedNames = allowedNames + certEntry.AllowedCommonNames = allowedCommonNames + certEntry.AllowedDNSSANs = allowedDNSSANs + certEntry.AllowedEmailSANs = allowedEmailSANs + certEntry.AllowedURISANs = allowedURISANs + certEntry.AllowedOrganizationalUnits = allowedOrganizationalUnits + certEntry.RequiredExtensions = requiredExtensions // Store it entry, err := logical.StorageEntryJSON("cert/"+name, certEntry) @@ -320,13 +300,11 @@ func (b *backend) pathCertWrite(ctx context.Context, req *logical.Request, d *fr } type CertEntry struct { + tokenhelper.TokenParams + Name string Certificate string DisplayName string - Policies []string - TTL time.Duration - MaxTTL time.Duration - Period time.Duration AllowedNames []string AllowedCommonNames []string AllowedDNSSANs []string @@ -334,7 +312,13 @@ type CertEntry struct { AllowedURISANs []string AllowedOrganizationalUnits []string RequiredExtensions []string - BoundCIDRs []*sockaddr.SockAddrMarshaler + + // These token-related fields have been moved to the embedded tokenhelper.TokenParams struct + OldPolicies []string `json:"Policies"` + OldTTL time.Duration `json:"TTL"` + OldMaxTTL time.Duration `json:"MaxTTL"` + OldPeriod time.Duration `json:"Period"` + OldBoundCIDRs []*sockaddr.SockAddrMarshaler `json:"BoundCIDRs"` } const pathCertHelpSyn = ` diff --git a/builtin/credential/cert/path_login.go b/builtin/credential/cert/path_login.go index 4ef6cefe1..32b86e895 100644 --- a/builtin/credential/cert/path_login.go +++ b/builtin/credential/cert/path_login.go @@ -83,32 +83,27 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, data *fra skid := base64.StdEncoding.EncodeToString(clientCerts[0].SubjectKeyId) akid := base64.StdEncoding.EncodeToString(clientCerts[0].AuthorityKeyId) - resp := &logical.Response{ - Auth: &logical.Auth{ - Period: matched.Entry.Period, - InternalData: map[string]interface{}{ - "subject_key_id": skid, - "authority_key_id": akid, - }, - Policies: matched.Entry.Policies, - DisplayName: matched.Entry.DisplayName, - Metadata: map[string]string{ - "cert_name": matched.Entry.Name, - "common_name": clientCerts[0].Subject.CommonName, - "serial_number": clientCerts[0].SerialNumber.String(), - "subject_key_id": certutil.GetHexFormatted(clientCerts[0].SubjectKeyId, ":"), - "authority_key_id": certutil.GetHexFormatted(clientCerts[0].AuthorityKeyId, ":"), - }, - LeaseOptions: logical.LeaseOptions{ - Renewable: true, - TTL: matched.Entry.TTL, - MaxTTL: matched.Entry.MaxTTL, - }, - Alias: &logical.Alias{ - Name: clientCerts[0].Subject.CommonName, - }, - BoundCIDRs: matched.Entry.BoundCIDRs, + auth := &logical.Auth{ + InternalData: map[string]interface{}{ + "subject_key_id": skid, + "authority_key_id": akid, }, + DisplayName: matched.Entry.DisplayName, + Metadata: map[string]string{ + "cert_name": matched.Entry.Name, + "common_name": clientCerts[0].Subject.CommonName, + "serial_number": clientCerts[0].SerialNumber.String(), + "subject_key_id": certutil.GetHexFormatted(clientCerts[0].SubjectKeyId, ":"), + "authority_key_id": certutil.GetHexFormatted(clientCerts[0].AuthorityKeyId, ":"), + }, + Alias: &logical.Alias{ + Name: clientCerts[0].Subject.CommonName, + }, + } + matched.Entry.PopulateTokenAuth(auth) + + resp := &logical.Response{ + Auth: auth, } // Generate a response diff --git a/builtin/credential/github/path_config.go b/builtin/credential/github/path_config.go index f42b156db..93c8ef7c8 100644 --- a/builtin/credential/github/path_config.go +++ b/builtin/credential/github/path_config.go @@ -4,15 +4,15 @@ import ( "context" "fmt" "net/url" - "time" "github.com/hashicorp/errwrap" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) func pathConfig(b *backend) *framework.Path { - return &framework.Path{ + ret := &framework.Path{ Pattern: "config", Fields: map[string]*framework.FieldSchema{ "organization": &framework.FieldSchema{ @@ -26,14 +26,6 @@ func pathConfig(b *backend) *framework.Path { are running GitHub Enterprise or an API-compatible authentication server.`, }, - "ttl": &framework.FieldSchema{ - Type: framework.TypeString, - Description: `Duration after which authentication will be expired`, - }, - "max_ttl": &framework.FieldSchema{ - Type: framework.TypeString, - Description: `Maximum duration after which authentication will be expired`, - }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -41,6 +33,9 @@ API-compatible authentication server.`, logical.ReadOperation: b.pathConfigRead, }, } + tokenhelper.AddTokenFields(ret.Fields) + + return ret } func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { @@ -53,35 +48,16 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, dat } } - var ttl time.Duration - var err error - ttlRaw, ok := data.GetOk("ttl") - if !ok || len(ttlRaw.(string)) == 0 { - ttl = 0 - } else { - ttl, err = time.ParseDuration(ttlRaw.(string)) - if err != nil { - return logical.ErrorResponse(fmt.Sprintf("Invalid 'ttl':%s", err)), nil - } - } - - var maxTTL time.Duration - maxTTLRaw, ok := data.GetOk("max_ttl") - if !ok || len(maxTTLRaw.(string)) == 0 { - maxTTL = 0 - } else { - maxTTL, err = time.ParseDuration(maxTTLRaw.(string)) - if err != nil { - return logical.ErrorResponse(fmt.Sprintf("Invalid 'max_ttl':%s", err)), nil - } - } - - entry, err := logical.StorageEntryJSON("config", config{ + cfg := &config{ Organization: organization, BaseURL: baseURL, - TTL: ttl, - MaxTTL: maxTTL, - }) + } + + if err := cfg.ParseTokenFields(req, data); err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + entry, err := logical.StorageEntryJSON("config", cfg) if err != nil { return nil, err @@ -104,18 +80,15 @@ func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, data return nil, fmt.Errorf("configuration object not found") } - config.TTL /= time.Second - config.MaxTTL /= time.Second - - resp := &logical.Response{ - Data: map[string]interface{}{ - "organization": config.Organization, - "base_url": config.BaseURL, - "ttl": config.TTL, - "max_ttl": config.MaxTTL, - }, + respData := map[string]interface{}{ + "organization": config.Organization, + "base_url": config.BaseURL, } - return resp, nil + config.PopulateTokenData(respData) + + return &logical.Response{ + Data: respData, + }, nil } // Config returns the configuration for this backend. @@ -136,8 +109,8 @@ func (b *backend) Config(ctx context.Context, s logical.Storage) (*config, error } type config struct { - Organization string `json:"organization" structs:"organization" mapstructure:"organization"` - BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"` - TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"` - MaxTTL time.Duration `json:"max_ttl" structs:"max_ttl" mapstructure:"max_ttl"` + tokenhelper.TokenParams + + Organization string `json:"organization" structs:"organization" mapstructure:"organization"` + BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"` } diff --git a/builtin/credential/github/path_login.go b/builtin/credential/github/path_login.go index b6e59cfd0..61617150e 100644 --- a/builtin/credential/github/path_login.go +++ b/builtin/credential/github/path_login.go @@ -9,6 +9,7 @@ import ( "github.com/google/go-github/github" "github.com/hashicorp/errwrap" "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/strutil" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -68,38 +69,35 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, data *fra return nil, err } - resp := &logical.Response{ - Auth: &logical.Auth{ - InternalData: map[string]interface{}{ - "token": token, - }, - Policies: verifyResp.Policies, - Metadata: map[string]string{ - "username": *verifyResp.User.Login, - "org": *verifyResp.Org.Login, - }, - DisplayName: *verifyResp.User.Login, - LeaseOptions: logical.LeaseOptions{ - TTL: config.TTL, - MaxTTL: config.MaxTTL, - Renewable: true, - }, - Alias: &logical.Alias{ - Name: *verifyResp.User.Login, - }, + auth := &logical.Auth{ + InternalData: map[string]interface{}{ + "token": token, + }, + Metadata: map[string]string{ + "username": *verifyResp.User.Login, + "org": *verifyResp.Org.Login, + }, + DisplayName: *verifyResp.User.Login, + Alias: &logical.Alias{ + Name: *verifyResp.User.Login, }, } + config.PopulateTokenAuth(auth) + auth.Policies = append(auth.Policies, verifyResp.Policies...) + auth.Policies = strutil.RemoveDuplicates(auth.Policies, false) for _, teamName := range verifyResp.TeamNames { if teamName == "" { continue } - resp.Auth.GroupAliases = append(resp.Auth.GroupAliases, &logical.Alias{ + auth.GroupAliases = append(auth.GroupAliases, &logical.Alias{ Name: teamName, }) } - return resp, nil + return &logical.Response{ + Auth: auth, + }, nil } func (b *backend) pathLoginRenew(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { diff --git a/builtin/credential/ldap/path_config.go b/builtin/credential/ldap/path_config.go index 81237930b..dfc5bad61 100644 --- a/builtin/credential/ldap/path_config.go +++ b/builtin/credential/ldap/path_config.go @@ -12,7 +12,7 @@ import ( func pathConfig(b *backend) *framework.Path { return &framework.Path{ Pattern: `config`, - Fields: ldaputil.ConfigFields(), + Fields: ldaputil.ConfigFields(true), Callbacks: map[logical.Operation]framework.OperationFunc{ logical.ReadOperation: b.pathConfigRead, @@ -89,8 +89,11 @@ func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, d *f return nil, nil } + data := cfg.PasswordlessMap() + cfg.PopulateTokenData(data) + resp := &logical.Response{ - Data: cfg.PasswordlessMap(), + Data: data, } return resp, nil } @@ -109,6 +112,10 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, d * *cfg.CaseSensitiveNames = false } + if err := cfg.ParseTokenFields(req, d); err != nil { + return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest + } + entry, err := logical.StorageEntryJSON("config", cfg) if err != nil { return nil, err diff --git a/builtin/credential/ldap/path_login.go b/builtin/credential/ldap/path_login.go index 114f20a90..b5fb98ac8 100644 --- a/builtin/credential/ldap/path_login.go +++ b/builtin/credential/ldap/path_login.go @@ -3,9 +3,9 @@ package ldap import ( "context" "fmt" - "sort" "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/strutil" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -54,6 +54,14 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew username := d.Get("username").(string) password := d.Get("password").(string) + cfg, err := b.Config(ctx, req) + if err != nil { + return nil, err + } + if cfg == nil { + return logical.ErrorResponse("ldap backend not configured"), nil + } + policies, resp, groupNames, err := b.Login(ctx, req, username, password) // Handle an internal error if err != nil { @@ -68,10 +76,7 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew resp = &logical.Response{} } - sort.Strings(policies) - - resp.Auth = &logical.Auth{ - Policies: policies, + auth := &logical.Auth{ Metadata: map[string]string{ "username": username, }, @@ -79,22 +84,24 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew "password": password, }, DisplayName: username, - LeaseOptions: logical.LeaseOptions{ - Renewable: true, - }, Alias: &logical.Alias{ Name: username, }, } + cfg.PopulateTokenAuth(auth) + auth.Policies = append(auth.Policies, policies...) + auth.Policies = strutil.RemoveDuplicates(auth.Policies, false) for _, groupName := range groupNames { if groupName == "" { continue } - resp.Auth.GroupAliases = append(resp.Auth.GroupAliases, &logical.Alias{ + auth.GroupAliases = append(auth.GroupAliases, &logical.Alias{ Name: groupName, }) } + + resp.Auth = auth return resp, nil } diff --git a/builtin/credential/okta/path_config.go b/builtin/credential/okta/path_config.go index 284a8dcc5..4e4b6a7d9 100644 --- a/builtin/credential/okta/path_config.go +++ b/builtin/credential/okta/path_config.go @@ -5,10 +5,9 @@ import ( "fmt" "net/url" - "time" - "github.com/chrismalek/oktasdk-go/okta" cleanhttp "github.com/hashicorp/go-cleanhttp" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -19,7 +18,7 @@ const ( ) func pathConfig(b *backend) *framework.Path { - return &framework.Path{ + ret := &framework.Path{ Pattern: `config`, Fields: map[string]*framework.FieldSchema{ "organization": &framework.FieldSchema{ @@ -46,14 +45,6 @@ func pathConfig(b *backend) *framework.Path { Type: framework.TypeBool, Description: `(DEPRECATED) Use base_url.`, }, - "ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: `Duration after which authentication will be expired`, - }, - "max_ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: `Maximum duration after which authentication will be expired`, - }, "bypass_okta_mfa": &framework.FieldSchema{ Type: framework.TypeBool, Description: `When set true, requests by Okta for a MFA check will be bypassed. This also disallows certain status checks on the account, such as whether the password is expired.`, @@ -70,6 +61,9 @@ func pathConfig(b *backend) *framework.Path { HelpSynopsis: pathConfigHelp, } + tokenhelper.AddTokenFields(ret.Fields) + + return ret } // Config returns the configuration for this backend. @@ -101,15 +95,17 @@ func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, d *f return nil, nil } - resp := &logical.Response{ - Data: map[string]interface{}{ - "organization": cfg.Org, - "org_name": cfg.Org, - "ttl": cfg.TTL.Seconds(), - "max_ttl": cfg.MaxTTL.Seconds(), - "bypass_okta_mfa": cfg.BypassOktaMFA, - }, + data := map[string]interface{}{ + "organization": cfg.Org, + "org_name": cfg.Org, + "bypass_okta_mfa": cfg.BypassOktaMFA, } + cfg.PopulateTokenData(data) + + resp := &logical.Response{ + Data: data, + } + if cfg.BaseURL != "" { resp.Data["base_url"] = cfg.BaseURL } @@ -185,18 +181,8 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, d * cfg.BypassOktaMFA = bypass.(bool) } - ttl, ok := d.GetOk("ttl") - if ok { - cfg.TTL = time.Duration(ttl.(int)) * time.Second - } else if req.Operation == logical.CreateOperation { - cfg.TTL = time.Duration(d.Get("ttl").(int)) * time.Second - } - - maxTTL, ok := d.GetOk("max_ttl") - if ok { - cfg.MaxTTL = time.Duration(maxTTL.(int)) * time.Second - } else if req.Operation == logical.CreateOperation { - cfg.MaxTTL = time.Duration(d.Get("max_ttl").(int)) * time.Second + if err := cfg.ParseTokenFields(req, d); err != nil { + return logical.ErrorResponse(err.Error()), nil } jsonCfg, err := logical.StorageEntryJSON("config", cfg) @@ -244,13 +230,13 @@ func (c *ConfigEntry) OktaClient() *okta.Client { // ConfigEntry for Okta type ConfigEntry struct { - Org string `json:"organization"` - Token string `json:"token"` - BaseURL string `json:"base_url"` - Production *bool `json:"is_production,omitempty"` - TTL time.Duration `json:"ttl"` - MaxTTL time.Duration `json:"max_ttl"` - BypassOktaMFA bool `json:"bypass_okta_mfa"` + tokenhelper.TokenParams + + Org string `json:"organization"` + Token string `json:"token"` + BaseURL string `json:"base_url"` + Production *bool `json:"is_production,omitempty"` + BypassOktaMFA bool `json:"bypass_okta_mfa"` } const pathConfigHelp = ` diff --git a/builtin/credential/okta/path_login.go b/builtin/credential/okta/path_login.go index af784e015..e9eaf44d5 100644 --- a/builtin/credential/okta/path_login.go +++ b/builtin/credential/okta/path_login.go @@ -8,6 +8,7 @@ import ( "github.com/go-errors/errors" "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/strutil" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -77,8 +78,7 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew return nil, err } - resp.Auth = &logical.Auth{ - Policies: policies, + auth := &logical.Auth{ Metadata: map[string]string{ "username": username, "policies": strings.Join(policies, ","), @@ -87,15 +87,15 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew "password": password, }, DisplayName: username, - LeaseOptions: logical.LeaseOptions{ - TTL: cfg.TTL, - MaxTTL: cfg.MaxTTL, - Renewable: true, - }, Alias: &logical.Alias{ Name: username, }, } + cfg.PopulateTokenAuth(auth) + auth.Policies = append(auth.Policies, policies...) + auth.Policies = strutil.RemoveDuplicates(auth.Policies, false) + + resp.Auth = auth for _, groupName := range groupNames { if groupName == "" { diff --git a/builtin/credential/radius/path_config.go b/builtin/credential/radius/path_config.go index 85d60a3d6..c99fb9508 100644 --- a/builtin/credential/radius/path_config.go +++ b/builtin/credential/radius/path_config.go @@ -4,12 +4,13 @@ import ( "context" "strings" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) func pathConfig(b *backend) *framework.Path { - return &framework.Path{ + ret := &framework.Path{ Pattern: "config", Fields: map[string]*framework.FieldSchema{ "host": &framework.FieldSchema{ @@ -64,6 +65,9 @@ func pathConfig(b *backend) *framework.Path { HelpSynopsis: pathConfigHelpSyn, HelpDescription: pathConfigHelpDesc, } + tokenhelper.AddTokenFields(ret.Fields) + + return ret } // Establishes dichotomy of request operation between CreateOperation and UpdateOperation. @@ -107,18 +111,20 @@ func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, d *f return nil, nil } - resp := &logical.Response{ - Data: map[string]interface{}{ - "host": cfg.Host, - "port": cfg.Port, - "unregistered_user_policies": cfg.UnregisteredUserPolicies, - "dial_timeout": cfg.DialTimeout, - "read_timeout": cfg.ReadTimeout, - "nas_port": cfg.NasPort, - "nas_identifier": cfg.NasIdentifier, - }, + data := map[string]interface{}{ + "host": cfg.Host, + "port": cfg.Port, + "unregistered_user_policies": cfg.UnregisteredUserPolicies, + "dial_timeout": cfg.DialTimeout, + "read_timeout": cfg.ReadTimeout, + "nas_port": cfg.NasPort, + "nas_identifier": cfg.NasIdentifier, } - return resp, nil + cfg.PopulateTokenData(data) + + return &logical.Response{ + Data: data, + }, nil } func (b *backend) pathConfigCreateUpdate(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { @@ -203,6 +209,10 @@ func (b *backend) pathConfigCreateUpdate(ctx context.Context, req *logical.Reque cfg.NasIdentifier = d.Get("nas_identifier").(string) } + if err := cfg.ParseTokenFields(req, d); err != nil { + return logical.ErrorResponse(err.Error()), nil + } + entry, err := logical.StorageEntryJSON("config", cfg) if err != nil { return nil, err @@ -215,6 +225,8 @@ func (b *backend) pathConfigCreateUpdate(ctx context.Context, req *logical.Reque } type ConfigEntry struct { + tokenhelper.TokenParams + Host string `json:"host" structs:"host" mapstructure:"host"` Port int `json:"port" structs:"port" mapstructure:"port"` Secret string `json:"secret" structs:"secret" mapstructure:"secret"` diff --git a/builtin/credential/radius/path_login.go b/builtin/credential/radius/path_login.go index 2cf2fa2f6..6db75ab0d 100644 --- a/builtin/credential/radius/path_login.go +++ b/builtin/credential/radius/path_login.go @@ -12,6 +12,7 @@ import ( . "layeh.com/radius/rfc2865" "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/strutil" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -76,6 +77,14 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew return logical.ErrorResponse("password cannot be empty"), nil } + cfg, err := b.Config(ctx, req) + if err != nil { + return nil, err + } + if cfg == nil { + return logical.ErrorResponse("radius backend not configured"), nil + } + policies, resp, err := b.RadiusLogin(ctx, req, username, password) // Handle an internal error if err != nil { @@ -88,8 +97,7 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew } } - resp.Auth = &logical.Auth{ - Policies: policies, + auth := &logical.Auth{ Metadata: map[string]string{ "username": username, "policies": strings.Join(policies, ","), @@ -98,13 +106,16 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew "password": password, }, DisplayName: username, - LeaseOptions: logical.LeaseOptions{ - Renewable: true, - }, Alias: &logical.Alias{ Name: username, }, } + cfg.PopulateTokenAuth(auth) + auth.Policies = append(auth.Policies, policies...) + auth.Policies = strutil.RemoveDuplicates(auth.Policies, false) + + resp.Auth = auth + return resp, nil } diff --git a/builtin/credential/userpass/backend_test.go b/builtin/credential/userpass/backend_test.go index fcca9273b..03618b006 100644 --- a/builtin/credential/userpass/backend_test.go +++ b/builtin/credential/userpass/backend_test.go @@ -9,7 +9,10 @@ import ( "crypto/tls" + "github.com/go-test/deep" + sockaddr "github.com/hashicorp/go-sockaddr" "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" logicaltest "github.com/hashicorp/vault/logical/testing" "github.com/mitchellh/mapstructure" @@ -20,6 +23,63 @@ const ( testSysMaxTTL = time.Hour * 20 ) +func TestBackend_UserUpgrade(t *testing.T) { + s := &logical.InmemStorage{} + + config := logical.TestBackendConfig() + config.StorageView = s + + ctx := context.Background() + + b := Backend() + if b == nil { + t.Fatalf("failed to create backend") + } + if err := b.Setup(ctx, config); err != nil { + t.Fatal(err) + } + + type B struct { + Policies []string + TTL time.Duration + MaxTTL time.Duration + BoundCIDRs []*sockaddr.SockAddrMarshaler + } + + foo := &B{ + Policies: []string{"foo"}, + TTL: time.Second, + MaxTTL: time.Second, + BoundCIDRs: []*sockaddr.SockAddrMarshaler{&sockaddr.SockAddrMarshaler{SockAddr: sockaddr.MustIPAddr("127.0.0.1")}}, + } + + entry, err := logical.StorageEntryJSON("user/foo", foo) + if err != nil { + t.Fatal(err) + } + err = s.Put(ctx, entry) + if err != nil { + t.Fatal(err) + } + + userEntry, err := b.user(ctx, s, "foo") + if err != nil { + t.Fatal(err) + } + + exp := &UserEntry{ + TokenParams: tokenhelper.TokenParams{ + Policies: []string{"foo"}, + TTL: time.Second, + MaxTTL: time.Second, + BoundCIDRs: []*sockaddr.SockAddrMarshaler{&sockaddr.SockAddrMarshaler{SockAddr: sockaddr.MustIPAddr("127.0.0.1")}}, + }, + } + if diff := deep.Equal(userEntry, exp); diff != nil { + t.Fatal(diff) + } +} + func TestBackend_TTL(t *testing.T) { var resp *logical.Response var err error diff --git a/builtin/credential/userpass/path_login.go b/builtin/credential/userpass/path_login.go index 8c8b92e03..d4c2d5261 100644 --- a/builtin/credential/userpass/path_login.go +++ b/builtin/credential/userpass/path_login.go @@ -108,23 +108,19 @@ func (b *backend) pathLogin(ctx context.Context, req *logical.Request, d *framew return logical.ErrorResponse("login request originated from invalid CIDR"), nil } - return &logical.Response{ - Auth: &logical.Auth{ - Policies: user.Policies, - Metadata: map[string]string{ - "username": username, - }, - DisplayName: username, - LeaseOptions: logical.LeaseOptions{ - TTL: user.TTL, - MaxTTL: user.MaxTTL, - Renewable: true, - }, - Alias: &logical.Alias{ - Name: username, - }, - BoundCIDRs: user.BoundCIDRs, + auth := &logical.Auth{ + Metadata: map[string]string{ + "username": username, }, + DisplayName: username, + Alias: &logical.Alias{ + Name: username, + }, + } + user.PopulateTokenAuth(auth) + + return &logical.Response{ + Auth: auth, }, nil } diff --git a/builtin/credential/userpass/path_users.go b/builtin/credential/userpass/path_users.go index b9603ee7a..19065b98c 100644 --- a/builtin/credential/userpass/path_users.go +++ b/builtin/credential/userpass/path_users.go @@ -7,8 +7,8 @@ import ( "time" sockaddr "github.com/hashicorp/go-sockaddr" - "github.com/hashicorp/vault/helper/parseutil" - "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/helper/consts" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -27,7 +27,7 @@ func pathUsersList(b *backend) *framework.Path { } func pathUsers(b *backend) *framework.Path { - return &framework.Path{ + p := &framework.Path{ Pattern: "users/" + framework.GenericNameRegex("username"), Fields: map[string]*framework.FieldSchema{ "username": &framework.FieldSchema{ @@ -39,27 +39,6 @@ func pathUsers(b *backend) *framework.Path { Type: framework.TypeString, Description: "Password for this user.", }, - - "policies": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: "Comma-separated list of policies", - }, - - "ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: "Duration after which authentication will be expired", - }, - - "max_ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Description: "Maximum duration after which authentication will be expired", - }, - - "bound_cidrs": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: `Comma separated string or list of CIDR blocks. If set, specifies the blocks of -IP addresses which can perform the login operation.`, - }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -74,6 +53,10 @@ IP addresses which can perform the login operation.`, HelpSynopsis: pathUserHelpSyn, HelpDescription: pathUserHelpDesc, } + + tokenhelper.AddTokenFields(p.Fields) + + return p } func (b *backend) userExistenceCheck(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) { @@ -103,6 +86,33 @@ func (b *backend) user(ctx context.Context, s logical.Storage, username string) return nil, err } + var needsUpgrade bool + if result.OldTTL != 0 { + needsUpgrade = true + result.TTL = result.OldTTL + result.OldTTL = 0 + } + if result.OldMaxTTL != 0 { + needsUpgrade = true + result.MaxTTL = result.OldMaxTTL + result.OldMaxTTL = 0 + } + if len(result.OldPolicies) != 0 { + needsUpgrade = true + result.Policies = result.OldPolicies + result.OldPolicies = nil + } + if result.OldBoundCIDRs != nil { + needsUpgrade = true + result.BoundCIDRs = result.OldBoundCIDRs + result.OldBoundCIDRs = nil + } + if needsUpgrade && (b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary|consts.ReplicationPerformanceStandby)) { + if err := b.setUser(ctx, s, strings.ToLower(username), &result); err != nil { + return nil, err + } + } + return &result, nil } @@ -141,13 +151,10 @@ func (b *backend) pathUserRead(ctx context.Context, req *logical.Request, d *fra return nil, nil } + data := map[string]interface{}{} + user.PopulateTokenData(data) return &logical.Response{ - Data: map[string]interface{}{ - "policies": user.Policies, - "ttl": user.TTL.Seconds(), - "max_ttl": user.MaxTTL.Seconds(), - "bound_cidrs": user.BoundCIDRs, - }, + Data: data, }, nil } @@ -172,25 +179,9 @@ func (b *backend) userCreateUpdate(ctx context.Context, req *logical.Request, d } } - if policiesRaw, ok := d.GetOk("policies"); ok { - userEntry.Policies = policyutil.ParsePolicies(policiesRaw) - } - - ttl, ok := d.GetOk("ttl") - if ok { - userEntry.TTL = time.Duration(ttl.(int)) * time.Second - } - - maxTTL, ok := d.GetOk("max_ttl") - if ok { - userEntry.MaxTTL = time.Duration(maxTTL.(int)) * time.Second - } - - boundCIDRs, err := parseutil.ParseAddrs(d.Get("bound_cidrs")) - if err != nil { + if err := userEntry.ParseTokenFields(req, d); err != nil { return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest } - userEntry.BoundCIDRs = boundCIDRs return nil, b.setUser(ctx, req.Storage, username, userEntry) } @@ -204,6 +195,8 @@ func (b *backend) pathUserWrite(ctx context.Context, req *logical.Request, d *fr } type UserEntry struct { + tokenhelper.TokenParams + // Password is deprecated in Vault 0.2 in favor of // PasswordHash, but is retained for backwards compatibility. Password string @@ -212,15 +205,16 @@ type UserEntry struct { // used instead of the actual password in Vault 0.2+. PasswordHash []byte - Policies []string + // These token-related fields have been moved to the embedded tokenhelper.TokenParams struct + OldPolicies []string `json:"Policies"` // Duration after which the user will be revoked unless renewed - TTL time.Duration + OldTTL time.Duration `json:"TTL"` // Maximum duration for which user can be valid - MaxTTL time.Duration + OldMaxTTL time.Duration `json:"MaxTTL"` - BoundCIDRs []*sockaddr.SockAddrMarshaler + OldBoundCIDRs []*sockaddr.SockAddrMarshaler `json:"BoundCIDRs"` } const pathUserHelpSyn = ` diff --git a/builtin/logical/database/dbplugin/database.pb.go b/builtin/logical/database/dbplugin/database.pb.go index 8e452430f..60d619e66 100644 --- a/builtin/logical/database/dbplugin/database.pb.go +++ b/builtin/logical/database/dbplugin/database.pb.go @@ -5,15 +5,11 @@ package dbplugin import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" timestamp "github.com/golang/protobuf/ptypes/timestamp" -) - -import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -679,6 +675,60 @@ func init() { proto.RegisterType((*Empty)(nil), "dbplugin.Empty") } +func init() { + proto.RegisterFile("builtin/logical/database/dbplugin/database.proto", fileDescriptor_7bf7b4c7fef2f66e) +} + +var fileDescriptor_7bf7b4c7fef2f66e = []byte{ + // 724 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xd1, 0x4e, 0xdb, 0x4a, + 0x10, 0x95, 0x93, 0x00, 0xc9, 0x80, 0x80, 0xec, 0x05, 0x64, 0xf9, 0x72, 0x6f, 0x91, 0x1f, 0x28, + 0x55, 0xd5, 0xb8, 0x82, 0x56, 0x54, 0xa8, 0xa2, 0x2a, 0xa1, 0xaa, 0x2a, 0x55, 0x3c, 0x2c, 0xf0, + 0x52, 0x55, 0x42, 0x1b, 0x67, 0x49, 0x56, 0x38, 0x5e, 0xd7, 0xbb, 0x0e, 0x4d, 0x7f, 0xa0, 0xfd, + 0x8c, 0x7e, 0x4e, 0x1f, 0xfb, 0x49, 0x95, 0x37, 0x59, 0xef, 0x26, 0x86, 0xf2, 0x40, 0xfb, 0xe6, + 0xd9, 0x99, 0x33, 0x73, 0xe6, 0x78, 0x76, 0x16, 0x9e, 0x76, 0x32, 0x16, 0x49, 0x16, 0x07, 0x11, + 0xef, 0xb1, 0x90, 0x44, 0x41, 0x97, 0x48, 0xd2, 0x21, 0x82, 0x06, 0xdd, 0x4e, 0x12, 0x65, 0x3d, + 0x16, 0x17, 0x27, 0xad, 0x24, 0xe5, 0x92, 0xa3, 0xba, 0x76, 0x78, 0x0f, 0x7a, 0x9c, 0xf7, 0x22, + 0x1a, 0xa8, 0xf3, 0x4e, 0x76, 0x19, 0x48, 0x36, 0xa0, 0x42, 0x92, 0x41, 0x32, 0x0e, 0xf5, 0x3f, + 0x42, 0xf3, 0x5d, 0xcc, 0x24, 0x23, 0x11, 0xfb, 0x42, 0x31, 0xfd, 0x94, 0x51, 0x21, 0xd1, 0x06, + 0xcc, 0x87, 0x3c, 0xbe, 0x64, 0x3d, 0xd7, 0xd9, 0x72, 0x76, 0x96, 0xf0, 0xc4, 0x42, 0x8f, 0xa1, + 0x39, 0xa4, 0x29, 0xbb, 0x1c, 0x5d, 0x84, 0x3c, 0x8e, 0x69, 0x28, 0x19, 0x8f, 0xdd, 0xca, 0x96, + 0xb3, 0x53, 0xc7, 0xab, 0x63, 0x47, 0xbb, 0x38, 0x3f, 0xa8, 0xb8, 0x8e, 0x8f, 0x61, 0x31, 0xcf, + 0xfe, 0x27, 0xf3, 0xfa, 0x3f, 0x1c, 0x68, 0xb6, 0x53, 0x4a, 0x24, 0x3d, 0x17, 0x34, 0xd5, 0xa9, + 0x9f, 0x01, 0x08, 0x49, 0x24, 0x1d, 0xd0, 0x58, 0x0a, 0x95, 0x7e, 0x71, 0x77, 0xad, 0xa5, 0x75, + 0x68, 0x9d, 0x16, 0x3e, 0x6c, 0xc5, 0xa1, 0xd7, 0xb0, 0x92, 0x09, 0x9a, 0xc6, 0x64, 0x40, 0x2f, + 0x26, 0xcc, 0x2a, 0x0a, 0xea, 0x1a, 0xe8, 0xf9, 0x24, 0xa0, 0xad, 0xfc, 0x78, 0x39, 0x9b, 0xb2, + 0xd1, 0x01, 0x00, 0xfd, 0x9c, 0xb0, 0x94, 0x28, 0xd2, 0x55, 0x85, 0xf6, 0x5a, 0x63, 0xd9, 0x5b, + 0x5a, 0xf6, 0xd6, 0x99, 0x96, 0x1d, 0x5b, 0xd1, 0xfe, 0x77, 0x07, 0x56, 0x31, 0x8d, 0xe9, 0xf5, + 0xfd, 0x3b, 0xf1, 0xa0, 0xae, 0x89, 0xa9, 0x16, 0x1a, 0xb8, 0xb0, 0xef, 0x45, 0x91, 0x42, 0x13, + 0xd3, 0x21, 0xbf, 0xa2, 0x7f, 0x95, 0xa2, 0x7f, 0x08, 0x9b, 0x98, 0xe7, 0xa1, 0x98, 0x73, 0xd9, + 0x4e, 0x69, 0x97, 0xc6, 0xf9, 0x4c, 0x0a, 0x5d, 0xf1, 0xff, 0x99, 0x8a, 0xd5, 0x9d, 0x86, 0x9d, + 0xdb, 0xff, 0x59, 0x01, 0x30, 0x65, 0xd1, 0x1e, 0xfc, 0x13, 0xe6, 0x23, 0xc2, 0x78, 0x7c, 0x31, + 0xc3, 0xb4, 0x71, 0x54, 0x71, 0x1d, 0x8c, 0xb4, 0xdb, 0x02, 0xed, 0xc3, 0x7a, 0x4a, 0x87, 0x3c, + 0x2c, 0xc1, 0x2a, 0x05, 0x6c, 0xcd, 0x04, 0x4c, 0x57, 0x4b, 0x79, 0x14, 0x75, 0x48, 0x78, 0x65, + 0xc3, 0xaa, 0xa6, 0x9a, 0x76, 0x5b, 0xa0, 0x27, 0xb0, 0x9a, 0xe6, 0xbf, 0xde, 0x46, 0xd4, 0x0a, + 0xc4, 0x8a, 0xf2, 0x9d, 0x4e, 0x89, 0xa7, 0x29, 0xbb, 0x73, 0xaa, 0xfd, 0xc2, 0xce, 0xc5, 0x31, + 0xbc, 0xdc, 0xf9, 0xb1, 0x38, 0xe6, 0x24, 0xc7, 0x6a, 0x02, 0xee, 0xc2, 0x18, 0xab, 0x6d, 0xe4, + 0xc2, 0x82, 0x2a, 0x45, 0x22, 0xb7, 0xae, 0x5c, 0xda, 0xf4, 0x4f, 0x60, 0x79, 0x7a, 0xf4, 0xd1, + 0x16, 0x2c, 0x1e, 0x33, 0x91, 0x44, 0x64, 0x74, 0x92, 0xff, 0x43, 0xa5, 0x26, 0xb6, 0x8f, 0xf2, + 0x4a, 0x98, 0x47, 0xf4, 0xc4, 0xfa, 0xc5, 0xda, 0xf6, 0xb7, 0x61, 0x69, 0xbc, 0x0b, 0x44, 0xc2, + 0x63, 0x41, 0x6f, 0x5b, 0x06, 0xfe, 0x7b, 0x40, 0xf6, 0xf5, 0x9e, 0x44, 0xdb, 0xc3, 0xe3, 0xcc, + 0xcc, 0xb7, 0x07, 0xf5, 0x84, 0x08, 0x71, 0xcd, 0xd3, 0xae, 0xae, 0xaa, 0x6d, 0xdf, 0x87, 0xa5, + 0xb3, 0x51, 0x42, 0x8b, 0x3c, 0x08, 0x6a, 0x72, 0x94, 0xe8, 0x1c, 0xea, 0xdb, 0xdf, 0x87, 0xff, + 0x6e, 0x19, 0xbe, 0x3b, 0xa8, 0x2e, 0xc0, 0xdc, 0x9b, 0x41, 0x22, 0x47, 0xbb, 0x5f, 0x6b, 0x50, + 0x3f, 0x9e, 0xec, 0x60, 0x14, 0x40, 0x2d, 0x2f, 0x89, 0x56, 0xcc, 0x8d, 0x50, 0x51, 0xde, 0x86, + 0x39, 0x98, 0xe2, 0xf4, 0x16, 0xc0, 0x74, 0x8c, 0xfe, 0x35, 0x51, 0xa5, 0x35, 0xe7, 0x6d, 0xde, + 0xec, 0x9c, 0x24, 0x7a, 0x01, 0x8d, 0x62, 0x9d, 0x20, 0xcf, 0x84, 0xce, 0xee, 0x18, 0x6f, 0x96, + 0x5a, 0xbe, 0x22, 0xcc, 0x35, 0xb7, 0x29, 0x94, 0x2e, 0x7f, 0x19, 0xdb, 0x87, 0xf5, 0x1b, 0xe5, + 0x43, 0xdb, 0x56, 0x9a, 0xdf, 0x5c, 0x6e, 0xef, 0xe1, 0x9d, 0x71, 0x93, 0xfe, 0x9e, 0x43, 0x2d, + 0x1f, 0x21, 0xb4, 0x6e, 0x00, 0xd6, 0xf3, 0x62, 0xeb, 0x3b, 0x35, 0x69, 0x8f, 0x60, 0xae, 0x1d, + 0x71, 0x71, 0xc3, 0x1f, 0x29, 0xf5, 0xf2, 0x0a, 0xc0, 0x3c, 0x87, 0xb6, 0x0e, 0xa5, 0x47, 0xb2, + 0x84, 0xf5, 0xab, 0xdf, 0x2a, 0xce, 0xd1, 0xe1, 0x87, 0x97, 0x3d, 0x26, 0xfb, 0x59, 0xa7, 0x15, + 0xf2, 0x41, 0xd0, 0x27, 0xa2, 0xcf, 0x42, 0x9e, 0x26, 0xc1, 0x90, 0x64, 0x91, 0x0c, 0xee, 0x7c, + 0xc9, 0x3b, 0xf3, 0x6a, 0x1f, 0xef, 0xfd, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x49, 0x0b, 0x5b, + 0xf5, 0x07, 0x00, 0x00, +} + // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn @@ -982,57 +1032,3 @@ var _Database_serviceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "builtin/logical/database/dbplugin/database.proto", } - -func init() { - proto.RegisterFile("builtin/logical/database/dbplugin/database.proto", fileDescriptor_7bf7b4c7fef2f66e) -} - -var fileDescriptor_7bf7b4c7fef2f66e = []byte{ - // 724 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xd1, 0x4e, 0xdb, 0x4a, - 0x10, 0x95, 0x93, 0x00, 0xc9, 0x80, 0x80, 0xec, 0x05, 0x64, 0xf9, 0x72, 0x6f, 0x91, 0x1f, 0x28, - 0x55, 0xd5, 0xb8, 0x82, 0x56, 0x54, 0xa8, 0xa2, 0x2a, 0xa1, 0xaa, 0x2a, 0x55, 0x3c, 0x2c, 0xf0, - 0x52, 0x55, 0x42, 0x1b, 0x67, 0x49, 0x56, 0x38, 0x5e, 0xd7, 0xbb, 0x0e, 0x4d, 0x7f, 0xa0, 0xfd, - 0x8c, 0x7e, 0x4e, 0x1f, 0xfb, 0x49, 0x95, 0x37, 0x59, 0xef, 0x26, 0x86, 0xf2, 0x40, 0xfb, 0xe6, - 0xd9, 0x99, 0x33, 0x73, 0xe6, 0x78, 0x76, 0x16, 0x9e, 0x76, 0x32, 0x16, 0x49, 0x16, 0x07, 0x11, - 0xef, 0xb1, 0x90, 0x44, 0x41, 0x97, 0x48, 0xd2, 0x21, 0x82, 0x06, 0xdd, 0x4e, 0x12, 0x65, 0x3d, - 0x16, 0x17, 0x27, 0xad, 0x24, 0xe5, 0x92, 0xa3, 0xba, 0x76, 0x78, 0x0f, 0x7a, 0x9c, 0xf7, 0x22, - 0x1a, 0xa8, 0xf3, 0x4e, 0x76, 0x19, 0x48, 0x36, 0xa0, 0x42, 0x92, 0x41, 0x32, 0x0e, 0xf5, 0x3f, - 0x42, 0xf3, 0x5d, 0xcc, 0x24, 0x23, 0x11, 0xfb, 0x42, 0x31, 0xfd, 0x94, 0x51, 0x21, 0xd1, 0x06, - 0xcc, 0x87, 0x3c, 0xbe, 0x64, 0x3d, 0xd7, 0xd9, 0x72, 0x76, 0x96, 0xf0, 0xc4, 0x42, 0x8f, 0xa1, - 0x39, 0xa4, 0x29, 0xbb, 0x1c, 0x5d, 0x84, 0x3c, 0x8e, 0x69, 0x28, 0x19, 0x8f, 0xdd, 0xca, 0x96, - 0xb3, 0x53, 0xc7, 0xab, 0x63, 0x47, 0xbb, 0x38, 0x3f, 0xa8, 0xb8, 0x8e, 0x8f, 0x61, 0x31, 0xcf, - 0xfe, 0x27, 0xf3, 0xfa, 0x3f, 0x1c, 0x68, 0xb6, 0x53, 0x4a, 0x24, 0x3d, 0x17, 0x34, 0xd5, 0xa9, - 0x9f, 0x01, 0x08, 0x49, 0x24, 0x1d, 0xd0, 0x58, 0x0a, 0x95, 0x7e, 0x71, 0x77, 0xad, 0xa5, 0x75, - 0x68, 0x9d, 0x16, 0x3e, 0x6c, 0xc5, 0xa1, 0xd7, 0xb0, 0x92, 0x09, 0x9a, 0xc6, 0x64, 0x40, 0x2f, - 0x26, 0xcc, 0x2a, 0x0a, 0xea, 0x1a, 0xe8, 0xf9, 0x24, 0xa0, 0xad, 0xfc, 0x78, 0x39, 0x9b, 0xb2, - 0xd1, 0x01, 0x00, 0xfd, 0x9c, 0xb0, 0x94, 0x28, 0xd2, 0x55, 0x85, 0xf6, 0x5a, 0x63, 0xd9, 0x5b, - 0x5a, 0xf6, 0xd6, 0x99, 0x96, 0x1d, 0x5b, 0xd1, 0xfe, 0x77, 0x07, 0x56, 0x31, 0x8d, 0xe9, 0xf5, - 0xfd, 0x3b, 0xf1, 0xa0, 0xae, 0x89, 0xa9, 0x16, 0x1a, 0xb8, 0xb0, 0xef, 0x45, 0x91, 0x42, 0x13, - 0xd3, 0x21, 0xbf, 0xa2, 0x7f, 0x95, 0xa2, 0x7f, 0x08, 0x9b, 0x98, 0xe7, 0xa1, 0x98, 0x73, 0xd9, - 0x4e, 0x69, 0x97, 0xc6, 0xf9, 0x4c, 0x0a, 0x5d, 0xf1, 0xff, 0x99, 0x8a, 0xd5, 0x9d, 0x86, 0x9d, - 0xdb, 0xff, 0x59, 0x01, 0x30, 0x65, 0xd1, 0x1e, 0xfc, 0x13, 0xe6, 0x23, 0xc2, 0x78, 0x7c, 0x31, - 0xc3, 0xb4, 0x71, 0x54, 0x71, 0x1d, 0x8c, 0xb4, 0xdb, 0x02, 0xed, 0xc3, 0x7a, 0x4a, 0x87, 0x3c, - 0x2c, 0xc1, 0x2a, 0x05, 0x6c, 0xcd, 0x04, 0x4c, 0x57, 0x4b, 0x79, 0x14, 0x75, 0x48, 0x78, 0x65, - 0xc3, 0xaa, 0xa6, 0x9a, 0x76, 0x5b, 0xa0, 0x27, 0xb0, 0x9a, 0xe6, 0xbf, 0xde, 0x46, 0xd4, 0x0a, - 0xc4, 0x8a, 0xf2, 0x9d, 0x4e, 0x89, 0xa7, 0x29, 0xbb, 0x73, 0xaa, 0xfd, 0xc2, 0xce, 0xc5, 0x31, - 0xbc, 0xdc, 0xf9, 0xb1, 0x38, 0xe6, 0x24, 0xc7, 0x6a, 0x02, 0xee, 0xc2, 0x18, 0xab, 0x6d, 0xe4, - 0xc2, 0x82, 0x2a, 0x45, 0x22, 0xb7, 0xae, 0x5c, 0xda, 0xf4, 0x4f, 0x60, 0x79, 0x7a, 0xf4, 0xd1, - 0x16, 0x2c, 0x1e, 0x33, 0x91, 0x44, 0x64, 0x74, 0x92, 0xff, 0x43, 0xa5, 0x26, 0xb6, 0x8f, 0xf2, - 0x4a, 0x98, 0x47, 0xf4, 0xc4, 0xfa, 0xc5, 0xda, 0xf6, 0xb7, 0x61, 0x69, 0xbc, 0x0b, 0x44, 0xc2, - 0x63, 0x41, 0x6f, 0x5b, 0x06, 0xfe, 0x7b, 0x40, 0xf6, 0xf5, 0x9e, 0x44, 0xdb, 0xc3, 0xe3, 0xcc, - 0xcc, 0xb7, 0x07, 0xf5, 0x84, 0x08, 0x71, 0xcd, 0xd3, 0xae, 0xae, 0xaa, 0x6d, 0xdf, 0x87, 0xa5, - 0xb3, 0x51, 0x42, 0x8b, 0x3c, 0x08, 0x6a, 0x72, 0x94, 0xe8, 0x1c, 0xea, 0xdb, 0xdf, 0x87, 0xff, - 0x6e, 0x19, 0xbe, 0x3b, 0xa8, 0x2e, 0xc0, 0xdc, 0x9b, 0x41, 0x22, 0x47, 0xbb, 0x5f, 0x6b, 0x50, - 0x3f, 0x9e, 0xec, 0x60, 0x14, 0x40, 0x2d, 0x2f, 0x89, 0x56, 0xcc, 0x8d, 0x50, 0x51, 0xde, 0x86, - 0x39, 0x98, 0xe2, 0xf4, 0x16, 0xc0, 0x74, 0x8c, 0xfe, 0x35, 0x51, 0xa5, 0x35, 0xe7, 0x6d, 0xde, - 0xec, 0x9c, 0x24, 0x7a, 0x01, 0x8d, 0x62, 0x9d, 0x20, 0xcf, 0x84, 0xce, 0xee, 0x18, 0x6f, 0x96, - 0x5a, 0xbe, 0x22, 0xcc, 0x35, 0xb7, 0x29, 0x94, 0x2e, 0x7f, 0x19, 0xdb, 0x87, 0xf5, 0x1b, 0xe5, - 0x43, 0xdb, 0x56, 0x9a, 0xdf, 0x5c, 0x6e, 0xef, 0xe1, 0x9d, 0x71, 0x93, 0xfe, 0x9e, 0x43, 0x2d, - 0x1f, 0x21, 0xb4, 0x6e, 0x00, 0xd6, 0xf3, 0x62, 0xeb, 0x3b, 0x35, 0x69, 0x8f, 0x60, 0xae, 0x1d, - 0x71, 0x71, 0xc3, 0x1f, 0x29, 0xf5, 0xf2, 0x0a, 0xc0, 0x3c, 0x87, 0xb6, 0x0e, 0xa5, 0x47, 0xb2, - 0x84, 0xf5, 0xab, 0xdf, 0x2a, 0xce, 0xd1, 0xe1, 0x87, 0x97, 0x3d, 0x26, 0xfb, 0x59, 0xa7, 0x15, - 0xf2, 0x41, 0xd0, 0x27, 0xa2, 0xcf, 0x42, 0x9e, 0x26, 0xc1, 0x90, 0x64, 0x91, 0x0c, 0xee, 0x7c, - 0xc9, 0x3b, 0xf3, 0x6a, 0x1f, 0xef, 0xfd, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x49, 0x0b, 0x5b, - 0xf5, 0x07, 0x00, 0x00, -} diff --git a/helper/forwarding/types.pb.go b/helper/forwarding/types.pb.go index 44342b209..e7b104c6a 100644 --- a/helper/forwarding/types.pb.go +++ b/helper/forwarding/types.pb.go @@ -5,9 +5,8 @@ package forwarding import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/helper/identity/mfa/types.pb.go b/helper/identity/mfa/types.pb.go index 9fcc7ab7f..5c1855e7f 100644 --- a/helper/identity/mfa/types.pb.go +++ b/helper/identity/mfa/types.pb.go @@ -6,9 +6,8 @@ package mfa import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/helper/identity/types.pb.go b/helper/identity/types.pb.go index 8b417e8d4..28263c896 100644 --- a/helper/identity/types.pb.go +++ b/helper/identity/types.pb.go @@ -5,11 +5,10 @@ package identity import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" timestamp "github.com/golang/protobuf/ptypes/timestamp" mfa "github.com/hashicorp/vault/helper/identity/mfa" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/helper/ldaputil/config.go b/helper/ldaputil/config.go index 9da1ffd71..d253ea4c7 100644 --- a/helper/ldaputil/config.go +++ b/helper/ldaputil/config.go @@ -9,6 +9,7 @@ import ( "text/template" "github.com/hashicorp/vault/helper/tlsutil" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical/framework" "github.com/hashicorp/errwrap" @@ -16,8 +17,8 @@ import ( // ConfigFields returns all the config fields that can potentially be used by the LDAP client. // Not all fields will be used by every integration. -func ConfigFields() map[string]*framework.FieldSchema { - return map[string]*framework.FieldSchema{ +func ConfigFields(tokenFields bool) map[string]*framework.FieldSchema { + ret := map[string]*framework.FieldSchema{ "url": { Type: framework.TypeString, Default: "ldap://127.0.0.1", @@ -122,6 +123,12 @@ Default: cn`, Description: "If true, use the Active Directory tokenGroups constructed attribute of the user to find the group memberships. This will find all security groups including nested ones.", }, } + + if tokenFields { + tokenhelper.AddTokenFields(ret) + } + + return ret } /* @@ -246,6 +253,8 @@ func NewConfigEntry(d *framework.FieldData) (*ConfigEntry, error) { } type ConfigEntry struct { + tokenhelper.TokenParams + Url string `json:"url"` UserDN string `json:"userdn"` GroupDN string `json:"groupdn"` diff --git a/helper/storagepacker/types.pb.go b/helper/storagepacker/types.pb.go index 9887c72b8..6319feef6 100644 --- a/helper/storagepacker/types.pb.go +++ b/helper/storagepacker/types.pb.go @@ -5,10 +5,9 @@ package storagepacker import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" any "github.com/golang/protobuf/ptypes/any" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/helper/strutil/strutil.go b/helper/strutil/strutil.go index 2304ebd9d..f741b6fab 100644 --- a/helper/strutil/strutil.go +++ b/helper/strutil/strutil.go @@ -14,6 +14,9 @@ import ( // StrListContainsGlob looks for a string in a list of strings and allows // globs. func StrListContainsGlob(haystack []string, needle string) bool { + if len(haystack) == 0 { + return false + } for _, item := range haystack { if glob.Glob(item, needle) { return true @@ -24,6 +27,9 @@ func StrListContainsGlob(haystack []string, needle string) bool { // StrListContains looks for a string in a list of strings. func StrListContains(haystack []string, needle string) bool { + if len(haystack) == 0 { + return false + } for _, item := range haystack { if item == needle { return true diff --git a/helper/tokenhelper/tokenhelper.go b/helper/tokenhelper/tokenhelper.go new file mode 100644 index 000000000..5e8a24aac --- /dev/null +++ b/helper/tokenhelper/tokenhelper.go @@ -0,0 +1,210 @@ +package tokenhelper + +import ( + "errors" + "fmt" + "time" + + sockaddr "github.com/hashicorp/go-sockaddr" + "github.com/hashicorp/vault/helper/parseutil" + "github.com/hashicorp/vault/helper/strutil" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/framework" +) + +type TokenParams struct { + // The set of CIDRs that tokens generated using this role will be bound to + BoundCIDRs []*sockaddr.SockAddrMarshaler `json:"bound_cidrs"` + + // If set, the token entry will have an explicit maximum TTL set, rather + // than deferring to role/mount values + ExplicitMaxTTL time.Duration `json:"explicit_max_ttl" mapstructure:"explicit_max_ttl"` + + // The max TTL to use for the token + MaxTTL time.Duration `json:"max_ttl" mapstructure:"max_ttl"` + + // If set, core will not automatically add default to the policy list + NoDefaultPolicy bool `json:"no_default_policy" mapstructure:"no_default_policy"` + + // If non-zero, tokens created using this role will be able to be renewed + // forever, but will have a fixed renewal period of this value + Period time.Duration `json:"period" mapstructure:"period"` + + // The policies to set + Policies []string `json:"policies" mapstructure:"policies"` + + // The type of token this role should issue + TokenType logical.TokenType `json:"token_type" mapstructure:"token_type"` + + // The TTL to user for the token + TTL time.Duration `json:"ttl" mapstructure:"ttl"` +} + +// AddTokenFields adds fields to an existing role. It panics if it would +// overwrite an existing field. +func AddTokenFields(m map[string]*framework.FieldSchema) { + AddTokenFieldsWithAllowList(m, nil) +} + +func AddTokenFieldsWithAllowList(m map[string]*framework.FieldSchema, allowed []string) { + r := TokenFields() + for k, v := range r { + if len(allowed) > 0 && !strutil.StrListContains(allowed, k) { + continue + } + if _, has := m[k]; has { + panic(fmt.Sprintf("adding role field %s would overwrite existing field", k)) + } + m[k] = v + } +} + +func TokenFields() map[string]*framework.FieldSchema { + return map[string]*framework.FieldSchema{ + "bound_cidrs": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `Comma separated string or JSON list of CIDR blocks. If set, specifies the blocks of IP addresses which are allowed to use the generated token.`, + }, + + "explicit_max_ttl": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: tokenExplicitMaxTTLHelp, + }, + + "max_ttl": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: "The maximum lifetime of the generated token", + }, + + "no_default_policy": &framework.FieldSchema{ + Type: framework.TypeBool, + Description: "If true, the 'default' policy will not automatically be added to generated tokens", + }, + + "period": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: tokenPeriodHelp, + }, + + "policies": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: "Comma-separated list of policies", + }, + + "token_type": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "The type of token to generate, service or batch", + }, + + "ttl": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: "The initial ttl of the token to generate", + }, + } +} + +func (t *TokenParams) ParseTokenFields(req *logical.Request, d *framework.FieldData) error { + if boundCIDRsRaw, ok := d.GetOk("bound_cidrs"); ok { + boundCIDRs, err := parseutil.ParseAddrs(boundCIDRsRaw.([]string)) + if err != nil { + return err + } + t.BoundCIDRs = boundCIDRs + } + + if explicitMaxTTLRaw, ok := d.GetOk("explicit_max_ttl"); ok { + t.ExplicitMaxTTL = time.Duration(explicitMaxTTLRaw.(int)) * time.Second + } + + if maxTTLRaw, ok := d.GetOk("max_ttl"); ok { + t.MaxTTL = time.Duration(maxTTLRaw.(int)) * time.Second + } else if maxTTLRaw, ok := d.GetOk("lease_max"); ok { + t.MaxTTL = time.Duration(maxTTLRaw.(int)) * time.Second + } + if t.MaxTTL < 0 { + return errors.New("'max_ttl' cannot be negative") + } + + if noDefaultRaw, ok := d.GetOk("no_default_policy"); ok { + t.NoDefaultPolicy = noDefaultRaw.(bool) + } + + if periodRaw, ok := d.GetOk("period"); ok { + t.Period = time.Duration(periodRaw.(int)) * time.Second + } + if t.Period < 0 { + return errors.New("'period' cannot be negative") + } + + if policiesRaw, ok := d.GetOk("policies"); ok { + t.Policies = policiesRaw.([]string) + } + + if tokenTypeRaw, ok := d.GetOk("token_type"); ok { + var tokenType logical.TokenType + tokenTypeStr := tokenTypeRaw.(string) + switch tokenTypeStr { + case "service": + tokenType = logical.TokenTypeService + case "batch": + tokenType = logical.TokenTypeBatch + case "default-service": + tokenType = logical.TokenTypeDefaultService + case "default-batch": + tokenType = logical.TokenTypeDefaultBatch + default: + return fmt.Errorf("invalid 'token_type' value %q", tokenTypeStr) + } + t.TokenType = tokenType + } + + if ttlRaw, ok := d.GetOk("ttl"); ok { + t.TTL = time.Duration(ttlRaw.(int)) * time.Second + } else if ttlRaw, ok := d.GetOk("lease"); ok { + t.TTL = time.Duration(ttlRaw.(int)) * time.Second + } + if t.TTL < 0 { + return errors.New("'ttl' cannot be negative") + } + if t.TTL > 0 && t.MaxTTL > 0 && t.TTL > t.MaxTTL { + return errors.New("'ttl' cannot be greater than 'max_ttl'") + } + + return nil +} + +func (t *TokenParams) PopulateTokenData(m map[string]interface{}) { + m["bound_cidrs"] = t.BoundCIDRs + m["explicit_max_ttl"] = t.ExplicitMaxTTL.Seconds() + m["max_ttl"] = t.MaxTTL.Seconds() + m["no_default_policy"] = t.NoDefaultPolicy + m["period"] = t.Period.Seconds() + m["policies"] = t.Policies + m["token_type"] = t.TokenType.String() + m["ttl"] = t.TTL.Seconds() +} + +func (t *TokenParams) PopulateTokenAuth(auth *logical.Auth) { + auth.BoundCIDRs = t.BoundCIDRs + auth.ExplicitMaxTTL = t.ExplicitMaxTTL + auth.MaxTTL = t.MaxTTL + auth.NoDefaultPolicy = t.NoDefaultPolicy + auth.Period = t.Period + auth.Policies = t.Policies + auth.TokenType = t.TokenType + auth.TTL = t.TTL +} + +const ( + tokenPeriodHelp = `If set, tokens created via this role +will have no max lifetime; instead, their +renewal period will be fixed to this value. +This takes an integer number of seconds, +or a string duration (e.g. "24h").` + tokenExplicitMaxTTLHelp = `If set, tokens created via this role +carry an explicit maximum TTL. During renewal, +the current maximum TTL values of the role +and the mount are not checked for changes, +and any updates to these values will have +no effect on the token being renewed.` +) diff --git a/logical/auth.go b/logical/auth.go index e458ed868..a6f6b11ae 100644 --- a/logical/auth.go +++ b/logical/auth.go @@ -38,6 +38,11 @@ type Auth struct { // different namespaces indexed by respective namespace identifiers ExternalNamespacePolicies map[string][]string `json:"external_namespace_policies" mapstructure:"external_namespace_policies" structs:"external_namespace_policies"` + // Indicates that the default policy should not be added by core when + // creating a token. The default policy will still be added if it's + // explicitly defined. + NoDefaultPolicy bool `json:"no_default_policy" mapstructure:"no_default_policy" structs:"no_default_policy"` + // Metadata is used to attach arbitrary string-type metadata to // an authenticated user. This metadata will be outputted into the // audit log. diff --git a/logical/identity.pb.go b/logical/identity.pb.go index 5b3342d48..cd1965221 100644 --- a/logical/identity.pb.go +++ b/logical/identity.pb.go @@ -5,9 +5,8 @@ package logical import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/logical/plugin.pb.go b/logical/plugin.pb.go index e8a4f096e..b66bea544 100644 --- a/logical/plugin.pb.go +++ b/logical/plugin.pb.go @@ -5,9 +5,8 @@ package logical import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/logical/plugin/pb/backend.pb.go b/logical/plugin/pb/backend.pb.go index 55f304024..11510787d 100644 --- a/logical/plugin/pb/backend.pb.go +++ b/logical/plugin/pb/backend.pb.go @@ -5,16 +5,12 @@ package pb import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" timestamp "github.com/golang/protobuf/ptypes/timestamp" logical "github.com/hashicorp/vault/logical" -) - -import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -530,7 +526,9 @@ type Auth struct { // TTL is a hard limit and cannot be exceeded, also counts for periodic tokens. ExplicitMaxTTL int64 `sentinel:"" protobuf:"varint,16,opt,name=explicit_max_ttl,json=explicitMaxTtl,proto3" json:"explicit_max_ttl,omitempty"` // TokenType is the type of token being requested - TokenType uint32 `sentinel:"" protobuf:"varint,17,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"` + TokenType uint32 `sentinel:"" protobuf:"varint,17,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"` + // Whether the default policy should be added automatically by core + NoDefaultPolicy bool `sentinel:"" protobuf:"varint,18,opt,name=no_default_policy,json=noDefaultPolicy,proto3" json:"no_default_policy,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -680,6 +678,13 @@ func (m *Auth) GetTokenType() uint32 { return 0 } +func (m *Auth) GetNoDefaultPolicy() bool { + if m != nil { + return m.NoDefaultPolicy + } + return false +} + type TokenEntry struct { ID string `sentinel:"" protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Accessor string `sentinel:"" protobuf:"bytes,2,opt,name=accessor,proto3" json:"accessor,omitempty"` @@ -2702,6 +2707,169 @@ func init() { proto.RegisterType((*Connection)(nil), "pb.Connection") } +func init() { proto.RegisterFile("logical/plugin/pb/backend.proto", fileDescriptor_25821d34acc7c5ef) } + +var fileDescriptor_25821d34acc7c5ef = []byte{ + // 2503 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdd, 0x72, 0xdb, 0xc6, + 0x15, 0x1e, 0x92, 0xe2, 0xdf, 0xe1, 0x9f, 0xb8, 0x56, 0x54, 0x98, 0x71, 0x6a, 0x06, 0xa9, 0x6d, + 0xc5, 0xb5, 0x29, 0x5b, 0x69, 0x1a, 0xa7, 0x9d, 0xa4, 0xa3, 0xc8, 0x8a, 0xa3, 0x46, 0x4a, 0x34, + 0x10, 0xdd, 0xf4, 0x6f, 0x06, 0x59, 0x02, 0x2b, 0x0a, 0x23, 0x10, 0x40, 0x17, 0x0b, 0x59, 0xbc, + 0xea, 0x5b, 0xf4, 0x35, 0x7a, 0xdb, 0xbb, 0xde, 0x75, 0x3a, 0xed, 0x75, 0x5f, 0xa1, 0x97, 0x7d, + 0x86, 0xce, 0x9e, 0x5d, 0x80, 0x00, 0x49, 0xc5, 0xce, 0x4c, 0x7b, 0xb7, 0x7b, 0xce, 0xd9, 0xbf, + 0xb3, 0xdf, 0xf9, 0xce, 0x59, 0x00, 0xee, 0xfa, 0xe1, 0xd4, 0x73, 0xa8, 0xbf, 0x1b, 0xf9, 0xc9, + 0xd4, 0x0b, 0x76, 0xa3, 0xc9, 0xee, 0x84, 0x3a, 0x97, 0x2c, 0x70, 0x47, 0x11, 0x0f, 0x45, 0x48, + 0xca, 0xd1, 0x64, 0x70, 0x77, 0x1a, 0x86, 0x53, 0x9f, 0xed, 0xa2, 0x64, 0x92, 0x9c, 0xef, 0x0a, + 0x6f, 0xc6, 0x62, 0x41, 0x67, 0x91, 0x32, 0x1a, 0x6c, 0xa7, 0xb3, 0x78, 0x2e, 0x0b, 0x84, 0x27, + 0xe6, 0x5a, 0xbe, 0x55, 0x9c, 0x5d, 0x49, 0xcd, 0x3a, 0x54, 0x0f, 0x67, 0x91, 0x98, 0x9b, 0x43, + 0xa8, 0x7d, 0xc1, 0xa8, 0xcb, 0x38, 0xd9, 0x86, 0xda, 0x05, 0xb6, 0x8c, 0xd2, 0xb0, 0xb2, 0xd3, + 0xb4, 0x74, 0xcf, 0xfc, 0x1d, 0xc0, 0xa9, 0x1c, 0x73, 0xc8, 0x79, 0xc8, 0xc9, 0x6d, 0x68, 0x30, + 0xce, 0x6d, 0x31, 0x8f, 0x98, 0x51, 0x1a, 0x96, 0x76, 0x3a, 0x56, 0x9d, 0x71, 0x3e, 0x9e, 0x47, + 0x8c, 0xfc, 0x00, 0x64, 0xd3, 0x9e, 0xc5, 0x53, 0xa3, 0x3c, 0x2c, 0xc9, 0x19, 0x18, 0xe7, 0x27, + 0xf1, 0x34, 0x1d, 0xe3, 0x84, 0x2e, 0x33, 0x2a, 0xc3, 0xd2, 0x4e, 0x05, 0xc7, 0x1c, 0x84, 0x2e, + 0x33, 0xff, 0x54, 0x82, 0xea, 0x29, 0x15, 0x17, 0x31, 0x21, 0xb0, 0xc1, 0xc3, 0x50, 0xe8, 0xc5, + 0xb1, 0x4d, 0x76, 0xa0, 0x97, 0x04, 0x34, 0x11, 0x17, 0xf2, 0x44, 0x0e, 0x15, 0xcc, 0x35, 0xca, + 0xa8, 0x5e, 0x16, 0x93, 0xf7, 0xa0, 0xe3, 0x87, 0x0e, 0xf5, 0xed, 0x58, 0x84, 0x9c, 0x4e, 0xe5, + 0x3a, 0xd2, 0xae, 0x8d, 0xc2, 0x33, 0x25, 0x23, 0x0f, 0xa1, 0x1f, 0x33, 0xea, 0xdb, 0xaf, 0x38, + 0x8d, 0x32, 0xc3, 0x0d, 0x35, 0xa1, 0x54, 0x7c, 0xc3, 0x69, 0xa4, 0x6d, 0xcd, 0xbf, 0xd6, 0xa0, + 0x6e, 0xb1, 0x3f, 0x24, 0x2c, 0x16, 0xa4, 0x0b, 0x65, 0xcf, 0xc5, 0xd3, 0x36, 0xad, 0xb2, 0xe7, + 0x92, 0x11, 0x10, 0x8b, 0x45, 0xbe, 0x5c, 0xda, 0x0b, 0x83, 0x03, 0x3f, 0x89, 0x05, 0xe3, 0xfa, + 0xcc, 0x6b, 0x34, 0xe4, 0x0e, 0x34, 0xc3, 0x88, 0x71, 0x94, 0xa1, 0x03, 0x9a, 0xd6, 0x42, 0x20, + 0x0f, 0x1e, 0x51, 0x71, 0x61, 0x6c, 0xa0, 0x02, 0xdb, 0x52, 0xe6, 0x52, 0x41, 0x8d, 0xaa, 0x92, + 0xc9, 0x36, 0x31, 0xa1, 0x16, 0x33, 0x87, 0x33, 0x61, 0xd4, 0x86, 0xa5, 0x9d, 0xd6, 0x1e, 0x8c, + 0xa2, 0xc9, 0xe8, 0x0c, 0x25, 0x96, 0xd6, 0x90, 0x3b, 0xb0, 0x21, 0xfd, 0x62, 0xd4, 0xd1, 0xa2, + 0x21, 0x2d, 0xf6, 0x13, 0x71, 0x61, 0xa1, 0x94, 0xec, 0x41, 0x5d, 0xdd, 0x69, 0x6c, 0x34, 0x86, + 0x95, 0x9d, 0xd6, 0x9e, 0x21, 0x0d, 0xf4, 0x29, 0x47, 0x0a, 0x06, 0xf1, 0x61, 0x20, 0xf8, 0xdc, + 0x4a, 0x0d, 0xc9, 0xbb, 0xd0, 0x76, 0x7c, 0x8f, 0x05, 0xc2, 0x16, 0xe1, 0x25, 0x0b, 0x8c, 0x26, + 0xee, 0xa8, 0xa5, 0x64, 0x63, 0x29, 0x22, 0x7b, 0xf0, 0x56, 0xde, 0xc4, 0xa6, 0x8e, 0xc3, 0xe2, + 0x38, 0xe4, 0x06, 0xa0, 0xed, 0xad, 0x9c, 0xed, 0xbe, 0x56, 0xc9, 0x69, 0x5d, 0x2f, 0x8e, 0x7c, + 0x3a, 0xb7, 0x03, 0x3a, 0x63, 0x46, 0x4b, 0x4d, 0xab, 0x65, 0x5f, 0xd1, 0x19, 0x23, 0x77, 0xa1, + 0x35, 0x0b, 0x93, 0x40, 0xd8, 0x51, 0xe8, 0x05, 0xc2, 0x68, 0xa3, 0x05, 0xa0, 0xe8, 0x54, 0x4a, + 0xc8, 0x3b, 0xa0, 0x7a, 0x0a, 0x8c, 0x1d, 0xe5, 0x57, 0x94, 0x20, 0x1c, 0xef, 0x41, 0x57, 0xa9, + 0xb3, 0xfd, 0x74, 0xd1, 0xa4, 0x83, 0xd2, 0x6c, 0x27, 0x4f, 0xa0, 0x89, 0x78, 0xf0, 0x82, 0xf3, + 0xd0, 0xe8, 0xa1, 0xdf, 0x6e, 0xe5, 0xdc, 0x22, 0x31, 0x71, 0x14, 0x9c, 0x87, 0x56, 0xe3, 0x95, + 0x6e, 0x91, 0x4f, 0xe0, 0xed, 0xc2, 0x79, 0x39, 0x9b, 0x51, 0x2f, 0xf0, 0x82, 0xa9, 0x9d, 0xc4, + 0x2c, 0x36, 0x36, 0x11, 0xe1, 0x46, 0xee, 0xd4, 0x56, 0x6a, 0xf0, 0x32, 0x66, 0x31, 0x79, 0x1b, + 0x9a, 0x2a, 0x40, 0x6d, 0xcf, 0x35, 0xfa, 0xb8, 0xa5, 0x86, 0x12, 0x1c, 0xb9, 0xe4, 0x01, 0xf4, + 0xa2, 0xd0, 0xf7, 0x9c, 0xb9, 0x1d, 0x5e, 0x31, 0xce, 0x3d, 0x97, 0x19, 0x64, 0x58, 0xda, 0x69, + 0x58, 0x5d, 0x25, 0xfe, 0x5a, 0x4b, 0xd7, 0x85, 0xc6, 0x2d, 0x34, 0x5c, 0x09, 0x8d, 0x11, 0x80, + 0x13, 0x06, 0x01, 0x73, 0x10, 0x7e, 0x5b, 0x78, 0xc2, 0xae, 0x3c, 0xe1, 0x41, 0x26, 0xb5, 0x72, + 0x16, 0x83, 0xcf, 0xa1, 0x9d, 0x87, 0x02, 0xd9, 0x84, 0xca, 0x25, 0x9b, 0x6b, 0xf8, 0xcb, 0x26, + 0x19, 0x42, 0xf5, 0x8a, 0xfa, 0x09, 0x43, 0xc8, 0x6b, 0x20, 0xaa, 0x21, 0x96, 0x52, 0xfc, 0xac, + 0xfc, 0xac, 0x64, 0xfe, 0xbb, 0x0a, 0x1b, 0x12, 0x7c, 0xe4, 0x43, 0xe8, 0xf8, 0x8c, 0xc6, 0xcc, + 0x0e, 0x23, 0xb9, 0x40, 0x8c, 0x53, 0xb5, 0xf6, 0x36, 0xe5, 0xb0, 0x63, 0xa9, 0xf8, 0x5a, 0xc9, + 0xad, 0xb6, 0x9f, 0xeb, 0xc9, 0x90, 0xf6, 0x02, 0xc1, 0x78, 0x40, 0x7d, 0x1b, 0x83, 0x41, 0x05, + 0x58, 0x3b, 0x15, 0x3e, 0x97, 0x41, 0xb1, 0x8c, 0xa3, 0xca, 0x2a, 0x8e, 0x06, 0xd0, 0x40, 0xdf, + 0x79, 0x2c, 0xd6, 0xc1, 0x9e, 0xf5, 0xc9, 0x1e, 0x34, 0x66, 0x4c, 0x50, 0x1d, 0x6b, 0x32, 0x24, + 0xb6, 0xd3, 0x98, 0x19, 0x9d, 0x68, 0x85, 0x0a, 0x88, 0xcc, 0x6e, 0x25, 0x22, 0x6a, 0xab, 0x11, + 0x31, 0x80, 0x46, 0x06, 0xba, 0xba, 0xba, 0xe1, 0xb4, 0x2f, 0x69, 0x36, 0x62, 0xdc, 0x0b, 0x5d, + 0xa3, 0x81, 0x40, 0xd1, 0x3d, 0x49, 0x92, 0x41, 0x32, 0x53, 0x10, 0x6a, 0x2a, 0x92, 0x0c, 0x92, + 0xd9, 0x2a, 0x62, 0x60, 0x09, 0x31, 0x3f, 0x82, 0x2a, 0xf5, 0x3d, 0x1a, 0x63, 0x08, 0xc9, 0x9b, + 0xd5, 0x7c, 0x3f, 0xda, 0x97, 0x52, 0x4b, 0x29, 0xc9, 0x07, 0xd0, 0x99, 0xf2, 0x30, 0x89, 0x6c, + 0xec, 0xb2, 0xd8, 0x68, 0xe3, 0x69, 0x97, 0xad, 0xdb, 0x68, 0xb4, 0xaf, 0x6c, 0x64, 0x04, 0x4e, + 0xc2, 0x24, 0x70, 0x6d, 0xc7, 0x73, 0x79, 0x6c, 0x74, 0xd0, 0x79, 0x80, 0xa2, 0x03, 0x29, 0x91, + 0x21, 0xa6, 0x42, 0x20, 0x73, 0x70, 0x17, 0x6d, 0x3a, 0x28, 0x3d, 0x4d, 0xbd, 0xfc, 0x63, 0xe8, + 0xa7, 0x49, 0x69, 0x61, 0xd9, 0x43, 0xcb, 0xcd, 0x54, 0x91, 0x19, 0xef, 0xc0, 0x26, 0xbb, 0x96, + 0x14, 0xea, 0x09, 0x7b, 0x46, 0xaf, 0x6d, 0x21, 0x7c, 0x1d, 0x52, 0xdd, 0x54, 0x7e, 0x42, 0xaf, + 0xc7, 0xc2, 0x97, 0xf1, 0xaf, 0x56, 0xc7, 0xf8, 0xef, 0x63, 0x32, 0x6a, 0xa2, 0x04, 0xe3, 0xff, + 0x21, 0xf4, 0x83, 0xd0, 0x76, 0xd9, 0x39, 0x4d, 0x7c, 0xa1, 0xd6, 0x9d, 0xeb, 0x60, 0xea, 0x05, + 0xe1, 0x73, 0x25, 0xc7, 0x65, 0xe7, 0x83, 0x9f, 0x43, 0xa7, 0x70, 0xdd, 0x6b, 0x40, 0xbf, 0x95, + 0x07, 0x7d, 0x33, 0x0f, 0xf4, 0x7f, 0x6c, 0x00, 0xe0, 0xbd, 0xab, 0xa1, 0xcb, 0xd9, 0x22, 0x0f, + 0x86, 0xf2, 0x1a, 0x30, 0x50, 0xce, 0x02, 0xa1, 0x81, 0xab, 0x7b, 0xdf, 0x89, 0xd9, 0x34, 0x5f, + 0x54, 0x73, 0xf9, 0xe2, 0x11, 0x6c, 0x48, 0x7c, 0x1a, 0xb5, 0x05, 0xad, 0x2f, 0x76, 0x84, 0x48, + 0x56, 0x28, 0x46, 0xab, 0x95, 0xa0, 0xa9, 0xaf, 0x06, 0x4d, 0x1e, 0x8d, 0x8d, 0x22, 0x1a, 0xdf, + 0x83, 0x8e, 0xc3, 0x19, 0xe6, 0x2e, 0x5b, 0x16, 0x21, 0x1a, 0xad, 0xed, 0x54, 0x38, 0xf6, 0x66, + 0x4c, 0xfa, 0x4f, 0x5e, 0x1c, 0xa0, 0x4a, 0x36, 0xd7, 0xde, 0x6b, 0x6b, 0xed, 0xbd, 0x62, 0x25, + 0xe0, 0x33, 0xcd, 0xf8, 0xd8, 0xce, 0x45, 0x4d, 0xa7, 0x10, 0x35, 0x85, 0xd0, 0xe8, 0x2e, 0x85, + 0xc6, 0x12, 0x7e, 0x7b, 0x2b, 0xf8, 0x7d, 0x17, 0xda, 0xd2, 0x01, 0x71, 0x44, 0x1d, 0x26, 0x27, + 0xd8, 0x54, 0x8e, 0xc8, 0x64, 0x47, 0x2e, 0x46, 0x7b, 0x32, 0x99, 0xcc, 0x2f, 0x42, 0x9f, 0x2d, + 0x08, 0xbb, 0x95, 0xc9, 0x8e, 0x5c, 0xb9, 0x5f, 0x44, 0x20, 0x41, 0x04, 0x62, 0x7b, 0xf0, 0x11, + 0x34, 0x33, 0xaf, 0x7f, 0x2f, 0x30, 0xfd, 0xb9, 0x04, 0xed, 0x3c, 0x29, 0xca, 0xc1, 0xe3, 0xf1, + 0x31, 0x0e, 0xae, 0x58, 0xb2, 0x29, 0xcb, 0x09, 0xce, 0x02, 0xf6, 0x8a, 0x4e, 0x7c, 0x35, 0x41, + 0xc3, 0x5a, 0x08, 0xa4, 0xd6, 0x0b, 0x1c, 0xce, 0x66, 0x29, 0xaa, 0x2a, 0xd6, 0x42, 0x40, 0x3e, + 0x06, 0xf0, 0xe2, 0x38, 0x61, 0xea, 0xe6, 0x36, 0x90, 0x32, 0x06, 0x23, 0x55, 0x5b, 0x8e, 0xd2, + 0xda, 0x72, 0x34, 0x4e, 0x6b, 0x4b, 0xab, 0x89, 0xd6, 0x78, 0xa5, 0xdb, 0x50, 0x93, 0x17, 0x34, + 0x3e, 0x46, 0xe4, 0x55, 0x2c, 0xdd, 0x33, 0xff, 0x08, 0x35, 0x55, 0x85, 0xfc, 0x5f, 0x89, 0xfe, + 0x36, 0x34, 0xd4, 0xdc, 0x9e, 0xab, 0x63, 0xa5, 0x8e, 0xfd, 0x23, 0xd7, 0xfc, 0x67, 0x09, 0x1a, + 0x16, 0x8b, 0xa3, 0x30, 0x88, 0x59, 0xae, 0x4a, 0x2a, 0xbd, 0xb6, 0x4a, 0x2a, 0xaf, 0xad, 0x92, + 0xd2, 0xda, 0xab, 0x92, 0xab, 0xbd, 0x06, 0xd0, 0xe0, 0xcc, 0xf5, 0x38, 0x73, 0x84, 0xae, 0xd3, + 0xb2, 0xbe, 0xd4, 0xbd, 0xa2, 0x5c, 0xa6, 0xf7, 0x18, 0x73, 0x48, 0xd3, 0xca, 0xfa, 0xe4, 0x69, + 0xbe, 0xb8, 0x50, 0x65, 0xdb, 0x96, 0x2a, 0x2e, 0xd4, 0x76, 0x57, 0xab, 0x0b, 0xf3, 0xef, 0x65, + 0xd8, 0x5c, 0x56, 0xaf, 0x01, 0xc1, 0x16, 0x54, 0x55, 0xfa, 0xd1, 0x08, 0x12, 0x2b, 0x89, 0xa7, + 0xb2, 0xc4, 0x35, 0xbf, 0x58, 0x8e, 0xdb, 0xd7, 0xdf, 0x7e, 0x31, 0xa6, 0xdf, 0x87, 0x4d, 0xb9, + 0xcb, 0x88, 0xb9, 0x8b, 0x92, 0x4a, 0x91, 0x50, 0x4f, 0xcb, 0xb3, 0xa2, 0xea, 0x21, 0xf4, 0x53, + 0xd3, 0x45, 0x78, 0xd6, 0x0a, 0xb6, 0x87, 0x69, 0x94, 0x6e, 0x43, 0xed, 0x3c, 0xe4, 0x33, 0x2a, + 0x34, 0x0f, 0xe9, 0x5e, 0x81, 0x67, 0x90, 0xf0, 0x1a, 0x0a, 0x16, 0xa9, 0x50, 0x3e, 0x1b, 0x64, + 0xfc, 0x67, 0x25, 0x3d, 0x12, 0x51, 0xc3, 0x6a, 0xa4, 0xa5, 0xbc, 0xf9, 0x6b, 0xe8, 0x2d, 0x55, + 0x71, 0x6b, 0x1c, 0xb9, 0x58, 0xbe, 0x5c, 0x58, 0xbe, 0x30, 0x73, 0x65, 0x69, 0xe6, 0xdf, 0x40, + 0xff, 0x0b, 0x1a, 0xb8, 0x3e, 0xd3, 0xf3, 0xef, 0xf3, 0x69, 0x2c, 0xf3, 0x91, 0x7e, 0x54, 0xd8, + 0x3a, 0x01, 0x74, 0xac, 0xa6, 0x96, 0x1c, 0xb9, 0xe4, 0x1e, 0xd4, 0xb9, 0xb2, 0xd6, 0xc0, 0x6b, + 0xe5, 0xca, 0x4c, 0x2b, 0xd5, 0x99, 0xdf, 0x02, 0x29, 0x4c, 0x2d, 0xdf, 0x13, 0x73, 0xb2, 0x23, + 0x01, 0xa8, 0x40, 0xa1, 0x81, 0xdd, 0xce, 0xe3, 0xc8, 0xca, 0xb4, 0x64, 0x08, 0x15, 0xc6, 0xb9, + 0x5e, 0x02, 0xeb, 0xbc, 0xc5, 0xeb, 0xcd, 0x92, 0x2a, 0xf3, 0x27, 0xd0, 0x3f, 0x8b, 0x98, 0xe3, + 0x51, 0x1f, 0x5f, 0x5e, 0x6a, 0x81, 0xbb, 0x50, 0x95, 0x4e, 0x4e, 0x63, 0xb6, 0x89, 0x03, 0x51, + 0xad, 0xe4, 0xe6, 0xb7, 0x60, 0xa8, 0x7d, 0x1d, 0x5e, 0x7b, 0xb1, 0x60, 0x81, 0xc3, 0x0e, 0x2e, + 0x98, 0x73, 0xf9, 0x3f, 0x3c, 0xf9, 0x15, 0xdc, 0x5e, 0xb7, 0x42, 0xba, 0xbf, 0x96, 0x23, 0x7b, + 0xf6, 0xb9, 0xa4, 0x6f, 0x5c, 0xa3, 0x61, 0x01, 0x8a, 0x3e, 0x97, 0x12, 0x79, 0x8f, 0x4c, 0x8e, + 0x8b, 0x35, 0x25, 0xea, 0x5e, 0xea, 0x8f, 0xca, 0xcd, 0xfe, 0xf8, 0x4b, 0x09, 0x9a, 0x67, 0x4c, + 0x24, 0x11, 0x9e, 0xe5, 0x6d, 0x68, 0x4e, 0x78, 0x78, 0xc9, 0xf8, 0xe2, 0x28, 0x0d, 0x25, 0x38, + 0x72, 0xc9, 0x53, 0xa8, 0x1d, 0x84, 0xc1, 0xb9, 0x37, 0xc5, 0x77, 0x68, 0x6b, 0xef, 0xb6, 0x62, + 0x17, 0x3d, 0x76, 0xa4, 0x74, 0x2a, 0xd5, 0x6a, 0x43, 0x32, 0x84, 0x96, 0x7e, 0xcd, 0xbf, 0x7c, + 0x79, 0xf4, 0x3c, 0x2d, 0x50, 0x73, 0xa2, 0xc1, 0xc7, 0xd0, 0xca, 0x0d, 0xfc, 0x5e, 0xd9, 0xe2, + 0x87, 0x00, 0xb8, 0xba, 0xf2, 0xd1, 0xa6, 0x3a, 0xaa, 0x1e, 0x29, 0x8f, 0x76, 0x17, 0x9a, 0xb2, + 0x16, 0x52, 0xea, 0x34, 0x4f, 0x95, 0x16, 0x79, 0xca, 0xbc, 0x07, 0xfd, 0xa3, 0xe0, 0x8a, 0xfa, + 0x9e, 0x4b, 0x05, 0xfb, 0x92, 0xcd, 0xd1, 0x05, 0x2b, 0x3b, 0x30, 0xcf, 0xa0, 0xad, 0x1f, 0xc6, + 0x6f, 0xb4, 0xc7, 0xb6, 0xde, 0xe3, 0x77, 0x07, 0xd1, 0xfb, 0xd0, 0xd3, 0x93, 0x1e, 0x7b, 0x3a, + 0x84, 0x64, 0x9a, 0xe7, 0xec, 0xdc, 0xbb, 0xd6, 0x53, 0xeb, 0x9e, 0xf9, 0x0c, 0x36, 0x73, 0xa6, + 0xd9, 0x71, 0x2e, 0xd9, 0x3c, 0x4e, 0x3f, 0x18, 0xc8, 0x76, 0xea, 0x81, 0xf2, 0xc2, 0x03, 0x26, + 0x74, 0xf5, 0xc8, 0x17, 0x4c, 0xdc, 0x70, 0xba, 0x2f, 0xb3, 0x8d, 0xbc, 0x60, 0x7a, 0xf2, 0xfb, + 0x50, 0x65, 0xf2, 0xa4, 0xf9, 0x14, 0x96, 0xf7, 0x80, 0xa5, 0xd4, 0x6b, 0x16, 0x7c, 0x96, 0x2d, + 0x78, 0x9a, 0xa8, 0x05, 0xdf, 0x70, 0x2e, 0xf3, 0xbd, 0x6c, 0x1b, 0xa7, 0x89, 0xb8, 0xe9, 0x46, + 0xef, 0x41, 0x5f, 0x1b, 0x3d, 0x67, 0x3e, 0x13, 0xec, 0x86, 0x23, 0xdd, 0x07, 0x52, 0x30, 0xbb, + 0x69, 0xba, 0x3b, 0xd0, 0x18, 0x8f, 0x8f, 0x33, 0x6d, 0x91, 0x1b, 0xcd, 0x4f, 0xa0, 0x7f, 0x96, + 0xb8, 0xe1, 0x29, 0xf7, 0xae, 0x3c, 0x9f, 0x4d, 0xd5, 0x62, 0x69, 0xfd, 0x59, 0xca, 0xd5, 0x9f, + 0x6b, 0xb3, 0x91, 0xb9, 0x03, 0xa4, 0x30, 0x3c, 0xbb, 0xb7, 0x38, 0x71, 0x43, 0x1d, 0xc2, 0xd8, + 0x36, 0x77, 0xa0, 0x3d, 0xa6, 0x32, 0xdf, 0xbb, 0xca, 0xc6, 0x80, 0xba, 0x50, 0x7d, 0x6d, 0x96, + 0x76, 0xcd, 0x3d, 0xd8, 0x3a, 0xa0, 0xce, 0x85, 0x17, 0x4c, 0x9f, 0x7b, 0xb1, 0x2c, 0x78, 0xf4, + 0x88, 0x01, 0x34, 0x5c, 0x2d, 0xd0, 0x43, 0xb2, 0xbe, 0xf9, 0x18, 0xde, 0xca, 0x7d, 0x95, 0x39, + 0x13, 0x34, 0xf5, 0xc7, 0x16, 0x54, 0x63, 0xd9, 0xc3, 0x11, 0x55, 0x4b, 0x75, 0xcc, 0xaf, 0x60, + 0x2b, 0x9f, 0x80, 0x65, 0xf9, 0x91, 0x1e, 0x1c, 0x0b, 0x83, 0x52, 0xae, 0x30, 0xd0, 0x3e, 0x2b, + 0x2f, 0xf2, 0xc9, 0x26, 0x54, 0x7e, 0xf9, 0xcd, 0x58, 0x83, 0x5d, 0x36, 0xcd, 0xdf, 0xcb, 0xe5, + 0x8b, 0xf3, 0xa9, 0xe5, 0x0b, 0xd5, 0x41, 0xe9, 0x4d, 0xaa, 0x83, 0x35, 0x78, 0x7b, 0x0c, 0xfd, + 0x13, 0x3f, 0x74, 0x2e, 0x0f, 0x83, 0x9c, 0x37, 0x0c, 0xa8, 0xb3, 0x20, 0xef, 0x8c, 0xb4, 0x6b, + 0x3e, 0x80, 0xde, 0x71, 0xe8, 0x50, 0xff, 0x24, 0x4c, 0x02, 0x91, 0x79, 0x01, 0x3f, 0x93, 0x69, + 0x53, 0xd5, 0x31, 0x1f, 0x43, 0x57, 0xa7, 0xe8, 0xe0, 0x3c, 0x4c, 0x99, 0x71, 0x91, 0xcc, 0x4b, + 0xc5, 0x5a, 0xdb, 0x3c, 0x86, 0xde, 0xc2, 0x5c, 0xcd, 0xfb, 0x00, 0x6a, 0x4a, 0xad, 0xcf, 0xd6, + 0xcb, 0x1e, 0x9b, 0xca, 0xd2, 0xd2, 0xea, 0x35, 0x87, 0x9a, 0x41, 0xf7, 0x14, 0x3f, 0x57, 0x1e, + 0x06, 0x57, 0x6a, 0xb2, 0x23, 0x20, 0xea, 0x03, 0xa6, 0xcd, 0x82, 0x2b, 0x8f, 0x87, 0x01, 0xd6, + 0xb7, 0x25, 0x5d, 0xc2, 0xa4, 0x13, 0x67, 0x83, 0x52, 0x0b, 0xab, 0x1f, 0x2d, 0x8b, 0xd6, 0xfa, + 0x10, 0x16, 0x1f, 0x43, 0x64, 0xaa, 0xe1, 0x6c, 0x16, 0x0a, 0x66, 0x53, 0xd7, 0x4d, 0xa3, 0x05, + 0x94, 0x68, 0xdf, 0x75, 0xf9, 0xde, 0x7f, 0xca, 0x50, 0xff, 0x4c, 0x11, 0x38, 0xf9, 0x14, 0x3a, + 0x85, 0x74, 0x4d, 0xde, 0xc2, 0xaf, 0x21, 0xcb, 0xc5, 0xc1, 0x60, 0x7b, 0x45, 0xac, 0xce, 0xf5, + 0x04, 0xda, 0xf9, 0x64, 0x4c, 0x30, 0xf1, 0xe2, 0xa7, 0xd9, 0x01, 0xce, 0xb4, 0x9a, 0xa9, 0xcf, + 0x60, 0x6b, 0x5d, 0x9a, 0x24, 0x77, 0x16, 0x2b, 0xac, 0xa6, 0xe8, 0xc1, 0x3b, 0x37, 0x69, 0xd3, + 0xf4, 0x5a, 0x3f, 0xf0, 0x19, 0x0d, 0x92, 0x28, 0xbf, 0x83, 0x45, 0x93, 0x3c, 0x85, 0x4e, 0x21, + 0x51, 0xa8, 0x73, 0xae, 0xe4, 0x8e, 0xfc, 0x90, 0xfb, 0x50, 0xc5, 0xe4, 0x44, 0x3a, 0x85, 0x2c, + 0x39, 0xe8, 0x66, 0x5d, 0xb5, 0xf6, 0x10, 0x36, 0xf0, 0xc1, 0x9e, 0x5b, 0x18, 0x47, 0x64, 0x99, + 0x6b, 0xef, 0x5f, 0x25, 0xa8, 0xa7, 0x1f, 0x71, 0x9f, 0xc2, 0x86, 0xcc, 0x01, 0xe4, 0x56, 0x8e, + 0x46, 0xd3, 0xfc, 0x31, 0xd8, 0x5a, 0x12, 0xaa, 0x05, 0x46, 0x50, 0x79, 0xc1, 0x04, 0x21, 0x39, + 0xa5, 0x4e, 0x06, 0x83, 0x5b, 0x45, 0x59, 0x66, 0x7f, 0x9a, 0x14, 0xed, 0x35, 0x97, 0x17, 0xec, + 0x33, 0x96, 0xfe, 0x08, 0x6a, 0x8a, 0x65, 0x95, 0x53, 0x56, 0xf8, 0x59, 0x5d, 0xfe, 0x2a, 0x1f, + 0xef, 0xfd, 0x6d, 0x03, 0xe0, 0x6c, 0x1e, 0x0b, 0x36, 0xfb, 0x95, 0xc7, 0x5e, 0x91, 0x87, 0xd0, + 0xd3, 0x9f, 0x25, 0xf0, 0xb5, 0x24, 0xd9, 0x24, 0xe7, 0x13, 0x2c, 0xf8, 0x32, 0xb2, 0xbe, 0x0f, + 0xad, 0x13, 0x7a, 0xfd, 0x7a, 0xbb, 0x4f, 0xa1, 0x53, 0xe0, 0x60, 0xbd, 0xc5, 0x65, 0x56, 0xd7, + 0x5b, 0x5c, 0x65, 0xeb, 0xfb, 0x50, 0xd7, 0xcc, 0x9c, 0x5f, 0x03, 0x73, 0x58, 0x81, 0xb1, 0x7f, + 0x0a, 0xbd, 0x25, 0x5e, 0xce, 0xdb, 0xe3, 0x17, 0x89, 0xb5, 0xbc, 0xfd, 0x4c, 0xbe, 0x76, 0x8a, + 0xdc, 0x9c, 0x1f, 0x78, 0x5b, 0xf1, 0xe1, 0x3a, 0xf2, 0x7e, 0x51, 0x7c, 0x27, 0xe1, 0x2b, 0xd1, + 0x58, 0xa6, 0xcf, 0x94, 0xbc, 0xd3, 0x89, 0xd6, 0xd1, 0xf0, 0x13, 0x68, 0xe7, 0x19, 0x74, 0x25, + 0x04, 0x57, 0xe9, 0xf5, 0x11, 0xc0, 0x82, 0x44, 0xf3, 0xf6, 0x08, 0x8f, 0x65, 0x7e, 0xfd, 0x10, + 0x60, 0x41, 0x8d, 0x0a, 0x55, 0x45, 0x66, 0x55, 0xc3, 0x96, 0xe9, 0xf3, 0x21, 0x34, 0x33, 0x3a, + 0xcb, 0xaf, 0x81, 0x13, 0x14, 0xd9, 0xf1, 0xb3, 0xd1, 0x6f, 0x1f, 0x4d, 0x3d, 0x71, 0x91, 0x4c, + 0x46, 0x4e, 0x38, 0xdb, 0xbd, 0xa0, 0xf1, 0x85, 0xe7, 0x84, 0x3c, 0xda, 0xbd, 0x92, 0x60, 0xda, + 0x5d, 0xf9, 0xbf, 0x34, 0xa9, 0xe1, 0x63, 0xef, 0x83, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x87, + 0x96, 0xca, 0x22, 0x7b, 0x1a, 0x00, 0x00, +} + // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn @@ -3628,165 +3796,3 @@ var _SystemView_serviceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "logical/plugin/pb/backend.proto", } - -func init() { proto.RegisterFile("logical/plugin/pb/backend.proto", fileDescriptor_25821d34acc7c5ef) } - -var fileDescriptor_25821d34acc7c5ef = []byte{ - // 2483 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcd, 0x72, 0x1b, 0xc7, - 0x11, 0x2e, 0x00, 0xc4, 0x5f, 0xe3, 0x8f, 0x18, 0xd1, 0xcc, 0x0a, 0x96, 0x23, 0x78, 0x1d, 0x49, - 0xb4, 0x22, 0x81, 0x12, 0x1d, 0xc7, 0x72, 0x52, 0x76, 0x8a, 0xa6, 0x68, 0x99, 0x31, 0x69, 0xb3, - 0x96, 0x50, 0x9c, 0xbf, 0x2a, 0x78, 0xb0, 0x3b, 0x04, 0xb7, 0xb8, 0xd8, 0xdd, 0xcc, 0xce, 0x52, - 0xc4, 0x29, 0x6f, 0x91, 0xd7, 0xc8, 0x35, 0x95, 0x4b, 0x6e, 0xa9, 0x54, 0x72, 0xce, 0x6b, 0xe4, - 0x19, 0x52, 0xd3, 0x33, 0xfb, 0x07, 0x80, 0x96, 0x5c, 0x95, 0xdc, 0x66, 0xba, 0x7b, 0x7a, 0x66, - 0x7a, 0xbe, 0xfe, 0xba, 0x17, 0x80, 0xbb, 0x5e, 0x30, 0x73, 0x6d, 0xea, 0xed, 0x86, 0x5e, 0x3c, - 0x73, 0xfd, 0xdd, 0x70, 0xba, 0x3b, 0xa5, 0xf6, 0x25, 0xf3, 0x9d, 0x51, 0xc8, 0x03, 0x11, 0x90, - 0x72, 0x38, 0x1d, 0xdc, 0x9d, 0x05, 0xc1, 0xcc, 0x63, 0xbb, 0x28, 0x99, 0xc6, 0xe7, 0xbb, 0xc2, - 0x9d, 0xb3, 0x48, 0xd0, 0x79, 0xa8, 0x8c, 0x06, 0xdb, 0x89, 0x17, 0xd7, 0x61, 0xbe, 0x70, 0xc5, - 0x42, 0xcb, 0xb7, 0x8a, 0xde, 0x95, 0xd4, 0xac, 0x43, 0xf5, 0x70, 0x1e, 0x8a, 0x85, 0x39, 0x84, - 0xda, 0x17, 0x8c, 0x3a, 0x8c, 0x93, 0x6d, 0xa8, 0x5d, 0xe0, 0xc8, 0x28, 0x0d, 0x2b, 0x3b, 0x4d, - 0x4b, 0xcf, 0xcc, 0xdf, 0x01, 0x9c, 0xca, 0x35, 0x87, 0x9c, 0x07, 0x9c, 0xdc, 0x86, 0x06, 0xe3, - 0x7c, 0x22, 0x16, 0x21, 0x33, 0x4a, 0xc3, 0xd2, 0x4e, 0xc7, 0xaa, 0x33, 0xce, 0xc7, 0x8b, 0x90, - 0x91, 0x1f, 0x80, 0x1c, 0x4e, 0xe6, 0xd1, 0xcc, 0x28, 0x0f, 0x4b, 0xd2, 0x03, 0xe3, 0xfc, 0x24, - 0x9a, 0x25, 0x6b, 0xec, 0xc0, 0x61, 0x46, 0x65, 0x58, 0xda, 0xa9, 0xe0, 0x9a, 0x83, 0xc0, 0x61, - 0xe6, 0x9f, 0x4a, 0x50, 0x3d, 0xa5, 0xe2, 0x22, 0x22, 0x04, 0x36, 0x78, 0x10, 0x08, 0xbd, 0x39, - 0x8e, 0xc9, 0x0e, 0xf4, 0x62, 0x9f, 0xc6, 0xe2, 0x42, 0xde, 0xc8, 0xa6, 0x82, 0x39, 0x46, 0x19, - 0xd5, 0xcb, 0x62, 0xf2, 0x1e, 0x74, 0xbc, 0xc0, 0xa6, 0xde, 0x24, 0x12, 0x01, 0xa7, 0x33, 0xb9, - 0x8f, 0xb4, 0x6b, 0xa3, 0xf0, 0x4c, 0xc9, 0xc8, 0x43, 0xe8, 0x47, 0x8c, 0x7a, 0x93, 0x57, 0x9c, - 0x86, 0xa9, 0xe1, 0x86, 0x72, 0x28, 0x15, 0xdf, 0x70, 0x1a, 0x6a, 0x5b, 0xf3, 0x6f, 0x35, 0xa8, - 0x5b, 0xec, 0x0f, 0x31, 0x8b, 0x04, 0xe9, 0x42, 0xd9, 0x75, 0xf0, 0xb6, 0x4d, 0xab, 0xec, 0x3a, - 0x64, 0x04, 0xc4, 0x62, 0xa1, 0x27, 0xb7, 0x76, 0x03, 0xff, 0xc0, 0x8b, 0x23, 0xc1, 0xb8, 0xbe, - 0xf3, 0x1a, 0x0d, 0xb9, 0x03, 0xcd, 0x20, 0x64, 0x1c, 0x65, 0x18, 0x80, 0xa6, 0x95, 0x09, 0xe4, - 0xc5, 0x43, 0x2a, 0x2e, 0x8c, 0x0d, 0x54, 0xe0, 0x58, 0xca, 0x1c, 0x2a, 0xa8, 0x51, 0x55, 0x32, - 0x39, 0x26, 0x26, 0xd4, 0x22, 0x66, 0x73, 0x26, 0x8c, 0xda, 0xb0, 0xb4, 0xd3, 0xda, 0x83, 0x51, - 0x38, 0x1d, 0x9d, 0xa1, 0xc4, 0xd2, 0x1a, 0x72, 0x07, 0x36, 0x64, 0x5c, 0x8c, 0x3a, 0x5a, 0x34, - 0xa4, 0xc5, 0x7e, 0x2c, 0x2e, 0x2c, 0x94, 0x92, 0x3d, 0xa8, 0xab, 0x37, 0x8d, 0x8c, 0xc6, 0xb0, - 0xb2, 0xd3, 0xda, 0x33, 0xa4, 0x81, 0xbe, 0xe5, 0x48, 0xc1, 0x20, 0x3a, 0xf4, 0x05, 0x5f, 0x58, - 0x89, 0x21, 0x79, 0x17, 0xda, 0xb6, 0xe7, 0x32, 0x5f, 0x4c, 0x44, 0x70, 0xc9, 0x7c, 0xa3, 0x89, - 0x27, 0x6a, 0x29, 0xd9, 0x58, 0x8a, 0xc8, 0x1e, 0xbc, 0x95, 0x37, 0x99, 0x50, 0xdb, 0x66, 0x51, - 0x14, 0x70, 0x03, 0xd0, 0xf6, 0x56, 0xce, 0x76, 0x5f, 0xab, 0xa4, 0x5b, 0xc7, 0x8d, 0x42, 0x8f, - 0x2e, 0x26, 0x3e, 0x9d, 0x33, 0xa3, 0xa5, 0xdc, 0x6a, 0xd9, 0x57, 0x74, 0xce, 0xc8, 0x5d, 0x68, - 0xcd, 0x83, 0xd8, 0x17, 0x93, 0x30, 0x70, 0x7d, 0x61, 0xb4, 0xd1, 0x02, 0x50, 0x74, 0x2a, 0x25, - 0xe4, 0x1d, 0x50, 0x33, 0x05, 0xc6, 0x8e, 0x8a, 0x2b, 0x4a, 0x10, 0x8e, 0xf7, 0xa0, 0xab, 0xd4, - 0xe9, 0x79, 0xba, 0x68, 0xd2, 0x41, 0x69, 0x7a, 0x92, 0x27, 0xd0, 0x44, 0x3c, 0xb8, 0xfe, 0x79, - 0x60, 0xf4, 0x30, 0x6e, 0xb7, 0x72, 0x61, 0x91, 0x98, 0x38, 0xf2, 0xcf, 0x03, 0xab, 0xf1, 0x4a, - 0x8f, 0xc8, 0x27, 0xf0, 0x76, 0xe1, 0xbe, 0x9c, 0xcd, 0xa9, 0xeb, 0xbb, 0xfe, 0x6c, 0x12, 0x47, - 0x2c, 0x32, 0x36, 0x11, 0xe1, 0x46, 0xee, 0xd6, 0x56, 0x62, 0xf0, 0x32, 0x62, 0x11, 0x79, 0x1b, - 0x9a, 0x2a, 0x41, 0x27, 0xae, 0x63, 0xf4, 0xf1, 0x48, 0x0d, 0x25, 0x38, 0x72, 0xc8, 0x03, 0xe8, - 0x85, 0x81, 0xe7, 0xda, 0x8b, 0x49, 0x70, 0xc5, 0x38, 0x77, 0x1d, 0x66, 0x90, 0x61, 0x69, 0xa7, - 0x61, 0x75, 0x95, 0xf8, 0x6b, 0x2d, 0x5d, 0x97, 0x1a, 0xb7, 0xd0, 0x70, 0x25, 0x35, 0x46, 0x00, - 0x76, 0xe0, 0xfb, 0xcc, 0x46, 0xf8, 0x6d, 0xe1, 0x0d, 0xbb, 0xf2, 0x86, 0x07, 0xa9, 0xd4, 0xca, - 0x59, 0x0c, 0x3e, 0x87, 0x76, 0x1e, 0x0a, 0x64, 0x13, 0x2a, 0x97, 0x6c, 0xa1, 0xe1, 0x2f, 0x87, - 0x64, 0x08, 0xd5, 0x2b, 0xea, 0xc5, 0x0c, 0x21, 0xaf, 0x81, 0xa8, 0x96, 0x58, 0x4a, 0xf1, 0xb3, - 0xf2, 0xb3, 0x92, 0xf9, 0xd7, 0x2a, 0x6c, 0x48, 0xf0, 0x91, 0x0f, 0xa1, 0xe3, 0x31, 0x1a, 0xb1, - 0x49, 0x10, 0xca, 0x0d, 0x22, 0x74, 0xd5, 0xda, 0xdb, 0x94, 0xcb, 0x8e, 0xa5, 0xe2, 0x6b, 0x25, - 0xb7, 0xda, 0x5e, 0x6e, 0x26, 0x53, 0xda, 0xf5, 0x05, 0xe3, 0x3e, 0xf5, 0x26, 0x98, 0x0c, 0x2a, - 0xc1, 0xda, 0x89, 0xf0, 0xb9, 0x4c, 0x8a, 0x65, 0x1c, 0x55, 0x56, 0x71, 0x34, 0x80, 0x06, 0xc6, - 0xce, 0x65, 0x91, 0x4e, 0xf6, 0x74, 0x4e, 0xf6, 0xa0, 0x31, 0x67, 0x82, 0xea, 0x5c, 0x93, 0x29, - 0xb1, 0x9d, 0xe4, 0xcc, 0xe8, 0x44, 0x2b, 0x54, 0x42, 0xa4, 0x76, 0x2b, 0x19, 0x51, 0x5b, 0xcd, - 0x88, 0x01, 0x34, 0x52, 0xd0, 0xd5, 0xd5, 0x0b, 0x27, 0x73, 0x49, 0xb3, 0x21, 0xe3, 0x6e, 0xe0, - 0x18, 0x0d, 0x04, 0x8a, 0x9e, 0x49, 0x92, 0xf4, 0xe3, 0xb9, 0x82, 0x50, 0x53, 0x91, 0xa4, 0x1f, - 0xcf, 0x57, 0x11, 0x03, 0x4b, 0x88, 0xf9, 0x11, 0x54, 0xa9, 0xe7, 0xd2, 0x08, 0x53, 0x48, 0xbe, - 0xac, 0xe6, 0xfb, 0xd1, 0xbe, 0x94, 0x5a, 0x4a, 0x49, 0x3e, 0x80, 0xce, 0x8c, 0x07, 0x71, 0x38, - 0xc1, 0x29, 0x8b, 0x8c, 0x36, 0xde, 0x76, 0xd9, 0xba, 0x8d, 0x46, 0xfb, 0xca, 0x46, 0x66, 0xe0, - 0x34, 0x88, 0x7d, 0x67, 0x62, 0xbb, 0x0e, 0x8f, 0x8c, 0x0e, 0x06, 0x0f, 0x50, 0x74, 0x20, 0x25, - 0x32, 0xc5, 0x54, 0x0a, 0xa4, 0x01, 0xee, 0xa2, 0x4d, 0x07, 0xa5, 0xa7, 0x49, 0x94, 0x7f, 0x0c, - 0xfd, 0xa4, 0x28, 0x65, 0x96, 0x3d, 0xb4, 0xdc, 0x4c, 0x14, 0xa9, 0xf1, 0x0e, 0x6c, 0xb2, 0x6b, - 0x49, 0xa1, 0xae, 0x98, 0xcc, 0xe9, 0xf5, 0x44, 0x08, 0x4f, 0xa7, 0x54, 0x37, 0x91, 0x9f, 0xd0, - 0xeb, 0xb1, 0xf0, 0x64, 0xfe, 0xab, 0xdd, 0x31, 0xff, 0xfb, 0x58, 0x8c, 0x9a, 0x28, 0x91, 0xf9, - 0x3f, 0xf8, 0x39, 0x74, 0x0a, 0x4f, 0xb8, 0x06, 0xc8, 0x5b, 0x79, 0x20, 0x37, 0xf3, 0xe0, 0xfd, - 0xe7, 0x06, 0x00, 0xbe, 0xa5, 0x5a, 0xba, 0x5c, 0x01, 0xf2, 0x0f, 0x5c, 0x5e, 0xf3, 0xc0, 0x94, - 0x33, 0x5f, 0x68, 0x30, 0xea, 0xd9, 0x77, 0xe2, 0x30, 0xa9, 0x01, 0xd5, 0x5c, 0x0d, 0x78, 0x04, - 0x1b, 0x12, 0x73, 0x46, 0x2d, 0xa3, 0xea, 0xec, 0x44, 0x88, 0x4e, 0x85, 0x4c, 0xb4, 0x5a, 0x49, - 0x84, 0xfa, 0x6a, 0x22, 0xe4, 0x11, 0xd6, 0x28, 0x22, 0xec, 0x3d, 0xe8, 0xd8, 0x9c, 0x61, 0x3d, - 0x9a, 0xc8, 0xc6, 0x42, 0x23, 0xb0, 0x9d, 0x08, 0xc7, 0xee, 0x9c, 0xc9, 0xf8, 0xc9, 0xc7, 0x00, - 0x54, 0xc9, 0xe1, 0xda, 0xb7, 0x6a, 0xad, 0x7d, 0x2b, 0xac, 0xee, 0x1e, 0xd3, 0x2c, 0x8e, 0xe3, - 0x5c, 0x26, 0x74, 0x0a, 0x99, 0x50, 0x80, 0x7b, 0x77, 0x09, 0xee, 0x4b, 0x98, 0xec, 0xad, 0x60, - 0xf2, 0x5d, 0x68, 0xcb, 0x00, 0x44, 0x21, 0xb5, 0x99, 0x74, 0xb0, 0xa9, 0x02, 0x91, 0xca, 0x8e, - 0x1c, 0xcc, 0xe0, 0x78, 0x3a, 0x5d, 0x5c, 0x04, 0x1e, 0xcb, 0x48, 0xb8, 0x95, 0xca, 0x8e, 0x1c, - 0x79, 0x5e, 0x44, 0x15, 0x41, 0x54, 0xe1, 0x78, 0xf0, 0x11, 0x34, 0xd3, 0xa8, 0x7f, 0x2f, 0x30, - 0xfd, 0xb9, 0x04, 0xed, 0x3c, 0xd1, 0xc9, 0xc5, 0xe3, 0xf1, 0x31, 0x2e, 0xae, 0x58, 0x72, 0x28, - 0x5b, 0x04, 0xce, 0x7c, 0xf6, 0x8a, 0x4e, 0x3d, 0xe5, 0xa0, 0x61, 0x65, 0x02, 0xa9, 0x75, 0x7d, - 0x9b, 0xb3, 0x79, 0x82, 0xaa, 0x8a, 0x95, 0x09, 0xc8, 0xc7, 0x00, 0x6e, 0x14, 0xc5, 0x4c, 0xbd, - 0xdc, 0x06, 0xd2, 0xc0, 0x60, 0xa4, 0xfa, 0xc5, 0x51, 0xd2, 0x2f, 0x8e, 0xc6, 0x49, 0xbf, 0x68, - 0x35, 0xd1, 0x1a, 0x9f, 0x74, 0x1b, 0x6a, 0xf2, 0x81, 0xc6, 0xc7, 0x88, 0xbc, 0x8a, 0xa5, 0x67, - 0xe6, 0x1f, 0xa1, 0xa6, 0x3a, 0x8b, 0xff, 0x2b, 0x79, 0xdf, 0x86, 0x86, 0xf2, 0xed, 0x3a, 0x3a, - 0x57, 0xea, 0x38, 0x3f, 0x72, 0xcc, 0x7f, 0x95, 0xa0, 0x61, 0xb1, 0x28, 0x0c, 0xfc, 0x88, 0xe5, - 0x3a, 0x9f, 0xd2, 0x6b, 0x3b, 0x9f, 0xf2, 0xda, 0xce, 0x27, 0xe9, 0xa7, 0x2a, 0xb9, 0x7e, 0x6a, - 0x00, 0x0d, 0xce, 0x1c, 0x97, 0x33, 0x5b, 0xe8, 0xde, 0x2b, 0x9d, 0x4b, 0xdd, 0x2b, 0xca, 0x65, - 0xc9, 0x8e, 0xb0, 0x2e, 0x34, 0xad, 0x74, 0x4e, 0x9e, 0xe6, 0x1b, 0x06, 0xd5, 0x8a, 0x6d, 0xa9, - 0x86, 0x41, 0x1d, 0x77, 0xb5, 0x63, 0x30, 0xff, 0x51, 0x86, 0xcd, 0x65, 0xf5, 0x1a, 0x10, 0x6c, - 0x41, 0x55, 0x95, 0x14, 0x8d, 0x20, 0xb1, 0x52, 0x4c, 0x2a, 0x4b, 0x5c, 0xf3, 0x8b, 0xe5, 0xbc, - 0x7d, 0xfd, 0xeb, 0x17, 0x73, 0xfa, 0x7d, 0xd8, 0x94, 0xa7, 0x0c, 0x99, 0x93, 0xb5, 0x49, 0x8a, - 0x84, 0x7a, 0x5a, 0x9e, 0x36, 0x4a, 0x0f, 0xa1, 0x9f, 0x98, 0x66, 0xe9, 0x59, 0x2b, 0xd8, 0x1e, - 0x26, 0x59, 0xba, 0x0d, 0xb5, 0xf3, 0x80, 0xcf, 0xa9, 0xd0, 0x3c, 0xa4, 0x67, 0x05, 0x9e, 0x41, - 0xc2, 0x6b, 0x28, 0x58, 0x24, 0x42, 0xf9, 0x29, 0x20, 0xf3, 0x3f, 0x6d, 0xd3, 0x91, 0x88, 0x1a, - 0x56, 0x23, 0x69, 0xcf, 0xcd, 0x5f, 0x43, 0x6f, 0xa9, 0x33, 0x5b, 0x13, 0xc8, 0x6c, 0xfb, 0x72, - 0x61, 0xfb, 0x82, 0xe7, 0xca, 0x92, 0xe7, 0xdf, 0x40, 0xff, 0x0b, 0xea, 0x3b, 0x1e, 0xd3, 0xfe, - 0xf7, 0xf9, 0x2c, 0x92, 0x35, 0x46, 0x7f, 0x28, 0x4c, 0x74, 0x01, 0xe8, 0x58, 0x4d, 0x2d, 0x39, - 0x72, 0xc8, 0x3d, 0xa8, 0x73, 0x65, 0xad, 0x81, 0xd7, 0xca, 0xb5, 0x8e, 0x56, 0xa2, 0x33, 0xbf, - 0x05, 0x52, 0x70, 0x2d, 0xbf, 0x11, 0x16, 0x64, 0x47, 0x02, 0x50, 0x81, 0x42, 0x03, 0xbb, 0x9d, - 0xc7, 0x91, 0x95, 0x6a, 0xc9, 0x10, 0x2a, 0x8c, 0x73, 0xbd, 0x05, 0xf6, 0x6e, 0xd9, 0x17, 0x99, - 0x25, 0x55, 0xe6, 0x4f, 0xa0, 0x7f, 0x16, 0x32, 0xdb, 0xa5, 0x1e, 0x7e, 0x4d, 0xa9, 0x0d, 0xee, - 0x42, 0x55, 0x06, 0x39, 0xc9, 0xd9, 0x26, 0x2e, 0x44, 0xb5, 0x92, 0x9b, 0xdf, 0x82, 0xa1, 0xce, - 0x75, 0x78, 0xed, 0x46, 0x82, 0xf9, 0x36, 0x3b, 0xb8, 0x60, 0xf6, 0xe5, 0xff, 0xf0, 0xe6, 0x57, - 0x70, 0x7b, 0xdd, 0x0e, 0xc9, 0xf9, 0x5a, 0xb6, 0x9c, 0x4d, 0xce, 0x25, 0x7d, 0xe3, 0x1e, 0x0d, - 0x0b, 0x50, 0xf4, 0xb9, 0x94, 0xc8, 0x77, 0x64, 0x72, 0x5d, 0xa4, 0x29, 0x51, 0xcf, 0x92, 0x78, - 0x54, 0x6e, 0x8e, 0xc7, 0x5f, 0x4a, 0xd0, 0x3c, 0x63, 0x22, 0x0e, 0xf1, 0x2e, 0x6f, 0x43, 0x73, - 0xca, 0x83, 0x4b, 0xc6, 0xb3, 0xab, 0x34, 0x94, 0xe0, 0xc8, 0x21, 0x4f, 0xa1, 0x76, 0x10, 0xf8, - 0xe7, 0xee, 0x0c, 0xbf, 0x2d, 0x5b, 0x7b, 0xb7, 0x15, 0xbb, 0xe8, 0xb5, 0x23, 0xa5, 0x53, 0xa5, - 0x56, 0x1b, 0x92, 0x21, 0xb4, 0xf4, 0x17, 0xfa, 0xcb, 0x97, 0x47, 0xcf, 0x93, 0xa6, 0x33, 0x27, - 0x1a, 0x7c, 0x0c, 0xad, 0xdc, 0xc2, 0xef, 0x55, 0x2d, 0x7e, 0x08, 0x80, 0xbb, 0xab, 0x18, 0x6d, - 0xaa, 0xab, 0xea, 0x95, 0xf2, 0x6a, 0x77, 0xa1, 0x29, 0xfb, 0x1b, 0xa5, 0x4e, 0xea, 0x54, 0x29, - 0xab, 0x53, 0xe6, 0x3d, 0xe8, 0x1f, 0xf9, 0x57, 0xd4, 0x73, 0x1d, 0x2a, 0xd8, 0x97, 0x6c, 0x81, - 0x21, 0x58, 0x39, 0x81, 0x79, 0x06, 0x6d, 0xfd, 0xb1, 0xfb, 0x46, 0x67, 0x6c, 0xeb, 0x33, 0x7e, - 0x77, 0x12, 0xbd, 0x0f, 0x3d, 0xed, 0xf4, 0xd8, 0xd5, 0x29, 0x24, 0xcb, 0x3c, 0x67, 0xe7, 0xee, - 0xb5, 0x76, 0xad, 0x67, 0xe6, 0x33, 0xd8, 0xcc, 0x99, 0xa6, 0xd7, 0xb9, 0x64, 0x8b, 0x28, 0xf9, - 0x11, 0x40, 0x8e, 0x93, 0x08, 0x94, 0xb3, 0x08, 0x98, 0xd0, 0xd5, 0x2b, 0x5f, 0x30, 0x71, 0xc3, - 0xed, 0xbe, 0x4c, 0x0f, 0xf2, 0x82, 0x69, 0xe7, 0xf7, 0xa1, 0xca, 0xe4, 0x4d, 0xf3, 0x25, 0x2c, - 0x1f, 0x01, 0x4b, 0xa9, 0xd7, 0x6c, 0xf8, 0x2c, 0xdd, 0xf0, 0x34, 0x56, 0x1b, 0xbe, 0xa1, 0x2f, - 0xf3, 0xbd, 0xf4, 0x18, 0xa7, 0xb1, 0xb8, 0xe9, 0x45, 0xef, 0x41, 0x5f, 0x1b, 0x3d, 0x67, 0x1e, - 0x13, 0xec, 0x86, 0x2b, 0xdd, 0x07, 0x52, 0x30, 0xbb, 0xc9, 0xdd, 0x1d, 0x68, 0x8c, 0xc7, 0xc7, - 0xa9, 0xb6, 0xc8, 0x8d, 0xe6, 0x27, 0xd0, 0x3f, 0x8b, 0x9d, 0xe0, 0x94, 0xbb, 0x57, 0xae, 0xc7, - 0x66, 0x6a, 0xb3, 0xa4, 0xff, 0x2c, 0xe5, 0xfa, 0xcf, 0xb5, 0xd5, 0xc8, 0xdc, 0x01, 0x52, 0x58, - 0x9e, 0xbe, 0x5b, 0x14, 0x3b, 0x81, 0x4e, 0x61, 0x1c, 0x9b, 0x3b, 0xd0, 0x1e, 0x53, 0x59, 0xef, - 0x1d, 0x65, 0x63, 0x40, 0x5d, 0xa8, 0xb9, 0x36, 0x4b, 0xa6, 0xe6, 0x1e, 0x6c, 0x1d, 0x50, 0xfb, - 0xc2, 0xf5, 0x67, 0xcf, 0xdd, 0x48, 0x36, 0x3c, 0x7a, 0xc5, 0x00, 0x1a, 0x8e, 0x16, 0xe8, 0x25, - 0xe9, 0xdc, 0x7c, 0x0c, 0x6f, 0xe5, 0x7e, 0x69, 0x39, 0x13, 0x34, 0x89, 0xc7, 0x16, 0x54, 0x23, - 0x39, 0xc3, 0x15, 0x55, 0x4b, 0x4d, 0xcc, 0xaf, 0x60, 0x2b, 0x5f, 0x80, 0x65, 0xfb, 0x91, 0x5c, - 0x1c, 0x1b, 0x83, 0x52, 0xae, 0x31, 0xd0, 0x31, 0x2b, 0x67, 0xf5, 0x64, 0x13, 0x2a, 0xbf, 0xfc, - 0x66, 0xac, 0xc1, 0x2e, 0x87, 0xe6, 0xef, 0xe5, 0xf6, 0x45, 0x7f, 0x6a, 0xfb, 0x42, 0x77, 0x50, - 0x7a, 0x93, 0xee, 0x60, 0x0d, 0xde, 0x1e, 0x43, 0xff, 0xc4, 0x0b, 0xec, 0xcb, 0x43, 0x3f, 0x17, - 0x0d, 0x03, 0xea, 0xcc, 0xcf, 0x07, 0x23, 0x99, 0x9a, 0x0f, 0xa0, 0x77, 0x1c, 0xd8, 0xd4, 0x3b, - 0x09, 0x62, 0x5f, 0xa4, 0x51, 0xc0, 0x9f, 0xbe, 0xb4, 0xa9, 0x9a, 0x98, 0x8f, 0xa1, 0xab, 0x4b, - 0xb4, 0x7f, 0x1e, 0x24, 0xcc, 0x98, 0x15, 0xf3, 0x52, 0xb1, 0xd7, 0x36, 0x8f, 0xa1, 0x97, 0x99, - 0x2b, 0xbf, 0x0f, 0xa0, 0xa6, 0xd4, 0xfa, 0x6e, 0xbd, 0xf4, 0x03, 0x52, 0x59, 0x5a, 0x5a, 0xbd, - 0xe6, 0x52, 0x73, 0xe8, 0x9e, 0xe2, 0x4f, 0x90, 0x87, 0xfe, 0x95, 0x72, 0x76, 0x04, 0x44, 0xfd, - 0x28, 0x39, 0x61, 0xfe, 0x95, 0xcb, 0x03, 0x1f, 0xfb, 0xdb, 0x92, 0x6e, 0x61, 0x12, 0xc7, 0xe9, - 0xa2, 0xc4, 0xc2, 0xea, 0x87, 0xcb, 0xa2, 0xb5, 0x31, 0x84, 0xec, 0x07, 0x0e, 0x59, 0x6a, 0x38, - 0x9b, 0x07, 0x82, 0x4d, 0xa8, 0xe3, 0x24, 0xd9, 0x02, 0x4a, 0xb4, 0xef, 0x38, 0x7c, 0xef, 0x3f, - 0x65, 0xa8, 0x7f, 0xa6, 0x08, 0x9c, 0x7c, 0x0a, 0x9d, 0x42, 0xb9, 0x26, 0x6f, 0xe1, 0x2f, 0x1c, - 0xcb, 0xcd, 0xc1, 0x60, 0x7b, 0x45, 0xac, 0xee, 0xf5, 0x04, 0xda, 0xf9, 0x62, 0x4c, 0xb0, 0xf0, - 0xe2, 0xcf, 0xad, 0x03, 0xf4, 0xb4, 0x5a, 0xa9, 0xcf, 0x60, 0x6b, 0x5d, 0x99, 0x24, 0x77, 0xb2, - 0x1d, 0x56, 0x4b, 0xf4, 0xe0, 0x9d, 0x9b, 0xb4, 0x49, 0x79, 0xad, 0x1f, 0x78, 0x8c, 0xfa, 0x71, - 0x98, 0x3f, 0x41, 0x36, 0x24, 0x4f, 0xa1, 0x53, 0x28, 0x14, 0xea, 0x9e, 0x2b, 0xb5, 0x23, 0xbf, - 0xe4, 0x3e, 0x54, 0xb1, 0x38, 0x91, 0x4e, 0xa1, 0x4a, 0x0e, 0xba, 0xe9, 0x54, 0xed, 0x3d, 0x84, - 0x0d, 0xfc, 0x11, 0x2e, 0xb7, 0x31, 0xae, 0x48, 0x2b, 0xd7, 0xde, 0xbf, 0x4b, 0x50, 0x4f, 0x7e, - 0x98, 0x7d, 0x0a, 0x1b, 0xb2, 0x06, 0x90, 0x5b, 0x39, 0x1a, 0x4d, 0xea, 0xc7, 0x60, 0x6b, 0x49, - 0xa8, 0x36, 0x18, 0x41, 0xe5, 0x05, 0x13, 0x84, 0xe4, 0x94, 0xba, 0x18, 0x0c, 0x6e, 0x15, 0x65, - 0xa9, 0xfd, 0x69, 0x5c, 0xb4, 0xd7, 0x5c, 0x5e, 0xb0, 0x4f, 0x59, 0xfa, 0x23, 0xa8, 0x29, 0x96, - 0x55, 0x41, 0x59, 0xe1, 0x67, 0xf5, 0xf8, 0xab, 0x7c, 0xbc, 0xf7, 0xf7, 0x0d, 0x80, 0xb3, 0x45, - 0x24, 0xd8, 0xfc, 0x57, 0x2e, 0x7b, 0x45, 0x1e, 0x42, 0xef, 0x39, 0x3b, 0xa7, 0xb1, 0x27, 0xf0, - 0x6b, 0x49, 0xb2, 0x49, 0x2e, 0x26, 0xd8, 0xf0, 0xa5, 0x64, 0x7d, 0x1f, 0x5a, 0x27, 0xf4, 0xfa, - 0xf5, 0x76, 0x9f, 0x42, 0xa7, 0xc0, 0xc1, 0xfa, 0x88, 0xcb, 0xac, 0xae, 0x8f, 0xb8, 0xca, 0xd6, - 0xf7, 0xa1, 0xae, 0x99, 0x39, 0xbf, 0x07, 0xd6, 0xb0, 0x02, 0x63, 0xff, 0x14, 0x7a, 0x4b, 0xbc, - 0x9c, 0xb7, 0xc7, 0x5f, 0x24, 0xd6, 0xf2, 0xf6, 0x33, 0xf9, 0xb5, 0x53, 0xe4, 0xe6, 0xfc, 0xc2, - 0xdb, 0x8a, 0x0f, 0xd7, 0x91, 0xf7, 0x8b, 0xe2, 0x77, 0x12, 0x7e, 0x25, 0x1a, 0xcb, 0xf4, 0x99, - 0x90, 0x77, 0xe2, 0x68, 0x1d, 0x0d, 0x3f, 0x81, 0x76, 0x9e, 0x41, 0x57, 0x52, 0x70, 0x95, 0x5e, - 0x1f, 0x01, 0x64, 0x24, 0x9a, 0xb7, 0x47, 0x78, 0x2c, 0xf3, 0xeb, 0x87, 0x00, 0x19, 0x35, 0x2a, - 0x54, 0x15, 0x99, 0x55, 0x2d, 0x5b, 0xa6, 0xcf, 0x87, 0xd0, 0x4c, 0xe9, 0x2c, 0xbf, 0x07, 0x3a, - 0x28, 0xb2, 0xe3, 0x67, 0xa3, 0xdf, 0x3e, 0x9a, 0xb9, 0xe2, 0x22, 0x9e, 0x8e, 0xec, 0x60, 0xbe, - 0x7b, 0x41, 0xa3, 0x0b, 0xd7, 0x0e, 0x78, 0xb8, 0x7b, 0x25, 0xc1, 0xb4, 0xbb, 0xf2, 0x9f, 0xd1, - 0xb4, 0x86, 0x1f, 0x7b, 0x1f, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x93, 0x15, 0xb9, 0x42, 0x4f, - 0x1a, 0x00, 0x00, -} diff --git a/logical/plugin/pb/backend.proto b/logical/plugin/pb/backend.proto index e02cc1f9a..8bae7aa4e 100644 --- a/logical/plugin/pb/backend.proto +++ b/logical/plugin/pb/backend.proto @@ -210,6 +210,9 @@ message Auth { // TokenType is the type of token being requested uint32 token_type = 17; + + // Whether the default policy should be added automatically by core + bool no_default_policy = 18; } message TokenEntry { diff --git a/logical/plugin/pb/translation.go b/logical/plugin/pb/translation.go index c777cae50..c4581cba2 100644 --- a/logical/plugin/pb/translation.go +++ b/logical/plugin/pb/translation.go @@ -492,6 +492,7 @@ func LogicalAuthToProtoAuth(a *logical.Auth) (*Auth, error) { Policies: a.Policies, TokenPolicies: a.TokenPolicies, IdentityPolicies: a.IdentityPolicies, + NoDefaultPolicy: a.NoDefaultPolicy, Metadata: a.Metadata, ClientToken: a.ClientToken, Accessor: a.Accessor, @@ -539,6 +540,7 @@ func ProtoAuthToLogicalAuth(a *Auth) (*logical.Auth, error) { Policies: a.Policies, TokenPolicies: a.TokenPolicies, IdentityPolicies: a.IdentityPolicies, + NoDefaultPolicy: a.NoDefaultPolicy, Metadata: a.Metadata, ClientToken: a.ClientToken, Accessor: a.Accessor, diff --git a/physical/types.pb.go b/physical/types.pb.go index e02137c0c..91fbb0e81 100644 --- a/physical/types.pb.go +++ b/physical/types.pb.go @@ -5,9 +5,8 @@ package physical import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/vault/external_tests/policy/no_default_test.go b/vault/external_tests/policy/no_default_test.go new file mode 100644 index 000000000..4ba37f9e6 --- /dev/null +++ b/vault/external_tests/policy/no_default_test.go @@ -0,0 +1,85 @@ +package policy + +import ( + "testing" + + "github.com/go-test/deep" + log "github.com/hashicorp/go-hclog" + "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/builtin/credential/ldap" + vaulthttp "github.com/hashicorp/vault/http" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/vault" +) + +func TestNoDefaultPolicy(t *testing.T) { + var err error + coreConfig := &vault.CoreConfig{ + DisableMlock: true, + DisableCache: true, + Logger: log.NewNullLogger(), + CredentialBackends: map[string]logical.Factory{ + "ldap": ldap.Factory, + }, + } + + cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{ + HandlerFunc: vaulthttp.Handler, + }) + + cluster.Start() + defer cluster.Cleanup() + + cores := cluster.Cores + + vault.TestWaitActive(t, cores[0].Core) + + client := cores[0].Client + + err = client.Sys().EnableAuthWithOptions("ldap", &api.EnableAuthOptions{ + Type: "ldap", + }) + if err != nil { + t.Fatal(err) + } + + // Configure LDAP auth backend + secret, err := client.Logical().Write("auth/ldap/config", map[string]interface{}{ + "url": "ldap://ldap.forumsys.com", + "userattr": "uid", + "userdn": "dc=example,dc=com", + "groupdn": "dc=example,dc=com", + "binddn": "cn=read-only-admin,dc=example,dc=com", + "no_default_policy": true, + }) + if err != nil { + t.Fatal(err) + } + + // Create a local user in LDAP + secret, err = client.Logical().Write("auth/ldap/users/tesla", map[string]interface{}{ + "policies": "foo", + }) + if err != nil { + t.Fatal(err) + } + + // Login with LDAP and create a token + secret, err = client.Logical().Write("auth/ldap/login/tesla", map[string]interface{}{ + "password": "password", + }) + if err != nil { + t.Fatal(err) + } + token := secret.Auth.ClientToken + + // Lookup the token to get the entity ID + secret, err = client.Auth().Token().Lookup(token) + if err != nil { + t.Fatal(err) + } + + if diff := deep.Equal(secret.Data["policies"], []interface{}{"foo"}); diff != nil { + t.Fatal(diff) + } +} diff --git a/vault/request_forwarding_service.pb.go b/vault/request_forwarding_service.pb.go index cfc53b0c4..805d6da96 100644 --- a/vault/request_forwarding_service.pb.go +++ b/vault/request_forwarding_service.pb.go @@ -5,15 +5,11 @@ package vault import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" forwarding "github.com/hashicorp/vault/helper/forwarding" -) - -import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -322,6 +318,45 @@ func init() { proto.RegisterType((*PerfStandbyElectionResponse)(nil), "vault.PerfStandbyElectionResponse") } +func init() { + proto.RegisterFile("vault/request_forwarding_service.proto", fileDescriptor_f5f7512e4ab7b58a) +} + +var fileDescriptor_f5f7512e4ab7b58a = []byte{ + // 493 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0x41, 0x6f, 0x1a, 0x3d, + 0x10, 0x8d, 0x81, 0x10, 0x31, 0x90, 0x88, 0xf8, 0x8b, 0xf4, 0xad, 0xa8, 0xa2, 0x90, 0xad, 0x54, + 0x21, 0x55, 0xda, 0x8d, 0xd2, 0x73, 0x0f, 0x2d, 0x4a, 0x25, 0xd4, 0x4b, 0xb5, 0xb9, 0xf5, 0xb2, + 0x32, 0xf6, 0x04, 0xac, 0x2e, 0x6b, 0xd7, 0x36, 0x49, 0xf6, 0x27, 0xf7, 0xd6, 0x9f, 0x50, 0xad, + 0xd7, 0x04, 0x10, 0x4d, 0x2f, 0x68, 0xe7, 0xcd, 0x63, 0xde, 0xf8, 0xf9, 0x19, 0xde, 0x3d, 0xb2, + 0x75, 0xe1, 0x52, 0x83, 0x3f, 0xd7, 0x68, 0x5d, 0xfe, 0xa0, 0xcc, 0x13, 0x33, 0x42, 0x96, 0x8b, + 0xdc, 0xa2, 0x79, 0x94, 0x1c, 0x13, 0x6d, 0x94, 0x53, 0xf4, 0xd8, 0xf3, 0x46, 0x97, 0x4b, 0x2c, + 0x34, 0x9a, 0x74, 0xcb, 0x4b, 0x5d, 0xa5, 0xd1, 0x36, 0xac, 0x58, 0x41, 0xff, 0x8e, 0x2f, 0x55, + 0xd6, 0x4c, 0xa3, 0x11, 0x9c, 0xac, 0xd0, 0x5a, 0xb6, 0xc0, 0x88, 0x8c, 0xc9, 0xa4, 0x97, 0x6d, + 0x4a, 0x7a, 0x0d, 0x03, 0x5e, 0xac, 0xad, 0x43, 0x93, 0x33, 0x21, 0x4c, 0xd4, 0xf2, 0xed, 0x7e, + 0xc0, 0x3e, 0x09, 0x61, 0xe8, 0x5b, 0x38, 0xdd, 0xa5, 0xd8, 0xa8, 0x3d, 0x6e, 0x4f, 0x7a, 0xd9, + 0x60, 0x87, 0x63, 0xe3, 0x27, 0xe8, 0x35, 0x82, 0xba, 0xa8, 0xfe, 0x21, 0x77, 0x30, 0xab, 0x75, + 0x38, 0x8b, 0xbe, 0x87, 0x73, 0x83, 0xba, 0x90, 0x9c, 0x39, 0xa9, 0xca, 0xdc, 0x3a, 0xe6, 0x30, + 0x6a, 0x8f, 0xc9, 0xe4, 0x34, 0x1b, 0xee, 0x34, 0xee, 0x6b, 0x3c, 0x9e, 0x41, 0x6f, 0x5a, 0x48, + 0x2c, 0xdd, 0x57, 0xac, 0x28, 0x85, 0x4e, 0xed, 0x42, 0x50, 0xf5, 0xdf, 0x74, 0x00, 0xe4, 0xd9, + 0x1f, 0x6b, 0x90, 0x91, 0xe7, 0xba, 0xaa, 0xfc, 0xac, 0x41, 0x46, 0xaa, 0xba, 0x12, 0x51, 0xa7, + 0xa9, 0x44, 0x3c, 0x82, 0xe8, 0x1b, 0x9a, 0x87, 0x7b, 0xc7, 0x4a, 0x31, 0xaf, 0xee, 0x0a, 0xe4, + 0xb5, 0xcc, 0xac, 0xd4, 0x6b, 0x17, 0xff, 0x22, 0xf0, 0xe6, 0x2f, 0xcd, 0x0c, 0xad, 0x56, 0xa5, + 0x45, 0x7a, 0x06, 0x2d, 0x29, 0x82, 0x6e, 0x4b, 0x0a, 0x7a, 0x09, 0xb0, 0x39, 0xa8, 0x14, 0xc1, + 0xd5, 0x5e, 0x40, 0x66, 0x82, 0xde, 0xc0, 0x85, 0x36, 0x72, 0xc5, 0x4c, 0x95, 0xef, 0xd9, 0xdf, + 0xf6, 0x44, 0x1a, 0x7a, 0xd3, 0x9d, 0x5b, 0xf8, 0x1f, 0x4e, 0x38, 0xcb, 0x39, 0x1a, 0x17, 0x16, + 0xee, 0x72, 0x36, 0x45, 0xe3, 0xe8, 0x15, 0xf4, 0xb9, 0x37, 0xa0, 0x69, 0x1e, 0xfb, 0x26, 0x34, + 0x90, 0x27, 0xa4, 0x10, 0xaa, 0xfc, 0x07, 0x56, 0x51, 0x77, 0x4c, 0x26, 0xfd, 0xdb, 0x61, 0xe2, + 0x63, 0x94, 0xbc, 0x58, 0x57, 0x2f, 0x17, 0x3e, 0x6f, 0x7f, 0x13, 0x38, 0x0f, 0xc9, 0xf9, 0xf2, + 0x12, 0x2f, 0xfa, 0x11, 0xce, 0x42, 0xb5, 0x49, 0xd5, 0x7f, 0xc9, 0x36, 0x7d, 0x49, 0x00, 0x47, + 0x17, 0xfb, 0x60, 0x63, 0x4f, 0x7c, 0x44, 0x13, 0xe8, 0xd4, 0x01, 0xa1, 0x34, 0x28, 0xef, 0xc4, + 0x73, 0x34, 0xdc, 0xc3, 0x74, 0x51, 0xc5, 0x47, 0xb4, 0x80, 0xeb, 0xda, 0x6f, 0x65, 0x56, 0xac, + 0xe4, 0x78, 0x60, 0x7b, 0xb3, 0xc1, 0x55, 0xf8, 0xe3, 0x6b, 0xd7, 0x36, 0x8a, 0x5f, 0x27, 0x6c, + 0x77, 0xbb, 0x21, 0x9f, 0xe3, 0xef, 0xe3, 0x85, 0x74, 0xcb, 0xf5, 0x3c, 0xe1, 0x6a, 0x95, 0x2e, + 0x99, 0x5d, 0x4a, 0xae, 0x8c, 0x4e, 0x9b, 0x47, 0xe9, 0x7f, 0xe7, 0x5d, 0xff, 0xb4, 0x3e, 0xfc, + 0x09, 0x00, 0x00, 0xff, 0xff, 0x03, 0x94, 0x0a, 0x17, 0xaa, 0x03, 0x00, 0x00, +} + // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn @@ -487,42 +522,3 @@ var _RequestForwarding_serviceDesc = grpc.ServiceDesc{ }, Metadata: "vault/request_forwarding_service.proto", } - -func init() { - proto.RegisterFile("vault/request_forwarding_service.proto", fileDescriptor_f5f7512e4ab7b58a) -} - -var fileDescriptor_f5f7512e4ab7b58a = []byte{ - // 493 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0x41, 0x6f, 0x1a, 0x3d, - 0x10, 0x8d, 0x81, 0x10, 0x31, 0x90, 0x88, 0xf8, 0x8b, 0xf4, 0xad, 0xa8, 0xa2, 0x90, 0xad, 0x54, - 0x21, 0x55, 0xda, 0x8d, 0xd2, 0x73, 0x0f, 0x2d, 0x4a, 0x25, 0xd4, 0x4b, 0xb5, 0xb9, 0xf5, 0xb2, - 0x32, 0xf6, 0x04, 0xac, 0x2e, 0x6b, 0xd7, 0x36, 0x49, 0xf6, 0x27, 0xf7, 0xd6, 0x9f, 0x50, 0xad, - 0xd7, 0x04, 0x10, 0x4d, 0x2f, 0x68, 0xe7, 0xcd, 0x63, 0xde, 0xf8, 0xf9, 0x19, 0xde, 0x3d, 0xb2, - 0x75, 0xe1, 0x52, 0x83, 0x3f, 0xd7, 0x68, 0x5d, 0xfe, 0xa0, 0xcc, 0x13, 0x33, 0x42, 0x96, 0x8b, - 0xdc, 0xa2, 0x79, 0x94, 0x1c, 0x13, 0x6d, 0x94, 0x53, 0xf4, 0xd8, 0xf3, 0x46, 0x97, 0x4b, 0x2c, - 0x34, 0x9a, 0x74, 0xcb, 0x4b, 0x5d, 0xa5, 0xd1, 0x36, 0xac, 0x58, 0x41, 0xff, 0x8e, 0x2f, 0x55, - 0xd6, 0x4c, 0xa3, 0x11, 0x9c, 0xac, 0xd0, 0x5a, 0xb6, 0xc0, 0x88, 0x8c, 0xc9, 0xa4, 0x97, 0x6d, - 0x4a, 0x7a, 0x0d, 0x03, 0x5e, 0xac, 0xad, 0x43, 0x93, 0x33, 0x21, 0x4c, 0xd4, 0xf2, 0xed, 0x7e, - 0xc0, 0x3e, 0x09, 0x61, 0xe8, 0x5b, 0x38, 0xdd, 0xa5, 0xd8, 0xa8, 0x3d, 0x6e, 0x4f, 0x7a, 0xd9, - 0x60, 0x87, 0x63, 0xe3, 0x27, 0xe8, 0x35, 0x82, 0xba, 0xa8, 0xfe, 0x21, 0x77, 0x30, 0xab, 0x75, - 0x38, 0x8b, 0xbe, 0x87, 0x73, 0x83, 0xba, 0x90, 0x9c, 0x39, 0xa9, 0xca, 0xdc, 0x3a, 0xe6, 0x30, - 0x6a, 0x8f, 0xc9, 0xe4, 0x34, 0x1b, 0xee, 0x34, 0xee, 0x6b, 0x3c, 0x9e, 0x41, 0x6f, 0x5a, 0x48, - 0x2c, 0xdd, 0x57, 0xac, 0x28, 0x85, 0x4e, 0xed, 0x42, 0x50, 0xf5, 0xdf, 0x74, 0x00, 0xe4, 0xd9, - 0x1f, 0x6b, 0x90, 0x91, 0xe7, 0xba, 0xaa, 0xfc, 0xac, 0x41, 0x46, 0xaa, 0xba, 0x12, 0x51, 0xa7, - 0xa9, 0x44, 0x3c, 0x82, 0xe8, 0x1b, 0x9a, 0x87, 0x7b, 0xc7, 0x4a, 0x31, 0xaf, 0xee, 0x0a, 0xe4, - 0xb5, 0xcc, 0xac, 0xd4, 0x6b, 0x17, 0xff, 0x22, 0xf0, 0xe6, 0x2f, 0xcd, 0x0c, 0xad, 0x56, 0xa5, - 0x45, 0x7a, 0x06, 0x2d, 0x29, 0x82, 0x6e, 0x4b, 0x0a, 0x7a, 0x09, 0xb0, 0x39, 0xa8, 0x14, 0xc1, - 0xd5, 0x5e, 0x40, 0x66, 0x82, 0xde, 0xc0, 0x85, 0x36, 0x72, 0xc5, 0x4c, 0x95, 0xef, 0xd9, 0xdf, - 0xf6, 0x44, 0x1a, 0x7a, 0xd3, 0x9d, 0x5b, 0xf8, 0x1f, 0x4e, 0x38, 0xcb, 0x39, 0x1a, 0x17, 0x16, - 0xee, 0x72, 0x36, 0x45, 0xe3, 0xe8, 0x15, 0xf4, 0xb9, 0x37, 0xa0, 0x69, 0x1e, 0xfb, 0x26, 0x34, - 0x90, 0x27, 0xa4, 0x10, 0xaa, 0xfc, 0x07, 0x56, 0x51, 0x77, 0x4c, 0x26, 0xfd, 0xdb, 0x61, 0xe2, - 0x63, 0x94, 0xbc, 0x58, 0x57, 0x2f, 0x17, 0x3e, 0x6f, 0x7f, 0x13, 0x38, 0x0f, 0xc9, 0xf9, 0xf2, - 0x12, 0x2f, 0xfa, 0x11, 0xce, 0x42, 0xb5, 0x49, 0xd5, 0x7f, 0xc9, 0x36, 0x7d, 0x49, 0x00, 0x47, - 0x17, 0xfb, 0x60, 0x63, 0x4f, 0x7c, 0x44, 0x13, 0xe8, 0xd4, 0x01, 0xa1, 0x34, 0x28, 0xef, 0xc4, - 0x73, 0x34, 0xdc, 0xc3, 0x74, 0x51, 0xc5, 0x47, 0xb4, 0x80, 0xeb, 0xda, 0x6f, 0x65, 0x56, 0xac, - 0xe4, 0x78, 0x60, 0x7b, 0xb3, 0xc1, 0x55, 0xf8, 0xe3, 0x6b, 0xd7, 0x36, 0x8a, 0x5f, 0x27, 0x6c, - 0x77, 0xbb, 0x21, 0x9f, 0xe3, 0xef, 0xe3, 0x85, 0x74, 0xcb, 0xf5, 0x3c, 0xe1, 0x6a, 0x95, 0x2e, - 0x99, 0x5d, 0x4a, 0xae, 0x8c, 0x4e, 0x9b, 0x47, 0xe9, 0x7f, 0xe7, 0x5d, 0xff, 0xb4, 0x3e, 0xfc, - 0x09, 0x00, 0x00, 0xff, 0xff, 0x03, 0x94, 0x0a, 0x17, 0xaa, 0x03, 0x00, 0x00, -} diff --git a/vault/request_handling.go b/vault/request_handling.go index a46921a08..2ec8c50dd 100644 --- a/vault/request_handling.go +++ b/vault/request_handling.go @@ -982,6 +982,10 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re var entity *identity.Entity auth = resp.Auth + // Only the token store can toggle this off, and that's via a + // different path since it's not a login request; it's explicitly + // disallowed above + auth.Renewable = true mEntry := c.router.MatchingMountEntry(ctx, req.Path) @@ -1058,7 +1062,7 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re return nil, nil, ErrInternalError } - auth.TokenPolicies = policyutil.SanitizePolicies(auth.Policies, policyutil.AddDefaultPolicy) + auth.TokenPolicies = policyutil.SanitizePolicies(auth.Policies, !auth.NoDefaultPolicy) allPolicies := policyutil.SanitizePolicies(append(auth.TokenPolicies, identityPolicies[ns.ID]...), policyutil.DoNotAddDefaultPolicy) // Prevent internal policies from being assigned to tokens. We check diff --git a/vault/token_store.go b/vault/token_store.go index 6381f630c..d53294e45 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -14,13 +14,13 @@ import ( "strings" "time" + metrics "github.com/armon/go-metrics" proto "github.com/golang/protobuf/proto" "github.com/hashicorp/errwrap" log "github.com/hashicorp/go-hclog" + multierror "github.com/hashicorp/go-multierror" sockaddr "github.com/hashicorp/go-sockaddr" - metrics "github.com/armon/go-metrics" - multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/vault/helper/base62" "github.com/hashicorp/vault/helper/consts" "github.com/hashicorp/vault/helper/identity" @@ -31,6 +31,7 @@ import ( "github.com/hashicorp/vault/helper/policyutil" "github.com/hashicorp/vault/helper/salt" "github.com/hashicorp/vault/helper/strutil" + "github.com/hashicorp/vault/helper/tokenhelper" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" "github.com/hashicorp/vault/logical/plugin/pb" @@ -103,7 +104,7 @@ var ( ) func (ts *TokenStore) paths() []*framework.Path { - return []*framework.Path{ + p := []*framework.Path{ { Pattern: "roles/?$", @@ -126,76 +127,6 @@ func (ts *TokenStore) paths() []*framework.Path { HelpDescription: tokenListAccessorsHelp, }, - { - Pattern: "roles/" + framework.GenericNameRegex("role_name"), - Fields: map[string]*framework.FieldSchema{ - "role_name": &framework.FieldSchema{ - Type: framework.TypeString, - Description: "Name of the role", - }, - - "allowed_policies": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: tokenAllowedPoliciesHelp, - }, - - "disallowed_policies": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: tokenDisallowedPoliciesHelp, - }, - - "orphan": &framework.FieldSchema{ - Type: framework.TypeBool, - Default: false, - Description: tokenOrphanHelp, - }, - - "period": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Default: 0, - Description: tokenPeriodHelp, - }, - - "path_suffix": &framework.FieldSchema{ - Type: framework.TypeString, - Default: "", - Description: tokenPathSuffixHelp + pathSuffixSanitize.String(), - }, - - "explicit_max_ttl": &framework.FieldSchema{ - Type: framework.TypeDurationSecond, - Default: 0, - Description: tokenExplicitMaxTTLHelp, - }, - - "renewable": &framework.FieldSchema{ - Type: framework.TypeBool, - Default: true, - Description: tokenRenewableHelp, - }, - - "bound_cidrs": &framework.FieldSchema{ - Type: framework.TypeCommaStringSlice, - Description: `Comma separated string or JSON list of CIDR blocks. If set, specifies the blocks of IP addresses which are allowed to use the generated token.`, - }, - - "token_type": &framework.FieldSchema{ - Type: framework.TypeString, - Default: "service", - Description: "The type of token to generate, service or batch", - }, - }, - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.ReadOperation: ts.tokenStoreRoleRead, - logical.CreateOperation: ts.tokenStoreRoleCreateUpdate, - logical.UpdateOperation: ts.tokenStoreRoleCreateUpdate, - logical.DeleteOperation: ts.tokenStoreRoleDelete, - }, - - ExistenceCheck: ts.tokenStoreRoleExistenceCheck, - }, - { Pattern: "create-orphan$", @@ -414,6 +345,61 @@ func (ts *TokenStore) paths() []*framework.Path { HelpDescription: strings.TrimSpace(tokenTidyDesc), }, } + + rolesPath := &framework.Path{ + Pattern: "roles/" + framework.GenericNameRegex("role_name"), + Fields: map[string]*framework.FieldSchema{ + "role_name": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Name of the role", + }, + + "allowed_policies": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: tokenAllowedPoliciesHelp, + }, + + "disallowed_policies": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: tokenDisallowedPoliciesHelp, + }, + + "orphan": &framework.FieldSchema{ + Type: framework.TypeBool, + Default: false, + Description: tokenOrphanHelp, + }, + + "path_suffix": &framework.FieldSchema{ + Type: framework.TypeString, + Default: "", + Description: tokenPathSuffixHelp + pathSuffixSanitize.String(), + }, + + "renewable": &framework.FieldSchema{ + Type: framework.TypeBool, + Default: true, + Description: tokenRenewableHelp, + }, + }, + + Callbacks: map[logical.Operation]framework.OperationFunc{ + logical.ReadOperation: ts.tokenStoreRoleRead, + logical.CreateOperation: ts.tokenStoreRoleCreateUpdate, + logical.UpdateOperation: ts.tokenStoreRoleCreateUpdate, + logical.DeleteOperation: ts.tokenStoreRoleDelete, + }, + + ExistenceCheck: ts.tokenStoreRoleExistenceCheck, + } + // Roles in token store handle policies and TTLs differently + tokenhelper.AddTokenFieldsWithAllowList(rolesPath.Fields, + []string{"bound_cidrs", "explicit_max_ttl", "period", "token_type"}) + // For this backend default to service + rolesPath.Fields["token_type"].Default = "service" + p = append(p, rolesPath) + + return p } // LookupToken returns the properties of the token from the token store. This @@ -581,6 +567,8 @@ func (ts *TokenStore) Salt(ctx context.Context) (*salt.Salt, error) { // tsRoleEntry contains token store role information type tsRoleEntry struct { + tokenhelper.TokenParams + // The name of the role. Embedded so it can be used for pathing Name string `json:"name" mapstructure:"name" structs:"name"` @@ -594,26 +582,12 @@ type tsRoleEntry struct { // If true, tokens created using this role will be orphans Orphan bool `json:"orphan" mapstructure:"orphan" structs:"orphan"` - // If non-zero, tokens created using this role will be able to be renewed - // forever, but will have a fixed renewal period of this value - Period time.Duration `json:"period" mapstructure:"period" structs:"period"` - // If set, a suffix will be set on the token path, making it easier to // revoke using 'revoke-prefix' PathSuffix string `json:"path_suffix" mapstructure:"path_suffix" structs:"path_suffix"` // If set, controls whether created tokens are marked as being renewable Renewable bool `json:"renewable" mapstructure:"renewable" structs:"renewable"` - - // If set, the token entry will have an explicit maximum TTL set, rather - // than deferring to role/mount values - ExplicitMaxTTL time.Duration `json:"explicit_max_ttl" mapstructure:"explicit_max_ttl" structs:"explicit_max_ttl"` - - // The set of CIDRs that tokens generated using this role will be bound to - BoundCIDRs []*sockaddr.SockAddrMarshaler `json:"bound_cidrs"` - - // The type of token this role should issue - TokenType logical.TokenType `json:"token_type" mapstructure:"token_type"` } type accessorEntry struct { diff --git a/vendor/github.com/hashicorp/vault-plugin-secrets-ad/plugin/path_config.go b/vendor/github.com/hashicorp/vault-plugin-secrets-ad/plugin/path_config.go index 3f8e7f8f3..3dc27bd35 100644 --- a/vendor/github.com/hashicorp/vault-plugin-secrets-ad/plugin/path_config.go +++ b/vendor/github.com/hashicorp/vault-plugin-secrets-ad/plugin/path_config.go @@ -54,7 +54,7 @@ func (b *backend) pathConfig() *framework.Path { } func (b *backend) configFields() map[string]*framework.FieldSchema { - fields := ldaputil.ConfigFields() + fields := ldaputil.ConfigFields(false) fields["ttl"] = &framework.FieldSchema{ Type: framework.TypeDurationSecond, Description: "In seconds, the default password time-to-live.",