1package token 2 3import ( 4 "encoding/base64" 5 "reflect" 6 "sort" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/go-test/deep" 12 "github.com/hashicorp/vault/api" 13 credLdap "github.com/hashicorp/vault/builtin/credential/ldap" 14 credUserpass "github.com/hashicorp/vault/builtin/credential/userpass" 15 "github.com/hashicorp/vault/helper/jsonutil" 16 vaulthttp "github.com/hashicorp/vault/http" 17 "github.com/hashicorp/vault/logical" 18 "github.com/hashicorp/vault/vault" 19) 20 21func TestTokenStore_TokenInvalidEntityID(t *testing.T) { 22 coreConfig := &vault.CoreConfig{ 23 CredentialBackends: map[string]logical.Factory{ 24 "userpass": credUserpass.Factory, 25 }, 26 } 27 cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{ 28 HandlerFunc: vaulthttp.Handler, 29 }) 30 cluster.Start() 31 defer cluster.Cleanup() 32 33 core := cluster.Cores[0].Core 34 vault.TestWaitActive(t, core) 35 client := cluster.Cores[0].Client 36 37 // Enable userpass auth 38 err := client.Sys().EnableAuthWithOptions("userpass", &api.EnableAuthOptions{ 39 Type: "userpass", 40 }) 41 if err != nil { 42 t.Fatal(err) 43 } 44 45 // Add a user to userpass backend 46 _, err = client.Logical().Write("auth/userpass/users/testuser", map[string]interface{}{ 47 "password": "testpassword", 48 }) 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 secret, err := client.Logical().Write("auth/userpass/login/testuser", map[string]interface{}{ 54 "password": "testpassword", 55 }) 56 if err != nil { 57 t.Fatal(err) 58 } 59 clientToken := secret.Auth.ClientToken 60 61 secret, err = client.Logical().Write("auth/token/lookup", map[string]interface{}{ 62 "token": clientToken, 63 }) 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 entityID := secret.Data["entity_id"].(string) 69 70 _, err = client.Logical().Delete("identity/entity/id/" + entityID) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 client.SetToken(clientToken) 76 77 secret, err = client.Logical().Write("auth/token/lookup-self", nil) 78 if err == nil { 79 t.Fatalf("expected error due to token being invalid when its entity is invalid") 80 } 81} 82 83func TestTokenStore_IdentityPolicies(t *testing.T) { 84 coreConfig := &vault.CoreConfig{ 85 CredentialBackends: map[string]logical.Factory{ 86 "ldap": credLdap.Factory, 87 }, 88 EnableRaw: true, 89 } 90 cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{ 91 HandlerFunc: vaulthttp.Handler, 92 }) 93 cluster.Start() 94 defer cluster.Cleanup() 95 96 core := cluster.Cores[0].Core 97 vault.TestWaitActive(t, core) 98 client := cluster.Cores[0].Client 99 100 // Enable LDAP auth 101 err := client.Sys().EnableAuthWithOptions("ldap", &api.EnableAuthOptions{ 102 Type: "ldap", 103 }) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 // Configure LDAP auth 109 _, err = client.Logical().Write("auth/ldap/config", map[string]interface{}{ 110 "url": "ldap://ldap.forumsys.com", 111 "userattr": "uid", 112 "userdn": "dc=example,dc=com", 113 "groupdn": "dc=example,dc=com", 114 "binddn": "cn=read-only-admin,dc=example,dc=com", 115 }) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 // Create group in LDAP auth 121 _, err = client.Logical().Write("auth/ldap/groups/testgroup1", map[string]interface{}{ 122 "policies": "testgroup1-policy", 123 }) 124 if err != nil { 125 t.Fatal(err) 126 } 127 128 // Create user in LDAP auth. We add two groups, but we should filter out 129 // the ones that don't match aliases later (we will check for this) 130 _, err = client.Logical().Write("auth/ldap/users/tesla", map[string]interface{}{ 131 "policies": "default", 132 "groups": "testgroup1,testgroup2", 133 }) 134 if err != nil { 135 t.Fatal(err) 136 } 137 138 // Login using LDAP 139 secret, err := client.Logical().Write("auth/ldap/login/tesla", map[string]interface{}{ 140 "password": "password", 141 }) 142 if err != nil { 143 t.Fatal(err) 144 } 145 ldapClientToken := secret.Auth.ClientToken 146 147 expectedPolicies := []string{ 148 "default", 149 "testgroup1-policy", 150 } 151 if !reflect.DeepEqual(expectedPolicies, secret.Auth.Policies) { 152 t.Fatalf("bad: identity policies; expected: %#v\nactual: %#v", expectedPolicies, secret.Auth.Policies) 153 } 154 155 // At this point there shouldn't be any identity policy on the token 156 secret, err = client.Logical().Write("auth/token/lookup", map[string]interface{}{ 157 "token": ldapClientToken, 158 }) 159 if err != nil { 160 t.Fatal(err) 161 } 162 _, ok := secret.Data["identity_policies"] 163 if ok { 164 t.Fatalf("identity_policies should not have been set") 165 } 166 167 // Extract the entity ID of the token and set some policies on the entity 168 entityID := secret.Data["entity_id"].(string) 169 _, err = client.Logical().Write("identity/entity/id/"+entityID, map[string]interface{}{ 170 "policies": []string{ 171 "entity_policy_1", 172 "entity_policy_2", 173 }, 174 }) 175 if err != nil { 176 t.Fatal(err) 177 } 178 179 // Lookup the token and expect entity policies on the token 180 secret, err = client.Logical().Write("auth/token/lookup", map[string]interface{}{ 181 "token": ldapClientToken, 182 }) 183 if err != nil { 184 t.Fatal(err) 185 } 186 identityPolicies := secret.Data["identity_policies"].([]interface{}) 187 var actualPolicies []string 188 for _, item := range identityPolicies { 189 actualPolicies = append(actualPolicies, item.(string)) 190 } 191 sort.Strings(actualPolicies) 192 193 expectedPolicies = []string{ 194 "entity_policy_1", 195 "entity_policy_2", 196 } 197 sort.Strings(expectedPolicies) 198 if !reflect.DeepEqual(expectedPolicies, actualPolicies) { 199 t.Fatalf("bad: identity policies; expected: %#v\nactual: %#v", expectedPolicies, actualPolicies) 200 } 201 202 // Create identity group and add entity as its member 203 secret, err = client.Logical().Write("identity/group", map[string]interface{}{ 204 "policies": []string{ 205 "group_policy_1", 206 "group_policy_2", 207 }, 208 "member_entity_ids": []string{ 209 entityID, 210 }, 211 }) 212 if err != nil { 213 t.Fatal(err) 214 } 215 216 // Lookup token and expect both entity and group policies on the token 217 secret, err = client.Logical().Write("auth/token/lookup", map[string]interface{}{ 218 "token": ldapClientToken, 219 }) 220 if err != nil { 221 t.Fatal(err) 222 } 223 identityPolicies = secret.Data["identity_policies"].([]interface{}) 224 actualPolicies = nil 225 for _, item := range identityPolicies { 226 actualPolicies = append(actualPolicies, item.(string)) 227 } 228 sort.Strings(actualPolicies) 229 230 expectedPolicies = []string{ 231 "entity_policy_1", 232 "entity_policy_2", 233 "group_policy_1", 234 "group_policy_2", 235 } 236 sort.Strings(expectedPolicies) 237 if !reflect.DeepEqual(expectedPolicies, actualPolicies) { 238 t.Fatalf("bad: identity policies; expected: %#v\nactual: %#v", expectedPolicies, actualPolicies) 239 } 240 241 // Create an external group and renew the token. This should add external 242 // group policies to the token. 243 auths, err := client.Sys().ListAuth() 244 if err != nil { 245 t.Fatal(err) 246 } 247 ldapMountAccessor1 := auths["ldap/"].Accessor 248 249 // Create an external group 250 secret, err = client.Logical().Write("identity/group", map[string]interface{}{ 251 "type": "external", 252 "policies": []string{ 253 "external_group_policy_1", 254 "external_group_policy_2", 255 }, 256 }) 257 if err != nil { 258 t.Fatal(err) 259 } 260 ldapExtGroupID1 := secret.Data["id"].(string) 261 262 // Associate a group from LDAP auth as a group-alias in the external group 263 _, err = client.Logical().Write("identity/group-alias", map[string]interface{}{ 264 "name": "testgroup1", 265 "mount_accessor": ldapMountAccessor1, 266 "canonical_id": ldapExtGroupID1, 267 }) 268 if err != nil { 269 t.Fatal(err) 270 } 271 272 // Renew token to refresh external group memberships 273 secret, err = client.Auth().Token().Renew(ldapClientToken, 10) 274 if err != nil { 275 t.Fatal(err) 276 } 277 278 // Lookup token and expect entity, group and external group policies on the 279 // token 280 secret, err = client.Logical().Write("auth/token/lookup", map[string]interface{}{ 281 "token": ldapClientToken, 282 }) 283 if err != nil { 284 t.Fatal(err) 285 } 286 identityPolicies = secret.Data["identity_policies"].([]interface{}) 287 actualPolicies = nil 288 for _, item := range identityPolicies { 289 actualPolicies = append(actualPolicies, item.(string)) 290 } 291 sort.Strings(actualPolicies) 292 293 expectedPolicies = []string{ 294 "entity_policy_1", 295 "entity_policy_2", 296 "group_policy_1", 297 "group_policy_2", 298 "external_group_policy_1", 299 "external_group_policy_2", 300 } 301 sort.Strings(expectedPolicies) 302 if !reflect.DeepEqual(expectedPolicies, actualPolicies) { 303 t.Fatalf("bad: identity policies; expected: %#v\nactual: %#v", expectedPolicies, actualPolicies) 304 } 305 306 // Log in and get a new token, then renew it. See issue #4829. The logic is 307 // continued after the next block. 308 secret, err = client.Logical().Write("auth/ldap/login/tesla", map[string]interface{}{ 309 "password": "password", 310 }) 311 if err != nil { 312 t.Fatal(err) 313 } 314 token4829 := secret.Auth.ClientToken 315 316 // Check that the lease for the token contains only the single group; this 317 // should be true for both as one was fresh and the other was a renew 318 // (which is why we do the renew check on the 4839 token after this block) 319 secret, err = client.Logical().List("sys/raw/sys/expire/id/auth/ldap/login/tesla/") 320 if err != nil { 321 t.Fatal(err) 322 } 323 for _, key := range secret.Data["keys"].([]interface{}) { 324 secret, err := client.Logical().Read("sys/raw/sys/expire/id/auth/ldap/login/tesla/" + key.(string)) 325 if err != nil { 326 t.Fatal(err) 327 } 328 //t.Logf("%#v", *secret) 329 var resp logical.Response 330 if err := jsonutil.DecodeJSON([]byte(secret.Data["value"].(string)), &resp); err != nil { 331 t.Fatal(err) 332 } 333 if len(resp.Auth.GroupAliases) != 1 || resp.Auth.GroupAliases[0].Name != "testgroup1" { 334 t.Fatalf("bad: %#v", resp.Auth.GroupAliases) 335 } 336 } 337 338 secret, err = client.Auth().Token().Renew(token4829, 10) 339 if err != nil { 340 t.Fatal(err) 341 } 342} 343 344func TestTokenStore_CIDRBlocks(t *testing.T) { 345 testPolicy := ` 346path "auth/token/create" { 347 capabilities = ["update"] 348} 349` 350 351 cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ 352 HandlerFunc: vaulthttp.Handler, 353 }) 354 cluster.Start() 355 defer cluster.Cleanup() 356 357 core := cluster.Cores[0].Core 358 vault.TestWaitActive(t, core) 359 client := cluster.Cores[0].Client 360 rootToken := client.Token() 361 362 var err error 363 var secret *api.Secret 364 365 _, err = client.Logical().Write("sys/policies/acl/test", map[string]interface{}{ 366 "policy": testPolicy, 367 }) 368 if err != nil { 369 t.Fatal(err) 370 } 371 372 // Test normally 373 _, err = client.Logical().Write("auth/token/roles/testrole", map[string]interface{}{ 374 "bound_cidrs": []string{}, 375 }) 376 if err != nil { 377 t.Fatal(err) 378 } 379 secret, err = client.Auth().Token().CreateWithRole(&api.TokenCreateRequest{ 380 Policies: []string{"default"}, 381 }, "testrole") 382 if err != nil { 383 t.Fatal(err) 384 } 385 client.SetToken(secret.Auth.ClientToken) 386 _, err = client.Auth().Token().LookupSelf() 387 if err != nil { 388 t.Fatal(err) 389 } 390 391 // CIDR blocks, containing localhost 392 client.SetToken(rootToken) 393 _, err = client.Logical().Write("auth/token/roles/testrole", map[string]interface{}{ 394 "bound_cidrs": []string{"127.0.0.1/32", "1.2.3.4/8", "5.6.7.8/24"}, 395 "allowed_policies": "test", 396 }) 397 if err != nil { 398 t.Fatal(err) 399 } 400 secret, err = client.Auth().Token().CreateWithRole(&api.TokenCreateRequest{ 401 Policies: []string{"test", "default"}, 402 }, "testrole") 403 if err != nil { 404 t.Fatal(err) 405 } 406 client.SetToken(secret.Auth.ClientToken) 407 _, err = client.Auth().Token().LookupSelf() 408 if err != nil { 409 t.Fatal(err) 410 } 411 412 // Before moving on, validate that a child token created from this token 413 // inherits the bound cidr blocks 414 client.SetToken(secret.Auth.ClientToken) 415 childSecret, err := client.Auth().Token().Create(&api.TokenCreateRequest{ 416 Policies: []string{"default"}, 417 }) 418 if err != nil { 419 t.Fatal(err) 420 } 421 if err != nil { 422 t.Fatal(err) 423 } 424 client.SetToken(childSecret.Auth.ClientToken) 425 childInfo, err := client.Auth().Token().LookupSelf() 426 if err != nil { 427 t.Fatal(err) 428 } 429 if diff := deep.Equal(childInfo.Data["bound_cidrs"], []interface{}{"127.0.0.1", "1.2.3.4/8", "5.6.7.8/24"}); diff != nil { 430 t.Fatal(diff) 431 } 432 433 // CIDR blocks, not containing localhost (should fail) 434 client.SetToken(rootToken) 435 _, err = client.Logical().Write("auth/token/roles/testrole", map[string]interface{}{ 436 "bound_cidrs": []string{"1.2.3.4/8", "5.6.7.8/24"}, 437 }) 438 if err != nil { 439 t.Fatal(err) 440 } 441 secret, err = client.Auth().Token().CreateWithRole(&api.TokenCreateRequest{ 442 Policies: []string{"default"}, 443 }, "testrole") 444 if err != nil { 445 t.Fatal(err) 446 } 447 client.SetToken(secret.Auth.ClientToken) 448 _, err = client.Auth().Token().LookupSelf() 449 if err == nil { 450 t.Fatal("expected error") 451 } 452 if !strings.Contains(err.Error(), "permission denied") { 453 t.Fatalf("unexpected error: %v", err) 454 } 455 456 // Root token, no ttl, should work 457 client.SetToken(rootToken) 458 _, err = client.Logical().Write("auth/token/roles/testrole", map[string]interface{}{ 459 "bound_cidrs": []string{"1.2.3.4/8", "5.6.7.8/24"}, 460 "allowed_policies": "", 461 }) 462 if err != nil { 463 t.Fatal(err) 464 } 465 secret, err = client.Auth().Token().CreateWithRole(&api.TokenCreateRequest{}, "testrole") 466 if err != nil { 467 t.Fatal(err) 468 } 469 client.SetToken(secret.Auth.ClientToken) 470 _, err = client.Auth().Token().LookupSelf() 471 if err != nil { 472 t.Fatal(err) 473 } 474 475 // Root token, ttl, should not work 476 client.SetToken(rootToken) 477 _, err = client.Logical().Write("auth/token/roles/testrole", map[string]interface{}{ 478 "bound_cidrs": []string{"1.2.3.4/8", "5.6.7.8/24"}, 479 "period": 3600, 480 }) 481 if err != nil { 482 t.Fatal(err) 483 } 484 secret, err = client.Auth().Token().CreateWithRole(&api.TokenCreateRequest{}, "testrole") 485 if err != nil { 486 t.Fatal(err) 487 } 488 client.SetToken(secret.Auth.ClientToken) 489 _, err = client.Auth().Token().LookupSelf() 490 if err == nil { 491 t.Fatal("expected error") 492 } 493 if !strings.Contains(err.Error(), "permission denied") { 494 t.Fatalf("unexpected error: %v", err) 495 } 496} 497 498func TestTokenStore_RevocationOnStartup(t *testing.T) { 499 cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ 500 HandlerFunc: vaulthttp.Handler, 501 NumCores: 1, 502 }) 503 cluster.Start() 504 defer cluster.Cleanup() 505 506 core := cluster.Cores[0].Core 507 vault.TestWaitActive(t, core) 508 client := cluster.Cores[0].Client 509 rootToken := client.Token() 510 511 type leaseEntry struct { 512 LeaseID string `json:"lease_id"` 513 ClientToken string `json:"client_token"` 514 Path string `json:"path"` 515 Data map[string]interface{} `json:"data"` 516 Secret *logical.Secret `json:"secret"` 517 Auth *logical.Auth `json:"auth"` 518 IssueTime time.Time `json:"issue_time"` 519 ExpireTime time.Time `json:"expire_time"` 520 LastRenewalTime time.Time `json:"last_renewal_time"` 521 } 522 523 var secret *api.Secret 524 var err error 525 var tokens []string 526 // Create tokens 527 for i := 0; i < 500; i++ { 528 secret, err = client.Auth().Token().Create(&api.TokenCreateRequest{ 529 Policies: []string{"default"}, 530 }) 531 if err != nil { 532 t.Fatal(err) 533 } 534 tokens = append(tokens, secret.Auth.ClientToken) 535 } 536 537 const tokenPath string = "sys/raw/sys/token/id/" 538 secret, err = client.Logical().List(tokenPath) 539 if err != nil { 540 t.Fatal(err) 541 } 542 totalTokens := len(secret.Data["keys"].([]interface{})) 543 544 // Get the list of leases 545 const leasePath string = "sys/raw/sys/expire/id/auth/token/create/" 546 secret, err = client.Logical().List(leasePath) 547 if err != nil { 548 t.Fatal(err) 549 } 550 leases := secret.Data["keys"].([]interface{}) 551 if len(leases) != 500 { 552 t.Fatalf("unexpected number of leases: %d", len(leases)) 553 } 554 555 // Holds non-root leases 556 var validLeases []string 557 // Fake times in the past 558 for _, lease := range leases { 559 secret, err = client.Logical().Read(leasePath + lease.(string)) 560 var entry leaseEntry 561 if err := jsonutil.DecodeJSON([]byte(secret.Data["value"].(string)), &entry); err != nil { 562 t.Fatal(err) 563 } 564 if entry.ExpireTime.IsZero() { 565 continue 566 } 567 validLeases = append(validLeases, lease.(string)) 568 entry.IssueTime = entry.IssueTime.Add(-1 * time.Hour * 24 * 365) 569 entry.ExpireTime = entry.ExpireTime.Add(-1 * time.Hour * 24 * 365) 570 jsonEntry, err := jsonutil.EncodeJSON(&entry) 571 if err != nil { 572 t.Fatal(err) 573 } 574 if _, err := client.Logical().Write(leasePath+lease.(string), map[string]interface{}{ 575 "value": string(jsonEntry), 576 }); err != nil { 577 t.Fatal(err) 578 } 579 } 580 581 if err := client.Sys().Seal(); err != nil { 582 t.Fatal(err) 583 } 584 585 var status *api.SealStatusResponse 586 for i := 0; i < len(cluster.BarrierKeys); i++ { 587 status, err = client.Sys().Unseal(string(base64.StdEncoding.EncodeToString(cluster.BarrierKeys[i]))) 588 if err != nil { 589 t.Fatal(err) 590 } 591 if !status.Sealed { 592 break 593 } 594 } 595 if status.Sealed { 596 t.Fatal("did not unseal properly") 597 } 598 599 // Give lease loading some time to process 600 time.Sleep(5 * time.Second) 601 602 for i, token := range tokens { 603 client.SetToken(token) 604 _, err := client.Logical().Write("cubbyhole/foo", map[string]interface{}{ 605 "value": "bar", 606 }) 607 if err == nil { 608 t.Errorf("expected error but did not get one, token num %d", i) 609 } 610 } 611 612 expectedLeases := len(leases) - len(validLeases) 613 614 client.SetToken(rootToken) 615 secret, err = client.Logical().List(leasePath) 616 if err != nil { 617 t.Fatal(err) 618 } 619 620 switch { 621 case secret == nil: 622 if expectedLeases != 0 { 623 t.Fatalf("nil secret back but expected %d leases", expectedLeases) 624 } 625 626 case secret.Data == nil: 627 if expectedLeases != 0 { 628 t.Fatalf("nil secret data back but expected %d leases, secret is %#v", expectedLeases, *secret) 629 } 630 631 default: 632 leasesLeft := len(secret.Data["keys"].([]interface{})) 633 if leasesLeft != expectedLeases { 634 t.Fatalf("found %d leases left, expected %d", leasesLeft, expectedLeases) 635 } 636 } 637 638 expectedTokens := totalTokens - len(validLeases) 639 secret, err = client.Logical().List(tokenPath) 640 if err != nil { 641 t.Fatal(err) 642 } 643 tokensLeft := len(secret.Data["keys"].([]interface{})) 644 if tokensLeft != expectedTokens { 645 t.Fatalf("found %d tokens left, expected %d", tokensLeft, expectedTokens) 646 } 647} 648