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