1package vault 2 3import ( 4 "context" 5 "crypto/sha256" 6 "encoding/base64" 7 "encoding/hex" 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "reflect" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/fatih/structs" 18 "github.com/go-test/deep" 19 hclog "github.com/hashicorp/go-hclog" 20 "github.com/hashicorp/vault/audit" 21 "github.com/hashicorp/vault/helper/builtinplugins" 22 "github.com/hashicorp/vault/helper/identity" 23 "github.com/hashicorp/vault/helper/namespace" 24 "github.com/hashicorp/vault/sdk/framework" 25 "github.com/hashicorp/vault/sdk/helper/consts" 26 "github.com/hashicorp/vault/sdk/helper/jsonutil" 27 "github.com/hashicorp/vault/sdk/helper/salt" 28 "github.com/hashicorp/vault/sdk/logical" 29 "github.com/hashicorp/vault/sdk/version" 30 "github.com/mitchellh/mapstructure" 31) 32 33func TestSystemBackend_RootPaths(t *testing.T) { 34 expected := []string{ 35 "auth/*", 36 "remount", 37 "audit", 38 "audit/*", 39 "raw", 40 "raw/*", 41 "replication/primary/secondary-token", 42 "replication/performance/primary/secondary-token", 43 "replication/dr/primary/secondary-token", 44 "replication/reindex", 45 "replication/dr/reindex", 46 "replication/performance/reindex", 47 "rotate", 48 "config/cors", 49 "config/auditing/*", 50 "config/ui/headers/*", 51 "plugins/catalog/*", 52 "revoke-prefix/*", 53 "revoke-force/*", 54 "leases/revoke-prefix/*", 55 "leases/revoke-force/*", 56 "leases/lookup/*", 57 } 58 59 b := testSystemBackend(t) 60 actual := b.SpecialPaths().Root 61 if !reflect.DeepEqual(actual, expected) { 62 t.Fatalf("bad: mismatch\nexpected:\n%#v\ngot:\n%#v", expected, actual) 63 } 64} 65 66func TestSystemConfigCORS(t *testing.T) { 67 b := testSystemBackend(t) 68 _, barrier, _ := mockBarrier(t) 69 view := NewBarrierView(barrier, "") 70 b.(*SystemBackend).Core.systemBarrierView = view 71 72 req := logical.TestRequest(t, logical.UpdateOperation, "config/cors") 73 req.Data["allowed_origins"] = "http://www.example.com" 74 req.Data["allowed_headers"] = "X-Custom-Header" 75 _, err := b.HandleRequest(namespace.RootContext(nil), req) 76 if err != nil { 77 t.Fatal(err) 78 } 79 80 expected := &logical.Response{ 81 Data: map[string]interface{}{ 82 "enabled": true, 83 "allowed_origins": []string{"http://www.example.com"}, 84 "allowed_headers": append(StdAllowedHeaders, "X-Custom-Header"), 85 }, 86 } 87 88 req = logical.TestRequest(t, logical.ReadOperation, "config/cors") 89 actual, err := b.HandleRequest(namespace.RootContext(nil), req) 90 if err != nil { 91 t.Fatalf("err: %v", err) 92 } 93 94 if !reflect.DeepEqual(actual, expected) { 95 t.Fatalf("bad: %#v", actual) 96 } 97 98 // Do it again. Bug #6182 99 req = logical.TestRequest(t, logical.UpdateOperation, "config/cors") 100 req.Data["allowed_origins"] = "http://www.example.com" 101 req.Data["allowed_headers"] = "X-Custom-Header" 102 _, err = b.HandleRequest(namespace.RootContext(nil), req) 103 if err != nil { 104 t.Fatal(err) 105 } 106 107 req = logical.TestRequest(t, logical.ReadOperation, "config/cors") 108 actual, err = b.HandleRequest(namespace.RootContext(nil), req) 109 if err != nil { 110 t.Fatalf("err: %v", err) 111 } 112 113 if !reflect.DeepEqual(actual, expected) { 114 t.Fatalf("bad: %#v", actual) 115 } 116 117 req = logical.TestRequest(t, logical.DeleteOperation, "config/cors") 118 _, err = b.HandleRequest(namespace.RootContext(nil), req) 119 if err != nil { 120 t.Fatalf("err: %v", err) 121 } 122 123 req = logical.TestRequest(t, logical.ReadOperation, "config/cors") 124 actual, err = b.HandleRequest(namespace.RootContext(nil), req) 125 if err != nil { 126 t.Fatalf("err: %v", err) 127 } 128 129 expected = &logical.Response{ 130 Data: map[string]interface{}{ 131 "enabled": false, 132 }, 133 } 134 135 if !reflect.DeepEqual(actual, expected) { 136 t.Fatalf("DELETE FAILED -- bad: %#v", actual) 137 } 138 139} 140 141func TestSystemBackend_mounts(t *testing.T) { 142 b := testSystemBackend(t) 143 req := logical.TestRequest(t, logical.ReadOperation, "mounts") 144 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 145 if err != nil { 146 t.Fatalf("err: %v", err) 147 } 148 149 // We can't know the pointer address ahead of time so simply 150 // copy what's given 151 exp := map[string]interface{}{ 152 "secret/": map[string]interface{}{ 153 "type": "kv", 154 "description": "key/value secret storage", 155 "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], 156 "uuid": resp.Data["secret/"].(map[string]interface{})["uuid"], 157 "config": map[string]interface{}{ 158 "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 159 "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 160 "force_no_cache": false, 161 }, 162 "local": false, 163 "seal_wrap": false, 164 "options": map[string]string{ 165 "version": "1", 166 }, 167 }, 168 "sys/": map[string]interface{}{ 169 "type": "system", 170 "description": "system endpoints used for control, policy and debugging", 171 "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], 172 "uuid": resp.Data["sys/"].(map[string]interface{})["uuid"], 173 "config": map[string]interface{}{ 174 "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 175 "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 176 "force_no_cache": false, 177 "passthrough_request_headers": []string{"Accept"}, 178 }, 179 "local": false, 180 "seal_wrap": false, 181 "options": map[string]string(nil), 182 }, 183 "cubbyhole/": map[string]interface{}{ 184 "description": "per-token private secret storage", 185 "type": "cubbyhole", 186 "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], 187 "uuid": resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], 188 "config": map[string]interface{}{ 189 "default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 190 "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 191 "force_no_cache": false, 192 }, 193 "local": true, 194 "seal_wrap": false, 195 "options": map[string]string(nil), 196 }, 197 "identity/": map[string]interface{}{ 198 "description": "identity store", 199 "type": "identity", 200 "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], 201 "uuid": resp.Data["identity/"].(map[string]interface{})["uuid"], 202 "config": map[string]interface{}{ 203 "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 204 "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 205 "force_no_cache": false, 206 }, 207 "local": false, 208 "seal_wrap": false, 209 "options": map[string]string(nil), 210 }, 211 } 212 if diff := deep.Equal(resp.Data, exp); len(diff) > 0 { 213 t.Fatalf("bad, diff: %#v", diff) 214 } 215} 216 217func TestSystemBackend_mount(t *testing.T) { 218 b := testSystemBackend(t) 219 220 req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/") 221 req.Data["type"] = "kv" 222 req.Data["config"] = map[string]interface{}{ 223 "default_lease_ttl": "35m", 224 "max_lease_ttl": "45m", 225 } 226 req.Data["local"] = true 227 req.Data["seal_wrap"] = true 228 req.Data["options"] = map[string]string{ 229 "version": "1", 230 } 231 232 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 233 if err != nil { 234 t.Fatalf("err: %v", err) 235 } 236 if resp != nil { 237 t.Fatalf("bad: %v", resp) 238 } 239 240 req = logical.TestRequest(t, logical.ReadOperation, "mounts") 241 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 242 if err != nil { 243 t.Fatalf("err: %v", err) 244 } 245 246 // We can't know the pointer address ahead of time so simply 247 // copy what's given 248 exp := map[string]interface{}{ 249 "secret/": map[string]interface{}{ 250 "type": "kv", 251 "description": "key/value secret storage", 252 "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], 253 "uuid": resp.Data["secret/"].(map[string]interface{})["uuid"], 254 "config": map[string]interface{}{ 255 "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 256 "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 257 "force_no_cache": false, 258 }, 259 "local": false, 260 "seal_wrap": false, 261 "options": map[string]string{ 262 "version": "1", 263 }, 264 }, 265 "sys/": map[string]interface{}{ 266 "type": "system", 267 "description": "system endpoints used for control, policy and debugging", 268 "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], 269 "uuid": resp.Data["sys/"].(map[string]interface{})["uuid"], 270 "config": map[string]interface{}{ 271 "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 272 "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 273 "force_no_cache": false, 274 "passthrough_request_headers": []string{"Accept"}, 275 }, 276 "local": false, 277 "seal_wrap": false, 278 "options": map[string]string(nil), 279 }, 280 "cubbyhole/": map[string]interface{}{ 281 "description": "per-token private secret storage", 282 "type": "cubbyhole", 283 "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], 284 "uuid": resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], 285 "config": map[string]interface{}{ 286 "default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 287 "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 288 "force_no_cache": false, 289 }, 290 "local": true, 291 "seal_wrap": false, 292 "options": map[string]string(nil), 293 }, 294 "identity/": map[string]interface{}{ 295 "description": "identity store", 296 "type": "identity", 297 "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], 298 "uuid": resp.Data["identity/"].(map[string]interface{})["uuid"], 299 "config": map[string]interface{}{ 300 "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 301 "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 302 "force_no_cache": false, 303 }, 304 "local": false, 305 "seal_wrap": false, 306 "options": map[string]string(nil), 307 }, 308 "prod/secret/": map[string]interface{}{ 309 "description": "", 310 "type": "kv", 311 "accessor": resp.Data["prod/secret/"].(map[string]interface{})["accessor"], 312 "uuid": resp.Data["prod/secret/"].(map[string]interface{})["uuid"], 313 "config": map[string]interface{}{ 314 "default_lease_ttl": int64(2100), 315 "max_lease_ttl": int64(2700), 316 "force_no_cache": false, 317 }, 318 "local": true, 319 "seal_wrap": true, 320 "options": map[string]string{ 321 "version": "1", 322 }, 323 }, 324 } 325 if diff := deep.Equal(resp.Data, exp); len(diff) > 0 { 326 t.Fatalf("bad: diff: %#v", diff) 327 } 328 329} 330 331func TestSystemBackend_mount_force_no_cache(t *testing.T) { 332 core, b, _ := testCoreSystemBackend(t) 333 334 req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/") 335 req.Data["type"] = "kv" 336 req.Data["config"] = map[string]interface{}{ 337 "force_no_cache": true, 338 } 339 340 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 341 if err != nil { 342 t.Fatalf("err: %v", err) 343 } 344 if resp != nil { 345 t.Fatalf("bad: %v", resp) 346 } 347 348 mountEntry := core.router.MatchingMountEntry(namespace.RootContext(nil), "prod/secret/") 349 if mountEntry == nil { 350 t.Fatalf("missing mount entry") 351 } 352 if !mountEntry.Config.ForceNoCache { 353 t.Fatalf("bad config %#v", mountEntry) 354 } 355} 356 357func TestSystemBackend_mount_invalid(t *testing.T) { 358 b := testSystemBackend(t) 359 360 req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/") 361 req.Data["type"] = "nope" 362 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 363 if err != logical.ErrInvalidRequest { 364 t.Fatalf("err: %v", err) 365 } 366 if resp.Data["error"] != `plugin not found in the catalog: nope` { 367 t.Fatalf("bad: %v", resp) 368 } 369} 370 371func TestSystemBackend_unmount(t *testing.T) { 372 b := testSystemBackend(t) 373 374 req := logical.TestRequest(t, logical.DeleteOperation, "mounts/secret/") 375 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 376 if err != nil { 377 t.Fatalf("err: %v", err) 378 } 379 if resp != nil { 380 t.Fatalf("bad: %v", resp) 381 } 382} 383 384var capabilitiesPolicy = ` 385name = "test" 386path "foo/bar*" { 387 capabilities = ["create", "sudo", "update"] 388} 389path "sys/capabilities*" { 390 capabilities = ["update"] 391} 392path "bar/baz" { 393 capabilities = ["read", "update"] 394} 395path "bar/baz" { 396 capabilities = ["delete"] 397} 398` 399 400func TestSystemBackend_PathCapabilities(t *testing.T) { 401 var resp *logical.Response 402 var err error 403 404 core, b, rootToken := testCoreSystemBackend(t) 405 406 policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy) 407 err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy) 408 if err != nil { 409 t.Fatalf("err: %v", err) 410 } 411 412 path1 := "foo/bar" 413 path2 := "foo/bar/sample" 414 path3 := "sys/capabilities" 415 path4 := "bar/baz" 416 417 rootCheckFunc := func(t *testing.T, resp *logical.Response) { 418 // All the paths should have "root" as the capability 419 expectedRoot := []string{"root"} 420 if !reflect.DeepEqual(resp.Data[path1], expectedRoot) || 421 !reflect.DeepEqual(resp.Data[path2], expectedRoot) || 422 !reflect.DeepEqual(resp.Data[path3], expectedRoot) || 423 !reflect.DeepEqual(resp.Data[path4], expectedRoot) { 424 t.Fatalf("bad: capabilities; expected: %#v, actual: %#v", expectedRoot, resp.Data) 425 } 426 } 427 428 // Check the capabilities using the root token 429 resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ 430 Path: "capabilities", 431 Operation: logical.UpdateOperation, 432 Data: map[string]interface{}{ 433 "paths": []string{path1, path2, path3, path4}, 434 "token": rootToken, 435 }, 436 }) 437 if err != nil || (resp != nil && resp.IsError()) { 438 t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) 439 } 440 rootCheckFunc(t, resp) 441 442 // Check the capabilities using capabilities-self 443 resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ 444 ClientToken: rootToken, 445 Path: "capabilities-self", 446 Operation: logical.UpdateOperation, 447 Data: map[string]interface{}{ 448 "paths": []string{path1, path2, path3, path4}, 449 }, 450 }) 451 if err != nil || (resp != nil && resp.IsError()) { 452 t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) 453 } 454 rootCheckFunc(t, resp) 455 456 // Lookup the accessor of the root token 457 te, err := core.tokenStore.Lookup(namespace.RootContext(nil), rootToken) 458 if err != nil { 459 t.Fatal(err) 460 } 461 462 // Check the capabilities using capabilities-accessor endpoint 463 resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ 464 Path: "capabilities-accessor", 465 Operation: logical.UpdateOperation, 466 Data: map[string]interface{}{ 467 "paths": []string{path1, path2, path3, path4}, 468 "accessor": te.Accessor, 469 }, 470 }) 471 if err != nil || (resp != nil && resp.IsError()) { 472 t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) 473 } 474 rootCheckFunc(t, resp) 475 476 // Create a non-root token 477 testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"}) 478 479 nonRootCheckFunc := func(t *testing.T, resp *logical.Response) { 480 expected1 := []string{"create", "sudo", "update"} 481 expected2 := expected1 482 expected3 := []string{"update"} 483 expected4 := []string{"delete", "read", "update"} 484 485 if !reflect.DeepEqual(resp.Data[path1], expected1) || 486 !reflect.DeepEqual(resp.Data[path2], expected2) || 487 !reflect.DeepEqual(resp.Data[path3], expected3) || 488 !reflect.DeepEqual(resp.Data[path4], expected4) { 489 t.Fatalf("bad: capabilities; actual: %#v", resp.Data) 490 } 491 } 492 493 // Check the capabilities using a non-root token 494 resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ 495 Path: "capabilities", 496 Operation: logical.UpdateOperation, 497 Data: map[string]interface{}{ 498 "paths": []string{path1, path2, path3, path4}, 499 "token": "tokenid", 500 }, 501 }) 502 if err != nil || (resp != nil && resp.IsError()) { 503 t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) 504 } 505 nonRootCheckFunc(t, resp) 506 507 // Check the capabilities of a non-root token using capabilities-self 508 // endpoint 509 resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ 510 ClientToken: "tokenid", 511 Path: "capabilities-self", 512 Operation: logical.UpdateOperation, 513 Data: map[string]interface{}{ 514 "paths": []string{path1, path2, path3, path4}, 515 }, 516 }) 517 if err != nil || (resp != nil && resp.IsError()) { 518 t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) 519 } 520 nonRootCheckFunc(t, resp) 521 522 // Lookup the accessor of the non-root token 523 te, err = core.tokenStore.Lookup(namespace.RootContext(nil), "tokenid") 524 if err != nil { 525 t.Fatal(err) 526 } 527 528 // Check the capabilities using a non-root token using 529 // capabilities-accessor endpoint 530 resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ 531 Path: "capabilities-accessor", 532 Operation: logical.UpdateOperation, 533 Data: map[string]interface{}{ 534 "paths": []string{path1, path2, path3, path4}, 535 "accessor": te.Accessor, 536 }, 537 }) 538 if err != nil || (resp != nil && resp.IsError()) { 539 t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) 540 } 541 nonRootCheckFunc(t, resp) 542} 543 544func TestSystemBackend_Capabilities_BC(t *testing.T) { 545 testCapabilities(t, "capabilities") 546 testCapabilities(t, "capabilities-self") 547} 548 549func testCapabilities(t *testing.T, endpoint string) { 550 core, b, rootToken := testCoreSystemBackend(t) 551 req := logical.TestRequest(t, logical.UpdateOperation, endpoint) 552 if endpoint == "capabilities-self" { 553 req.ClientToken = rootToken 554 } else { 555 req.Data["token"] = rootToken 556 } 557 req.Data["path"] = "any_path" 558 559 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 560 if err != nil { 561 t.Fatal(err) 562 } 563 if resp == nil { 564 t.Fatalf("bad: %v", resp) 565 } 566 567 actual := resp.Data["capabilities"] 568 expected := []string{"root"} 569 if !reflect.DeepEqual(actual, expected) { 570 t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) 571 } 572 573 policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy) 574 err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy) 575 if err != nil { 576 t.Fatalf("err: %v", err) 577 } 578 579 testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"}) 580 req = logical.TestRequest(t, logical.UpdateOperation, endpoint) 581 if endpoint == "capabilities-self" { 582 req.ClientToken = "tokenid" 583 } else { 584 req.Data["token"] = "tokenid" 585 } 586 req.Data["path"] = "foo/bar" 587 588 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 589 if err != nil { 590 t.Fatalf("err: %v", err) 591 } 592 if resp == nil { 593 t.Fatalf("bad: %v", resp) 594 } 595 596 actual = resp.Data["capabilities"] 597 expected = []string{"create", "sudo", "update"} 598 if !reflect.DeepEqual(actual, expected) { 599 t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) 600 } 601} 602 603func TestSystemBackend_CapabilitiesAccessor_BC(t *testing.T) { 604 core, b, rootToken := testCoreSystemBackend(t) 605 te, err := core.tokenStore.Lookup(namespace.RootContext(nil), rootToken) 606 if err != nil { 607 t.Fatal(err) 608 } 609 610 req := logical.TestRequest(t, logical.UpdateOperation, "capabilities-accessor") 611 // Accessor of root token 612 req.Data["accessor"] = te.Accessor 613 req.Data["path"] = "any_path" 614 615 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 616 if err != nil { 617 t.Fatalf("err: %v", err) 618 } 619 if resp == nil { 620 t.Fatalf("bad: %v", resp) 621 } 622 623 actual := resp.Data["capabilities"] 624 expected := []string{"root"} 625 if !reflect.DeepEqual(actual, expected) { 626 t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) 627 } 628 629 policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy) 630 err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy) 631 if err != nil { 632 t.Fatalf("err: %v", err) 633 } 634 635 testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"}) 636 637 te, err = core.tokenStore.Lookup(namespace.RootContext(nil), "tokenid") 638 if err != nil { 639 t.Fatal(err) 640 } 641 642 req = logical.TestRequest(t, logical.UpdateOperation, "capabilities-accessor") 643 req.Data["accessor"] = te.Accessor 644 req.Data["path"] = "foo/bar" 645 646 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 647 if err != nil { 648 t.Fatalf("err: %v", err) 649 } 650 if resp == nil { 651 t.Fatalf("bad: %v", resp) 652 } 653 654 actual = resp.Data["capabilities"] 655 expected = []string{"create", "sudo", "update"} 656 if !reflect.DeepEqual(actual, expected) { 657 t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) 658 } 659} 660 661func TestSystemBackend_remount(t *testing.T) { 662 b := testSystemBackend(t) 663 664 req := logical.TestRequest(t, logical.UpdateOperation, "remount") 665 req.Data["from"] = "secret" 666 req.Data["to"] = "foo" 667 req.Data["config"] = structs.Map(MountConfig{}) 668 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 669 if err != nil { 670 t.Fatalf("err: %v", err) 671 } 672 if resp != nil { 673 t.Fatalf("bad: %v", resp) 674 } 675} 676 677func TestSystemBackend_remount_invalid(t *testing.T) { 678 b := testSystemBackend(t) 679 680 req := logical.TestRequest(t, logical.UpdateOperation, "remount") 681 req.Data["from"] = "unknown" 682 req.Data["to"] = "foo" 683 req.Data["config"] = structs.Map(MountConfig{}) 684 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 685 if err != logical.ErrInvalidRequest { 686 t.Fatalf("err: %v", err) 687 } 688 if resp.Data["error"] != `no matching mount at "unknown/"` { 689 t.Fatalf("bad: %v", resp) 690 } 691} 692 693func TestSystemBackend_remount_system(t *testing.T) { 694 b := testSystemBackend(t) 695 696 req := logical.TestRequest(t, logical.UpdateOperation, "remount") 697 req.Data["from"] = "sys" 698 req.Data["to"] = "foo" 699 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 700 if err != logical.ErrInvalidRequest { 701 t.Fatalf("err: %v", err) 702 } 703 if resp.Data["error"] != `cannot remount "sys/"` { 704 t.Fatalf("bad: %v", resp) 705 } 706} 707 708func TestSystemBackend_leases(t *testing.T) { 709 core, b, root := testCoreSystemBackend(t) 710 711 // Create a key with a lease 712 req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 713 req.Data["foo"] = "bar" 714 req.ClientToken = root 715 resp, err := core.HandleRequest(namespace.RootContext(nil), req) 716 if err != nil { 717 t.Fatalf("err: %v", err) 718 } 719 if resp != nil { 720 t.Fatalf("bad: %#v", resp) 721 } 722 723 // Read a key with a LeaseID 724 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 725 req.ClientToken = root 726 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 727 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 728 if err != nil { 729 t.Fatalf("err: %v", err) 730 } 731 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 732 t.Fatalf("bad: %#v", resp) 733 } 734 735 // Read lease 736 req = logical.TestRequest(t, logical.UpdateOperation, "leases/lookup") 737 req.Data["lease_id"] = resp.Secret.LeaseID 738 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 739 if err != nil { 740 t.Fatalf("err: %v", err) 741 } 742 if resp.Data["renewable"] == nil || resp.Data["renewable"].(bool) { 743 t.Fatal("kv leases are not renewable") 744 } 745 746 // Invalid lease 747 req = logical.TestRequest(t, logical.UpdateOperation, "leases/lookup") 748 req.Data["lease_id"] = "invalid" 749 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 750 if err != logical.ErrInvalidRequest { 751 t.Fatalf("expected invalid request, got err: %v", err) 752 } 753} 754 755func TestSystemBackend_leases_list(t *testing.T) { 756 core, b, root := testCoreSystemBackend(t) 757 758 // Create a key with a lease 759 req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 760 req.Data["foo"] = "bar" 761 req.ClientToken = root 762 resp, err := core.HandleRequest(namespace.RootContext(nil), req) 763 if err != nil { 764 t.Fatalf("err: %v", err) 765 } 766 if resp != nil { 767 t.Fatalf("bad: %#v", resp) 768 } 769 770 // Read a key with a LeaseID 771 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 772 req.ClientToken = root 773 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 774 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 775 if err != nil { 776 t.Fatalf("err: %v", err) 777 } 778 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 779 t.Fatalf("bad: %#v", resp) 780 } 781 782 // List top level 783 req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/") 784 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 785 if err != nil { 786 t.Fatalf("err: %v", err) 787 } 788 if resp == nil || resp.Data == nil { 789 t.Fatalf("bad: %#v", resp) 790 } 791 var keys []string 792 if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil { 793 t.Fatalf("err: %v", err) 794 } 795 if len(keys) != 1 { 796 t.Fatalf("Expected 1 subkey lease, got %d: %#v", len(keys), keys) 797 } 798 if keys[0] != "secret/" { 799 t.Fatal("Expected only secret subkey") 800 } 801 802 // List lease 803 req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret/foo") 804 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 805 if err != nil { 806 t.Fatalf("err: %v", err) 807 } 808 if resp == nil || resp.Data == nil { 809 t.Fatalf("bad: %#v", resp) 810 } 811 keys = []string{} 812 if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil { 813 t.Fatalf("err: %v", err) 814 } 815 if len(keys) != 1 { 816 t.Fatalf("Expected 1 secret lease, got %d: %#v", len(keys), keys) 817 } 818 819 // Generate multiple leases 820 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 821 req.ClientToken = root 822 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 823 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 824 if err != nil { 825 t.Fatalf("err: %v", err) 826 } 827 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 828 t.Fatalf("bad: %#v", resp) 829 } 830 831 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 832 req.ClientToken = root 833 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 834 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 835 if err != nil { 836 t.Fatalf("err: %v", err) 837 } 838 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 839 t.Fatalf("bad: %#v", resp) 840 } 841 842 req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret/foo") 843 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 844 if err != nil { 845 t.Fatalf("err: %v", err) 846 } 847 if resp == nil || resp.Data == nil { 848 t.Fatalf("bad: %#v", resp) 849 } 850 keys = []string{} 851 if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil { 852 t.Fatalf("err: %v", err) 853 } 854 if len(keys) != 3 { 855 t.Fatalf("Expected 3 secret lease, got %d: %#v", len(keys), keys) 856 } 857 858 // Listing subkeys 859 req = logical.TestRequest(t, logical.UpdateOperation, "secret/bar") 860 req.Data["foo"] = "bar" 861 req.ClientToken = root 862 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 863 if err != nil { 864 t.Fatalf("err: %v", err) 865 } 866 if resp != nil { 867 t.Fatalf("bad: %#v", resp) 868 } 869 870 // Read a key with a LeaseID 871 req = logical.TestRequest(t, logical.ReadOperation, "secret/bar") 872 req.ClientToken = root 873 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 874 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 875 if err != nil { 876 t.Fatalf("err: %v", err) 877 } 878 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 879 t.Fatalf("bad: %#v", resp) 880 } 881 882 req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret") 883 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 884 if err != nil { 885 t.Fatalf("err: %v", err) 886 } 887 if resp == nil || resp.Data == nil { 888 t.Fatalf("bad: %#v", resp) 889 } 890 keys = []string{} 891 if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil { 892 t.Fatalf("err: %v", err) 893 } 894 if len(keys) != 2 { 895 t.Fatalf("Expected 2 secret lease, got %d: %#v", len(keys), keys) 896 } 897 expected := []string{"bar/", "foo/"} 898 if !reflect.DeepEqual(expected, keys) { 899 t.Fatalf("exp: %#v, act: %#v", expected, keys) 900 } 901} 902 903func TestSystemBackend_renew(t *testing.T) { 904 core, b, root := testCoreSystemBackend(t) 905 906 // Create a key with a lease 907 req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 908 req.Data["foo"] = "bar" 909 req.ClientToken = root 910 resp, err := core.HandleRequest(namespace.RootContext(nil), req) 911 if err != nil { 912 t.Fatalf("err: %v", err) 913 } 914 if resp != nil { 915 t.Fatalf("bad: %#v", resp) 916 } 917 918 // Read a key with a LeaseID 919 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 920 req.ClientToken = root 921 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 922 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 923 if err != nil { 924 t.Fatalf("err: %v", err) 925 } 926 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 927 t.Fatalf("bad: %#v", resp) 928 } 929 930 // Attempt renew 931 req2 := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID) 932 resp2, err := b.HandleRequest(namespace.RootContext(nil), req2) 933 if err != logical.ErrInvalidRequest { 934 t.Fatalf("err: %v", err) 935 } 936 937 // Should get error about non-renewability 938 if resp2.Data["error"] != "lease is not renewable" { 939 t.Fatalf("bad: %#v", resp) 940 } 941 942 // Add a TTL to the lease 943 req = logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 944 req.Data["foo"] = "bar" 945 req.Data["ttl"] = "180s" 946 req.ClientToken = root 947 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 948 if err != nil { 949 t.Fatalf("err: %v", err) 950 } 951 if resp != nil { 952 t.Fatalf("bad: %#v", resp) 953 } 954 955 // Read a key with a LeaseID 956 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 957 req.ClientToken = root 958 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 959 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 960 if err != nil { 961 t.Fatalf("err: %v", err) 962 } 963 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 964 t.Fatalf("bad: %#v", resp) 965 } 966 967 // Attempt renew 968 req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID) 969 resp2, err = b.HandleRequest(namespace.RootContext(nil), req2) 970 if err != nil { 971 t.Fatalf("err: %v", err) 972 } 973 if resp2.IsError() { 974 t.Fatalf("got an error") 975 } 976 if resp2.Data == nil { 977 t.Fatal("nil data") 978 } 979 if resp.Secret.TTL != 180*time.Second { 980 t.Fatalf("bad lease duration: %v", resp.Secret.TTL) 981 } 982 983 // Test the other route path 984 req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/renew") 985 req2.Data["lease_id"] = resp.Secret.LeaseID 986 resp2, err = b.HandleRequest(namespace.RootContext(nil), req2) 987 if err != nil { 988 t.Fatalf("err: %v", err) 989 } 990 if resp2.IsError() { 991 t.Fatalf("got an error") 992 } 993 if resp2.Data == nil { 994 t.Fatal("nil data") 995 } 996 if resp.Secret.TTL != 180*time.Second { 997 t.Fatalf("bad lease duration: %v", resp.Secret.TTL) 998 } 999 1000 // Test orig path 1001 req2 = logical.TestRequest(t, logical.UpdateOperation, "renew") 1002 req2.Data["lease_id"] = resp.Secret.LeaseID 1003 resp2, err = b.HandleRequest(namespace.RootContext(nil), req2) 1004 if err != nil { 1005 t.Fatalf("err: %v", err) 1006 } 1007 if resp2.IsError() { 1008 t.Fatalf("got an error") 1009 } 1010 if resp2.Data == nil { 1011 t.Fatal("nil data") 1012 } 1013 if resp.Secret.TTL != time.Second*180 { 1014 t.Fatalf("bad lease duration: %v", resp.Secret.TTL) 1015 } 1016} 1017 1018func TestSystemBackend_renew_invalidID(t *testing.T) { 1019 b := testSystemBackend(t) 1020 1021 // Attempt renew 1022 req := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/foobarbaz") 1023 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1024 if err != logical.ErrInvalidRequest { 1025 t.Fatalf("err: %v", err) 1026 } 1027 if resp.Data["error"] != "lease not found" { 1028 t.Fatalf("bad: %v", resp) 1029 } 1030 1031 // Attempt renew with other method 1032 req = logical.TestRequest(t, logical.UpdateOperation, "leases/renew") 1033 req.Data["lease_id"] = "foobarbaz" 1034 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1035 if err != logical.ErrInvalidRequest { 1036 t.Fatalf("err: %v", err) 1037 } 1038 if resp.Data["error"] != "lease not found" { 1039 t.Fatalf("bad: %v", resp) 1040 } 1041} 1042 1043func TestSystemBackend_renew_invalidID_origUrl(t *testing.T) { 1044 b := testSystemBackend(t) 1045 1046 // Attempt renew 1047 req := logical.TestRequest(t, logical.UpdateOperation, "renew/foobarbaz") 1048 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1049 if err != logical.ErrInvalidRequest { 1050 t.Fatalf("err: %v", err) 1051 } 1052 if resp.Data["error"] != "lease not found" { 1053 t.Fatalf("bad: %v", resp) 1054 } 1055 1056 // Attempt renew with other method 1057 req = logical.TestRequest(t, logical.UpdateOperation, "renew") 1058 req.Data["lease_id"] = "foobarbaz" 1059 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1060 if err != logical.ErrInvalidRequest { 1061 t.Fatalf("err: %v", err) 1062 } 1063 if resp.Data["error"] != "lease not found" { 1064 t.Fatalf("bad: %v", resp) 1065 } 1066} 1067 1068func TestSystemBackend_revoke(t *testing.T) { 1069 core, b, root := testCoreSystemBackend(t) 1070 1071 // Create a key with a lease 1072 req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 1073 req.Data["foo"] = "bar" 1074 req.Data["lease"] = "1h" 1075 req.ClientToken = root 1076 resp, err := core.HandleRequest(namespace.RootContext(nil), req) 1077 if err != nil { 1078 t.Fatalf("err: %v", err) 1079 } 1080 if resp != nil { 1081 t.Fatalf("bad: %#v", resp) 1082 } 1083 1084 // Read a key with a LeaseID 1085 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 1086 req.ClientToken = root 1087 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 1088 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 1089 if err != nil { 1090 t.Fatalf("err: %v", err) 1091 } 1092 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 1093 t.Fatalf("bad: %#v", resp) 1094 } 1095 1096 // Attempt revoke 1097 req2 := logical.TestRequest(t, logical.UpdateOperation, "revoke/"+resp.Secret.LeaseID) 1098 resp2, err := b.HandleRequest(namespace.RootContext(nil), req2) 1099 if err != nil { 1100 t.Fatalf("err: %v %#v", err, resp2) 1101 } 1102 if resp2 != nil { 1103 t.Fatalf("bad: %#v", resp) 1104 } 1105 1106 // Attempt renew 1107 req3 := logical.TestRequest(t, logical.UpdateOperation, "renew/"+resp.Secret.LeaseID) 1108 resp3, err := b.HandleRequest(namespace.RootContext(nil), req3) 1109 if err != logical.ErrInvalidRequest { 1110 t.Fatalf("err: %v", err) 1111 } 1112 if resp3.Data["error"] != "lease not found" { 1113 t.Fatalf("bad: %v", *resp3) 1114 } 1115 1116 // Read a key with a LeaseID 1117 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 1118 req.ClientToken = root 1119 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 1120 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 1121 if err != nil { 1122 t.Fatalf("err: %v", err) 1123 } 1124 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 1125 t.Fatalf("bad: %#v", resp) 1126 } 1127 1128 // Test the other route path 1129 req2 = logical.TestRequest(t, logical.UpdateOperation, "revoke") 1130 req2.Data["lease_id"] = resp.Secret.LeaseID 1131 resp2, err = b.HandleRequest(namespace.RootContext(nil), req2) 1132 if err != nil { 1133 t.Fatalf("err: %v %#v", err, resp2) 1134 } 1135 if resp2 != nil { 1136 t.Fatalf("bad: %#v", resp) 1137 } 1138 1139 // Read a key with a LeaseID 1140 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 1141 req.ClientToken = root 1142 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 1143 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 1144 if err != nil { 1145 t.Fatalf("err: %v", err) 1146 } 1147 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 1148 t.Fatalf("bad: %#v", resp) 1149 } 1150 1151 // Test the other route path 1152 req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/revoke") 1153 req2.Data["lease_id"] = resp.Secret.LeaseID 1154 resp2, err = b.HandleRequest(namespace.RootContext(nil), req2) 1155 if err != nil { 1156 t.Fatalf("err: %v %#v", err, resp2) 1157 } 1158 if resp2 != nil { 1159 t.Fatalf("bad: %#v", resp) 1160 } 1161} 1162 1163func TestSystemBackend_revoke_invalidID(t *testing.T) { 1164 b := testSystemBackend(t) 1165 1166 // Attempt revoke 1167 req := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke/foobarbaz") 1168 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1169 if err != nil { 1170 t.Fatalf("err: %v", err) 1171 } 1172 if resp != nil { 1173 t.Fatalf("bad: %v", resp) 1174 } 1175 1176 // Attempt revoke with other method 1177 req = logical.TestRequest(t, logical.UpdateOperation, "leases/revoke") 1178 req.Data["lease_id"] = "foobarbaz" 1179 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1180 if err != nil { 1181 t.Fatalf("err: %v", err) 1182 } 1183 if resp != nil { 1184 t.Fatalf("bad: %v", resp) 1185 } 1186} 1187 1188func TestSystemBackend_revoke_invalidID_origUrl(t *testing.T) { 1189 b := testSystemBackend(t) 1190 1191 // Attempt revoke 1192 req := logical.TestRequest(t, logical.UpdateOperation, "revoke/foobarbaz") 1193 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1194 if err != nil { 1195 t.Fatalf("err: %v", err) 1196 } 1197 if resp != nil { 1198 t.Fatalf("bad: %v", resp) 1199 } 1200 1201 // Attempt revoke with other method 1202 req = logical.TestRequest(t, logical.UpdateOperation, "revoke") 1203 req.Data["lease_id"] = "foobarbaz" 1204 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1205 if err != nil { 1206 t.Fatalf("err: %v", err) 1207 } 1208 if resp != nil { 1209 t.Fatalf("bad: %v", resp) 1210 } 1211} 1212 1213func TestSystemBackend_revokePrefix(t *testing.T) { 1214 core, b, root := testCoreSystemBackend(t) 1215 1216 // Create a key with a lease 1217 req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 1218 req.Data["foo"] = "bar" 1219 req.Data["lease"] = "1h" 1220 req.ClientToken = root 1221 resp, err := core.HandleRequest(namespace.RootContext(nil), req) 1222 if err != nil { 1223 t.Fatalf("err: %v", err) 1224 } 1225 if resp != nil { 1226 t.Fatalf("bad: %#v", resp) 1227 } 1228 1229 // Read a key with a LeaseID 1230 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 1231 req.ClientToken = root 1232 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 1233 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 1234 if err != nil { 1235 t.Fatalf("err: %v", err) 1236 } 1237 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 1238 t.Fatalf("bad: %#v", resp) 1239 } 1240 1241 // Attempt revoke 1242 req2 := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke-prefix/secret/") 1243 resp2, err := b.HandleRequest(namespace.RootContext(nil), req2) 1244 if err != nil { 1245 t.Fatalf("err: %v %#v", err, resp2) 1246 } 1247 if resp2 != nil { 1248 t.Fatalf("bad: %#v", resp) 1249 } 1250 1251 // Attempt renew 1252 req3 := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID) 1253 resp3, err := b.HandleRequest(namespace.RootContext(nil), req3) 1254 if err != logical.ErrInvalidRequest { 1255 t.Fatalf("err: %v", err) 1256 } 1257 if resp3.Data["error"] != "lease not found" { 1258 t.Fatalf("bad: %v", *resp3) 1259 } 1260} 1261 1262func TestSystemBackend_revokePrefix_origUrl(t *testing.T) { 1263 core, b, root := testCoreSystemBackend(t) 1264 1265 // Create a key with a lease 1266 req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo") 1267 req.Data["foo"] = "bar" 1268 req.Data["lease"] = "1h" 1269 req.ClientToken = root 1270 resp, err := core.HandleRequest(namespace.RootContext(nil), req) 1271 if err != nil { 1272 t.Fatalf("err: %v", err) 1273 } 1274 if resp != nil { 1275 t.Fatalf("bad: %#v", resp) 1276 } 1277 1278 // Read a key with a LeaseID 1279 req = logical.TestRequest(t, logical.ReadOperation, "secret/foo") 1280 req.ClientToken = root 1281 req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}}) 1282 resp, err = core.HandleRequest(namespace.RootContext(nil), req) 1283 if err != nil { 1284 t.Fatalf("err: %v", err) 1285 } 1286 if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" { 1287 t.Fatalf("bad: %#v", resp) 1288 } 1289 1290 // Attempt revoke 1291 req2 := logical.TestRequest(t, logical.UpdateOperation, "revoke-prefix/secret/") 1292 resp2, err := b.HandleRequest(namespace.RootContext(nil), req2) 1293 if err != nil { 1294 t.Fatalf("err: %v %#v", err, resp2) 1295 } 1296 if resp2 != nil { 1297 t.Fatalf("bad: %#v", resp) 1298 } 1299 1300 // Attempt renew 1301 req3 := logical.TestRequest(t, logical.UpdateOperation, "renew/"+resp.Secret.LeaseID) 1302 resp3, err := b.HandleRequest(namespace.RootContext(nil), req3) 1303 if err != logical.ErrInvalidRequest { 1304 t.Fatalf("err: %v", err) 1305 } 1306 if resp3.Data["error"] != "lease not found" { 1307 t.Fatalf("bad: %#v", *resp3) 1308 } 1309} 1310 1311func TestSystemBackend_revokePrefixAuth_newUrl(t *testing.T) { 1312 core, _, _ := TestCoreUnsealed(t) 1313 1314 ts := core.tokenStore 1315 bc := &logical.BackendConfig{ 1316 Logger: core.logger, 1317 System: logical.StaticSystemView{ 1318 DefaultLeaseTTLVal: time.Hour * 24, 1319 MaxLeaseTTLVal: time.Hour * 24 * 32, 1320 }, 1321 } 1322 b := NewSystemBackend(core, hclog.New(&hclog.LoggerOptions{})) 1323 err := b.Backend.Setup(namespace.RootContext(nil), bc) 1324 if err != nil { 1325 t.Fatal(err) 1326 } 1327 1328 exp := ts.expiration 1329 1330 te := &logical.TokenEntry{ 1331 ID: "foo", 1332 Path: "auth/github/login/bar", 1333 TTL: time.Hour, 1334 NamespaceID: namespace.RootNamespaceID, 1335 } 1336 testMakeTokenDirectly(t, ts, te) 1337 1338 te, err = ts.Lookup(namespace.RootContext(nil), "foo") 1339 if err != nil { 1340 t.Fatal(err) 1341 } 1342 if te == nil { 1343 t.Fatal("token entry was nil") 1344 } 1345 1346 // Create a new token 1347 auth := &logical.Auth{ 1348 ClientToken: te.ID, 1349 LeaseOptions: logical.LeaseOptions{ 1350 TTL: time.Hour, 1351 }, 1352 } 1353 err = exp.RegisterAuth(namespace.RootContext(nil), te, auth) 1354 if err != nil { 1355 t.Fatalf("err: %v", err) 1356 } 1357 1358 req := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke-prefix/auth/github/") 1359 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1360 if err != nil { 1361 t.Fatalf("err: %v %v", err, resp) 1362 } 1363 if resp != nil { 1364 t.Fatalf("bad: %#v", resp) 1365 } 1366 1367 te, err = ts.Lookup(namespace.RootContext(nil), te.ID) 1368 if err != nil { 1369 t.Fatalf("err: %v", err) 1370 } 1371 if te != nil { 1372 t.Fatalf("bad: %v", te) 1373 } 1374} 1375 1376func TestSystemBackend_revokePrefixAuth_origUrl(t *testing.T) { 1377 core, _, _ := TestCoreUnsealed(t) 1378 ts := core.tokenStore 1379 bc := &logical.BackendConfig{ 1380 Logger: core.logger, 1381 System: logical.StaticSystemView{ 1382 DefaultLeaseTTLVal: time.Hour * 24, 1383 MaxLeaseTTLVal: time.Hour * 24 * 32, 1384 }, 1385 } 1386 b := NewSystemBackend(core, hclog.New(&hclog.LoggerOptions{})) 1387 err := b.Backend.Setup(namespace.RootContext(nil), bc) 1388 if err != nil { 1389 t.Fatal(err) 1390 } 1391 1392 exp := ts.expiration 1393 1394 te := &logical.TokenEntry{ 1395 ID: "foo", 1396 Path: "auth/github/login/bar", 1397 TTL: time.Hour, 1398 NamespaceID: namespace.RootNamespaceID, 1399 } 1400 testMakeTokenDirectly(t, ts, te) 1401 1402 te, err = ts.Lookup(namespace.RootContext(nil), "foo") 1403 if err != nil { 1404 t.Fatal(err) 1405 } 1406 if te == nil { 1407 t.Fatal("token entry was nil") 1408 } 1409 1410 // Create a new token 1411 auth := &logical.Auth{ 1412 ClientToken: te.ID, 1413 LeaseOptions: logical.LeaseOptions{ 1414 TTL: time.Hour, 1415 }, 1416 } 1417 err = exp.RegisterAuth(namespace.RootContext(nil), te, auth) 1418 if err != nil { 1419 t.Fatalf("err: %v", err) 1420 } 1421 1422 req := logical.TestRequest(t, logical.UpdateOperation, "revoke-prefix/auth/github/") 1423 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1424 if err != nil { 1425 t.Fatalf("err: %v %v", err, resp) 1426 } 1427 if resp != nil { 1428 t.Fatalf("bad: %#v", resp) 1429 } 1430 1431 te, err = ts.Lookup(namespace.RootContext(nil), te.ID) 1432 if err != nil { 1433 t.Fatalf("err: %v", err) 1434 } 1435 if te != nil { 1436 t.Fatalf("bad: %v", te) 1437 } 1438} 1439 1440func TestSystemBackend_authTable(t *testing.T) { 1441 b := testSystemBackend(t) 1442 req := logical.TestRequest(t, logical.ReadOperation, "auth") 1443 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1444 if err != nil { 1445 t.Fatalf("err: %v", err) 1446 } 1447 1448 exp := map[string]interface{}{ 1449 "token/": map[string]interface{}{ 1450 "type": "token", 1451 "description": "token based credentials", 1452 "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], 1453 "uuid": resp.Data["token/"].(map[string]interface{})["uuid"], 1454 "config": map[string]interface{}{ 1455 "default_lease_ttl": int64(0), 1456 "max_lease_ttl": int64(0), 1457 "force_no_cache": false, 1458 "token_type": "default-service", 1459 }, 1460 "local": false, 1461 "seal_wrap": false, 1462 "options": map[string]string(nil), 1463 }, 1464 } 1465 if diff := deep.Equal(resp.Data, exp); diff != nil { 1466 t.Fatal(diff) 1467 } 1468} 1469 1470func TestSystemBackend_enableAuth(t *testing.T) { 1471 c, b, _ := testCoreSystemBackend(t) 1472 c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) { 1473 return &NoopBackend{BackendType: logical.TypeCredential}, nil 1474 } 1475 1476 req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo") 1477 req.Data["type"] = "noop" 1478 req.Data["config"] = map[string]interface{}{ 1479 "default_lease_ttl": "35m", 1480 "max_lease_ttl": "45m", 1481 } 1482 req.Data["local"] = true 1483 req.Data["seal_wrap"] = true 1484 1485 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1486 if err != nil { 1487 t.Fatalf("err: %v", err) 1488 } 1489 if resp != nil { 1490 t.Fatalf("bad: %v", resp) 1491 } 1492 1493 req = logical.TestRequest(t, logical.ReadOperation, "auth") 1494 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1495 if err != nil { 1496 t.Fatalf("err: %v", err) 1497 } 1498 if resp == nil { 1499 t.Fatal("resp is nil") 1500 } 1501 1502 exp := map[string]interface{}{ 1503 "foo/": map[string]interface{}{ 1504 "type": "noop", 1505 "description": "", 1506 "accessor": resp.Data["foo/"].(map[string]interface{})["accessor"], 1507 "uuid": resp.Data["foo/"].(map[string]interface{})["uuid"], 1508 "config": map[string]interface{}{ 1509 "default_lease_ttl": int64(2100), 1510 "max_lease_ttl": int64(2700), 1511 "force_no_cache": false, 1512 "token_type": "default-service", 1513 }, 1514 "local": true, 1515 "seal_wrap": true, 1516 "options": map[string]string{}, 1517 }, 1518 "token/": map[string]interface{}{ 1519 "type": "token", 1520 "description": "token based credentials", 1521 "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], 1522 "uuid": resp.Data["token/"].(map[string]interface{})["uuid"], 1523 "config": map[string]interface{}{ 1524 "default_lease_ttl": int64(0), 1525 "max_lease_ttl": int64(0), 1526 "force_no_cache": false, 1527 "token_type": "default-service", 1528 }, 1529 "local": false, 1530 "seal_wrap": false, 1531 "options": map[string]string(nil), 1532 }, 1533 } 1534 if diff := deep.Equal(resp.Data, exp); diff != nil { 1535 t.Fatal(diff) 1536 } 1537} 1538 1539func TestSystemBackend_enableAuth_invalid(t *testing.T) { 1540 b := testSystemBackend(t) 1541 req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo") 1542 req.Data["type"] = "nope" 1543 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1544 if err != logical.ErrInvalidRequest { 1545 t.Fatalf("err: %v", err) 1546 } 1547 if resp.Data["error"] != `plugin not found in the catalog: nope` { 1548 t.Fatalf("bad: %v", resp) 1549 } 1550} 1551 1552func TestSystemBackend_disableAuth(t *testing.T) { 1553 c, b, _ := testCoreSystemBackend(t) 1554 c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) { 1555 return &NoopBackend{}, nil 1556 } 1557 1558 // Register the backend 1559 req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo") 1560 req.Data["type"] = "noop" 1561 b.HandleRequest(namespace.RootContext(nil), req) 1562 1563 // Deregister it 1564 req = logical.TestRequest(t, logical.DeleteOperation, "auth/foo") 1565 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1566 if err != nil { 1567 t.Fatalf("err: %v", err) 1568 } 1569 if resp != nil { 1570 t.Fatalf("bad: %v", resp) 1571 } 1572} 1573 1574func TestSystemBackend_policyList(t *testing.T) { 1575 b := testSystemBackend(t) 1576 req := logical.TestRequest(t, logical.ReadOperation, "policy") 1577 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1578 if err != nil { 1579 t.Fatalf("err: %v", err) 1580 } 1581 1582 exp := map[string]interface{}{ 1583 "keys": []string{"default", "root"}, 1584 "policies": []string{"default", "root"}, 1585 } 1586 if !reflect.DeepEqual(resp.Data, exp) { 1587 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1588 } 1589} 1590 1591func TestSystemBackend_policyCRUD(t *testing.T) { 1592 b := testSystemBackend(t) 1593 1594 // Create the policy 1595 rules := `path "foo/" { policy = "read" }` 1596 req := logical.TestRequest(t, logical.UpdateOperation, "policy/Foo") 1597 req.Data["rules"] = rules 1598 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1599 if err != nil { 1600 t.Fatalf("err: %v %#v", err, resp) 1601 } 1602 if resp != nil && (resp.IsError() || len(resp.Data) > 0) { 1603 t.Fatalf("bad: %#v", resp) 1604 } 1605 1606 // Read the policy 1607 req = logical.TestRequest(t, logical.ReadOperation, "policy/foo") 1608 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1609 if err != nil { 1610 t.Fatalf("err: %v", err) 1611 } 1612 1613 exp := map[string]interface{}{ 1614 "name": "foo", 1615 "rules": rules, 1616 } 1617 if !reflect.DeepEqual(resp.Data, exp) { 1618 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1619 } 1620 1621 // Read, and make sure that case has been normalized 1622 req = logical.TestRequest(t, logical.ReadOperation, "policy/Foo") 1623 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1624 if err != nil { 1625 t.Fatalf("err: %v", err) 1626 } 1627 1628 exp = map[string]interface{}{ 1629 "name": "foo", 1630 "rules": rules, 1631 } 1632 if !reflect.DeepEqual(resp.Data, exp) { 1633 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1634 } 1635 1636 // List the policies 1637 req = logical.TestRequest(t, logical.ReadOperation, "policy") 1638 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1639 if err != nil { 1640 t.Fatalf("err: %v", err) 1641 } 1642 1643 exp = map[string]interface{}{ 1644 "keys": []string{"default", "foo", "root"}, 1645 "policies": []string{"default", "foo", "root"}, 1646 } 1647 if !reflect.DeepEqual(resp.Data, exp) { 1648 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1649 } 1650 1651 // Delete the policy 1652 req = logical.TestRequest(t, logical.DeleteOperation, "policy/foo") 1653 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1654 if err != nil { 1655 t.Fatalf("err: %v", err) 1656 } 1657 if resp != nil { 1658 t.Fatalf("bad: %#v", resp) 1659 } 1660 1661 // Read the policy (deleted) 1662 req = logical.TestRequest(t, logical.ReadOperation, "policy/foo") 1663 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1664 if err != nil { 1665 t.Fatalf("err: %v", err) 1666 } 1667 if resp != nil { 1668 t.Fatalf("bad: %#v", resp) 1669 } 1670 1671 // List the policies (deleted) 1672 req = logical.TestRequest(t, logical.ReadOperation, "policy") 1673 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1674 if err != nil { 1675 t.Fatalf("err: %v", err) 1676 } 1677 1678 exp = map[string]interface{}{ 1679 "keys": []string{"default", "root"}, 1680 "policies": []string{"default", "root"}, 1681 } 1682 if !reflect.DeepEqual(resp.Data, exp) { 1683 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1684 } 1685} 1686 1687func TestSystemBackend_enableAudit(t *testing.T) { 1688 c, b, _ := testCoreSystemBackend(t) 1689 c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) { 1690 return &NoopAudit{ 1691 Config: config, 1692 }, nil 1693 } 1694 1695 req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo") 1696 req.Data["type"] = "noop" 1697 1698 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1699 if err != nil { 1700 t.Fatalf("err: %v", err) 1701 } 1702 if resp != nil { 1703 t.Fatalf("bad: %v", resp) 1704 } 1705} 1706 1707func TestSystemBackend_auditHash(t *testing.T) { 1708 c, b, _ := testCoreSystemBackend(t) 1709 c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) { 1710 view := &logical.InmemStorage{} 1711 view.Put(namespace.RootContext(nil), &logical.StorageEntry{ 1712 Key: "salt", 1713 Value: []byte("foo"), 1714 }) 1715 config.SaltView = view 1716 config.SaltConfig = &salt.Config{ 1717 HMAC: sha256.New, 1718 HMACType: "hmac-sha256", 1719 Location: salt.DefaultLocation, 1720 } 1721 return &NoopAudit{ 1722 Config: config, 1723 }, nil 1724 } 1725 1726 req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo") 1727 req.Data["type"] = "noop" 1728 1729 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1730 if err != nil { 1731 t.Fatalf("err: %v", err) 1732 } 1733 if resp != nil { 1734 t.Fatalf("bad: %v", resp) 1735 } 1736 1737 req = logical.TestRequest(t, logical.UpdateOperation, "audit-hash/foo") 1738 req.Data["input"] = "bar" 1739 1740 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1741 if err != nil { 1742 t.Fatalf("err: %v", err) 1743 } 1744 if resp == nil || resp.Data == nil { 1745 t.Fatalf("response or its data was nil") 1746 } 1747 hash, ok := resp.Data["hash"] 1748 if !ok { 1749 t.Fatalf("did not get hash back in response, response was %#v", resp.Data) 1750 } 1751 if hash.(string) != "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317" { 1752 t.Fatalf("bad hash back: %s", hash.(string)) 1753 } 1754} 1755 1756func TestSystemBackend_enableAudit_invalid(t *testing.T) { 1757 b := testSystemBackend(t) 1758 req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo") 1759 req.Data["type"] = "nope" 1760 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1761 if err != logical.ErrInvalidRequest { 1762 t.Fatalf("err: %v", err) 1763 } 1764 if resp.Data["error"] != `unknown backend type: "nope"` { 1765 t.Fatalf("bad: %v", resp) 1766 } 1767} 1768 1769func TestSystemBackend_auditTable(t *testing.T) { 1770 c, b, _ := testCoreSystemBackend(t) 1771 c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) { 1772 return &NoopAudit{ 1773 Config: config, 1774 }, nil 1775 } 1776 1777 req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo") 1778 req.Data["type"] = "noop" 1779 req.Data["description"] = "testing" 1780 req.Data["options"] = map[string]interface{}{ 1781 "foo": "bar", 1782 } 1783 req.Data["local"] = true 1784 b.HandleRequest(namespace.RootContext(nil), req) 1785 1786 req = logical.TestRequest(t, logical.ReadOperation, "audit") 1787 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1788 if err != nil { 1789 t.Fatalf("err: %v", err) 1790 } 1791 1792 exp := map[string]interface{}{ 1793 "foo/": map[string]interface{}{ 1794 "path": "foo/", 1795 "type": "noop", 1796 "description": "testing", 1797 "options": map[string]string{ 1798 "foo": "bar", 1799 }, 1800 "local": true, 1801 }, 1802 } 1803 if !reflect.DeepEqual(resp.Data, exp) { 1804 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1805 } 1806} 1807 1808func TestSystemBackend_disableAudit(t *testing.T) { 1809 c, b, _ := testCoreSystemBackend(t) 1810 c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) { 1811 return &NoopAudit{ 1812 Config: config, 1813 }, nil 1814 } 1815 1816 req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo") 1817 req.Data["type"] = "noop" 1818 req.Data["description"] = "testing" 1819 req.Data["options"] = map[string]interface{}{ 1820 "foo": "bar", 1821 } 1822 b.HandleRequest(namespace.RootContext(nil), req) 1823 1824 // Deregister it 1825 req = logical.TestRequest(t, logical.DeleteOperation, "audit/foo") 1826 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1827 if err != nil { 1828 t.Fatalf("err: %v", err) 1829 } 1830 if resp != nil { 1831 t.Fatalf("bad: %v", resp) 1832 } 1833} 1834 1835func TestSystemBackend_rawRead_Compressed(t *testing.T) { 1836 b := testSystemBackendRaw(t) 1837 1838 req := logical.TestRequest(t, logical.ReadOperation, "raw/core/mounts") 1839 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1840 if err != nil { 1841 t.Fatalf("err: %v", err) 1842 } 1843 if !strings.HasPrefix(resp.Data["value"].(string), "{\"type\":\"mounts\"") { 1844 t.Fatalf("bad: %v", resp) 1845 } 1846} 1847 1848func TestSystemBackend_rawRead_Protected(t *testing.T) { 1849 b := testSystemBackendRaw(t) 1850 1851 req := logical.TestRequest(t, logical.ReadOperation, "raw/"+keyringPath) 1852 _, err := b.HandleRequest(namespace.RootContext(nil), req) 1853 if err != logical.ErrInvalidRequest { 1854 t.Fatalf("err: %v", err) 1855 } 1856} 1857 1858func TestSystemBackend_rawWrite_Protected(t *testing.T) { 1859 b := testSystemBackendRaw(t) 1860 1861 req := logical.TestRequest(t, logical.UpdateOperation, "raw/"+keyringPath) 1862 _, err := b.HandleRequest(namespace.RootContext(nil), req) 1863 if err != logical.ErrInvalidRequest { 1864 t.Fatalf("err: %v", err) 1865 } 1866} 1867 1868func TestSystemBackend_rawReadWrite(t *testing.T) { 1869 _, b, _ := testCoreSystemBackendRaw(t) 1870 1871 req := logical.TestRequest(t, logical.UpdateOperation, "raw/sys/policy/test") 1872 req.Data["value"] = `path "secret/" { policy = "read" }` 1873 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1874 if err != nil { 1875 t.Fatalf("err: %v", err) 1876 } 1877 if resp != nil { 1878 t.Fatalf("bad: %v", resp) 1879 } 1880 1881 // Read via raw API 1882 req = logical.TestRequest(t, logical.ReadOperation, "raw/sys/policy/test") 1883 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1884 if err != nil { 1885 t.Fatalf("err: %v", err) 1886 } 1887 if !strings.HasPrefix(resp.Data["value"].(string), "path") { 1888 t.Fatalf("bad: %v", resp) 1889 } 1890 1891 // Note: since the upgrade code is gone that upgraded from 0.1, we can't 1892 // simply parse this out directly via GetPolicy, so the test now ends here. 1893} 1894 1895func TestSystemBackend_rawDelete_Protected(t *testing.T) { 1896 b := testSystemBackendRaw(t) 1897 1898 req := logical.TestRequest(t, logical.DeleteOperation, "raw/"+keyringPath) 1899 _, err := b.HandleRequest(namespace.RootContext(nil), req) 1900 if err != logical.ErrInvalidRequest { 1901 t.Fatalf("err: %v", err) 1902 } 1903} 1904 1905func TestSystemBackend_rawDelete(t *testing.T) { 1906 c, b, _ := testCoreSystemBackendRaw(t) 1907 1908 // set the policy! 1909 p := &Policy{ 1910 Name: "test", 1911 Type: PolicyTypeACL, 1912 namespace: namespace.RootNamespace, 1913 } 1914 err := c.policyStore.SetPolicy(namespace.RootContext(nil), p) 1915 if err != nil { 1916 t.Fatalf("err: %v", err) 1917 } 1918 1919 // Delete the policy 1920 req := logical.TestRequest(t, logical.DeleteOperation, "raw/sys/policy/test") 1921 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1922 if err != nil { 1923 t.Fatalf("err: %v", err) 1924 } 1925 if resp != nil { 1926 t.Fatalf("bad: %v", resp) 1927 } 1928 1929 // Policy should be gone 1930 c.policyStore.tokenPoliciesLRU.Purge() 1931 out, err := c.policyStore.GetPolicy(namespace.RootContext(nil), "test", PolicyTypeToken) 1932 if err != nil { 1933 t.Fatalf("err: %v", err) 1934 } 1935 if out != nil { 1936 t.Fatalf("policy should be gone") 1937 } 1938} 1939 1940func TestSystemBackend_keyStatus(t *testing.T) { 1941 b := testSystemBackend(t) 1942 req := logical.TestRequest(t, logical.ReadOperation, "key-status") 1943 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1944 if err != nil { 1945 t.Fatalf("err: %v", err) 1946 } 1947 1948 exp := map[string]interface{}{ 1949 "term": 1, 1950 } 1951 delete(resp.Data, "install_time") 1952 if !reflect.DeepEqual(resp.Data, exp) { 1953 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1954 } 1955} 1956 1957func TestSystemBackend_rotate(t *testing.T) { 1958 b := testSystemBackend(t) 1959 1960 req := logical.TestRequest(t, logical.UpdateOperation, "rotate") 1961 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 1962 if err != nil { 1963 t.Fatalf("err: %v", err) 1964 } 1965 if resp != nil { 1966 t.Fatalf("bad: %v", resp) 1967 } 1968 1969 req = logical.TestRequest(t, logical.ReadOperation, "key-status") 1970 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 1971 if err != nil { 1972 t.Fatalf("err: %v", err) 1973 } 1974 1975 exp := map[string]interface{}{ 1976 "term": 2, 1977 } 1978 delete(resp.Data, "install_time") 1979 if !reflect.DeepEqual(resp.Data, exp) { 1980 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 1981 } 1982} 1983 1984func testSystemBackend(t *testing.T) logical.Backend { 1985 c, _, _ := TestCoreUnsealed(t) 1986 return c.systemBackend 1987} 1988 1989func testSystemBackendRaw(t *testing.T) logical.Backend { 1990 c, _, _ := TestCoreUnsealedRaw(t) 1991 return c.systemBackend 1992} 1993 1994func testCoreSystemBackend(t *testing.T) (*Core, logical.Backend, string) { 1995 c, _, root := TestCoreUnsealed(t) 1996 return c, c.systemBackend, root 1997} 1998 1999func testCoreSystemBackendRaw(t *testing.T) (*Core, logical.Backend, string) { 2000 c, _, root := TestCoreUnsealedRaw(t) 2001 return c, c.systemBackend, root 2002} 2003 2004func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) { 2005 c, b, _ := testCoreSystemBackend(t) 2006 // Bootstrap the pluginCatalog 2007 sym, err := filepath.EvalSymlinks(os.TempDir()) 2008 if err != nil { 2009 t.Fatalf("error: %v", err) 2010 } 2011 c.pluginCatalog.directory = sym 2012 2013 req := logical.TestRequest(t, logical.ListOperation, "plugins/catalog/database") 2014 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 2015 if err != nil { 2016 t.Fatalf("err: %v", err) 2017 } 2018 2019 if len(resp.Data["keys"].([]string)) != len(c.builtinRegistry.Keys(consts.PluginTypeDatabase)) { 2020 t.Fatalf("Wrong number of plugins, got %d, expected %d", len(resp.Data["keys"].([]string)), len(builtinplugins.Registry.Keys(consts.PluginTypeDatabase))) 2021 } 2022 2023 req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/mysql-database-plugin") 2024 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2025 if err != nil { 2026 t.Fatalf("err: %v", err) 2027 } 2028 2029 actualRespData := resp.Data 2030 expectedRespData := map[string]interface{}{ 2031 "name": "mysql-database-plugin", 2032 "command": "", 2033 "args": []string(nil), 2034 "sha256": "", 2035 "builtin": true, 2036 } 2037 if !reflect.DeepEqual(actualRespData, expectedRespData) { 2038 t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actualRespData, expectedRespData) 2039 } 2040 2041 // Set a plugin 2042 file, err := ioutil.TempFile(os.TempDir(), "temp") 2043 if err != nil { 2044 t.Fatal(err) 2045 } 2046 defer file.Close() 2047 2048 // Check we can only specify args in one of command or args. 2049 command := fmt.Sprintf("%s --test", filepath.Base(file.Name())) 2050 req = logical.TestRequest(t, logical.UpdateOperation, "plugins/catalog/database/test-plugin") 2051 req.Data["args"] = []string{"--foo"} 2052 req.Data["sha_256"] = hex.EncodeToString([]byte{'1'}) 2053 req.Data["command"] = command 2054 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2055 if err != nil { 2056 t.Fatalf("err: %v", err) 2057 } 2058 if resp.Error().Error() != "must not specify args in command and args field" { 2059 t.Fatalf("err: %v", resp.Error()) 2060 } 2061 2062 delete(req.Data, "args") 2063 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2064 if err != nil || resp.Error() != nil { 2065 t.Fatalf("err: %v %v", err, resp.Error()) 2066 } 2067 2068 req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/test-plugin") 2069 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2070 if err != nil { 2071 t.Fatalf("err: %v", err) 2072 } 2073 2074 actual := resp.Data 2075 expected := map[string]interface{}{ 2076 "name": "test-plugin", 2077 "command": filepath.Base(file.Name()), 2078 "args": []string{"--test"}, 2079 "sha256": "31", 2080 "builtin": false, 2081 } 2082 if !reflect.DeepEqual(actual, expected) { 2083 t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actual, expected) 2084 } 2085 2086 // Delete plugin 2087 req = logical.TestRequest(t, logical.DeleteOperation, "plugins/catalog/database/test-plugin") 2088 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2089 if err != nil { 2090 t.Fatalf("err: %v", err) 2091 } 2092 2093 req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/test-plugin") 2094 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2095 if resp != nil || err != nil { 2096 t.Fatalf("expected nil response, plugin not deleted correctly got resp: %v, err: %v", resp, err) 2097 } 2098} 2099 2100func TestSystemBackend_ToolsHash(t *testing.T) { 2101 b := testSystemBackend(t) 2102 req := logical.TestRequest(t, logical.UpdateOperation, "tools/hash") 2103 req.Data = map[string]interface{}{ 2104 "input": "dGhlIHF1aWNrIGJyb3duIGZveA==", 2105 } 2106 _, err := b.HandleRequest(namespace.RootContext(nil), req) 2107 if err != nil { 2108 t.Fatalf("err: %v", err) 2109 } 2110 2111 doRequest := func(req *logical.Request, errExpected bool, expected string) { 2112 t.Helper() 2113 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 2114 if err != nil && !errExpected { 2115 t.Fatal(err) 2116 } 2117 if resp == nil { 2118 t.Fatal("expected non-nil response") 2119 } 2120 if errExpected { 2121 if !resp.IsError() { 2122 t.Fatalf("bad: got error response: %#v", *resp) 2123 } 2124 return 2125 } 2126 if resp.IsError() { 2127 t.Fatalf("bad: got error response: %#v", *resp) 2128 } 2129 sum, ok := resp.Data["sum"] 2130 if !ok { 2131 t.Fatal("no sum key found in returned data") 2132 } 2133 if sum.(string) != expected { 2134 t.Fatal("mismatched hashes") 2135 } 2136 } 2137 2138 // Test defaults -- sha2-256 2139 doRequest(req, false, "9ecb36561341d18eb65484e833efea61edc74b84cf5e6ae1b81c63533e25fc8f") 2140 2141 // Test algorithm selection in the path 2142 req.Path = "tools/hash/sha2-224" 2143 doRequest(req, false, "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865") 2144 2145 // Reset and test algorithm selection in the data 2146 req.Path = "tools/hash" 2147 req.Data["algorithm"] = "sha2-224" 2148 doRequest(req, false, "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865") 2149 2150 req.Data["algorithm"] = "sha2-384" 2151 doRequest(req, false, "15af9ec8be783f25c583626e9491dbf129dd6dd620466fdf05b3a1d0bb8381d30f4d3ec29f923ff1e09a0f6b337365a6") 2152 2153 req.Data["algorithm"] = "sha2-512" 2154 doRequest(req, false, "d9d380f29b97ad6a1d92e987d83fa5a02653301e1006dd2bcd51afa59a9147e9caedaf89521abc0f0b682adcd47fb512b8343c834a32f326fe9bef00542ce887") 2155 2156 // Test returning as base64 2157 req.Data["format"] = "base64" 2158 doRequest(req, false, "2dOA8puXrWodkumH2D+loCZTMB4QBt0rzVGvpZqRR+nK7a+JUhq8DwtoKtzUf7USuDQ8g0oy8yb+m+8AVCzohw==") 2159 2160 // Test bad input/format/algorithm 2161 req.Data["format"] = "base92" 2162 doRequest(req, true, "") 2163 2164 req.Data["format"] = "hex" 2165 req.Data["algorithm"] = "foobar" 2166 doRequest(req, true, "") 2167 2168 req.Data["algorithm"] = "sha2-256" 2169 req.Data["input"] = "foobar" 2170 doRequest(req, true, "") 2171} 2172 2173func TestSystemBackend_ToolsRandom(t *testing.T) { 2174 b := testSystemBackend(t) 2175 req := logical.TestRequest(t, logical.UpdateOperation, "tools/random") 2176 2177 _, err := b.HandleRequest(namespace.RootContext(nil), req) 2178 if err != nil { 2179 t.Fatalf("err: %v", err) 2180 } 2181 2182 doRequest := func(req *logical.Request, errExpected bool, format string, numBytes int) { 2183 t.Helper() 2184 getResponse := func() []byte { 2185 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 2186 if err != nil && !errExpected { 2187 t.Fatal(err) 2188 } 2189 if resp == nil { 2190 t.Fatal("expected non-nil response") 2191 } 2192 if errExpected { 2193 if !resp.IsError() { 2194 t.Fatalf("bad: got error response: %#v", *resp) 2195 } 2196 return nil 2197 } 2198 if resp.IsError() { 2199 t.Fatalf("bad: got error response: %#v", *resp) 2200 } 2201 if _, ok := resp.Data["random_bytes"]; !ok { 2202 t.Fatal("no random_bytes found in response") 2203 } 2204 2205 outputStr := resp.Data["random_bytes"].(string) 2206 var outputBytes []byte 2207 switch format { 2208 case "base64": 2209 outputBytes, err = base64.StdEncoding.DecodeString(outputStr) 2210 case "hex": 2211 outputBytes, err = hex.DecodeString(outputStr) 2212 default: 2213 t.Fatal("unknown format") 2214 } 2215 if err != nil { 2216 t.Fatal(err) 2217 } 2218 2219 return outputBytes 2220 } 2221 2222 rand1 := getResponse() 2223 // Expected error 2224 if rand1 == nil { 2225 return 2226 } 2227 rand2 := getResponse() 2228 if len(rand1) != numBytes || len(rand2) != numBytes { 2229 t.Fatal("length of output random bytes not what is expected") 2230 } 2231 if reflect.DeepEqual(rand1, rand2) { 2232 t.Fatal("found identical ouputs") 2233 } 2234 } 2235 2236 // Test defaults 2237 doRequest(req, false, "base64", 32) 2238 2239 // Test size selection in the path 2240 req.Path = "tools/random/24" 2241 req.Data["format"] = "hex" 2242 doRequest(req, false, "hex", 24) 2243 2244 // Test bad input/format 2245 req.Path = "tools/random" 2246 req.Data["format"] = "base92" 2247 doRequest(req, true, "", 0) 2248 2249 req.Data["format"] = "hex" 2250 req.Data["bytes"] = -1 2251 doRequest(req, true, "", 0) 2252 2253 req.Data["format"] = "hex" 2254 req.Data["bytes"] = maxBytes + 1 2255 doRequest(req, true, "", 0) 2256 2257} 2258 2259func TestSystemBackend_InternalUIMounts(t *testing.T) { 2260 _, b, rootToken := testCoreSystemBackend(t) 2261 2262 // Ensure no entries are in the endpoint as a starting point 2263 req := logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts") 2264 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 2265 if err != nil { 2266 t.Fatalf("err: %v", err) 2267 } 2268 2269 exp := map[string]interface{}{ 2270 "secret": map[string]interface{}{}, 2271 "auth": map[string]interface{}{}, 2272 } 2273 if !reflect.DeepEqual(resp.Data, exp) { 2274 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 2275 } 2276 2277 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts") 2278 req.ClientToken = rootToken 2279 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2280 if err != nil { 2281 t.Fatalf("err: %v", err) 2282 } 2283 2284 exp = map[string]interface{}{ 2285 "secret": map[string]interface{}{ 2286 "secret/": map[string]interface{}{ 2287 "type": "kv", 2288 "description": "key/value secret storage", 2289 "accessor": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["accessor"], 2290 "uuid": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["uuid"], 2291 "config": map[string]interface{}{ 2292 "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 2293 "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 2294 "force_no_cache": false, 2295 }, 2296 "local": false, 2297 "seal_wrap": false, 2298 "options": map[string]string{ 2299 "version": "1", 2300 }, 2301 }, 2302 "sys/": map[string]interface{}{ 2303 "type": "system", 2304 "description": "system endpoints used for control, policy and debugging", 2305 "accessor": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["accessor"], 2306 "uuid": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["uuid"], 2307 "config": map[string]interface{}{ 2308 "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 2309 "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 2310 "force_no_cache": false, 2311 "passthrough_request_headers": []string{"Accept"}, 2312 }, 2313 "local": false, 2314 "seal_wrap": false, 2315 "options": map[string]string(nil), 2316 }, 2317 "cubbyhole/": map[string]interface{}{ 2318 "description": "per-token private secret storage", 2319 "type": "cubbyhole", 2320 "accessor": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["accessor"], 2321 "uuid": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["uuid"], 2322 "config": map[string]interface{}{ 2323 "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 2324 "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 2325 "force_no_cache": false, 2326 }, 2327 "local": true, 2328 "seal_wrap": false, 2329 "options": map[string]string(nil), 2330 }, 2331 "identity/": map[string]interface{}{ 2332 "description": "identity store", 2333 "type": "identity", 2334 "accessor": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["accessor"], 2335 "uuid": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["uuid"], 2336 "config": map[string]interface{}{ 2337 "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), 2338 "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), 2339 "force_no_cache": false, 2340 }, 2341 "local": false, 2342 "seal_wrap": false, 2343 "options": map[string]string(nil), 2344 }, 2345 }, 2346 "auth": map[string]interface{}{ 2347 "token/": map[string]interface{}{ 2348 "options": map[string]string(nil), 2349 "config": map[string]interface{}{ 2350 "default_lease_ttl": int64(0), 2351 "max_lease_ttl": int64(0), 2352 "force_no_cache": false, 2353 "token_type": "default-service", 2354 }, 2355 "type": "token", 2356 "description": "token based credentials", 2357 "accessor": resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["accessor"], 2358 "uuid": resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["uuid"], 2359 "local": false, 2360 "seal_wrap": false, 2361 }, 2362 }, 2363 } 2364 if diff := deep.Equal(resp.Data, exp); diff != nil { 2365 t.Fatal(diff) 2366 } 2367 2368 // Mount-tune an auth mount 2369 req = logical.TestRequest(t, logical.UpdateOperation, "auth/token/tune") 2370 req.Data["listing_visibility"] = "unauth" 2371 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2372 if resp.IsError() || err != nil { 2373 t.Fatalf("resp.Error: %v, err:%v", resp.Error(), err) 2374 } 2375 2376 // Mount-tune a secret mount 2377 req = logical.TestRequest(t, logical.UpdateOperation, "mounts/secret/tune") 2378 req.Data["listing_visibility"] = "unauth" 2379 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2380 if resp.IsError() || err != nil { 2381 t.Fatalf("resp.Error: %v, err:%v", resp.Error(), err) 2382 } 2383 2384 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts") 2385 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2386 if err != nil { 2387 t.Fatalf("err: %v", err) 2388 } 2389 2390 exp = map[string]interface{}{ 2391 "secret": map[string]interface{}{ 2392 "secret/": map[string]interface{}{ 2393 "type": "kv", 2394 "description": "key/value secret storage", 2395 "options": map[string]string{"version": "1"}, 2396 }, 2397 }, 2398 "auth": map[string]interface{}{ 2399 "token/": map[string]interface{}{ 2400 "type": "token", 2401 "description": "token based credentials", 2402 "options": map[string]string(nil), 2403 }, 2404 }, 2405 } 2406 if !reflect.DeepEqual(resp.Data, exp) { 2407 t.Fatalf("got: %#v expect: %#v", resp.Data, exp) 2408 } 2409} 2410 2411func TestSystemBackend_InternalUIMount(t *testing.T) { 2412 core, b, rootToken := testCoreSystemBackend(t) 2413 2414 req := logical.TestRequest(t, logical.UpdateOperation, "policy/secret") 2415 req.ClientToken = rootToken 2416 req.Data = map[string]interface{}{ 2417 "rules": `path "secret/foo/*" { 2418 capabilities = ["create", "read", "update", "delete", "list"] 2419}`, 2420 } 2421 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 2422 if err != nil || (resp != nil && resp.IsError()) { 2423 t.Fatalf("Bad %#v %#v", err, resp) 2424 } 2425 2426 req = logical.TestRequest(t, logical.UpdateOperation, "mounts/kv") 2427 req.ClientToken = rootToken 2428 req.Data = map[string]interface{}{ 2429 "type": "kv", 2430 } 2431 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2432 if err != nil || (resp != nil && resp.IsError()) { 2433 t.Fatalf("Bad %#v %#v", err, resp) 2434 } 2435 2436 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv/bar") 2437 req.ClientToken = rootToken 2438 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2439 if err != nil || (resp != nil && resp.IsError()) { 2440 t.Fatalf("Bad %#v %#v", err, resp) 2441 } 2442 if resp.Data["type"] != "kv" { 2443 t.Fatalf("Bad Response: %#v", resp) 2444 } 2445 2446 testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"secret"}) 2447 2448 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv") 2449 req.ClientToken = "tokenid" 2450 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2451 if err != logical.ErrPermissionDenied { 2452 t.Fatal("expected permission denied error") 2453 } 2454 2455 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/secret") 2456 req.ClientToken = "tokenid" 2457 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2458 if err != nil || (resp != nil && resp.IsError()) { 2459 t.Fatalf("Bad %#v %#v", err, resp) 2460 } 2461 if resp.Data["type"] != "kv" { 2462 t.Fatalf("Bad Response: %#v", resp) 2463 } 2464 2465 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/sys") 2466 req.ClientToken = "tokenid" 2467 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2468 if err != nil || (resp != nil && resp.IsError()) { 2469 t.Fatalf("Bad %#v %#v", err, resp) 2470 } 2471 if resp.Data["type"] != "system" { 2472 t.Fatalf("Bad Response: %#v", resp) 2473 } 2474 2475 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/non-existent") 2476 req.ClientToken = "tokenid" 2477 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2478 if err != logical.ErrPermissionDenied { 2479 t.Fatal("expected permission denied error") 2480 } 2481} 2482 2483func TestSystemBackend_OpenAPI(t *testing.T) { 2484 _, b, rootToken := testCoreSystemBackend(t) 2485 var oapi map[string]interface{} 2486 2487 // Ensure no paths are reported if there is no token 2488 req := logical.TestRequest(t, logical.ReadOperation, "internal/specs/openapi") 2489 resp, err := b.HandleRequest(namespace.RootContext(nil), req) 2490 if err != nil { 2491 t.Fatalf("err: %v", err) 2492 } 2493 2494 body := resp.Data["http_raw_body"].([]byte) 2495 err = jsonutil.DecodeJSON(body, &oapi) 2496 if err != nil { 2497 t.Fatalf("err: %v", err) 2498 } 2499 exp := map[string]interface{}{ 2500 "openapi": framework.OASVersion, 2501 "info": map[string]interface{}{ 2502 "title": "HashiCorp Vault API", 2503 "description": "HTTP API that gives you full access to Vault. All API routes are prefixed with `/v1/`.", 2504 "version": version.GetVersion().Version, 2505 "license": map[string]interface{}{ 2506 "name": "Mozilla Public License 2.0", 2507 "url": "https://www.mozilla.org/en-US/MPL/2.0", 2508 }, 2509 }, 2510 "paths": map[string]interface{}{}, 2511 } 2512 2513 if diff := deep.Equal(oapi, exp); diff != nil { 2514 t.Fatal(diff) 2515 } 2516 2517 // Check that default paths are present with a root token 2518 req = logical.TestRequest(t, logical.ReadOperation, "internal/specs/openapi") 2519 req.ClientToken = rootToken 2520 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2521 if err != nil { 2522 t.Fatalf("err: %v", err) 2523 } 2524 2525 body = resp.Data["http_raw_body"].([]byte) 2526 err = jsonutil.DecodeJSON(body, &oapi) 2527 if err != nil { 2528 t.Fatalf("err: %v", err) 2529 } 2530 2531 doc, err := framework.NewOASDocumentFromMap(oapi) 2532 if err != nil { 2533 t.Fatal(err) 2534 } 2535 2536 pathSamples := []struct { 2537 path string 2538 tag string 2539 }{ 2540 {"/auth/token/lookup", "auth"}, 2541 {"/cubbyhole/{path}", "secrets"}, 2542 {"/identity/group/id", "identity"}, 2543 {"/secret/.*", "secrets"}, // TODO update after kv repo update 2544 {"/sys/policy", "system"}, 2545 } 2546 2547 for _, path := range pathSamples { 2548 if doc.Paths[path.path] == nil { 2549 t.Fatalf("didn't find expected path '%s'.", path) 2550 } 2551 tag := doc.Paths[path.path].Get.Tags[0] 2552 if tag != path.tag { 2553 t.Fatalf("path: %s; expected tag: %s, actual: %s", path.path, tag, path.tag) 2554 } 2555 } 2556 2557 // Simple sanity check of response size (which is much larger than most 2558 // Vault responses), mainly to catch mass omission of expected path data. 2559 minLen := 70000 2560 if len(body) < minLen { 2561 t.Fatalf("response size too small; expected: min %d, actual: %d", minLen, len(body)) 2562 } 2563 2564 // Test path-help response 2565 req = logical.TestRequest(t, logical.HelpOperation, "rotate") 2566 req.ClientToken = rootToken 2567 resp, err = b.HandleRequest(namespace.RootContext(nil), req) 2568 if err != nil { 2569 t.Fatalf("err: %v", err) 2570 } 2571 2572 doc = resp.Data["openapi"].(*framework.OASDocument) 2573 if len(doc.Paths) != 1 { 2574 t.Fatalf("expected 1 path, actual: %d", len(doc.Paths)) 2575 } 2576 2577 if doc.Paths["/rotate"] == nil { 2578 t.Fatalf("expected to find path '/rotate'") 2579 } 2580} 2581 2582func TestSystemBackend_PathWildcardPreflight(t *testing.T) { 2583 core, b, _ := testCoreSystemBackend(t) 2584 2585 ctx := namespace.RootContext(nil) 2586 2587 // Add another mount 2588 me := &MountEntry{ 2589 Table: mountTableType, 2590 Path: sanitizeMountPath("kv-v1"), 2591 Type: "kv", 2592 Options: map[string]string{"version": "1"}, 2593 } 2594 if err := core.mount(ctx, me); err != nil { 2595 t.Fatal(err) 2596 } 2597 2598 // Create the policy, designed to fail 2599 rules := `path "foo" { capabilities = ["read"] }` 2600 req := logical.TestRequest(t, logical.UpdateOperation, "policy/foo") 2601 req.Data["rules"] = rules 2602 resp, err := b.HandleRequest(ctx, req) 2603 if err != nil { 2604 t.Fatalf("err: %v %#v", err, resp) 2605 } 2606 if resp != nil && (resp.IsError() || len(resp.Data) > 0) { 2607 t.Fatalf("bad: %#v", resp) 2608 } 2609 2610 if err := core.identityStore.upsertEntity(ctx, &identity.Entity{ 2611 ID: "abcd", 2612 Name: "abcd", 2613 BucketKey: "abcd", 2614 }, nil, false); err != nil { 2615 t.Fatal(err) 2616 } 2617 2618 te := &logical.TokenEntry{ 2619 TTL: 300 * time.Second, 2620 EntityID: "abcd", 2621 Policies: []string{"default", "foo"}, 2622 NamespaceID: namespace.RootNamespaceID, 2623 } 2624 if err := core.tokenStore.create(ctx, te); err != nil { 2625 t.Fatal(err) 2626 } 2627 t.Logf("token id: %s", te.ID) 2628 2629 if err := core.expiration.RegisterAuth(ctx, te, &logical.Auth{ 2630 LeaseOptions: logical.LeaseOptions{ 2631 TTL: te.TTL, 2632 }, 2633 ClientToken: te.ID, 2634 Accessor: te.Accessor, 2635 Orphan: true, 2636 }); err != nil { 2637 t.Fatal(err) 2638 } 2639 2640 // Check the mount access func 2641 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv-v1/baz") 2642 req.ClientToken = te.ID 2643 resp, err = b.HandleRequest(ctx, req) 2644 if err == nil || !strings.Contains(err.Error(), "permission denied") { 2645 t.Fatalf("expected 403, got err: %v", err) 2646 } 2647 2648 // Modify policy to pass 2649 rules = `path "kv-v1/+" { capabilities = ["read"] }` 2650 req = logical.TestRequest(t, logical.UpdateOperation, "policy/foo") 2651 req.Data["rules"] = rules 2652 resp, err = b.HandleRequest(ctx, req) 2653 if err != nil { 2654 t.Fatalf("err: %v %#v", err, resp) 2655 } 2656 if resp != nil && (resp.IsError() || len(resp.Data) > 0) { 2657 t.Fatalf("bad: %#v", resp) 2658 } 2659 2660 // Check the mount access func again 2661 req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv-v1/baz") 2662 req.ClientToken = te.ID 2663 resp, err = b.HandleRequest(ctx, req) 2664 if err != nil { 2665 t.Fatalf("err: %v", err) 2666 } 2667} 2668